From 2795d8e2029ceeacbc521a3b913c3acb0147498e Mon Sep 17 00:00:00 2001 From: WindyMadman Date: Fri, 17 Nov 2023 19:47:45 +0800 Subject: [PATCH] Sync Repo Tag v23.6.2 and b7bdf899f9 --- .editorconfig | 28 + .gitattributes | 22 + .github/FUNDING.yml | 12 + .github/ISSUE_TEMPLATE/bug_report.yml | 96 + .github/ISSUE_TEMPLATE/config.yml | 8 + .github/ISSUE_TEMPLATE/feature_request.yml | 79 + .github/ISSUE_TEMPLATE/server_request.yml | 57 + .github/dependabot.yml | 8 + .github/labeler.yml | 160 ++ .github/pull_request_template.md | 35 + .github/workflows/add-to-project.yml | 17 + .github/workflows/details-check.yml | 85 + .../workflows/detals-check-generate-matrix.sh | 25 + .github/workflows/git-sync.yml | 26 + .github/workflows/labeler.yml | 30 + .github/workflows/lock.yml | 25 + .github/workflows/potential-duplicates.yml | 22 + .../serverlist-validate-game-icons.sh | 40 + .github/workflows/serverlist-validate.sh | 38 + .github/workflows/serverlist-validate.yml | 17 + .github/workflows/trigger-docker-build.yml | 31 + .github/workflows/update-check.yml | 48 + ...update-copyright-years-in-license-file.yml | 24 + .github/workflows/version-check.sh | 15 + .github/workflows/version-check.yml | 16 + .gitignore | 2 + .prettierrc | 3 + .vscode/extensions.json | 10 + CODE_OF_CONDUCT.md | 132 + CONTRIBUTING.md | 226 ++ LICENSE.md | 21 + README.md | 56 + .../config-lgsm/acserver/_default.cfg | 182 ++ .../config-lgsm/ahl2server/_default.cfg | 190 ++ .../config-lgsm/ahlserver/_default.cfg | 186 ++ .../config-lgsm/arkserver/_default.cfg | 188 ++ .../config-lgsm/arma3server/_default.cfg | 204 ++ .../config-lgsm/armarserver/_default.cfg | 185 ++ .../config-lgsm/atsserver/_default.cfg | 177 ++ .../config-lgsm/avserver/_default.cfg | 180 ++ .../config-lgsm/bb2server/_default.cfg | 191 ++ .../config-lgsm/bbserver/_default.cfg | 186 ++ .../config-lgsm/bdserver/_default.cfg | 185 ++ .../config-lgsm/bf1942server/_default.cfg | 168 ++ .../config-lgsm/bfvserver/_default.cfg | 168 ++ .../config-lgsm/bmdmserver/_default.cfg | 191 ++ .../config-lgsm/boserver/_default.cfg | 183 ++ .../config-lgsm/bsserver/_default.cfg | 195 ++ .../config-lgsm/btlserver/_default.cfg | 183 ++ .../config-lgsm/btserver/_default.cfg | 178 ++ .../config-lgsm/ccserver/_default.cfg | 186 ++ .../config-lgsm/cdserver/_default.cfg | 178 ++ .../config-lgsm/ckserver/_default.cfg | 185 ++ .../config-lgsm/cmwserver/_default.cfg | 186 ++ .../config-lgsm/cod2server/_default.cfg | 171 ++ .../config-lgsm/cod4server/_default.cfg | 171 ++ .../config-lgsm/codserver/_default.cfg | 171 ++ .../config-lgsm/coduoserver/_default.cfg | 171 ++ .../config-lgsm/codwawserver/_default.cfg | 171 ++ .../config-lgsm/colserver/_default.cfg | 181 ++ .../config-lgsm/common-template.cfg | 5 + .../config-lgsm/cs2server/_default.cfg | 213 ++ .../config-lgsm/csczserver/_default.cfg | 186 ++ .../config-lgsm/csgoserver/_default.cfg | 222 ++ .../config-lgsm/csserver/_default.cfg | 186 ++ .../config-lgsm/cssserver/_default.cfg | 191 ++ .../config-lgsm/ctserver/_default.cfg | 176 ++ .../config-lgsm/dabserver/_default.cfg | 186 ++ .../config-lgsm/dayzserver/_default.cfg | 196 ++ .../config-lgsm/dmcserver/_default.cfg | 186 ++ .../config-lgsm/dodrserver/_default.cfg | 184 ++ .../config-lgsm/dodserver/_default.cfg | 186 ++ .../config-lgsm/dodsserver/_default.cfg | 186 ++ .../config-lgsm/doiserver/_default.cfg | 187 ++ .../config-lgsm/dstserver/_default.cfg | 192 ++ .../config-lgsm/dysserver/_default.cfg | 191 ++ .../config-lgsm/ecoserver/_default.cfg | 179 ++ .../config-lgsm/emserver/_default.cfg | 191 ++ .../config-lgsm/etlserver/_default.cfg | 165 ++ .../config-lgsm/ets2server/_default.cfg | 177 ++ .../config-lgsm/fctrserver/_default.cfg | 175 ++ .../config-lgsm/fofserver/_default.cfg | 186 ++ .../config-lgsm/gmodserver/_default.cfg | 199 ++ .../config-lgsm/hcuserver/_default.cfg | 193 ++ .../config-lgsm/hl2dmserver/_default.cfg | 186 ++ .../config-lgsm/hldmserver/_default.cfg | 185 ++ .../config-lgsm/hldmsserver/_default.cfg | 186 ++ .../config-lgsm/hwserver/_default.cfg | 194 ++ .../config-lgsm/insserver/_default.cfg | 192 ++ .../config-lgsm/inssserver/_default.cfg | 192 ++ .../config-lgsm/instance-template.cfg | 5 + .../config-lgsm/iosserver/_default.cfg | 186 ++ .../config-lgsm/jc2server/_default.cfg | 178 ++ .../config-lgsm/jc3server/_default.cfg | 177 ++ .../config-lgsm/jk2server/_default.cfg | 187 ++ .../config-lgsm/kf2server/_default.cfg | 184 ++ .../config-lgsm/kfserver/_default.cfg | 193 ++ .../config-lgsm/l4d2server/_default.cfg | 185 ++ .../config-lgsm/l4dserver/_default.cfg | 185 ++ .../config-lgsm/mcbserver/_default.cfg | 171 ++ .../config-lgsm/mcserver/_default.cfg | 178 ++ .../config-lgsm/mhserver/_default.cfg | 186 ++ .../config-lgsm/mohaaserver/_default.cfg | 170 ++ .../config-lgsm/momserver/_default.cfg | 183 ++ .../config-lgsm/mtaserver/_default.cfg | 169 ++ .../config-lgsm/ndserver/_default.cfg | 186 ++ .../config-lgsm/necserver/_default.cfg | 181 ++ .../config-lgsm/nmrihserver/_default.cfg | 191 ++ .../config-lgsm/ns2cserver/_default.cfg | 191 ++ .../config-lgsm/ns2server/_default.cfg | 191 ++ .../config-lgsm/nsserver/_default.cfg | 186 ++ .../config-lgsm/ohdserver/_default.cfg | 185 ++ .../config-lgsm/onsetserver/_default.cfg | 178 ++ .../config-lgsm/opforserver/_default.cfg | 186 ++ .../config-lgsm/pc2server/_default.cfg | 182 ++ .../config-lgsm/pcserver/_default.cfg | 178 ++ .../config-lgsm/pmcserver/_default.cfg | 176 ++ .../config-lgsm/psserver/_default.cfg | 188 ++ .../config-lgsm/pvkiiserver/_default.cfg | 186 ++ .../config-lgsm/pvrserver/_default.cfg | 186 ++ .../config-lgsm/pzserver/_default.cfg | 182 ++ .../config-lgsm/q2server/_default.cfg | 170 ++ .../config-lgsm/q3server/_default.cfg | 170 ++ .../config-lgsm/qlserver/_default.cfg | 179 ++ .../config-lgsm/qwserver/_default.cfg | 169 ++ .../config-lgsm/ricochetserver/_default.cfg | 186 ++ .../config-lgsm/roserver/_default.cfg | 189 ++ .../config-lgsm/rtcwserver/_default.cfg | 170 ++ .../config-lgsm/rustserver/_default.cfg | 199 ++ .../config-lgsm/rwserver/_default.cfg | 178 ++ .../config-lgsm/sampserver/_default.cfg | 169 ++ .../config-lgsm/sbotsserver/_default.cfg | 179 ++ .../config-lgsm/sbserver/_default.cfg | 185 ++ .../config-lgsm/scpslserver/_default.cfg | 183 ++ .../config-lgsm/scpslsmserver/_default.cfg | 183 ++ .../config-lgsm/sdtdserver/_default.cfg | 183 ++ .../config-lgsm/secrets-common-template.cfg | 5 + .../config-lgsm/secrets-instance-template.cfg | 5 + .../config-lgsm/sfcserver/_default.cfg | 186 ++ .../config-lgsm/sfserver/_default.cfg | 184 ++ .../config-lgsm/sof2server/_default.cfg | 170 ++ .../config-lgsm/solserver/_default.cfg | 182 ++ .../config-lgsm/squadserver/_default.cfg | 184 ++ .../config-lgsm/stnserver/_default.cfg | 184 ++ .../config-lgsm/stserver/_default.cfg | 182 ++ .../config-lgsm/svenserver/_default.cfg | 185 ++ .../config-lgsm/terrariaserver/_default.cfg | 185 ++ .../config-lgsm/tf2server/_default.cfg | 191 ++ .../config-lgsm/tfcserver/_default.cfg | 186 ++ .../config-lgsm/tfserver/_default.cfg | 198 ++ .../config-lgsm/tiserver/_default.cfg | 183 ++ .../config-lgsm/ts3server/_default.cfg | 169 ++ .../config-lgsm/tsserver/_default.cfg | 186 ++ .../config-lgsm/tuserver/_default.cfg | 188 ++ .../config-lgsm/twserver/_default.cfg | 186 ++ .../config-lgsm/untserver/_default.cfg | 192 ++ .../config-lgsm/ut2k4server/_default.cfg | 172 ++ .../config-lgsm/ut3server/_default.cfg | 187 ++ .../config-lgsm/ut99server/_default.cfg | 170 ++ .../config-lgsm/utserver/_default.cfg | 173 ++ .../config-lgsm/vhserver/_default.cfg | 218 ++ .../config-lgsm/vintsserver/_default.cfg | 173 ++ .../config-lgsm/vpmcserver/_default.cfg | 177 ++ .../config-lgsm/vsserver/_default.cfg | 186 ++ .../config-lgsm/wetserver/_default.cfg | 165 ++ .../config-lgsm/wfserver/_default.cfg | 184 ++ .../config-lgsm/wmcserver/_default.cfg | 176 ++ .../config-lgsm/wurmserver/_default.cfg | 218 ++ .../config-lgsm/zmrserver/_default.cfg | 186 ++ .../config-lgsm/zpsserver/_default.cfg | 191 ++ lgsm/data/alert_discord_logo.jpg | Bin 0 -> 34529 bytes lgsm/data/almalinux-8.csv | 136 + lgsm/data/almalinux-9.csv | 136 + lgsm/data/appmanifest/ahl/appmanifest_10.acf | 36 + lgsm/data/appmanifest/ahl/appmanifest_70.acf | 41 + lgsm/data/appmanifest/ahl/appmanifest_90.acf | 49 + lgsm/data/appmanifest/bb/appmanifest_10.acf | 36 + lgsm/data/appmanifest/bb/appmanifest_70.acf | 41 + lgsm/data/appmanifest/bb/appmanifest_90.acf | 49 + lgsm/data/appmanifest/cscz/appmanifest_10.acf | 36 + lgsm/data/appmanifest/cscz/appmanifest_70.acf | 41 + lgsm/data/appmanifest/cscz/appmanifest_80.acf | 36 + lgsm/data/appmanifest/cscz/appmanifest_90.acf | 50 + lgsm/data/appmanifest/css/appmanifest_10.acf | 36 + lgsm/data/appmanifest/css/appmanifest_70.acf | 41 + lgsm/data/appmanifest/css/appmanifest_90.acf | 49 + lgsm/data/appmanifest/dmc/appmanifest_10.acf | 36 + lgsm/data/appmanifest/dmc/appmanifest_40.acf | 36 + lgsm/data/appmanifest/dmc/appmanifest_70.acf | 41 + lgsm/data/appmanifest/dmc/appmanifest_90.acf | 50 + lgsm/data/appmanifest/dod/appmanifest_10.acf | 36 + lgsm/data/appmanifest/dod/appmanifest_30.acf | 36 + lgsm/data/appmanifest/dod/appmanifest_70.acf | 41 + lgsm/data/appmanifest/dod/appmanifest_90.acf | 50 + lgsm/data/appmanifest/hldm/appmanifest_10.acf | 36 + lgsm/data/appmanifest/hldm/appmanifest_70.acf | 41 + lgsm/data/appmanifest/hldm/appmanifest_90.acf | 47 + lgsm/data/appmanifest/ns/appmanifest_10.acf | 36 + lgsm/data/appmanifest/ns/appmanifest_70.acf | 41 + lgsm/data/appmanifest/ns/appmanifest_90.acf | 49 + .../data/appmanifest/opfor/appmanifest_10.acf | 36 + .../data/appmanifest/opfor/appmanifest_50.acf | 36 + .../data/appmanifest/opfor/appmanifest_70.acf | 41 + .../data/appmanifest/opfor/appmanifest_90.acf | 50 + .../appmanifest/ricochet/appmanifest_10.acf | 36 + .../appmanifest/ricochet/appmanifest_60.acf | 36 + .../appmanifest/ricochet/appmanifest_70.acf | 41 + .../appmanifest/ricochet/appmanifest_90.acf | 50 + lgsm/data/appmanifest/tfc/appmanifest_10.acf | 36 + lgsm/data/appmanifest/tfc/appmanifest_20.acf | 36 + lgsm/data/appmanifest/tfc/appmanifest_70.acf | 41 + lgsm/data/appmanifest/tfc/appmanifest_90.acf | 50 + lgsm/data/appmanifest/ts/appmanifest_10.acf | 36 + lgsm/data/appmanifest/ts/appmanifest_70.acf | 41 + lgsm/data/appmanifest/ts/appmanifest_90.acf | 49 + lgsm/data/appmanifest/vs/appmanifest_10.acf | 36 + lgsm/data/appmanifest/vs/appmanifest_70.acf | 41 + lgsm/data/appmanifest/vs/appmanifest_90.acf | 49 + lgsm/data/bo_header.jpg | Bin 0 -> 19790 bytes lgsm/data/centos-7.csv | 136 + lgsm/data/centos-8.csv | 136 + lgsm/data/centos-9.csv | 136 + lgsm/data/debian-10.csv | 136 + lgsm/data/debian-11.csv | 136 + lgsm/data/debian-12.csv | 136 + lgsm/data/debian-9.csv | 136 + lgsm/data/gameicons/ac-icon.png | Bin 0 -> 1801 bytes lgsm/data/gameicons/ahl-icon.png | Bin 0 -> 2983 bytes lgsm/data/gameicons/ahl2-icon.png | Bin 0 -> 2532 bytes lgsm/data/gameicons/ark-icon.png | Bin 0 -> 2006 bytes lgsm/data/gameicons/arma3-icon.png | Bin 0 -> 954 bytes lgsm/data/gameicons/armar-icon.png | Bin 0 -> 722 bytes lgsm/data/gameicons/ats-icon.png | Bin 0 -> 2037 bytes lgsm/data/gameicons/av-icon.png | Bin 0 -> 1983 bytes lgsm/data/gameicons/bb-icon.png | Bin 0 -> 2837 bytes lgsm/data/gameicons/bb2-icon.png | Bin 0 -> 2082 bytes lgsm/data/gameicons/bd-icon.png | Bin 0 -> 2094 bytes lgsm/data/gameicons/bf1942-icon.png | Bin 0 -> 2847 bytes lgsm/data/gameicons/bfv-icon.png | Bin 0 -> 2094 bytes lgsm/data/gameicons/bmdm-icon.png | Bin 0 -> 2082 bytes lgsm/data/gameicons/bo-icon.png | Bin 0 -> 2030 bytes lgsm/data/gameicons/bs-icon.png | Bin 0 -> 1916 bytes lgsm/data/gameicons/bt-icon.png | Bin 0 -> 2091 bytes lgsm/data/gameicons/btl-icon.png | Bin 0 -> 2334 bytes lgsm/data/gameicons/cc-icon.png | Bin 0 -> 2147 bytes lgsm/data/gameicons/cd-icon.png | Bin 0 -> 2819 bytes lgsm/data/gameicons/ck-icon.png | Bin 0 -> 2828 bytes lgsm/data/gameicons/cmw-icon.png | Bin 0 -> 2645 bytes lgsm/data/gameicons/cod-icon.png | Bin 0 -> 2050 bytes lgsm/data/gameicons/cod2-icon.png | Bin 0 -> 2707 bytes lgsm/data/gameicons/cod4-icon.png | Bin 0 -> 2878 bytes lgsm/data/gameicons/coduo-icon.png | Bin 0 -> 2652 bytes lgsm/data/gameicons/codwaw-icon.png | Bin 0 -> 2819 bytes lgsm/data/gameicons/col-icon.png | Bin 0 -> 2411 bytes lgsm/data/gameicons/cs-icon.png | Bin 0 -> 2150 bytes lgsm/data/gameicons/cs2-icon.png | Bin 0 -> 2397 bytes lgsm/data/gameicons/cscz-icon.png | Bin 0 -> 2362 bytes lgsm/data/gameicons/csgo-icon.png | Bin 0 -> 2735 bytes lgsm/data/gameicons/css-icon.png | Bin 0 -> 2791 bytes lgsm/data/gameicons/ct-icon.png | Bin 0 -> 2951 bytes lgsm/data/gameicons/dab-icon.png | Bin 0 -> 2589 bytes lgsm/data/gameicons/dayz-icon.png | Bin 0 -> 2370 bytes lgsm/data/gameicons/dmc-icon.png | Bin 0 -> 2774 bytes lgsm/data/gameicons/dod-icon.png | Bin 0 -> 2489 bytes lgsm/data/gameicons/dodr-icon.png | Bin 0 -> 3083 bytes lgsm/data/gameicons/dods-icon.png | Bin 0 -> 2359 bytes lgsm/data/gameicons/doi-icon.png | Bin 0 -> 2520 bytes lgsm/data/gameicons/dst-icon.png | Bin 0 -> 3125 bytes lgsm/data/gameicons/dys-icon.png | Bin 0 -> 2777 bytes lgsm/data/gameicons/eco-icon.png | Bin 0 -> 2910 bytes lgsm/data/gameicons/em-icon.png | Bin 0 -> 2442 bytes lgsm/data/gameicons/etl-icon.png | Bin 0 -> 1774 bytes lgsm/data/gameicons/ets2-icon.png | Bin 0 -> 2997 bytes lgsm/data/gameicons/fctr-icon.png | Bin 0 -> 2596 bytes lgsm/data/gameicons/fof-icon.png | Bin 0 -> 2491 bytes lgsm/data/gameicons/gmod-icon.png | Bin 0 -> 2429 bytes lgsm/data/gameicons/hcu-icon.png | Bin 0 -> 2241 bytes lgsm/data/gameicons/hl2dm-icon.png | Bin 0 -> 2549 bytes lgsm/data/gameicons/hldm-icon.png | Bin 0 -> 2722 bytes lgsm/data/gameicons/hldms-icon.png | Bin 0 -> 2834 bytes lgsm/data/gameicons/hw-icon.png | Bin 0 -> 2207 bytes lgsm/data/gameicons/ins-icon.png | Bin 0 -> 2738 bytes lgsm/data/gameicons/inss-icon.png | Bin 0 -> 3200 bytes lgsm/data/gameicons/ios-icon.png | Bin 0 -> 2815 bytes lgsm/data/gameicons/jc2-icon.png | Bin 0 -> 2983 bytes lgsm/data/gameicons/jc3-icon.png | Bin 0 -> 2979 bytes lgsm/data/gameicons/jk2-icon.png | Bin 0 -> 2805 bytes lgsm/data/gameicons/kf-icon.png | Bin 0 -> 2687 bytes lgsm/data/gameicons/kf2-icon.png | Bin 0 -> 2706 bytes lgsm/data/gameicons/l4d-icon.png | Bin 0 -> 2487 bytes lgsm/data/gameicons/l4d2-icon.png | Bin 0 -> 2741 bytes lgsm/data/gameicons/mc-icon.png | Bin 0 -> 2423 bytes lgsm/data/gameicons/mcb-icon.png | Bin 0 -> 2737 bytes lgsm/data/gameicons/mh-icon.png | Bin 0 -> 2638 bytes lgsm/data/gameicons/mohaa-icon.png | Bin 0 -> 2845 bytes lgsm/data/gameicons/mom-icon.png | Bin 0 -> 3025 bytes lgsm/data/gameicons/mta-icon.png | Bin 0 -> 2147 bytes lgsm/data/gameicons/nd-icon.png | Bin 0 -> 2520 bytes lgsm/data/gameicons/nec-icon.png | Bin 0 -> 2009 bytes lgsm/data/gameicons/nmrih-icon.png | Bin 0 -> 1100 bytes lgsm/data/gameicons/ns-icon.png | Bin 0 -> 3113 bytes lgsm/data/gameicons/ns2-icon.png | Bin 0 -> 2859 bytes lgsm/data/gameicons/ns2c-icon.png | Bin 0 -> 2603 bytes lgsm/data/gameicons/ohd-icon.png | Bin 0 -> 2630 bytes lgsm/data/gameicons/onset-icon.png | Bin 0 -> 2927 bytes lgsm/data/gameicons/opfor-icon.png | Bin 0 -> 2428 bytes lgsm/data/gameicons/pc-icon.png | Bin 0 -> 2605 bytes lgsm/data/gameicons/pc2-icon.png | Bin 0 -> 2504 bytes lgsm/data/gameicons/pmc-icon.png | Bin 0 -> 1312 bytes lgsm/data/gameicons/ps-icon.png | Bin 0 -> 1216 bytes lgsm/data/gameicons/pvkii-icon.png | Bin 0 -> 2938 bytes lgsm/data/gameicons/pvr-icon.png | Bin 0 -> 3021 bytes lgsm/data/gameicons/pz-icon.png | Bin 0 -> 2489 bytes lgsm/data/gameicons/q2-icon.png | Bin 0 -> 2584 bytes lgsm/data/gameicons/q3-icon.png | Bin 0 -> 2734 bytes lgsm/data/gameicons/ql-icon.png | Bin 0 -> 2974 bytes lgsm/data/gameicons/qw-icon.png | Bin 0 -> 2725 bytes lgsm/data/gameicons/ricochet-icon.png | Bin 0 -> 2727 bytes lgsm/data/gameicons/ro-icon.png | Bin 0 -> 2393 bytes lgsm/data/gameicons/rtcw-icon.png | Bin 0 -> 2244 bytes lgsm/data/gameicons/rust-icon.png | Bin 0 -> 2351 bytes lgsm/data/gameicons/rw-icon.png | Bin 0 -> 2644 bytes lgsm/data/gameicons/samp-icon.png | Bin 0 -> 3026 bytes lgsm/data/gameicons/sb-icon.png | Bin 0 -> 2598 bytes lgsm/data/gameicons/sbots-icon.png | Bin 0 -> 2927 bytes lgsm/data/gameicons/scpsl-icon.png | Bin 0 -> 3090 bytes lgsm/data/gameicons/scpslsm-icon.png | Bin 0 -> 3090 bytes lgsm/data/gameicons/sdtd-icon.png | Bin 0 -> 2010 bytes lgsm/data/gameicons/sf-icon.png | Bin 0 -> 1649 bytes lgsm/data/gameicons/sfc-icon.png | Bin 0 -> 2165 bytes lgsm/data/gameicons/sof2-icon.png | Bin 0 -> 1476 bytes lgsm/data/gameicons/sol-icon.png | Bin 0 -> 2978 bytes lgsm/data/gameicons/squad-icon.png | Bin 0 -> 2321 bytes lgsm/data/gameicons/st-icon.png | Bin 0 -> 3083 bytes lgsm/data/gameicons/stn-icon.png | Bin 0 -> 1622 bytes lgsm/data/gameicons/sven-icon.png | Bin 0 -> 2878 bytes lgsm/data/gameicons/terraria-icon.png | Bin 0 -> 2241 bytes lgsm/data/gameicons/tf-icon.png | Bin 0 -> 1828 bytes lgsm/data/gameicons/tf2-icon.png | Bin 0 -> 2745 bytes lgsm/data/gameicons/tfc-icon.png | Bin 0 -> 2349 bytes lgsm/data/gameicons/ti-icon.png | Bin 0 -> 2163 bytes lgsm/data/gameicons/ts-icon.png | Bin 0 -> 2922 bytes lgsm/data/gameicons/ts3-icon.png | Bin 0 -> 2561 bytes lgsm/data/gameicons/tu-icon.png | Bin 0 -> 2389 bytes lgsm/data/gameicons/tw-icon.png | Bin 0 -> 2644 bytes lgsm/data/gameicons/unt-icon.png | Bin 0 -> 1495 bytes lgsm/data/gameicons/ut-icon.png | Bin 0 -> 1134 bytes lgsm/data/gameicons/ut2k4-icon.png | Bin 0 -> 2814 bytes lgsm/data/gameicons/ut3-icon.png | Bin 0 -> 2749 bytes lgsm/data/gameicons/ut99-icon.png | Bin 0 -> 2797 bytes lgsm/data/gameicons/vh-icon.png | Bin 0 -> 2598 bytes lgsm/data/gameicons/vints-icon.png | Bin 0 -> 9075 bytes lgsm/data/gameicons/vpmc-icon.png | Bin 0 -> 1171 bytes lgsm/data/gameicons/vs-icon.png | Bin 0 -> 500 bytes lgsm/data/gameicons/wet-icon.png | Bin 0 -> 478 bytes lgsm/data/gameicons/wf-icon.png | Bin 0 -> 2494 bytes lgsm/data/gameicons/wmc-icon.png | Bin 0 -> 1017 bytes lgsm/data/gameicons/wurm-icon.png | Bin 0 -> 2643 bytes lgsm/data/gameicons/zmr-icon.png | Bin 0 -> 1696 bytes lgsm/data/gameicons/zps-icon.png | Bin 0 -> 2679 bytes lgsm/data/name-left.csv | 108 + lgsm/data/name-right.csv | 237 ++ lgsm/data/rhel-7.csv | 136 + lgsm/data/rhel-8.csv | 136 + lgsm/data/rhel-9.csv | 136 + lgsm/data/rocky-8.csv | 136 + lgsm/data/rocky-9.csv | 136 + lgsm/data/rust_header.jpg | Bin 0 -> 117845 bytes lgsm/data/serverlist.csv | 135 + lgsm/data/ubuntu-16.04.csv | 136 + lgsm/data/ubuntu-18.04.csv | 136 + lgsm/data/ubuntu-20.04.csv | 136 + lgsm/data/ubuntu-22.04.csv | 136 + lgsm/data/ubuntu-23.04.csv | 136 + lgsm/data/ubuntu-23.10.csv | 136 + lgsm/modules/README.md | 17 + lgsm/modules/alert.sh | 359 +++ lgsm/modules/alert_discord.sh | 153 + lgsm/modules/alert_email.sh | 24 + lgsm/modules/alert_gotify.sh | 45 + lgsm/modules/alert_ifttt.sh | 45 + lgsm/modules/alert_pushbullet.sh | 47 + lgsm/modules/alert_pushover.sh | 37 + lgsm/modules/alert_rocketchat.sh | 134 + lgsm/modules/alert_slack.sh | 193 ++ lgsm/modules/alert_telegram.sh | 47 + lgsm/modules/check.sh | 101 + lgsm/modules/check_config.sh | 32 + lgsm/modules/check_deps.sh | 394 +++ lgsm/modules/check_executable.sh | 27 + lgsm/modules/check_glibc.sh | 31 + lgsm/modules/check_ip.sh | 63 + lgsm/modules/check_last_update.sh | 28 + lgsm/modules/check_logs.sh | 31 + lgsm/modules/check_permissions.sh | 234 ++ lgsm/modules/check_root.sh | 21 + lgsm/modules/check_status.sh | 10 + lgsm/modules/check_steamcmd.sh | 22 + lgsm/modules/check_system_dir.sh | 24 + lgsm/modules/check_system_requirements.sh | 55 + lgsm/modules/check_tmuxception.sh | 33 + lgsm/modules/check_version.sh | 23 + lgsm/modules/command_backup.sh | 258 ++ lgsm/modules/command_check_update.sh | 39 + lgsm/modules/command_console.sh | 58 + lgsm/modules/command_debug.sh | 142 + lgsm/modules/command_details.sh | 42 + lgsm/modules/command_dev_clear_modules.sh | 24 + lgsm/modules/command_dev_debug.sh | 27 + lgsm/modules/command_dev_details.sh | 98 + lgsm/modules/command_dev_detect_deps.sh | 231 ++ lgsm/modules/command_dev_detect_glibc.sh | 92 + lgsm/modules/command_dev_detect_ldd.sh | 61 + lgsm/modules/command_dev_query_raw.sh | 279 ++ lgsm/modules/command_fastdl.sh | 441 +++ lgsm/modules/command_install.sh | 52 + lgsm/modules/command_install_resources_mta.sh | 32 + lgsm/modules/command_mods_install.sh | 135 + lgsm/modules/command_mods_remove.sh | 153 + lgsm/modules/command_mods_update.sh | 109 + lgsm/modules/command_monitor.sh | 415 +++ lgsm/modules/command_postdetails.sh | 78 + lgsm/modules/command_restart.sh | 18 + lgsm/modules/command_send.sh | 41 + lgsm/modules/command_skeleton.sh | 26 + lgsm/modules/command_sponsor.sh | 26 + lgsm/modules/command_start.sh | 232 ++ lgsm/modules/command_stop.sh | 319 +++ lgsm/modules/command_test_alert.sh | 19 + lgsm/modules/command_ts3_server_pass.sh | 57 + lgsm/modules/command_update.sh | 43 + lgsm/modules/command_update_linuxgsm.sh | 236 ++ lgsm/modules/command_validate.sh | 52 + lgsm/modules/command_wipe.sh | 187 ++ lgsm/modules/compress_unreal2_maps.sh | 35 + lgsm/modules/compress_ut99_maps.sh | 35 + lgsm/modules/core_dl.sh | 630 +++++ lgsm/modules/core_exit.sh | 65 + lgsm/modules/core_getopt.sh | 216 ++ lgsm/modules/core_github.sh | 114 + lgsm/modules/core_legacy.sh | 50 + lgsm/modules/core_logs.sh | 109 + lgsm/modules/core_messages.sh | 621 ++++ lgsm/modules/core_modules.sh | 821 ++++++ lgsm/modules/core_steamcmd.sh | 426 +++ lgsm/modules/core_trap.sh | 22 + lgsm/modules/fix.sh | 87 + lgsm/modules/fix_ark.sh | 62 + lgsm/modules/fix_arma3.sh | 16 + lgsm/modules/fix_armar.sh | 17 + lgsm/modules/fix_av.sh | 18 + lgsm/modules/fix_bo.sh | 10 + lgsm/modules/fix_bt.sh | 24 + lgsm/modules/fix_cmw.sh | 25 + lgsm/modules/fix_csgo.sh | 42 + lgsm/modules/fix_dst.sh | 17 + lgsm/modules/fix_hw.sh | 10 + lgsm/modules/fix_ins.sh | 20 + lgsm/modules/fix_kf.sh | 36 + lgsm/modules/fix_kf2.sh | 19 + lgsm/modules/fix_mcb.sh | 11 + lgsm/modules/fix_mta.sh | 15 + lgsm/modules/fix_nmrih.sh | 17 + lgsm/modules/fix_onset.sh | 19 + lgsm/modules/fix_pvr.sh | 14 + lgsm/modules/fix_ro.sh | 39 + lgsm/modules/fix_rust.sh | 32 + lgsm/modules/fix_rw.sh | 10 + lgsm/modules/fix_samp.sh | 34 + lgsm/modules/fix_sdtd.sh | 10 + lgsm/modules/fix_sfc.sh | 48 + lgsm/modules/fix_sof2.sh | 11 + lgsm/modules/fix_squad.sh | 26 + lgsm/modules/fix_st.sh | 11 + lgsm/modules/fix_steamcmd.sh | 141 + lgsm/modules/fix_terraria.sh | 10 + lgsm/modules/fix_tf2.sh | 16 + lgsm/modules/fix_ts3.sh | 46 + lgsm/modules/fix_unt.sh | 10 + lgsm/modules/fix_ut.sh | 13 + lgsm/modules/fix_ut2k4.sh | 36 + lgsm/modules/fix_ut3.sh | 19 + lgsm/modules/fix_vh.sh | 35 + lgsm/modules/fix_wurm.sh | 24 + lgsm/modules/fix_zmr.sh | 48 + lgsm/modules/info_distro.sh | 290 ++ lgsm/modules/info_game.sh | 2506 +++++++++++++++++ lgsm/modules/info_messages.sh | 1873 ++++++++++++ lgsm/modules/info_stats.sh | 167 ++ lgsm/modules/install_complete.sh | 32 + lgsm/modules/install_config.sh | 850 ++++++ lgsm/modules/install_dst_token.sh | 44 + lgsm/modules/install_eula.sh | 46 + lgsm/modules/install_factorio_save.sh | 14 + lgsm/modules/install_gslt.sh | 47 + lgsm/modules/install_header.sh | 20 + lgsm/modules/install_logs.sh | 99 + lgsm/modules/install_mta_resources.sh | 12 + lgsm/modules/install_retry.sh | 16 + lgsm/modules/install_server_dir.sh | 25 + lgsm/modules/install_server_files.sh | 256 ++ lgsm/modules/install_squad_license.sh | 24 + lgsm/modules/install_stats.sh | 28 + lgsm/modules/install_steamcmd.sh | 13 + lgsm/modules/install_ts3db.sh | 73 + lgsm/modules/install_ut2k4_key.sh | 29 + lgsm/modules/mods_core.sh | 755 +++++ lgsm/modules/mods_list.sh | 209 ++ lgsm/modules/query_gamedig.sh | 88 + lgsm/modules/query_gsquery.py | 151 + lgsm/modules/update_fctr.sh | 171 ++ lgsm/modules/update_jk2.sh | 166 ++ lgsm/modules/update_mc.sh | 180 ++ lgsm/modules/update_mcb.sh | 186 ++ lgsm/modules/update_mta.sh | 173 ++ lgsm/modules/update_pmc.sh | 198 ++ lgsm/modules/update_steamcmd.sh | 40 + lgsm/modules/update_ts3.sh | 184 ++ lgsm/modules/update_ut99.sh | 166 ++ lgsm/modules/update_vints.sh | 173 ++ linuxgsm.sh | 513 ++++ package-lock.json | 76 + package.json | 24 + 523 files changed, 51536 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .github/FUNDING.yml create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/ISSUE_TEMPLATE/server_request.yml create mode 100644 .github/dependabot.yml create mode 100644 .github/labeler.yml create mode 100644 .github/pull_request_template.md create mode 100644 .github/workflows/add-to-project.yml create mode 100644 .github/workflows/details-check.yml create mode 100755 .github/workflows/detals-check-generate-matrix.sh create mode 100644 .github/workflows/git-sync.yml create mode 100644 .github/workflows/labeler.yml create mode 100644 .github/workflows/lock.yml create mode 100644 .github/workflows/potential-duplicates.yml create mode 100755 .github/workflows/serverlist-validate-game-icons.sh create mode 100755 .github/workflows/serverlist-validate.sh create mode 100644 .github/workflows/serverlist-validate.yml create mode 100644 .github/workflows/trigger-docker-build.yml create mode 100644 .github/workflows/update-check.yml create mode 100644 .github/workflows/update-copyright-years-in-license-file.yml create mode 100644 .github/workflows/version-check.sh create mode 100644 .github/workflows/version-check.yml create mode 100644 .gitignore create mode 100644 .prettierrc create mode 100644 .vscode/extensions.json create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 lgsm/config-default/config-lgsm/acserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/ahl2server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/ahlserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/arkserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/arma3server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/armarserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/atsserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/avserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/bb2server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/bbserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/bdserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/bf1942server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/bfvserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/bmdmserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/boserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/bsserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/btlserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/btserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/ccserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/cdserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/ckserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/cmwserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/cod2server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/cod4server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/codserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/coduoserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/codwawserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/colserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/common-template.cfg create mode 100644 lgsm/config-default/config-lgsm/cs2server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/csczserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/csgoserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/csserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/cssserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/ctserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/dabserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/dayzserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/dmcserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/dodrserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/dodserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/dodsserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/doiserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/dstserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/dysserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/ecoserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/emserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/etlserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/ets2server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/fctrserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/fofserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/gmodserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/hcuserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/hl2dmserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/hldmserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/hldmsserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/hwserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/insserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/inssserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/instance-template.cfg create mode 100644 lgsm/config-default/config-lgsm/iosserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/jc2server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/jc3server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/jk2server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/kf2server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/kfserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/l4d2server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/l4dserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/mcbserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/mcserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/mhserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/mohaaserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/momserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/mtaserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/ndserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/necserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/nmrihserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/ns2cserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/ns2server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/nsserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/ohdserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/onsetserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/opforserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/pc2server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/pcserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/pmcserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/psserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/pvkiiserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/pvrserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/pzserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/q2server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/q3server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/qlserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/qwserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/ricochetserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/roserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/rtcwserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/rustserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/rwserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/sampserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/sbotsserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/sbserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/scpslserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/scpslsmserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/sdtdserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/secrets-common-template.cfg create mode 100644 lgsm/config-default/config-lgsm/secrets-instance-template.cfg create mode 100644 lgsm/config-default/config-lgsm/sfcserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/sfserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/sof2server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/solserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/squadserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/stnserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/stserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/svenserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/terrariaserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/tf2server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/tfcserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/tfserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/tiserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/ts3server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/tsserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/tuserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/twserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/untserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/ut2k4server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/ut3server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/ut99server/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/utserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/vhserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/vintsserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/vpmcserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/vsserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/wetserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/wfserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/wmcserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/wurmserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/zmrserver/_default.cfg create mode 100644 lgsm/config-default/config-lgsm/zpsserver/_default.cfg create mode 100644 lgsm/data/alert_discord_logo.jpg create mode 100644 lgsm/data/almalinux-8.csv create mode 100644 lgsm/data/almalinux-9.csv create mode 100644 lgsm/data/appmanifest/ahl/appmanifest_10.acf create mode 100644 lgsm/data/appmanifest/ahl/appmanifest_70.acf create mode 100644 lgsm/data/appmanifest/ahl/appmanifest_90.acf create mode 100644 lgsm/data/appmanifest/bb/appmanifest_10.acf create mode 100644 lgsm/data/appmanifest/bb/appmanifest_70.acf create mode 100644 lgsm/data/appmanifest/bb/appmanifest_90.acf create mode 100644 lgsm/data/appmanifest/cscz/appmanifest_10.acf create mode 100644 lgsm/data/appmanifest/cscz/appmanifest_70.acf create mode 100644 lgsm/data/appmanifest/cscz/appmanifest_80.acf create mode 100644 lgsm/data/appmanifest/cscz/appmanifest_90.acf create mode 100644 lgsm/data/appmanifest/css/appmanifest_10.acf create mode 100644 lgsm/data/appmanifest/css/appmanifest_70.acf create mode 100644 lgsm/data/appmanifest/css/appmanifest_90.acf create mode 100644 lgsm/data/appmanifest/dmc/appmanifest_10.acf create mode 100644 lgsm/data/appmanifest/dmc/appmanifest_40.acf create mode 100644 lgsm/data/appmanifest/dmc/appmanifest_70.acf create mode 100644 lgsm/data/appmanifest/dmc/appmanifest_90.acf create mode 100644 lgsm/data/appmanifest/dod/appmanifest_10.acf create mode 100644 lgsm/data/appmanifest/dod/appmanifest_30.acf create mode 100644 lgsm/data/appmanifest/dod/appmanifest_70.acf create mode 100644 lgsm/data/appmanifest/dod/appmanifest_90.acf create mode 100644 lgsm/data/appmanifest/hldm/appmanifest_10.acf create mode 100644 lgsm/data/appmanifest/hldm/appmanifest_70.acf create mode 100644 lgsm/data/appmanifest/hldm/appmanifest_90.acf create mode 100644 lgsm/data/appmanifest/ns/appmanifest_10.acf create mode 100644 lgsm/data/appmanifest/ns/appmanifest_70.acf create mode 100644 lgsm/data/appmanifest/ns/appmanifest_90.acf create mode 100644 lgsm/data/appmanifest/opfor/appmanifest_10.acf create mode 100644 lgsm/data/appmanifest/opfor/appmanifest_50.acf create mode 100644 lgsm/data/appmanifest/opfor/appmanifest_70.acf create mode 100644 lgsm/data/appmanifest/opfor/appmanifest_90.acf create mode 100644 lgsm/data/appmanifest/ricochet/appmanifest_10.acf create mode 100644 lgsm/data/appmanifest/ricochet/appmanifest_60.acf create mode 100644 lgsm/data/appmanifest/ricochet/appmanifest_70.acf create mode 100644 lgsm/data/appmanifest/ricochet/appmanifest_90.acf create mode 100644 lgsm/data/appmanifest/tfc/appmanifest_10.acf create mode 100644 lgsm/data/appmanifest/tfc/appmanifest_20.acf create mode 100644 lgsm/data/appmanifest/tfc/appmanifest_70.acf create mode 100644 lgsm/data/appmanifest/tfc/appmanifest_90.acf create mode 100644 lgsm/data/appmanifest/ts/appmanifest_10.acf create mode 100644 lgsm/data/appmanifest/ts/appmanifest_70.acf create mode 100644 lgsm/data/appmanifest/ts/appmanifest_90.acf create mode 100644 lgsm/data/appmanifest/vs/appmanifest_10.acf create mode 100644 lgsm/data/appmanifest/vs/appmanifest_70.acf create mode 100644 lgsm/data/appmanifest/vs/appmanifest_90.acf create mode 100644 lgsm/data/bo_header.jpg create mode 100644 lgsm/data/centos-7.csv create mode 100644 lgsm/data/centos-8.csv create mode 100644 lgsm/data/centos-9.csv create mode 100644 lgsm/data/debian-10.csv create mode 100644 lgsm/data/debian-11.csv create mode 100644 lgsm/data/debian-12.csv create mode 100644 lgsm/data/debian-9.csv create mode 100644 lgsm/data/gameicons/ac-icon.png create mode 100644 lgsm/data/gameicons/ahl-icon.png create mode 100644 lgsm/data/gameicons/ahl2-icon.png create mode 100644 lgsm/data/gameicons/ark-icon.png create mode 100644 lgsm/data/gameicons/arma3-icon.png create mode 100644 lgsm/data/gameicons/armar-icon.png create mode 100644 lgsm/data/gameicons/ats-icon.png create mode 100644 lgsm/data/gameicons/av-icon.png create mode 100644 lgsm/data/gameicons/bb-icon.png create mode 100644 lgsm/data/gameicons/bb2-icon.png create mode 100644 lgsm/data/gameicons/bd-icon.png create mode 100644 lgsm/data/gameicons/bf1942-icon.png create mode 100644 lgsm/data/gameicons/bfv-icon.png create mode 100644 lgsm/data/gameicons/bmdm-icon.png create mode 100644 lgsm/data/gameicons/bo-icon.png create mode 100644 lgsm/data/gameicons/bs-icon.png create mode 100644 lgsm/data/gameicons/bt-icon.png create mode 100644 lgsm/data/gameicons/btl-icon.png create mode 100644 lgsm/data/gameicons/cc-icon.png create mode 100644 lgsm/data/gameicons/cd-icon.png create mode 100644 lgsm/data/gameicons/ck-icon.png create mode 100644 lgsm/data/gameicons/cmw-icon.png create mode 100644 lgsm/data/gameicons/cod-icon.png create mode 100644 lgsm/data/gameicons/cod2-icon.png create mode 100644 lgsm/data/gameicons/cod4-icon.png create mode 100644 lgsm/data/gameicons/coduo-icon.png create mode 100644 lgsm/data/gameicons/codwaw-icon.png create mode 100644 lgsm/data/gameicons/col-icon.png create mode 100644 lgsm/data/gameicons/cs-icon.png create mode 100644 lgsm/data/gameicons/cs2-icon.png create mode 100644 lgsm/data/gameicons/cscz-icon.png create mode 100644 lgsm/data/gameicons/csgo-icon.png create mode 100644 lgsm/data/gameicons/css-icon.png create mode 100644 lgsm/data/gameicons/ct-icon.png create mode 100644 lgsm/data/gameicons/dab-icon.png create mode 100644 lgsm/data/gameicons/dayz-icon.png create mode 100644 lgsm/data/gameicons/dmc-icon.png create mode 100644 lgsm/data/gameicons/dod-icon.png create mode 100644 lgsm/data/gameicons/dodr-icon.png create mode 100644 lgsm/data/gameicons/dods-icon.png create mode 100644 lgsm/data/gameicons/doi-icon.png create mode 100644 lgsm/data/gameicons/dst-icon.png create mode 100644 lgsm/data/gameicons/dys-icon.png create mode 100644 lgsm/data/gameicons/eco-icon.png create mode 100644 lgsm/data/gameicons/em-icon.png create mode 100644 lgsm/data/gameicons/etl-icon.png create mode 100644 lgsm/data/gameicons/ets2-icon.png create mode 100644 lgsm/data/gameicons/fctr-icon.png create mode 100644 lgsm/data/gameicons/fof-icon.png create mode 100644 lgsm/data/gameicons/gmod-icon.png create mode 100644 lgsm/data/gameicons/hcu-icon.png create mode 100644 lgsm/data/gameicons/hl2dm-icon.png create mode 100644 lgsm/data/gameicons/hldm-icon.png create mode 100644 lgsm/data/gameicons/hldms-icon.png create mode 100644 lgsm/data/gameicons/hw-icon.png create mode 100644 lgsm/data/gameicons/ins-icon.png create mode 100644 lgsm/data/gameicons/inss-icon.png create mode 100644 lgsm/data/gameicons/ios-icon.png create mode 100644 lgsm/data/gameicons/jc2-icon.png create mode 100644 lgsm/data/gameicons/jc3-icon.png create mode 100644 lgsm/data/gameicons/jk2-icon.png create mode 100644 lgsm/data/gameicons/kf-icon.png create mode 100644 lgsm/data/gameicons/kf2-icon.png create mode 100644 lgsm/data/gameicons/l4d-icon.png create mode 100644 lgsm/data/gameicons/l4d2-icon.png create mode 100644 lgsm/data/gameicons/mc-icon.png create mode 100644 lgsm/data/gameicons/mcb-icon.png create mode 100644 lgsm/data/gameicons/mh-icon.png create mode 100644 lgsm/data/gameicons/mohaa-icon.png create mode 100644 lgsm/data/gameicons/mom-icon.png create mode 100644 lgsm/data/gameicons/mta-icon.png create mode 100644 lgsm/data/gameicons/nd-icon.png create mode 100644 lgsm/data/gameicons/nec-icon.png create mode 100644 lgsm/data/gameicons/nmrih-icon.png create mode 100644 lgsm/data/gameicons/ns-icon.png create mode 100644 lgsm/data/gameicons/ns2-icon.png create mode 100644 lgsm/data/gameicons/ns2c-icon.png create mode 100644 lgsm/data/gameicons/ohd-icon.png create mode 100644 lgsm/data/gameicons/onset-icon.png create mode 100644 lgsm/data/gameicons/opfor-icon.png create mode 100644 lgsm/data/gameicons/pc-icon.png create mode 100644 lgsm/data/gameicons/pc2-icon.png create mode 100644 lgsm/data/gameicons/pmc-icon.png create mode 100644 lgsm/data/gameicons/ps-icon.png create mode 100644 lgsm/data/gameicons/pvkii-icon.png create mode 100644 lgsm/data/gameicons/pvr-icon.png create mode 100644 lgsm/data/gameicons/pz-icon.png create mode 100644 lgsm/data/gameicons/q2-icon.png create mode 100644 lgsm/data/gameicons/q3-icon.png create mode 100644 lgsm/data/gameicons/ql-icon.png create mode 100644 lgsm/data/gameicons/qw-icon.png create mode 100644 lgsm/data/gameicons/ricochet-icon.png create mode 100644 lgsm/data/gameicons/ro-icon.png create mode 100644 lgsm/data/gameicons/rtcw-icon.png create mode 100644 lgsm/data/gameicons/rust-icon.png create mode 100644 lgsm/data/gameicons/rw-icon.png create mode 100644 lgsm/data/gameicons/samp-icon.png create mode 100644 lgsm/data/gameicons/sb-icon.png create mode 100644 lgsm/data/gameicons/sbots-icon.png create mode 100644 lgsm/data/gameicons/scpsl-icon.png create mode 100644 lgsm/data/gameicons/scpslsm-icon.png create mode 100644 lgsm/data/gameicons/sdtd-icon.png create mode 100644 lgsm/data/gameicons/sf-icon.png create mode 100644 lgsm/data/gameicons/sfc-icon.png create mode 100644 lgsm/data/gameicons/sof2-icon.png create mode 100644 lgsm/data/gameicons/sol-icon.png create mode 100644 lgsm/data/gameicons/squad-icon.png create mode 100644 lgsm/data/gameicons/st-icon.png create mode 100644 lgsm/data/gameicons/stn-icon.png create mode 100644 lgsm/data/gameicons/sven-icon.png create mode 100644 lgsm/data/gameicons/terraria-icon.png create mode 100644 lgsm/data/gameicons/tf-icon.png create mode 100644 lgsm/data/gameicons/tf2-icon.png create mode 100644 lgsm/data/gameicons/tfc-icon.png create mode 100644 lgsm/data/gameicons/ti-icon.png create mode 100644 lgsm/data/gameicons/ts-icon.png create mode 100644 lgsm/data/gameicons/ts3-icon.png create mode 100644 lgsm/data/gameicons/tu-icon.png create mode 100644 lgsm/data/gameicons/tw-icon.png create mode 100644 lgsm/data/gameicons/unt-icon.png create mode 100644 lgsm/data/gameicons/ut-icon.png create mode 100644 lgsm/data/gameicons/ut2k4-icon.png create mode 100644 lgsm/data/gameicons/ut3-icon.png create mode 100644 lgsm/data/gameicons/ut99-icon.png create mode 100644 lgsm/data/gameicons/vh-icon.png create mode 100644 lgsm/data/gameicons/vints-icon.png create mode 100644 lgsm/data/gameicons/vpmc-icon.png create mode 100644 lgsm/data/gameicons/vs-icon.png create mode 100644 lgsm/data/gameicons/wet-icon.png create mode 100644 lgsm/data/gameicons/wf-icon.png create mode 100644 lgsm/data/gameicons/wmc-icon.png create mode 100644 lgsm/data/gameicons/wurm-icon.png create mode 100644 lgsm/data/gameicons/zmr-icon.png create mode 100644 lgsm/data/gameicons/zps-icon.png create mode 100644 lgsm/data/name-left.csv create mode 100644 lgsm/data/name-right.csv create mode 100644 lgsm/data/rhel-7.csv create mode 100644 lgsm/data/rhel-8.csv create mode 100644 lgsm/data/rhel-9.csv create mode 100644 lgsm/data/rocky-8.csv create mode 100644 lgsm/data/rocky-9.csv create mode 100644 lgsm/data/rust_header.jpg create mode 100644 lgsm/data/serverlist.csv create mode 100644 lgsm/data/ubuntu-16.04.csv create mode 100644 lgsm/data/ubuntu-18.04.csv create mode 100644 lgsm/data/ubuntu-20.04.csv create mode 100644 lgsm/data/ubuntu-22.04.csv create mode 100644 lgsm/data/ubuntu-23.04.csv create mode 100644 lgsm/data/ubuntu-23.10.csv create mode 100644 lgsm/modules/README.md create mode 100644 lgsm/modules/alert.sh create mode 100644 lgsm/modules/alert_discord.sh create mode 100644 lgsm/modules/alert_email.sh create mode 100644 lgsm/modules/alert_gotify.sh create mode 100644 lgsm/modules/alert_ifttt.sh create mode 100644 lgsm/modules/alert_pushbullet.sh create mode 100644 lgsm/modules/alert_pushover.sh create mode 100644 lgsm/modules/alert_rocketchat.sh create mode 100644 lgsm/modules/alert_slack.sh create mode 100644 lgsm/modules/alert_telegram.sh create mode 100644 lgsm/modules/check.sh create mode 100644 lgsm/modules/check_config.sh create mode 100644 lgsm/modules/check_deps.sh create mode 100644 lgsm/modules/check_executable.sh create mode 100644 lgsm/modules/check_glibc.sh create mode 100644 lgsm/modules/check_ip.sh create mode 100644 lgsm/modules/check_last_update.sh create mode 100644 lgsm/modules/check_logs.sh create mode 100644 lgsm/modules/check_permissions.sh create mode 100644 lgsm/modules/check_root.sh create mode 100644 lgsm/modules/check_status.sh create mode 100644 lgsm/modules/check_steamcmd.sh create mode 100644 lgsm/modules/check_system_dir.sh create mode 100644 lgsm/modules/check_system_requirements.sh create mode 100644 lgsm/modules/check_tmuxception.sh create mode 100644 lgsm/modules/check_version.sh create mode 100644 lgsm/modules/command_backup.sh create mode 100644 lgsm/modules/command_check_update.sh create mode 100644 lgsm/modules/command_console.sh create mode 100644 lgsm/modules/command_debug.sh create mode 100644 lgsm/modules/command_details.sh create mode 100644 lgsm/modules/command_dev_clear_modules.sh create mode 100644 lgsm/modules/command_dev_debug.sh create mode 100644 lgsm/modules/command_dev_details.sh create mode 100644 lgsm/modules/command_dev_detect_deps.sh create mode 100644 lgsm/modules/command_dev_detect_glibc.sh create mode 100644 lgsm/modules/command_dev_detect_ldd.sh create mode 100644 lgsm/modules/command_dev_query_raw.sh create mode 100644 lgsm/modules/command_fastdl.sh create mode 100644 lgsm/modules/command_install.sh create mode 100644 lgsm/modules/command_install_resources_mta.sh create mode 100644 lgsm/modules/command_mods_install.sh create mode 100644 lgsm/modules/command_mods_remove.sh create mode 100644 lgsm/modules/command_mods_update.sh create mode 100644 lgsm/modules/command_monitor.sh create mode 100644 lgsm/modules/command_postdetails.sh create mode 100644 lgsm/modules/command_restart.sh create mode 100644 lgsm/modules/command_send.sh create mode 100644 lgsm/modules/command_skeleton.sh create mode 100755 lgsm/modules/command_sponsor.sh create mode 100644 lgsm/modules/command_start.sh create mode 100644 lgsm/modules/command_stop.sh create mode 100644 lgsm/modules/command_test_alert.sh create mode 100644 lgsm/modules/command_ts3_server_pass.sh create mode 100644 lgsm/modules/command_update.sh create mode 100644 lgsm/modules/command_update_linuxgsm.sh create mode 100644 lgsm/modules/command_validate.sh create mode 100644 lgsm/modules/command_wipe.sh create mode 100644 lgsm/modules/compress_unreal2_maps.sh create mode 100644 lgsm/modules/compress_ut99_maps.sh create mode 100644 lgsm/modules/core_dl.sh create mode 100644 lgsm/modules/core_exit.sh create mode 100644 lgsm/modules/core_getopt.sh create mode 100644 lgsm/modules/core_github.sh create mode 100644 lgsm/modules/core_legacy.sh create mode 100644 lgsm/modules/core_logs.sh create mode 100644 lgsm/modules/core_messages.sh create mode 100644 lgsm/modules/core_modules.sh create mode 100644 lgsm/modules/core_steamcmd.sh create mode 100644 lgsm/modules/core_trap.sh create mode 100644 lgsm/modules/fix.sh create mode 100644 lgsm/modules/fix_ark.sh create mode 100644 lgsm/modules/fix_arma3.sh create mode 100755 lgsm/modules/fix_armar.sh create mode 100644 lgsm/modules/fix_av.sh create mode 100644 lgsm/modules/fix_bo.sh create mode 100755 lgsm/modules/fix_bt.sh create mode 100644 lgsm/modules/fix_cmw.sh create mode 100644 lgsm/modules/fix_csgo.sh create mode 100644 lgsm/modules/fix_dst.sh create mode 100644 lgsm/modules/fix_hw.sh create mode 100644 lgsm/modules/fix_ins.sh create mode 100644 lgsm/modules/fix_kf.sh create mode 100644 lgsm/modules/fix_kf2.sh create mode 100644 lgsm/modules/fix_mcb.sh create mode 100644 lgsm/modules/fix_mta.sh create mode 100644 lgsm/modules/fix_nmrih.sh create mode 100644 lgsm/modules/fix_onset.sh create mode 100644 lgsm/modules/fix_pvr.sh create mode 100644 lgsm/modules/fix_ro.sh create mode 100644 lgsm/modules/fix_rust.sh create mode 100644 lgsm/modules/fix_rw.sh create mode 100644 lgsm/modules/fix_samp.sh create mode 100644 lgsm/modules/fix_sdtd.sh create mode 100644 lgsm/modules/fix_sfc.sh create mode 100644 lgsm/modules/fix_sof2.sh create mode 100644 lgsm/modules/fix_squad.sh create mode 100644 lgsm/modules/fix_st.sh create mode 100644 lgsm/modules/fix_steamcmd.sh create mode 100644 lgsm/modules/fix_terraria.sh create mode 100644 lgsm/modules/fix_tf2.sh create mode 100644 lgsm/modules/fix_ts3.sh create mode 100644 lgsm/modules/fix_unt.sh create mode 100644 lgsm/modules/fix_ut.sh create mode 100644 lgsm/modules/fix_ut2k4.sh create mode 100644 lgsm/modules/fix_ut3.sh create mode 100644 lgsm/modules/fix_vh.sh create mode 100644 lgsm/modules/fix_wurm.sh create mode 100644 lgsm/modules/fix_zmr.sh create mode 100644 lgsm/modules/info_distro.sh create mode 100644 lgsm/modules/info_game.sh create mode 100644 lgsm/modules/info_messages.sh create mode 100644 lgsm/modules/info_stats.sh create mode 100644 lgsm/modules/install_complete.sh create mode 100644 lgsm/modules/install_config.sh create mode 100644 lgsm/modules/install_dst_token.sh create mode 100644 lgsm/modules/install_eula.sh create mode 100644 lgsm/modules/install_factorio_save.sh create mode 100644 lgsm/modules/install_gslt.sh create mode 100644 lgsm/modules/install_header.sh create mode 100644 lgsm/modules/install_logs.sh create mode 100644 lgsm/modules/install_mta_resources.sh create mode 100644 lgsm/modules/install_retry.sh create mode 100644 lgsm/modules/install_server_dir.sh create mode 100644 lgsm/modules/install_server_files.sh create mode 100644 lgsm/modules/install_squad_license.sh create mode 100644 lgsm/modules/install_stats.sh create mode 100644 lgsm/modules/install_steamcmd.sh create mode 100644 lgsm/modules/install_ts3db.sh create mode 100644 lgsm/modules/install_ut2k4_key.sh create mode 100644 lgsm/modules/mods_core.sh create mode 100644 lgsm/modules/mods_list.sh create mode 100644 lgsm/modules/query_gamedig.sh create mode 100644 lgsm/modules/query_gsquery.py create mode 100644 lgsm/modules/update_fctr.sh create mode 100644 lgsm/modules/update_jk2.sh create mode 100644 lgsm/modules/update_mc.sh create mode 100644 lgsm/modules/update_mcb.sh create mode 100644 lgsm/modules/update_mta.sh create mode 100644 lgsm/modules/update_pmc.sh create mode 100644 lgsm/modules/update_steamcmd.sh create mode 100644 lgsm/modules/update_ts3.sh create mode 100644 lgsm/modules/update_ut99.sh create mode 100644 lgsm/modules/update_vints.sh create mode 100755 linuxgsm.sh create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f20e02e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,28 @@ +# EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs. +# Atom: Please assure your Atom's config setting Tab Type is set to auto, otherwise Atom-EditorConfig may not work as expected. Also disable whitespace package. +# http://editorconfig.org/ + +root = true + +[*] +charset = utf-8 +indent_style = tab +indent_size = 4 +trim_trailing_whitespace = true +end_of_line = lf +insert_final_newline = true + +# YAML Files +[*.{yml,yaml}] +indent_size = 2 +indent_style = space + +# JSON Files +[*.{json,json5,webmanifest}] +indent_size = 2 +indent_style = space + +# BASH Files +[*.{.sh}] +indent_style = tab +indent_size = 4 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..cfa570e --- /dev/null +++ b/.gitattributes @@ -0,0 +1,22 @@ +# crlf line endings for text files +* text eol=lf + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.jpg binary +*.so.6 binary + +# Custom for Visual Studio +*.cs diff=csharp + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..441867e --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: dgibbs64 # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: dgibbs # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with a single custom sponsorship URL diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..2b339d1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,96 @@ +--- +name: Bug Report +description: File a bug report +title: "[Bug]: " +labels: ["type: bug"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! + - type: input + id: user-story + attributes: + label: User story + description: As a [user description], I want [desired action] so that [desired outcome]. + placeholder: As a [user description], I want [desired action] so that [desired outcome]. + validations: + required: true + - type: input + id: game + attributes: + label: Game + description: What game server are you hosting? + placeholder: Valheim + validations: + required: true + - type: dropdown + id: distro + attributes: + label: Linux distro + multiple: true + options: + - Ubuntu 22.04 + - Ubuntu 20.04 + - Ubuntu 18.04 + - Ubuntu 16.04 + - Debian 12 + - Debian 11 + - Debian 10 + - Debian 9 + - RedHat 9 + - RedHat 8 + - RedHat 7 + - Other + validations: + required: true + - type: dropdown + id: command + attributes: + label: Command + multiple: true + options: + - "command: start" + - "command: stop" + - "command: restart" + - "command: monitor" + - "command: details" + - "command: update" + - "command: validate" + - "command: backup" + - "command: mods-install" + - "command: mods-update" + - "command: mods-remove" + - "command: debug" + - "command: console" + - "command: install" + - "command: auto-update" + - "command: update-lgsm" + - "command: wipe" + - "command: send" + validations: + required: true + - type: textarea + id: further-info + attributes: + label: Further information + description: A clear description of what the bug is, any ideas on how to resolve it and any further context that might be relevant to the issue. + placeholder: Tell us what you see! + validations: + required: true + - type: textarea + id: logs + attributes: + label: Relevant log output + description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. + render: shell + - type: textarea + id: steps + attributes: + label: Steps to reproduce + description: Steps to reproduce the behaviour. + placeholder: | + 1. Go to '...' + 2. Click on '....' + 3. Scroll down to '....' + 4. See error diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..d2113c6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Ask a question + about: Ask questions and discuss with other users of LinuxGSM. + url: https://github.com/GameServerManagers/LinuxGSM/discussions + - name: Discord Server + about: Join the LinuxGSM Discord community server. Discuss your LinuxGSM setup, get help and advice + url: https://linuxgsm.com/discord diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..45aced3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,79 @@ +--- +name: Feature Request +description: Suggest a feature +title: "[Feature]: " +labels: ["type: feature"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this feature request! + - type: input + id: user-story + attributes: + label: User story + description: As a [user description], I want [desired action] so that [desired outcome]. + placeholder: As a [user description], I want [desired action] so that [desired outcome]. + validations: + required: true + - type: input + id: game + attributes: + label: Game + description: What game server are you hosting? + placeholder: Valheim + validations: + required: false + - type: dropdown + id: distro + attributes: + label: Linux distro + multiple: true + options: + - Ubuntu 22.04 + - Ubuntu 20.04 + - Ubuntu 18.04 + - Ubuntu 16.04 + - Debian 12 + - Debian 11 + - Debian 10 + - Debian 9 + - RedHat 9 + - RedHat 8 + - RedHat 7 + - Other + validations: + required: false + - type: dropdown + id: command + attributes: + label: Command + multiple: true + options: + - "command: start" + - "command: stop" + - "command: restart" + - "command: monitor" + - "command: details" + - "command: update" + - "command: validate" + - "command: backup" + - "command: mods-install" + - "command: mods-update" + - "command: mods-remove" + - "command: debug" + - "command: console" + - "command: install" + - "command: auto-update" + - "command: update-lgsm" + - "command: wipe" + - "command: send" + validations: + required: true + - type: textarea + id: further-info + attributes: + label: Further information + description: A clear description of what the feature is and any ideas on how to achieve this. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/server_request.yml b/.github/ISSUE_TEMPLATE/server_request.yml new file mode 100644 index 0000000..31dbc6b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/server_request.yml @@ -0,0 +1,57 @@ +--- +name: Server Request +description: Suggest a new game server to be added +title: "[Server Request]: " +labels: ["type: game server request"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this game server! + - type: input + id: game-server + attributes: + label: Game server + description: What game server would you like to add? + validations: + required: true + - type: checkboxes + id: on-linux + attributes: + label: Linux support + description: Does this game server have Linux support? (not wine) + options: + - label: "Yes" + validations: + required: true + - type: dropdown + id: on-steam + attributes: + label: Steam + description: Is this game server available on Steam? + options: + - "Yes" + - "No" + validations: + required: true + - type: input + id: steam-id + attributes: + label: Steam appid + description: What is the Steam appid of the game server? Use SteamDB to get the appid. (https://steamdb.info). + placeholder: "892970" + validations: + required: false + - type: textarea + id: guides + attributes: + label: Guides + description: Links to guides on how to install the game server + - type: checkboxes + id: terms + attributes: + label: Code of Conduct + description: By submitting this issue, you agree to follow our [Code of Conduct](https://example.com) + options: + - label: I agree to follow this project's Code of Conduct + required: true diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..443cf3b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +# Set update schedule for GitHub Actions +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every weekday + interval: "daily" diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 0000000..3da0d47 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,160 @@ +"command: backup": + - "/(backup)/i" +"command: console": + - "/(console|tmux)/i" +"command: debug": + - "/(command: debug)/i" +"command: details": + - "/(command: details)/i" +"command: fast-dl": + - "/(fast-dl|fastdl)/i" +"command: install": + - "/(install)/i" +"command: mods": + - "/(command: mods)/i" +"command: monitor": + - "/(command: monitor)/i" +"command: post-details": + - "/(command: post-details)/i" +"command: restart": + - "/(command: restart)/i" +"command: send": + - "/(command: send)/i" +"command: skeleton": + - "/(command: skeleton)/i" +"command: start": + - "/(command: start)/i" +"command: stop": + - "/(command: stop)/i" +"command: update-lgsm": + - "/(update-lgsm)/i" +"command: update": + - "/(command: update)/i" +"command: validate": + - "/(validate)/i" +"command: wipe": + - "/(wipe)/i" + +# Distros +"distro: AlmaLinux": + - "/(Alma)/i" +"distro: Arch Linux": + - "/(Arch Linux)/i" +"distro: CentOS": + - "/(CentOS)/i" +"distro: Debian": + - "/(Debian)/i" +"distro: Fedora": + - "/(Fedora)/i" +"distro: openSUSE": + - "/(openSUSE|suse)/i" +"distro: Rocky Linux": + - "/(Rocky)/i" +"distro: Slackware": + - "/(Slackware)/i" +"distro: Ubuntu": + - "/(Ubuntu)/i" + +# Games +"game: 7 Days to Die": + - "/(7 Days to Die|sdtd)/i" +"game: Ark: Survival Evolved": + - "/(Ark: Survival Evolved|Ark)/i" +"game: ARMA 3": + - "/(ARMA 3|ARMA3)/i" +"game: Assetto Corsa": + - "/(Assetto Corsa)/i" +"game: Avorion": + - "/(Avorion)/i" +"game: Ballistic Overkill": + - "/(Ballistic Overkill)/i" +"game: BATTALION: Legacy": + - "/(BATTALION: Legacy)/i" +"game: Barotrauma": + - "/(Barotrauma)/i" +"game: Counter-Strike: Global Offensive": + - "/(Counter-Strike: Global Offensive|CS:GO|csgo)/i" +"game: Counter-Strike: Source": + - "/(Counter-Strike: Source|CS:S)/i" +"game: Counter-Strike 1.6": + - "/(Counter-Strike 1.6|Counter Strike 1.6|CS 1.6|cs1.6)/i" +"game: Dayz": + - "/(Dayz)/i" +"game: Don't Starve Together": + - "/(Don't Starve Together|Dont Starve Together|DST)/i" +"game: Eco": + - "/(^Eco$)/i" +"game: Factorio": + - "/(Factorio)/i" +"game: Garry's Mod": + - "/(Garry's Mod|Garrys Mod|GMod)/i" +"game: Insurgency: Sandstorm": + - "/(Insurgency: Sandstorm|Insurgency)/i" +"game: Killing Floor 2": + - "/(Killing Floor 2|KF2)/i" +"game: Left 4 Dead 2": + - "/(Left 4 Dead 2|L4D2)/i" +"game: Minecraft": + - "/(minecraft)((?!bedrock).)*$/i" +"game: Minecraft Bedrock": + - "/(Bedrock)/i" +"game: Mumble": + - "/(Mumble)/i" +"game: Project Zomboid": + - "/(Project Zomboid)/i" +"game: Quake 3": + - "/(Quake 3|Q3A|q3)/i" +"game: Rising World": + - "/(Rising World)/i" +"game: Satisfactory": + - "/(Satisfactory)/i" +"game: Squad": + - "/(Squad)/i" +"game: Starbound": + - "/(Starbound)/i" +"game: Stationeers": + - "/(Stationeers)/i" +"game: Teamspeak 3": + - "/(Teamspeak 3|ts3)/i" +"game: Rust": + - "/(Rust)/i" +"game: Unturned": + - "/(Unturned)/i" +"game: Unreal Tournament 99": + - "/(Unreal Tournament 99|ut99)/i" +"game: Unreal Tournament 2004": + - "/(Unreal Tournament 2004|ut2k4)/i" +"game: Unreal Tournament 3": + - "/(Unreal Tournament 3|ut3)/i" +"game: Valheim": + - "/(Valheim)/i" + +# Info +"info: alerts": + - "/(alert)/i" +"info: dependency": + - "/(dependency|deps)/i" +"info: docker": + - "/(docker)/i" +"info: docs": + - "/(documentation|^docs$)/i" +"info: email": + - "/(postfix|sendmail|exim|smtp)/i" +"info: query": + - "/(gamedig|gsquery)/i" +"info: steamcmd": + - "/(steamcmd)/i" +"info: systemd": + - "/(systemd)/i" +"info: tmux": + - "/(tmux)/i" +"info: website": + - "/(website)/i" + +# Type +"type: game server request": + - "/(Server Request)/i" +"type: bug": + - "/(bug)/i" +"type: feature request": + - "/(feature)/i" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..4e6d083 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,35 @@ +# Description + +Please include a summary of the change and which issues are fixed. + +Fixes #[issue] + +## Type of change + +- [ ] Bug fix (a change which fixes an issue). +- [ ] New feature (a change which adds functionality). +- [ ] New Server (new server added). +- [ ] Refactor (restructures existing code). +- [ ] Comment update (typo, spelling, explanation, examples, etc). + +## Checklist + +PR will not be merged until all steps are complete. + +- [ ] This pull request links to an issue. +- [ ] This pull request uses the `develop` branch as its base. +- [ ] This pull request subject follows the Conventional Commits standard. +- [ ] This code follows the style guidelines of this project. +- [ ] I have performed a self-review of my code. +- [ ] I have checked that this code is commented where required. +- [ ] I have provided a detailed enough description of this PR. +- [ ] I have checked if documentation needs updating. + +## Documentation + +If documentation does need updating either update it by creating a PR (preferred) or request a documentation update. + +- User docs: https://github.com/GameServerManagers/LinuxGSM-Docs +- Dev docs: https://github.com/GameServerManagers/LinuxGSM-Dev-Docs + +**Thank you for your Pull Request!** diff --git a/.github/workflows/add-to-project.yml b/.github/workflows/add-to-project.yml new file mode 100644 index 0000000..e429645 --- /dev/null +++ b/.github/workflows/add-to-project.yml @@ -0,0 +1,17 @@ +name: Add to Project +on: + issues: + types: + - opened + - labeled + +jobs: + add-to-project: + runs-on: ubuntu-latest + steps: + - name: Add to Project + uses: actions/add-to-project@v0.5.0 + with: + project-url: https://github.com/orgs/GameServerManagers/projects/11 + github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} + labeled: "type: game server request" diff --git a/.github/workflows/details-check.yml b/.github/workflows/details-check.yml new file mode 100644 index 0000000..ce9b459 --- /dev/null +++ b/.github/workflows/details-check.yml @@ -0,0 +1,85 @@ +# This action will check that LinuxGSM is picking up game server config and parameter variables. +name: Details Check +on: + workflow_dispatch: + push: + +concurrency: + group: details-check-${{ github.ref_name }} + cancel-in-progress: true + +jobs: + create-matrix: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Generate matrix with generate-matrix.sh + run: chmod +x .github/workflows/detals-check-generate-matrix.sh; .github/workflows/detals-check-generate-matrix.sh + + - name: Set Matrix + id: set-matrix + run: | + shortnamearray=$(cat shortnamearray.json) + echo "${shortnamearray}" + echo -n "matrix=${shortnamearray}" >> $GITHUB_OUTPUT + + details-check: + needs: create-matrix + continue-on-error: true + runs-on: ubuntu-latest + + strategy: + matrix: ${{ fromJSON(needs.create-matrix.outputs.matrix) }} + + steps: + - name: Download linuxgsm.sh + run: wget https://raw.githubusercontent.com/GameServerManagers/LinuxGSM/${GITHUB_REF#refs/heads/}/linuxgsm.sh; chmod +x linuxgsm.sh + + - name: Install dependencies + run: sudo apt-get install libxml2-utils jq + + - name: Create serverfiles directory + run: mkdir -p serverfiles + + - name: Grab server + run: LGSM_GITHUBBRANCH="${GITHUB_REF#refs/heads/}" ./linuxgsm.sh ${{ matrix.shortname }}server + + - name: Enable developer mode + run: LGSM_GITHUBBRANCH="${GITHUB_REF#refs/heads/}" ./${{ matrix.shortname }}server developer + + - name: Generate servercfgname + id: sets-servercfgname + run: | + servercfg=$(sed -n "/^\/ { s/.*= *\"\?\([^\"']*\)\"\?/\1/p;q }" lgsm/config-lgsm/${{ matrix.shortname }}server/_default.cfg) + echo "servercfgname=$servercfg" >> "$GITHUB_OUTPUT" + + - name: Download config + run: | + if [ "${{ steps.sets-servercfgname.outputs.servercfgname }}" == "" ]; then + echo "This game server has no config file." + else + curl -f -o config "https://raw.githubusercontent.com/GameServerManagers/Game-Server-Configs/main/${{ matrix.shortname }}/${{ steps.sets-servercfgname.outputs.servercfgname }}" + fi + - name: Display config + run: | + if [ "${{ steps.sets-servercfgname.outputs.servercfgname }}" == "" ]; then + echo "This game server has no config file." + else + cat config + fi + + - name: Display parameters + run: grep "startparameters" lgsm/config-default/config-lgsm/${{ matrix.shortname }}server/_default.cfg + + - name: Details + run: LGSM_GITHUBBRANCH="${GITHUB_REF#refs/heads/}" ./${{ matrix.shortname }}server details + + - name: Detect details + run: LGSM_GITHUBBRANCH="${GITHUB_REF#refs/heads/}" ./${{ matrix.shortname }}server detect-details + + - name: Query Raw + run: LGSM_GITHUBBRANCH="${GITHUB_REF#refs/heads/}" ./${{ matrix.shortname }}server query-raw diff --git a/.github/workflows/detals-check-generate-matrix.sh b/.github/workflows/detals-check-generate-matrix.sh new file mode 100755 index 0000000..bba9e8d --- /dev/null +++ b/.github/workflows/detals-check-generate-matrix.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +curl "https://raw.githubusercontent.com/GameServerManagers/LinuxGSM/${GITHUB_REF#refs/heads/}/lgsm/data/serverlist.csv" | grep -v '^[[:blank:]]*$' > serverlist.csv + +echo -n "{" > "shortnamearray.json" +echo -n "\"include\":[" >> "shortnamearray.json" + +while read -r line; do + shortname=$(echo "$line" | awk -F, '{ print $1 }') + export shortname + servername=$(echo "$line" | awk -F, '{ print $2 }') + export servername + gamename=$(echo "$line" | awk -F, '{ print $3 }') + export gamename + distro=$(echo "$line" | awk -F, '{ print $4 }') + export distro + echo -n "{" >> "shortnamearray.json" + echo -n "\"shortname\":" >> "shortnamearray.json" + echo -n "\"${shortname}\"" >> "shortnamearray.json" + echo -n "}," >> "shortnamearray.json" +done < <(tail -n +2 serverlist.csv) +sed -i '$ s/.$//' "shortnamearray.json" +echo -n "]" >> "shortnamearray.json" +echo -n "}" >> "shortnamearray.json" +rm serverlist.csv diff --git a/.github/workflows/git-sync.yml b/.github/workflows/git-sync.yml new file mode 100644 index 0000000..42ddd42 --- /dev/null +++ b/.github/workflows/git-sync.yml @@ -0,0 +1,26 @@ +name: Github to Bitbucket Sync +# This action will sync the github repo with a backup bitbucket repo. +# This will allow LinuxGSM to use Bitbucket as and alternative download if github fails. +on: + push: + branches: + - master + - develop + +jobs: + gitHub-to-bitbucket: + runs-on: ubuntu-latest + steps: + - name: SSH Agent + uses: webfactory/ssh-agent@v0.8.0 + with: + ssh-private-key: ${{ secrets.BITBUCKET_SECRET }} + + - name: Git Sync + uses: wei/git-sync@v3.0.0 + with: + ssh_private_key: ${{ secrets.BITBUCKET_SECRET }} + source_repo: "https://github.com/GameServerManagers/LinuxGSM" + source_branch: "refs/heads/*" + destination_repo: "git@bitbucket.org:GameServerManagers/linuxgsm.git" + destination_branch: "refs/heads/*" diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 0000000..44beca0 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,30 @@ +name: Issue Labeler +on: + issues: + types: + - opened + - edited + +permissions: + issues: write + contents: read + +jobs: + issue-labeler: + runs-on: ubuntu-latest + steps: + - name: Issue Labeler + uses: github/issue-labeler@v3.2 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + configuration-path: .github/labeler.yml + enable-versioned-regex: 0 + include-title: 1 + + is-sponsor-label: + runs-on: ubuntu-latest + steps: + - name: Is Sponsor Label + uses: JasonEtco/is-sponsor-label-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml new file mode 100644 index 0000000..4883914 --- /dev/null +++ b/.github/workflows/lock.yml @@ -0,0 +1,25 @@ +name: Lock Threads +on: + schedule: + - cron: "0 0 * * 1" + +permissions: + issues: write + pull-requests: write + +jobs: + lock: + runs-on: ubuntu-latest + steps: + - name: Lock Threads + uses: dessant/lock-threads@v4 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + issue-comment: > + This issue has been automatically locked since there + has not been any recent activity after it was closed. + Please open a new issue for related bugs. + pr-comment: > + This pull request has been automatically locked since there + has not been any recent activity after it was closed. + Please open a new issue for related bugs. diff --git a/.github/workflows/potential-duplicates.yml b/.github/workflows/potential-duplicates.yml new file mode 100644 index 0000000..3c7f433 --- /dev/null +++ b/.github/workflows/potential-duplicates.yml @@ -0,0 +1,22 @@ +name: Potential Duplicates +on: + issues: + types: + - opened +jobs: + potential-duplicates: + runs-on: ubuntu-latest + steps: + - name: Potential Duplicates + uses: wow-actions/potential-duplicates@v1 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + filter: "" + exclude: "" + label: potential-duplicate + state: all + threshold: 0.8 + comment: > + Potential duplicates: {{#issues}} + - [#{{ number }}] {{ title }} ({{ accuracy }}%) + {{/issues}} diff --git a/.github/workflows/serverlist-validate-game-icons.sh b/.github/workflows/serverlist-validate-game-icons.sh new file mode 100755 index 0000000..ca41892 --- /dev/null +++ b/.github/workflows/serverlist-validate-game-icons.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +cd "lgsm/data" || exit + +echo "" +echo "Checking that all the game servers listed in serverlist.csv have a shortname-icon.png file" +for shortname in $(tail -n +2 serverlist.csv | cut -d ',' -f1); do + # check if $shortname-icon.png exists + if [ ! -f "gameicons/${shortname}-icon.png" ]; then + echo "ERROR: gameicons/${shortname}-icon.png does not exist" + exitcode=1 + else + echo "OK: gameicons/${shortname}-icon.png exists" + fi +done + +echo "" +echo "Checking if an unexpected gameicon exists" +for gameicon in $(ls -1 gameicons); do + # check if $gameicon is in serverlist.csv + if ! grep -q "${gameicon%-icon.png}" serverlist.csv; then + echo "ERROR: gameicon ${gameicon} is not in serverlist.csv" + exitcode=1 + else + echo "OK: gameicon ${gameicon} is in serverlist.csv" + fi +done + +echo "" +echo "Checking that the number of gameicons matches the number of servers in serverlist.csv" +gameiconcount="$(ls -1 gameicons | wc -l)" +serverlistcount="$(tail -n +2 serverlist.csv | wc -l)" +if [ "${gameiconcount}" -ne "${serverlistcount}" ]; then + echo "ERROR: game icons (${gameiconcount}) does not match serverlist.csv ($serverlistcount)" + exitcode=1 +else + echo "OK: gameiconcount ($gameiconcount) matches serverlistcount ($serverlistcount)" +fi + +exit ${exitcode} diff --git a/.github/workflows/serverlist-validate.sh b/.github/workflows/serverlist-validate.sh new file mode 100755 index 0000000..0c76340 --- /dev/null +++ b/.github/workflows/serverlist-validate.sh @@ -0,0 +1,38 @@ +#!/bin/bash +echo "Checking that all the game servers are listed in all csv files" +echo "this check will ensure serverlist.csv has the same number of lines (-2 lines) as the other csv files" +# count the number of lines in the serverlist.csv +cd "lgsm/data" || exit +serverlistcount="$(tail -n +2 serverlist.csv | wc -l)" +echo "serverlistcount: $serverlistcount" +# get list of all csv files starting with ubunutu debian centos +csvlist="$(ls -1 | grep -E '^(ubuntu|debian|centos|rhel|almalinux|rocky).*\.csv$')" +# loop though each csv file and make sure the number of lines is the same as the serverlistcount +for csv in $csvlist; do + csvcount="$(wc -l < "${csv}")" + csvcount=$((csvcount - 2)) + if [ "$csvcount" -ne "$serverlistcount" ]; then + echo "ERROR: $csv ($csvcount) does not match serverlist.csv ($serverlistcount)" + exitcode=1 + else + echo "OK: $csv ($csvcount) and serverlist.csv ($serverlistcount) match" + fi +done + +# Compare all game servers listed in serverlist.csv to $shortname-icon.png files in lgsm/data/gameicons +# if the game server is listed in serverlist.csv then it will have a $shortname-icon.png file + +# loop though shortname in serverlist.csv +echo "" +echo "Checking that all the game servers listed in serverlist.csv have a shortname-icon.png file" +for shortname in $(tail -n +2 serverlist.csv | cut -d ',' -f1); do + # check if $shortname-icon.png exists + if [ ! -f "gameicons/${shortname}-icon.png" ]; then + echo "ERROR: gameicons/${shortname}-icon.png does not exist" + exitcode=1 + else + echo "OK: gameicons/${shortname}-icon.png exists" + fi +done + +exit ${exitcode} diff --git a/.github/workflows/serverlist-validate.yml b/.github/workflows/serverlist-validate.yml new file mode 100644 index 0000000..9313295 --- /dev/null +++ b/.github/workflows/serverlist-validate.yml @@ -0,0 +1,17 @@ +name: Server List Validation +on: + workflow_dispatch: + push: + +jobs: + serverlist-validate: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Compare Versions + run: chmod +x .github/workflows/serverlist-validate.sh; .github/workflows/serverlist-validate.sh + + - name: Validate Game Icons + run: chmod +x .github/workflows/serverlist-validate-game-icons.sh; .github/workflows/serverlist-validate-game-icons.sh diff --git a/.github/workflows/trigger-docker-build.yml b/.github/workflows/trigger-docker-build.yml new file mode 100644 index 0000000..61ec91d --- /dev/null +++ b/.github/workflows/trigger-docker-build.yml @@ -0,0 +1,31 @@ +name: Trigger Docker Build +on: + release: + types: + - published + +jobs: + trigger_build_docker-linuxgsm: + name: Trigger Build Docker LinuxGSM + runs-on: ubuntu-latest + steps: + - name: Trigger Workflow and Wait (linuxgsm) + uses: convictional/trigger-workflow-and-wait@v1.6.5 + with: + owner: GameServerManagers + repo: docker-linuxgsm + github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + workflow_file_name: docker-publish.yml + + trigger_build_docker-gameserver: + name: Trigger Build Docker GameServer + needs: trigger_build_docker-linuxgsm + runs-on: ubuntu-latest + steps: + - name: Trigger Workflow and Wait (gameserver) + uses: convictional/trigger-workflow-and-wait@v1.6.5 + with: + owner: GameServerManagers + repo: docker-gameserver + github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + workflow_file_name: docker-publish.yml diff --git a/.github/workflows/update-check.yml b/.github/workflows/update-check.yml new file mode 100644 index 0000000..dfbc7dd --- /dev/null +++ b/.github/workflows/update-check.yml @@ -0,0 +1,48 @@ +name: Update Check +# This action will check that LinuxGSM is picking up game server config and parameter variables. +on: + workflow_dispatch: + push: + +concurrency: + group: update-check-${{ github.ref_name }} + cancel-in-progress: true + +jobs: + update-check: + continue-on-error: true + runs-on: ubuntu-latest + + strategy: + matrix: + shortname: [css, fctr, jk2, mc, mcb, mta, pmc, ts3, ut99, vints] + + steps: + - name: Download linuxgsm.sh + run: wget https://raw.githubusercontent.com/GameServerManagers/LinuxGSM/${GITHUB_REF#refs/heads/}/linuxgsm.sh; chmod +x linuxgsm.sh + + - name: Install dependencies + run: sudo dpkg --add-architecture i386; sudo apt-get update; + + - name: Grab server + run: LGSM_GITHUBBRANCH="${GITHUB_REF#refs/heads/}" ./linuxgsm.sh ${{ matrix.shortname }}server + + - name: Enable developer mode + run: LGSM_GITHUBBRANCH="${GITHUB_REF#refs/heads/}" ./${{ matrix.shortname }}server developer + + - name: Insert steamuser + if: matrix.shortname == 'jk2' + run: echo -e "steamuser=\"${{ secrets.STEAMCMD_USER }}\"\nsteampass='${{ secrets.STEAMCMD_PASS }}'" > lgsm/config-lgsm/${{ matrix.shortname }}server/common.cfg + + - name: Install server + run: LGSM_GITHUBBRANCH="${GITHUB_REF#refs/heads/}" ./${{ matrix.shortname }}server auto-install + + - name: Check Update server + run: LGSM_GITHUBBRANCH="${GITHUB_REF#refs/heads/}" ./${{ matrix.shortname }}server check-update + + - name: Update server + run: LGSM_GITHUBBRANCH="${GITHUB_REF#refs/heads/}" ./${{ matrix.shortname }}server update + + - name: Force Update server + if: matrix.shortname == 'css' + run: LGSM_GITHUBBRANCH="${GITHUB_REF#refs/heads/}" ./${{ matrix.shortname }}server force-update diff --git a/.github/workflows/update-copyright-years-in-license-file.yml b/.github/workflows/update-copyright-years-in-license-file.yml new file mode 100644 index 0000000..2d6d3ee --- /dev/null +++ b/.github/workflows/update-copyright-years-in-license-file.yml @@ -0,0 +1,24 @@ +name: Update copyright year(s) in license file +on: + workflow_dispatch: + schedule: + - cron: "0 3 1 1 *" # 03:00 AM on January 1 + +jobs: + update-license-year: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Action Update License Year + uses: FantasticFiasco/action-update-license-year@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + path: LICENSE.md + - name: Merge pull request + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh pr merge --merge --delete-branch diff --git a/.github/workflows/version-check.sh b/.github/workflows/version-check.sh new file mode 100644 index 0000000..a5f21c5 --- /dev/null +++ b/.github/workflows/version-check.sh @@ -0,0 +1,15 @@ +#!/bin/bash +version=$(grep "version=" linuxgsm.sh | sed -e 's/version//g' | tr -d '="') +modulesversion=$(grep "modulesversion=" lgsm/modules/core_modules.sh | sed -e 's/modulesversion//g' | tr -d '="') + +if [ "${version}" != "${modulesversion}" ]; then + echo "Error! LinuxGSM version mismatch" + echo "Version: ${version}" + echo "Modules Version: ${modulesversion}" + exit 1 +else + echo "Success! LinuxGSM version match" + echo "Version: ${version}" + echo "Modules Version: ${modulesversion}" + exit +fi diff --git a/.github/workflows/version-check.yml b/.github/workflows/version-check.yml new file mode 100644 index 0000000..a66eaca --- /dev/null +++ b/.github/workflows/version-check.yml @@ -0,0 +1,16 @@ +name: Version Check +on: + push: + +permissions: + contents: read + +jobs: + version-Check: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Version Check + run: chmod +x .github/workflows/version-check.sh; .github/workflows/version-check.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e5c465c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.vscode/settings.json +/node_modules diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..1902f80 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "plugins": ["prettier-plugin-sh"] +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..c7a7dab --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + "recommendations": [ + "ms-python.python", + "editorconfig.editorconfig", + "yzhang.markdown-all-in-one", + "esbenp.prettier-vscode", + "timonwong.shellcheck", + "redhat.vscode-yaml" + ] +} diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..a693252 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,132 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or + advances of any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email + address, without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[INSERT CONTACT METHOD]. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][mozilla coc]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][faq]. Translations are available +at [https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[mozilla coc]: https://github.com/mozilla/diversity +[faq]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..7b549c7 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,226 @@ +# Contributing to LinuxGSM + +👍🎉 Thank you for taking the time to contribute! 🎉👍 + +The following is a set of guidelines for contributing to LinuxGSM, which are hosted in the [GameServerManagers Organization](https://github.com/gameservermanagers) on GitHub. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. + +## Table of Contents + +[Contributing to LinuxGSM](#contributing-to-linuxgsm) + +- [Table of Contents](#table-of-contents) +- [Code of Conduct](#code-of-conduct) +- [🎉 Bug/Enhancement Contributions 🐛](#bug-enhancement-contributions) + - [🐛Reporting Bugs](#reporting-bugs) + - [Before Submitting A Bug Report](#before-submitting-a-bug-report) + - [How Do I Submit A (Good) Bug Report?](#how-do-i-submit-a--good--bug-report-) + - [🎉Suggesting Features](#suggesting-features) + - [Before Submitting An Feature Suggestion](#before-submitting-an-feature-suggestion) + - [How Do I Submit A (Good) Feature Suggestion?](#how-do-i-submit-a--good--feature-suggestion-) + - [🎮 Game Server Requests](#game-server-requests) + - [Before Submitting a Game Server Request](#before-submitting-a-game-server-request) + - [How Do I Submit A (Good) Game Server Request?](#how-do-i-submit-a--good--game-server-request-) + - [🎮 Game Server Specific Issues](#game-server-specific-issues) +- [💻 Code Contributions](#code-contributions) + - [Pull Requests](#pull-requests) + - [Pull Request naming convention](#pull-request-naming-convention) + - [Testing](#testing) + - [Pull Request Status Checks](#pull-request-status-checks) + - [Test Environment](#test-environment) + - [:wine_glass: Styleguides](#-wine-glass--styleguides) + - [Git Commit Messages](#git-commit-messages) + - [BASH Styleguide](#bash-styleguide) +- [:blue_book: Document Contributions](#-blue-book--document-contributions) + - [Documentation Styleguide](#documentation-styleguide) +- [Issue and Pull Request Labels](#issue-and-pull-request-labels) + +## Code of Conduct + +This project and everyone participating in it is governed by the [LinuxGSM Code of Conduct](https://github.com/GameServerManagers/linuxgsm/blob/master/CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behaviour to [daniel.gibbs@linuxgsm.com](mailto:daniel.gibbs@linuxgsm.com). + +## 🎉 Bug/Enhancement Contributions 🐛 + +### 🐛Reporting Bugs + +This section guides you through submitting a bug report for LinuxGSM. Following these guidelines help maintainers and the community understand your report 📝, reproduce the behaviour💻, and find any related reports 🔎. + +Before creating bug reports, please check [this list](https://github.com/GameServerManagers/linuxgsm/blob/master/CONTRIBUTING.md#before-submitting-a-bug-report) as you might find out that you don’t need to create one. When you are creating a bug report, please [include as many details as possible](https://github.com/GameServerManagers/linuxgsm/blob/master/CONTRIBUTING.md#how-do-i-submit-a-good-bug-report). Fill out [the required template](<[https://github.com/GameServerManagers/LinuxGSM/issues/new/choose](https://github.com/GameServerManagers/LinuxGSM/issues/new/choose)>), the information it asks for helps us resolve issues faster. + +#### Before Submitting A Bug Report + +- **Check the [documentation](https://docs.linuxgsm.com).** You might be able to find the cause of the problem and fix things yourself. +- **Check the** [**support page**](https://linuxgsm.com/support) for links to other support options. +- **Perform a** [**cursory search**](https://github.com/search?q=org:GameServerManagers%20type:issues&type=Issues) to see if the problem has already been reported. If it has **and the issue is still open**, add a comment to the existing issue and give it a thumbs up instead of opening a new one. + +#### How Do I Submit A (Good) Bug Report? + +Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). Create an issue and provide the following information by filling in [the issues form](https://github.com/GameServerManagers/LinuxGSM/issues/new/choose). + +- **Use a clear and descriptive title** for the issue to identify the problem. +- **Complete the user story** to give a summary of the issue. +- **Provide basic info** to help us understand the context of the issue. +- **Provide further info** to give specifics and more detail. +- **Give steps to reproduce** the issue, allowing developers to follow steps that lead to the issue. +- **Explain what you expect** to happen, so we know what you think should occur. + +### 🎉Suggesting Features + +This section guides you through submitting a feature suggestion for LinuxGSM, including completely new features and minor improvements to existing functionality. Following these guidelines help maintainers and the community understand your suggestion 📝 and find related suggestions 🔎. + +#### Before Submitting An Feature Suggestion + +- **Check the** [**documentation**]() to confirm that the enhancement doesn’t already exist. +- **Check your** [**LinuxGSM version**](https://docs.linuxgsm.com/commands/update-lgsm)**.** A newer version of LinuxGSM may already have your enhancement. +- **Perform a** [**cursory search**](https://github.com/search?q=org:GameServerManagers%20type:issues&type=Issues) to see if the enhancement has already been suggested. If it has **and the enhancement is still open**, add a comment to the existing issue and give it a thumbs up instead of opening a new one. + +#### How Do I Submit A (Good) Feature Suggestion? + +Features are tracked as [GitHub issues](https://guides.github.com/features/issues/). Create an issue and provide the following information by filling in [the issues form](https://github.com/GameServerManagers/LinuxGSM/issues/new/choose). + +- **Use a clear and descriptive title** for the issue to identify the problem. +- **Complete the user story** to give a summary of the issue. +- **Provide basic info** to help us understand the context of the enhancement. +- **Provide further info** to give specifics and more detail. +- **Provide any further reading** materials that might assist in developing the enhancement. + +### 🎮 Game Server Requests + +This section guides you through submitting a game server request for LinuxGSM, Following these guidelines help maintainers and the community understand your game server request 📝. + +#### Before Submitting a Game Server Request + +- **Check for existing** [**game server requests**](https://github.com/GameServerManagers/LinuxGSM/labels/type%3A%20game%20server%20request) to see if the new game server has already been suggested. If it has **and if the new game server is still open**, give it a thumbs up. +- **Check the game server is supported on Linux**, this does not include Wine servers which we do not support. + +#### How Do I Submit A (Good) Game Server Request? + +- The title should be as follows: **[Server Request] Game Name** +- **Provide Steam App ID** if applicable +- **Supply any documentation/how-to guides** for the game server. + +### 🎮 Game Server Specific Issues + +LinuxGSM is a management script that acts as a wrapper around game servers. These game servers are developed by different game developers such as Valve, Epic and Facepunch to name a few. + +LinuxGSM has no control over the development and limited knowledge of issues directly relating to the game servers themselves. The same also applies to any mods, add-ons, maps etc. + +If there is an issue with a specific game server or mod the best action may be to contact the game/mod developers on their support forums. If it is unclear some community members should be able to help. + +A [list](https://docs.linuxgsm.com/support/game-server) of known game developer forums is available on the [LinuxGSM docs](https://docs.linuxgsm.com/support/game-server). + +## 💻 Code Contributions + +### Pull Requests + +The process described here has several goals: + +- Maintain LinuxGSM quality. +- Fix problems that are important to users. +- Engage the community in working toward the best possible LinuxGSM. +- Enable a sustainable system for LinuxGSM maintainers to review contributions. + +Please follow these steps to have your contribution considered by the maintainers: + +1. Follow all check-list in [the template](https://github.com/GameServerManagers/LinuxGSM/blob/master/.github/pull_request_template.md) +2. Follow the [style guides](#styleguides) +3. After you submit your pull request, verify that all [status checks](https://help.github.com/articles/about-status-checks/) are passing + +What if the status checks are failing? If a status check is failing, and you believe that the failure is unrelated to your change, please leave a comment on the pull request explaining why you believe the failure is unrelated. A maintainer will re-run the status check for you. If we conclude that the failure was a false positive, then we will open an issue to track that problem with our status check suite. + +While the prerequisites above must be satisfied before having your pull request reviewed, the reviewer(s) may ask you to complete additional design work, tests, or other changes before your pull request can be ultimately accepted. + +#### Pull Request naming convention + +When naming a pull request to ensure that it is following [Conventional Commits](https://www.conventionalcommits.org/) standards; as your pull request commits will be squashed, with the PR subject becoming the commit that is used for generating the [changelog](https://github.com/GameServerManagers/LinuxGSM/releases) for the next release. + +The pull request subject line should always be able to complete the following sentence: + +If applied, this commit will _your subject line here_ + +For example: + +- If applied, this commit will **refactor subsystem X for readability** +- If applied, this commit will **update getting started documentation** +- If applied, this commit will **remove deprecated methods** +- If applied, this commit will **release version 1.0.0** +- If applied, this commit will **merge pull request #123 from user/branch** + +Notice how this doesn’t work for the other non-imperative forms: + +- If applied, this commit will **fixed bug with Y** +- If applied, this commit will **change the behaviour of X** +- If applied, this commit will **more fixes for broken stuff** +- If applied, this commit will **sweet new API methods** + +Below is an example of the subject line for a pull request: + +**feat(alerts): add slack support to alerts** + +**fix(csgoserver): remove SteamCMD auth requirement 32-bit workaround** + +### Testing + +#### Pull Request Status Checks + +When a Pull Request is submitted, a series of status check tests are conducted. These tests will assess the code quality, complete CI tests etc. To get your PR merged these status checks must pass. + +#### Test Environment + +It is recommended that you have a testing environment available to test your code during development. To test your own code you must change some variables within the `linuxgsm.sh` file. This will force the use of your own code branch. + +```bash +## GitHub Branch Select +# Allows for the use of different function files +# from a different repo and/or branch. +githubuser="GameServerManagers" +githubrepo="LinuxGSM" +githubbranch="master" +``` + +### :wine_glass: Styleguides + +#### Git Commit Messages + +LinuxGSM uses the Conventional commits standard to allow other developers to get easy to understand, descriptive commit messages as you develop. While it is recommended that you use this standard for your commits, as your commits will eventually be squashed when your PR is merged following this standard is not strictly enforced for commits, however, it is recommended for more complex commits. + +#### BASH Styleguide + +LinuxGSM uses [ShellCheck](https://www.shellcheck.net/) to follow BASH best practices. It is recommended that you make use of linter tools for your text editor such as [linter-shellcheck](https://atom.io/packages/linter-shellcheck). LinuxGSM uses [Codacy](https://app.codacy.com/manual/GameServerManagers/LinuxGSM/dashboard) to analyse any Pull Requests to give you feedback on code standards. + +LinuxGSM also has some of its style standards that should be followed. These are available in the [dev docs](https://dev-docs.linuxgsm.com/) + +## :blue_book: Document Contributions + +As well as code contributions it is possible to contribute by writing and improving documentation. Documents contributions can be submitted similarly by submitting a Pull Request. + +### Documentation Styleguide + +LinuxGSM has various documentation available to assist [users](https://docs.linuxgsm.com) and [developers](dev-docs.linuxgsm.com). LinuxGSM primarily uses [GitBook](http://gitbook.com/) which uses the [Markdown](https://www.markdownguide.org/) document standard. LinuxGSM uses [Codacy](https://app.codacy.com/manual/GameServerManagers/LinuxGSM/dashboard) to analyse any Pull Requests to give you feedback on markup standards. + +## Issue and Pull Request Labels + +This section lists the labels we use to help us track and manage issues and pull requests. + +[GitHub search](https://help.github.com/articles/searching-issues/) makes it easy to use labels for finding groups of issues or pull requests you're interested in. There are several categories of labels available: + +**command** Labels +Highlights the LinuxGSM command the Issue/PR relates to. + +**info** Labels +Labels to help pinpoint what the issue or PR relates to. + +variants: + +- _distro_ +- _engine_ +- _game_ +- _info_ + +**outcome** Labels +Labels that identify why an issue was closed. + +**status** Labels +Labels to update people on the status of the issue. + +**type** Labels +Labels identifying the type of issue, such as a bug, feature, refactor etc. diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..12352ea --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +# The MIT License (MIT) + +Copyright (c) 2012-2023 Daniel Gibbs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..db89b85 --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +

+ LinuxGSM + Codacy grade + GitHub Workflow Status + Discord + SteamCMD + MIT License +

+ +[LinuxGSM](https://linuxgsm.com) is the command-line tool for quick, simple deployment and management of Linux dedicated game servers. + +## Hassle-Free Dedicated Game Servers + +Traditionally game servers are not easy to manage yourself. Admins often have to spend hours messing around trying to get their servers working. LinuxGSM is a command-line tool designed to be as simple as possible, allowing admins to spend less time on management and more time gaming. + +## Main features + +100+ game servers supported + +- :truck: Installer +- :mag: Monitor +- :phone: Alerts +- :cloud: Updater +- :blue_book: Server Details +- :floppy_disk: Backup +- :computer: Console + +## :penguin: Compatibility + +LinuxGSM will run on popular distros as long as the minimum requirements are met. + +- Ubuntu +- Debian +- CentOS + +Other distros are likely to work but are not fully tested. + +## :wrench: Requirements + +Each game server has specific dependency requirements. Visit a specific game server installation page on the [LinuxGSM](https://linuxgsm.com) website to check dependency requirements for the game server you want to install. + +## :blue_book: Documentation + +Documentation is found at [linuxgsm.com](https://linuxgsm.com) and [docs.linuxgsm.com](https://docs.linuxgsm.com). + +## :question: Support + +There are various ways to get support, check out the [support](https://linuxgsm.com/support/) page for the right support. + +## :heart: Sponsor + +If you would like to [sponsor](https://linuxgsm.com/sponsor) to the project there are several ways you can, via [GitHub Sponsors](https://github.com/sponsors/dgibbs64) and [PayPal](https://www.paypal.me/dgibbs64). I would like to thank everyone who sponsors me. Since 2012 LinuxGSM has been steadily growing with new servers, features, and improvements added regularly. + +## 🧙‍♂️ Contributors + +A big thank you goes to all the wonderful people who contribute ideas, code, docs, and support to this project. diff --git a/lgsm/config-default/config-lgsm/acserver/_default.cfg b/lgsm/config-default/config-lgsm/acserver/_default.cfg new file mode 100644 index 0000000..b3ad14c --- /dev/null +++ b/lgsm/config-default/config-lgsm/acserver/_default.cfg @@ -0,0 +1,182 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## SteamCMD Login | https://docs.linuxgsm.com/steamcmd#steamcmd-login +steamuser="username" +steampass='password' + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-c ${servercfgfullpath}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="302550" +steamcmdforcewindows="yes" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="5" +querytype="assettocorsa" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Assetto Corsa" +engine="unity3d" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}" +executable="./acServer" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server_cfg.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/ahl2server/_default.cfg b/lgsm/config-default/config-lgsm/ahl2server/_default.cfg new file mode 100644 index 0000000..0860470 --- /dev/null +++ b/lgsm/config-default/config-lgsm/ahl2server/_default.cfg @@ -0,0 +1,190 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## SteamCMD Login | https://docs.linuxgsm.com/steamcmd#steamcmd-login +steamuser="username" +steampass='password' + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="act_airport" +maxplayers="20" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game ahl2 -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="985050" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Action: Source" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/ahl2" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/ahlserver/_default.cfg b/lgsm/config-default/config-lgsm/ahlserver/_default.cfg new file mode 100644 index 0000000..fb7725e --- /dev/null +++ b/lgsm/config-default/config-lgsm/ahlserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="ahl_hydro" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game action -strictportbind +ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers} " + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="90" +steamcmdforcewindows="no" +appidmod="cstrike" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Action Half-Life" +engine="goldsrc" +glibc="2.3.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/action" +executabledir="${serverfiles}" +executable="./hlds_run" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/arkserver/_default.cfg b/lgsm/config-default/config-lgsm/arkserver/_default.cfg new file mode 100644 index 0000000..7f38c97 --- /dev/null +++ b/lgsm/config-default/config-lgsm/arkserver/_default.cfg @@ -0,0 +1,188 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="7777" +queryport="27015" +rconport="27020" +# Default Map: TheIsland, Ragnarok, CrystalIsles, Aberration_P, ScorchedEarth_P, TheCenter, Extinction, Valguero_P, Genesis, Gen2 +defaultmap="TheIsland" +altsavedirectoryname="${defaultmap}" +maxplayers="70" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="${defaultmap}?AltSaveDirectoryName=${altsavedirectoryname}?listen?MultiHome=${ip}?MaxPlayers=${maxplayers}?QueryPort=${queryport}?RCONPort=${rconport}?Port=${port} -automanagedmods -crossplay -PublicIPForEpic=${publicip}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="5" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="376030" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="no" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="ARK: Survival Evolved" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/ShooterGame" +executabledir="${systemdir}/Binaries/Linux" +executable="./ShooterGameServer" +servercfgdir="${systemdir}/Saved/Config/LinuxServer" +servercfg="GameUserSettings.ini" +servercfgdefault="GameUserSettings.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/arma3server/_default.cfg b/lgsm/config-default/config-lgsm/arma3server/_default.cfg new file mode 100644 index 0000000..f89b751 --- /dev/null +++ b/lgsm/config-default/config-lgsm/arma3server/_default.cfg @@ -0,0 +1,204 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## SteamCMD Login | https://docs.linuxgsm.com/steamcmd#steamcmd-login +steamuser="username" +steampass='password' + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="2302" + +## ARMA 3 Modules +# Add mods with relative paths: +# mods/@cba_a3 +# To load the "Community Base Addons v3" module found in the +# directory serverfiles/mods/@cba_a3. Load several mods as: +# mods="mods/@ace\;mods/@acex\;mods/@cba_a3" +mods="" + +## Server-side Mods +servermods="" + +## Path to BattlEye +# Leave empty for default +bepath="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-ip=${ip} -port=${port} -cfg=${networkcfgfullpath} -config=${servercfgfullpath} -mod='${mods}' -servermod=${servermods} -bepath=${bepath} -autoinit -loadmissiontomemory" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="5" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="233780" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="ARMA 3" +engine="realvirtuality" +glibc="2.27" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./arma3server_x64" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.server.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" +networkcfgdir="${systemdir}/cfg" +networkcfg="${selfname}.network.cfg" +networkcfgdefault="network.cfg" +networkcfgfullpath="${networkcfgdir}/${networkcfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/armarserver/_default.cfg b/lgsm/config-default/config-lgsm/armarserver/_default.cfg new file mode 100644 index 0000000..3637f46 --- /dev/null +++ b/lgsm/config-default/config-lgsm/armarserver/_default.cfg @@ -0,0 +1,185 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +# https://community.bistudio.com/wiki/Arma_Reforger:Server_Hosting +# MaxFPS to limit the used Server resouces +maxfps="60" + +# Profile Name +serverprofile="server" +serverprofilefullpath="${serverfiles}/profiles/${serverprofile}" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-config ${servercfgfullpath} -profile ${serverprofilefullpath} -maxFPS ${maxfps}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="5" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="1874900" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Arma Reforger" +engine="enfusion" +glibc="2.27" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./ArmaReforgerServer" +servercfgdir="${systemdir}" +servercfg="${selfname}_config.json" +servercfgdefault="server.json" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/atsserver/_default.cfg b/lgsm/config-default/config-lgsm/atsserver/_default.cfg new file mode 100644 index 0000000..9d8125a --- /dev/null +++ b/lgsm/config-default/config-lgsm/atsserver/_default.cfg @@ -0,0 +1,177 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-nosingle" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="2239530" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="4" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="American Truck Simulator" +engine="prism3d" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}/bin/linux_x64" +executable="./amtrucks_server" +servercfgdir="${HOME}/.local/share/American Truck Simulator" +servercfg="server_config.sii" +servercfgdefault="server_config.sii" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/avserver/_default.cfg b/lgsm/config-default/config-lgsm/avserver/_default.cfg new file mode 100644 index 0000000..5777198 --- /dev/null +++ b/lgsm/config-default/config-lgsm/avserver/_default.cfg @@ -0,0 +1,180 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="--galaxy-name ${selfname} --ip ${ip} --datapath ${avdatapath}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="565060" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="10" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Avorion" +engine="avorion" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +avdatapath="${serverfiles}/galaxy" +avgalaxypath="${avdatapath}/${selfname}" +systemdir="${serverfiles}" +executabledir="${systemdir}/bin" +executable="./bin/AvorionServer" +servercfgdir="${avgalaxypath}" +servercfg="server.ini" +servercfgdefault="server.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/ServerLogs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/bb2server/_default.cfg b/lgsm/config-default/config-lgsm/bb2server/_default.cfg new file mode 100644 index 0000000..c52c8c5 --- /dev/null +++ b/lgsm/config-default/config-lgsm/bb2server/_default.cfg @@ -0,0 +1,191 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="bba_barracks" +maxplayers="20" + +## Game Server Login Token (GSLT): Optional +# GSLT can be used for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game brainbread2 -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +sv_setsteamaccount ${gslt} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="475370" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="BrainBread 2" +engine="source" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/brainbread2" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/bbserver/_default.cfg b/lgsm/config-default/config-lgsm/bbserver/_default.cfg new file mode 100644 index 0000000..2cfabab --- /dev/null +++ b/lgsm/config-default/config-lgsm/bbserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="bb_chp4_slaywatch" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game brainbread -strictportbind +ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="90" +steamcmdforcewindows="no" +appidmod="cstrike" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="BrainBread" +engine="goldsrc" +glibc="2.3.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/brainbread" +executabledir="${serverfiles}" +executable="./hlds_run" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/bdserver/_default.cfg b/lgsm/config-default/config-lgsm/bdserver/_default.cfg new file mode 100644 index 0000000..674fabb --- /dev/null +++ b/lgsm/config-default/config-lgsm/bdserver/_default.cfg @@ -0,0 +1,185 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="pve_tomb" +maxplayers="3" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game bdef -strictportbind +ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="817300" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Base Defense" +engine="goldsrc" +glibc="2.14" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/bdef" +executabledir="${serverfiles}" +executable="./hlds_run" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/bf1942server/_default.cfg b/lgsm/config-default/config-lgsm/bf1942server/_default.cfg new file mode 100644 index 0000000..5bd576b --- /dev/null +++ b/lgsm/config-default/config-lgsm/bf1942server/_default.cfg @@ -0,0 +1,168 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+hostServer 1 +dedicated 1" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-gamespy1" + +## Console type +consoleverbose="no" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Battlefield: 1942" +engine="refractor" +glibc="2.0" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}" +executable="./start.sh" +servercfgdir="${systemdir}/mods/bf1942/settings" +servercfg="serversettings.con" +servercfgdefault="serversettings.con" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/bfvserver/_default.cfg b/lgsm/config-default/config-lgsm/bfvserver/_default.cfg new file mode 100644 index 0000000..66c4ef8 --- /dev/null +++ b/lgsm/config-default/config-lgsm/bfvserver/_default.cfg @@ -0,0 +1,168 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+statusMonitor 1" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Battlefield: Vietnam" +engine="refractor" +glibc="2.2.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}" +executable="./start.sh" +servercfgdir="${systemdir}/mods/bfvietnam/settings" +servercfg="serversettings.con" +servercfgdefault="serversettings.con" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/mods/bfvietnam/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/bmdmserver/_default.cfg b/lgsm/config-default/config-lgsm/bmdmserver/_default.cfg new file mode 100644 index 0000000..dfe04bc --- /dev/null +++ b/lgsm/config-default/config-lgsm/bmdmserver/_default.cfg @@ -0,0 +1,191 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="dm_bounce" +maxplayers="16" + +## Game Server Login Token (GSLT): Optional +# GSLT can be used for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game bms -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +sv_setsteamaccount ${gslt} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="346680" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Black Mesa: Deathmatch" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/bms" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/boserver/_default.cfg b/lgsm/config-default/config-lgsm/boserver/_default.cfg new file mode 100644 index 0000000..d6e2b4f --- /dev/null +++ b/lgsm/config-default/config-lgsm/boserver/_default.cfg @@ -0,0 +1,183 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Game Server Login Token (GSLT): Optional +# GSLT can be used for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-batchmode -nographics -dedicated -configfile=${servercfgfullpath}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="416880" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Ballistic Overkill" +engine="unity3d" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./BODS.x86_64" +servercfgdir="${systemdir}" +servercfg="${selfname}.txt" +servercfgdefault="config.txt" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/bsserver/_default.cfg b/lgsm/config-default/config-lgsm/bsserver/_default.cfg new file mode 100644 index 0000000..b5f6017 --- /dev/null +++ b/lgsm/config-default/config-lgsm/bsserver/_default.cfg @@ -0,0 +1,195 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## SteamCMD Login | https://docs.linuxgsm.com/steamcmd#steamcmd-login +steamuser="username" +steampass='password' + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="duel_winter" +maxplayers="16" + +## Game Server Login Token (GSLT): Required +# GSLT is required for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game "${serverfiles}/berimbau" -autoupdate -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +sv_setsteamaccount ${gslt} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="228780" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Blade Symphony" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/berimbau" +executabledir="${serverfiles}/bin" +executable="./srcds_run.sh" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/btlserver/_default.cfg b/lgsm/config-default/config-lgsm/btlserver/_default.cfg new file mode 100644 index 0000000..b6cf3da --- /dev/null +++ b/lgsm/config-default/config-lgsm/btlserver/_default.cfg @@ -0,0 +1,183 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="7777" +queryport="7780" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="/Game/Maps/Final_Maps/Derailed?Game=/Script/ShooterGame.WartideGameMode?listen -log -broadcastip=\"${publicip}\" -PORT=${port} -QueryPort=${queryport} -defgameini=\"${servercfgfullpath}\"" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="805140" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="BATTALION: Legacy" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/Battalion" +executabledir="${systemdir}/Binaries/Linux" +executable="./BattalionServer-Linux-Shipping" +servercfgdir="${systemdir}/Saved/Config/LinuxServer" +servercfg="${selfname}.ini" +servercfgdefault="DefaultGame.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/btserver/_default.cfg b/lgsm/config-default/config-lgsm/btserver/_default.cfg new file mode 100644 index 0000000..c02b8c6 --- /dev/null +++ b/lgsm/config-default/config-lgsm/btserver/_default.cfg @@ -0,0 +1,178 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="1026340" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="7" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Barotrauma" +engine="barotrauma" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}" +executable="./DedicatedServer.exe" +servercfgdir="${systemdir}" +servercfg="serversettings.xml" +servercfgdefault="serversettings.xml" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/ServerLogs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/ccserver/_default.cfg b/lgsm/config-default/config-lgsm/ccserver/_default.cfg new file mode 100644 index 0000000..a8cd9f6 --- /dev/null +++ b/lgsm/config-default/config-lgsm/ccserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="cbe_bunker" +maxplayers="6" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game cure -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="383410" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Codename CURE" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/cure" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/cdserver/_default.cfg b/lgsm/config-default/config-lgsm/cdserver/_default.cfg new file mode 100644 index 0000000..28deeb6 --- /dev/null +++ b/lgsm/config-default/config-lgsm/cdserver/_default.cfg @@ -0,0 +1,178 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-batchmode -nographics" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="685100" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Crafting Dead" +engine="unity3d" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./crafting_dead.x86_64" +servercfgdir="${systemdir}" +servercfg="properties.json" +servercfgdefault="properties.json" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/ckserver/_default.cfg b/lgsm/config-default/config-lgsm/ckserver/_default.cfg new file mode 100644 index 0000000..c662f3b --- /dev/null +++ b/lgsm/config-default/config-lgsm/ckserver/_default.cfg @@ -0,0 +1,185 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="1234" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-batchmode -ip ${ip} -port ${port} -datapath ${servercfgdir} -logfile ${gamelog}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="1963720" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="no" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Core Keeper" +engine="unity3d" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +preexecutable="xvfb-run" +executable="./CoreKeeperServer" +servercfgdir="${systemdir}/gamedata/${selfname}" +servercfg="ServerConfig.json" +servercfgdefault="ServerConfig.json" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +gamelogdate="${gamelogdir}/${selfname}-game-$(date '+%Y-%m-%d-%H:%M:%S').log" +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/cmwserver/_default.cfg b/lgsm/config-default/config-lgsm/cmwserver/_default.cfg new file mode 100644 index 0000000..29df71d --- /dev/null +++ b/lgsm/config-default/config-lgsm/cmwserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="7777" +queryport="7779" +defaultmap="AOCTD-Frigid_p" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="${defaultmap}?steamsockets -multihome=${ip} -Port=${port} -QueryPort=${queryport} -seekfreeloadingserver -configsubdir=${selfname} -log=${gamelog}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="220070" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Chivalry: Medieval Warfare" +engine="unreal3" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}/Binaries/Linux" +executable="./UDKGameServer-Linux" +servercfgdir="${systemdir}/UDKGame/Config/${selfname}" +servercfg="PCServer-UDKGame.ini" +servercfgdefault="PCServer-UDKGame.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" +gamelogdate="${gamelogdir}/${selfname}-game-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/cod2server/_default.cfg b/lgsm/config-default/config-lgsm/cod2server/_default.cfg new file mode 100644 index 0000000..95b76ae --- /dev/null +++ b/lgsm/config-default/config-lgsm/cod2server/_default.cfg @@ -0,0 +1,171 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="28960" +defaultmap="mp_leningrad" +maxplayers="20" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+set sv_punkbuster 0 +set fs_basepath ${serverfiles} +set dedicated 2 +set net_ip ${ip} +set net_port ${port} +set sv_maxclients ${maxplayers} +exec ${servercfg} +map ${defaultmap}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-quake3" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Call of Duty 2" +engine="iw2.0" +glibc="2.1.3" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./cod2_lnxded" +servercfgdir="${systemdir}/main" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/cod4server/_default.cfg b/lgsm/config-default/config-lgsm/cod4server/_default.cfg new file mode 100644 index 0000000..a932378 --- /dev/null +++ b/lgsm/config-default/config-lgsm/cod4server/_default.cfg @@ -0,0 +1,171 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="28960" +defaultmap="mp_crossfire" +maxplayers="32" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+set sv_punkbuster 0 +set fs_basepath ${serverfiles} +set fs_homepath ${serverfiles} +set sv_authorizemode "-1" +set dedicated 2 +set net_ip ${ip} +set net_port ${port} +set sv_maxclients ${maxplayers} +exec ${servercfg} +map ${defaultmap}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-quake3" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Call of Duty 4" +engine="iw3.0" +glibc="2.12" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./cod4x18_dedrun" +servercfgdir="${systemdir}/main" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/codserver/_default.cfg b/lgsm/config-default/config-lgsm/codserver/_default.cfg new file mode 100644 index 0000000..6263d79 --- /dev/null +++ b/lgsm/config-default/config-lgsm/codserver/_default.cfg @@ -0,0 +1,171 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="28960" +defaultmap="mp_neuville" +maxplayers="20" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+set sv_punkbuster 0 +set fs_basepath ${serverfiles} +set dedicated 2 +set net_ip ${ip} +set net_port ${port} +set sv_maxclients ${maxplayers} +exec ${servercfg} +map ${defaultmap}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-quake3" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Call of Duty" +engine="idtech3" +glibc="2.1" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./cod_lnxded" +servercfgdir="${systemdir}/main" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/coduoserver/_default.cfg b/lgsm/config-default/config-lgsm/coduoserver/_default.cfg new file mode 100644 index 0000000..b7c6036 --- /dev/null +++ b/lgsm/config-default/config-lgsm/coduoserver/_default.cfg @@ -0,0 +1,171 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="28960" +defaultmap="mp_cassino" +maxplayers="20" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+set sv_punkbuster 0 +set fs_basepath ${serverfiles} +set dedicated 2 +set net_ip ${ip} +set net_port ${port} +set sv_maxclients ${maxplayers} +exec ${servercfg} +map ${defaultmap}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-quake3" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Call of Duty: United Offensive" +engine="idtech3" +glibc="2.1" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./coduo_lnxded" +servercfgdir="${systemdir}/uo" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/codwawserver/_default.cfg b/lgsm/config-default/config-lgsm/codwawserver/_default.cfg new file mode 100644 index 0000000..0820475 --- /dev/null +++ b/lgsm/config-default/config-lgsm/codwawserver/_default.cfg @@ -0,0 +1,171 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="28960" +defaultmap="mp_castle" +maxplayers="20" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+set sv_punkbuster 0 +set fs_basepath ${serverfiles} +set dedicated 2 +set net_ip ${ip} +set net_port ${port} +set sv_maxclients ${maxplayers} +exec ${servercfg} +map ${defaultmap}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-quake3" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Call of Duty: World at War" +engine="iw3.0" +glibc="2.3.2" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./codwaw_lnxded" +servercfgdir="${systemdir}/main" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/colserver/_default.cfg b/lgsm/config-default/config-lgsm/colserver/_default.cfg new file mode 100644 index 0000000..63182f5 --- /dev/null +++ b/lgsm/config-default/config-lgsm/colserver/_default.cfg @@ -0,0 +1,181 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +## https://colonysurvival.gamepedia.com/Dedicated_Server#Installation_.28Linux.29 +startparameters="-batchmode -nographics +server.config ${servercfgfullpath}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="748090" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="no" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Colony Survival" +engine="unity3d" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./colonyserver.x86_64" +servercfgdir="${systemdir}/gamedata/settings" +servercfg="${selfname}.json" +servercfgdefault="colserver.json" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/gamedata/logs/server/" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +gamelogdate="${gamelogdir}/${selfname}-game-$(date '+%Y-%m-%d-%H:%M:%S').log" +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/common-template.cfg b/lgsm/config-default/config-lgsm/common-template.cfg new file mode 100644 index 0000000..e050a94 --- /dev/null +++ b/lgsm/config-default/config-lgsm/common-template.cfg @@ -0,0 +1,5 @@ +################################## +######## Common Settings ######### +################################## +# PLACE GLOBAL SETTINGS HERE +## These settings will apply to all instances. diff --git a/lgsm/config-default/config-lgsm/cs2server/_default.cfg b/lgsm/config-default/config-lgsm/cs2server/_default.cfg new file mode 100644 index 0000000..4eca78e --- /dev/null +++ b/lgsm/config-default/config-lgsm/cs2server/_default.cfg @@ -0,0 +1,213 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +# https://docs.linuxgsm.com/game-servers/counter-strike-2 +# [Game Modes] gametype gamemode gamemodeflags skirmishid mapgroup (you can mix these across all Game Modes except Danger Zone, but use only one) +# Arms Race 1 0 0 0 mg_armsrace +# Boom! Headshot! 1 2 0 6 mg_skirmish_headshots +# Classic Casual 0 0 0 0 mg_casualsigma, mg_casualdelta +# Classic Competitive (Default) 0 1 0 0 mg_active, mg_reserves, mg_hostage, mg_de_dust2, ... +# Classic Competitive (Short Match) 0 1 32 0 mg_active, mg_reserves, mg_hostage, mg_de_dust2, ... +# Danger Zone 6 0 0 0 mg_dz_blacksite (map: dz_blacksite), mg_dz_sirocco (map: dz_sirocco) +# Deathmatch (Default) 1 2 0 0 mg_deathmatch +# Deathmatch (Free For All) 1 2 32 0 mg_deathmatch +# Deathmatch (Team vs Team) 1 2 4 0 mg_deathmatch +# Demolition 1 1 0 0 mg_demolition +# Flying Scoutsman 0 0 0 3 mg_skirmish_flyingscoutsman +# Hunter-Gatherers 1 2 0 7 mg_skirmish_huntergatherers +# Retakes 0 0 0 12 mg_skirmish_retakes +# Stab Stab Zap 0 0 0 1 mg_skirmish_stabstabzap +# Trigger Discipline 0 0 0 4 mg_skirmish_triggerdiscipline +# Wingman 0 2 0 0 mg_de_prime, mg_de_blagai, mg_de_vertigo, mg_de_inferno, mg_de_overpass, mg_de_cbble, mg_de_train, mg_de_shortnuke, mg_de_shortdust, mg_de_lake +gametype="0" +gamemode="1" +gamemodeflags="0" +skirmishid="0" +mapgroup="mg_active" +ip="0.0.0.0" +port="27015" +defaultmap="de_dust2" +maxplayers="16" +tickrate="64" + +## Game Server Login Token (GSLT): Required +# GSLT is required for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-dedicated -ip ${ip} -port ${port} -maxplayers ${maxplayers} -tickrate ${tickrate} -serverlogging +sv_setsteamaccount ${gslt} +map ${defaultmap} +game_type ${gametype} +game_mode ${gamemode} +sv_game_mode_flags ${gamemodeflags} +sv_skirmish_id ${skirmishid} +sv_logfile 1 +exec ${selfname}.cfg" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="730" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Counter-Strike 2" +engine="source2" +glibc="2.31" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/game/csgo" +executabledir="${serverfiles}/game/bin/linuxsteamrt64" +executable="./cs2" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/csczserver/_default.cfg b/lgsm/config-default/config-lgsm/csczserver/_default.cfg new file mode 100644 index 0000000..11d0da1 --- /dev/null +++ b/lgsm/config-default/config-lgsm/csczserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="de_dust2" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game czero -strictportbind +ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="90" +steamcmdforcewindows="no" +appidmod="czero" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Counter-Strike: Condition Zero" +engine="goldsrc" +glibc="2.3.6" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/czero" +executabledir="${serverfiles}" +executable="./hlds_run" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/csgoserver/_default.cfg b/lgsm/config-default/config-lgsm/csgoserver/_default.cfg new file mode 100644 index 0000000..5efdd49 --- /dev/null +++ b/lgsm/config-default/config-lgsm/csgoserver/_default.cfg @@ -0,0 +1,222 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +# https://docs.linuxgsm.com/game-servers/counter-strike-global-offensive +# [Game Modes] gametype gamemode gamemodeflags skirmishid mapgroup (you can mix these across all Game Modes except Danger Zone, but use only one) +# Arms Race 1 0 0 0 mg_armsrace +# Boom! Headshot! 1 2 0 6 mg_skirmish_headshots +# Classic Casual 0 0 0 0 mg_casualsigma, mg_casualdelta +# Classic Competitive (Default) 0 1 0 0 mg_active, mg_reserves, mg_hostage, mg_de_dust2, ... +# Classic Competitive (Short Match) 0 1 32 0 mg_active, mg_reserves, mg_hostage, mg_de_dust2, ... +# Danger Zone 6 0 0 0 mg_dz_blacksite (map: dz_blacksite), mg_dz_sirocco (map: dz_sirocco) +# Deathmatch (Default) 1 2 0 0 mg_deathmatch +# Deathmatch (Free For All) 1 2 32 0 mg_deathmatch +# Deathmatch (Team vs Team) 1 2 4 0 mg_deathmatch +# Demolition 1 1 0 0 mg_demolition +# Flying Scoutsman 0 0 0 3 mg_skirmish_flyingscoutsman +# Hunter-Gatherers 1 2 0 7 mg_skirmish_huntergatherers +# Retakes 0 0 0 12 mg_skirmish_retakes +# Stab Stab Zap 0 0 0 1 mg_skirmish_stabstabzap +# Trigger Discipline 0 0 0 4 mg_skirmish_triggerdiscipline +# Wingman 0 2 0 0 mg_de_prime, mg_de_blagai, mg_de_vertigo, mg_de_inferno, mg_de_overpass, mg_de_cbble, mg_de_train, mg_de_shortnuke, mg_de_shortdust, mg_de_lake +gametype="0" +gamemode="0" +gamemodeflags="0" +skirmishid="0" +mapgroup="mg_active" +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +steamport="26901" +defaultmap="de_mirage" +maxplayers="16" +tickrate="64" + +## Game Server Login Token (GSLT): Required +# GSLT is required for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Workshop Parameters | https://developer.valvesoftware.com/wiki/CSGO_Workshop_For_Server_Operators +# To get an API key visit - https://steamcommunity.com/dev/apikey +wsapikey="" +wscollectionid="" +wsstartmap="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game csgo -usercon -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +sv_setsteamaccount ${gslt} -tickrate ${tickrate} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers_override ${maxplayers} +mapgroup ${mapgroup} +game_type ${gametype} +game_mode ${gamemode} +sv_game_mode_flags ${gamemodeflags} +sv_skirmish_id ${skirmishid} +host_workshop_collection ${wscollectionid} +workshop_start_map ${wsstartmap} -authkey ${wsapikey} -nobreakpad" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="740" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Counter-Strike: Global Offensive" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/csgo" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/csserver/_default.cfg b/lgsm/config-default/config-lgsm/csserver/_default.cfg new file mode 100644 index 0000000..2e53616 --- /dev/null +++ b/lgsm/config-default/config-lgsm/csserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="de_dust2" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game cstrike -strictportbind +ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="90" +steamcmdforcewindows="no" +appidmod="cstrike" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Counter-Strike 1.6" +engine="goldsrc" +glibc="2.3.6" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/cstrike" +executabledir="${serverfiles}" +executable="./hlds_run" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/cssserver/_default.cfg b/lgsm/config-default/config-lgsm/cssserver/_default.cfg new file mode 100644 index 0000000..1af41c5 --- /dev/null +++ b/lgsm/config-default/config-lgsm/cssserver/_default.cfg @@ -0,0 +1,191 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="de_dust2" +maxplayers="16" + +## Game Server Login Token (GSLT): Required +# GSLT is required for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game cstrike -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +sv_setsteamaccount ${gslt} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="232330" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Counter-Strike: Source" +engine="source" +glibc="2.3.6" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/cstrike" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/ctserver/_default.cfg b/lgsm/config-default/config-lgsm/ctserver/_default.cfg new file mode 100644 index 0000000..74bd230 --- /dev/null +++ b/lgsm/config-default/config-lgsm/ctserver/_default.cfg @@ -0,0 +1,176 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-batchmode -showlogs" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="1670340" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="5" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="no" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Craftopia" +engine="unity3d" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./Craftopia.x86_64" +servercfgdir="${systemdir}" +servercfg="ServerSetting.ini" +servercfgdefault="ServerSetting.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +#gamelogdir="${serverfiles}" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +gamelogdate="${gamelogdir}/${selfname}-game-$(date '+%Y-%m-%d-%H:%M:%S').log" +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" diff --git a/lgsm/config-default/config-lgsm/dabserver/_default.cfg b/lgsm/config-default/config-lgsm/dabserver/_default.cfg new file mode 100644 index 0000000..62e3acf --- /dev/null +++ b/lgsm/config-default/config-lgsm/dabserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="da_rooftops" +maxplayers="10" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="317800" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Double Action: Boogaloo" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/dab" +executabledir="${serverfiles}" +executable="./dabds.sh" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/dayzserver/_default.cfg b/lgsm/config-default/config-lgsm/dayzserver/_default.cfg new file mode 100644 index 0000000..ed9e878 --- /dev/null +++ b/lgsm/config-default/config-lgsm/dayzserver/_default.cfg @@ -0,0 +1,196 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="2302" + +## DayZ Modules +# Add mods with relative paths: +# mods/@cf +# To load the "Community framework for DayZ SA" module found in the +# directory serverfiles/mods/@cf. Load several mods as: +# mods="mods/@cf\;mods/@dayz-expansion\;mods/@deerisle" +mods="" + +## Server-side Mods +servermods="" + +## Path to BattlEye +# Leave empty for default +bepath="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-ip=${ip} -port=${port} -config=${servercfgfullpath} -mod=${mods} -servermod=${servermods} -bepath=${bepath} -limitFPS=60 -dologs -adminlog -freezeCheck" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="5" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="1042420" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="DayZ" +engine="enfusion" +glibc="2.27" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./DayZServer" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.server.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/dmcserver/_default.cfg b/lgsm/config-default/config-lgsm/dmcserver/_default.cfg new file mode 100644 index 0000000..5f56a84 --- /dev/null +++ b/lgsm/config-default/config-lgsm/dmcserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="dcdm5" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game dmc -strictportbind +ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="90" +steamcmdforcewindows="no" +appidmod="dmc" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Deathmatch Classic" +engine="goldsrc" +glibc="2.3.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/dmc" +executabledir="${serverfiles}" +executable="./hlds_run" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/dodrserver/_default.cfg b/lgsm/config-default/config-lgsm/dodrserver/_default.cfg new file mode 100644 index 0000000..555a1a0 --- /dev/null +++ b/lgsm/config-default/config-lgsm/dodrserver/_default.cfg @@ -0,0 +1,184 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +servername="LinuxGSM" +ip="0.0.0.0" +port="7777" +queryport="27015" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-MultiHome=${ip} -Port=${port} -QueryPort=${queryport} -SteamServerName='${servername}' -log" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="1088320" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Day of Dragons" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/Dragons" +executabledir="${systemdir}/Binaries/Linux" +executable="./DragonsServer-Linux-Shipping" +servercfgdir="${systemdir}/Saved/Config/LinuxServer" +servercfg="Game.ini" +servercfgdefault="Game.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/dodserver/_default.cfg b/lgsm/config-default/config-lgsm/dodserver/_default.cfg new file mode 100644 index 0000000..61700d6 --- /dev/null +++ b/lgsm/config-default/config-lgsm/dodserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="dod_Anzio" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game dod -strictportbind +ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="90" +steamcmdforcewindows="no" +appidmod="dod" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Day of Defeat" +engine="goldsrc" +glibc="2.3.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/dod" +executabledir="${serverfiles}" +executable="./hlds_run" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/dodsserver/_default.cfg b/lgsm/config-default/config-lgsm/dodsserver/_default.cfg new file mode 100644 index 0000000..390f87b --- /dev/null +++ b/lgsm/config-default/config-lgsm/dodsserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="dod_Anzio" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game dod -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="232290" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Day of Defeat: Source" +engine="source" +glibc="2.3.6" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/dod" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/doiserver/_default.cfg b/lgsm/config-default/config-lgsm/doiserver/_default.cfg new file mode 100644 index 0000000..6aa10ee --- /dev/null +++ b/lgsm/config-default/config-lgsm/doiserver/_default.cfg @@ -0,0 +1,187 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="bastogne stronghold" +maxplayers="32" +tickrate="64" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game doi -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} -tickrate ${tickrate} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers} -workshop -norestart" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="462310" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Day of Infamy" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/doi" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/dstserver/_default.cfg b/lgsm/config-default/config-lgsm/dstserver/_default.cfg new file mode 100644 index 0000000..d757ea7 --- /dev/null +++ b/lgsm/config-default/config-lgsm/dstserver/_default.cfg @@ -0,0 +1,192 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +sharding="false" +master="true" +shard="Master" +cluster="Cluster_1" +cave="false" + +persistentstorageroot="${HOME}/.klei" +confdir="DoNotStarveTogether" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-persistent_storage_root ${persistentstorageroot} -conf_dir ${confdir} -cluster ${cluster} -shard ${shard}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="343050" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Don't Starve Together" +engine="dontstarve" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}/bin" +executable="./dontstarve_dedicated_server_nullrenderer" +clustercfgdir="${persistentstorageroot}/${confdir}/${cluster}" +clustercfg="cluster.ini" +clustercfgdefault="cluster.ini" +clustercfgfullpath="${clustercfgdir}/${clustercfg}" +servercfgdir="${clustercfgdir}/${shard}" +servercfg="server.ini" +servercfgdefault="server.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/dysserver/_default.cfg b/lgsm/config-default/config-lgsm/dysserver/_default.cfg new file mode 100644 index 0000000..eb1861c --- /dev/null +++ b/lgsm/config-default/config-lgsm/dysserver/_default.cfg @@ -0,0 +1,191 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="dys_broadcast" +maxplayers="16" + +## Game Server Login Token (GSLT): Optional +# GSLT can be used for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game "${serverfiles}/dystopia" -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +sv_setsteamaccount ${gslt} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="17585" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Dystopia" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/dystopia" +executabledir="${serverfiles}/bin" +executable="./srcds_run.sh" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/ecoserver/_default.cfg b/lgsm/config-default/config-lgsm/ecoserver/_default.cfg new file mode 100644 index 0000000..470b43d --- /dev/null +++ b/lgsm/config-default/config-lgsm/ecoserver/_default.cfg @@ -0,0 +1,179 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-nogui" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="739590" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Eco" +engine="unity3d" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./EcoServer" +servercfgdir="${systemdir}/Configs" +servercfg="Network.eco" +servercfgdefault="Network.eco" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${logdir}/server" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" +gamelogdate="${gamelogdir}/${selfname}-game-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/emserver/_default.cfg b/lgsm/config-default/config-lgsm/emserver/_default.cfg new file mode 100644 index 0000000..1610d08 --- /dev/null +++ b/lgsm/config-default/config-lgsm/emserver/_default.cfg @@ -0,0 +1,191 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="con_district402" +maxplayers="62" + +## Game Server Login Token (GSLT): Optional +# GSLT can be used for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game empires -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="460040" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Empires Mod" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/empires" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/etlserver/_default.cfg b/lgsm/config-default/config-lgsm/etlserver/_default.cfg new file mode 100644 index 0000000..18d6d30 --- /dev/null +++ b/lgsm/config-default/config-lgsm/etlserver/_default.cfg @@ -0,0 +1,165 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+set net_strict 1 +set fs_homepath ${serverfiles} +exec ${servercfg}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-quake3" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="ET: Legacy" +engine="idtech3" +glibc="2.7" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}" +executable="./etlded" +servercfgdir="${systemdir}/etmain" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/ets2server/_default.cfg b/lgsm/config-default/config-lgsm/ets2server/_default.cfg new file mode 100644 index 0000000..24462bc --- /dev/null +++ b/lgsm/config-default/config-lgsm/ets2server/_default.cfg @@ -0,0 +1,177 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-nosingle" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="1948160" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="4" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Euro Truck Simulator 2" +engine="prism3d" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}/bin/linux_x64" +executable="./eurotrucks2_server" +servercfgdir="${HOME}/.local/share/Euro Truck Simulator 2" +servercfg="server_config.sii" +servercfgdefault="server_config.sii" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/fctrserver/_default.cfg b/lgsm/config-default/config-lgsm/fctrserver/_default.cfg new file mode 100644 index 0000000..d77284d --- /dev/null +++ b/lgsm/config-default/config-lgsm/fctrserver/_default.cfg @@ -0,0 +1,175 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="34197" +rconport="34198" +rconpassword="CHANGE_ME" +branch="stable" # values: stable, experimental + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="--bind ${ip} --start-server ${serverfiles}/save1.zip --server-settings ${servercfgfullpath} --port ${port} --rcon-port ${rconport} --rcon-password ${rconpassword}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Factorio" +engine="factorio" +glibc="2.18" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}/bin/x64" +executable="./factorio" +servercfgdir="${systemdir}/data" +servercfg="${selfname}.json" +servercfgdefault="server-settings.json" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/fofserver/_default.cfg b/lgsm/config-default/config-lgsm/fofserver/_default.cfg new file mode 100644 index 0000000..1f7ef01 --- /dev/null +++ b/lgsm/config-default/config-lgsm/fofserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="fof_depot" +maxplayers="20" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game fof -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="295230" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Fistful of Frags" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/fof" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/gmodserver/_default.cfg b/lgsm/config-default/config-lgsm/gmodserver/_default.cfg new file mode 100644 index 0000000..869628e --- /dev/null +++ b/lgsm/config-default/config-lgsm/gmodserver/_default.cfg @@ -0,0 +1,199 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="gm_construct" +maxplayers="16" +tickrate="66" +gamemode="sandbox" + +## Workshop Parameters | https://wiki.facepunch.com/gmod/Workshop_for_Dedicated_Servers +# To get an API key visit - https://steamcommunity.com/dev/apikey +wsapikey="" +wscollectionid="" + +## Game Server Login Token (GSLT): Optional +# GSLT can be used for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game garrysmod -strictportbind -ip ${ip} -port ${port} -tickrate ${tickrate} +host_workshop_collection ${wscollectionid} -authkey ${wsapikey} +clientport ${clientport} +tv_port ${sourcetvport} +gamemode ${gamemode} +map ${defaultmap} +sv_setsteamaccount ${gslt} +servercfgfile ${servercfg} -maxplayers ${maxplayers} -disableluarefresh" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="5" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="4020" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Garry's Mod" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/garrysmod" +addonsdir="${systemdir}/addons" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/hcuserver/_default.cfg b/lgsm/config-default/config-lgsm/hcuserver/_default.cfg new file mode 100644 index 0000000..225482c --- /dev/null +++ b/lgsm/config-default/config-lgsm/hcuserver/_default.cfg @@ -0,0 +1,193 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +defaultmap="KidsBedroom" +ip="0.0.0.0" +maxplayers="8" +port="7777" +queryport="27015" +servername="LinuxGSM" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="${defaultmap}?Difficulty=1?Game=DM?MapList=KidsBedroom,Playground,Garden,Hallway_Simple,Bathroom,Hallway_Hard,Attic_Daytime,Shed,ToyPalace,Kitchen,Garage?MaxPlayers=${maxplayers}?WeaponTypes=7?TimeLimit=600?ScoreLimit=30?Teamplay -ServerName='${servername}' -Port=${port} -QueryPort=${queryport} -NOCONSOLE -unattended" + +## Server Parameters for Plague mode +#startparameters="${defaultmap}?Game=PL?MapList=KidsBedroom,Garden,Hallway_Simple,Attic_Daytime,Garage,Shed,Kitchen,Hallway_Hard,ToyPalace,Bathroom?MaxPlayers=${maxplayers}?WeaponTypes=7?TimeLimit=600 -ServerName='${servername}' -Port=${port} -QueryPort=${queryport} -NOCONSOLE -unattended" + +## Server Parameters for Co-op mode +#startparameters="${defaultmap}?Difficulty=1?Game=WV?MapList=KidsBedroom?MaxPlayers=4 -ServerName='${servername}' -Port=${port} -QueryPort=${queryport} -NOCONSOLE -unattended" + + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="5" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="1045940" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="no" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="HYPERCHARGE: Unboxed" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/Unboxed" +executabledir="${systemdir}/Binaries/Linux" +executable="./UnboxedServer-Linux-Shipping" +servercfgdir="${systemdir}/Saved/Config/LinuxServer" +servercfg="GameUserSettings.ini" +servercfgdefault="GameUserSettings.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/hl2dmserver/_default.cfg b/lgsm/config-default/config-lgsm/hl2dmserver/_default.cfg new file mode 100644 index 0000000..cdbbfb1 --- /dev/null +++ b/lgsm/config-default/config-lgsm/hl2dmserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="dm_lockdown" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game hl2mp -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="232370" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Half Life 2: Deathmatch" +engine="source" +glibc="2.3.6" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/hl2mp" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/hldmserver/_default.cfg b/lgsm/config-default/config-lgsm/hldmserver/_default.cfg new file mode 100644 index 0000000..f69d56c --- /dev/null +++ b/lgsm/config-default/config-lgsm/hldmserver/_default.cfg @@ -0,0 +1,185 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="crossfire" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game valve -strictportbind +ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="90" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Half Life: Deathmatch" +engine="goldsrc" +glibc="2.3.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/valve" +executabledir="${serverfiles}" +executable="./hlds_run" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/hldmsserver/_default.cfg b/lgsm/config-default/config-lgsm/hldmsserver/_default.cfg new file mode 100644 index 0000000..0baf4f9 --- /dev/null +++ b/lgsm/config-default/config-lgsm/hldmsserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="crossfire" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game hl1mp -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="255470" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Half-Life Deathmatch: Source" +engine="source" +glibc="2.3.6" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/hl1mp" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/hwserver/_default.cfg b/lgsm/config-default/config-lgsm/hwserver/_default.cfg new file mode 100644 index 0000000..ea18f00 --- /dev/null +++ b/lgsm/config-default/config-lgsm/hwserver/_default.cfg @@ -0,0 +1,194 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +servername="LinuxGSM" +ip="0.0.0.0" +port="12871" +queryport="12881" +maxplayers="20" +defaultmap="nullius" +creativemode="0" # values: Free Build = 1, Survival = 0 + +## Add admins using STEAMID64 +# Example : addadmin 012345678901234567; addadmin 987654321098765432 +admins="" + +## Advanced Server Start Settings +# Rollback server state (remove after start command) +loadsave="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +# http://hurtworld.wikia.com/wiki/Hosting_A_Server +startparameters="-batchmode -nographics -logfile ${gamelog} -exec \"host ${port} ${defaultmap} ${loadsave};queryport ${queryport};maxplayers ${maxplayers};servername ${servername};creativemode ${creativemode};${admins}\"" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="405100" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="no" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Hurtworld" +engine="unity3d" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./Hurtworld.x86_64" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${logdir}/server" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +gamelogdate="${gamelogdir}/${selfname}-game-$(date '+%Y-%m-%d-%H:%M:%S').log" +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/insserver/_default.cfg b/lgsm/config-default/config-lgsm/insserver/_default.cfg new file mode 100644 index 0000000..b41fb24 --- /dev/null +++ b/lgsm/config-default/config-lgsm/insserver/_default.cfg @@ -0,0 +1,192 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="embassy_coop checkpoint" +maxplayers="32" +tickrate="64" + +## Game Server Login Token (GSLT): Optional +# GSLT can be used for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game insurgency -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} -tickrate ${tickrate} +sv_setsteamaccount ${gslt} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers} -workshop -norestart" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="237410" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Insurgency" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/insurgency" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/inssserver/_default.cfg b/lgsm/config-default/config-lgsm/inssserver/_default.cfg new file mode 100644 index 0000000..13addae --- /dev/null +++ b/lgsm/config-default/config-lgsm/inssserver/_default.cfg @@ -0,0 +1,192 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27102" +queryport="27131" +rconport="27015" +rconpassword="" +servername="LinuxGSM" +defaultmap="Canyon" +defaultscenario="Scenario_Crossing_Push_Security" +maxplayers="28" + +## Game Server Login Token (GSLT): Optional +# GSLT can be used for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +## Parameter Docs | https://mod.io/g/insurgencysandstorm/r/server-admin-guide +startparameters="${defaultmap}?Scenario=${defaultscenario}?MaxPlayers=${maxplayers} -Port=${port} -QueryPort=${queryport} -hostname='${servername}' -Rcon -RconPassword=${rconpassword} -RconListenPort=${rconport} -GSLTToken=${gslt} -log" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="581330" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Insurgency: Sandstorm" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/Insurgency" +executabledir="${systemdir}/Binaries/Linux" +executable="./InsurgencyServer-Linux-Shipping" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/instance-template.cfg b/lgsm/config-default/config-lgsm/instance-template.cfg new file mode 100644 index 0000000..162b176 --- /dev/null +++ b/lgsm/config-default/config-lgsm/instance-template.cfg @@ -0,0 +1,5 @@ +################################## +####### Instance Settings ######## +################################## +# PLACE INSTANCE SETTINGS HERE +## These settings will apply to a specific instance. diff --git a/lgsm/config-default/config-lgsm/iosserver/_default.cfg b/lgsm/config-default/config-lgsm/iosserver/_default.cfg new file mode 100644 index 0000000..bcc35e4 --- /dev/null +++ b/lgsm/config-default/config-lgsm/iosserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="8v8_vienna" +maxplayers="32" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game iosoccer -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="673990" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="IOSoccer" +engine="source" +glibc="2.3.6" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/iosoccer" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/jc2server/_default.cfg b/lgsm/config-default/config-lgsm/jc2server/_default.cfg new file mode 100644 index 0000000..caa40d9 --- /dev/null +++ b/lgsm/config-default/config-lgsm/jc2server/_default.cfg @@ -0,0 +1,178 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="261140" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="jc2mp" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Just Cause 2" +engine="avalanche2.0" +glibc="2.13" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./Jcmp-Server" +servercfgdir="${systemdir}" +servercfg="config.lua" +servercfgdefault="config.lua" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +#gamelogdir="" # No server logs available +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/jc3server/_default.cfg b/lgsm/config-default/config-lgsm/jc3server/_default.cfg new file mode 100644 index 0000000..9c902f4 --- /dev/null +++ b/lgsm/config-default/config-lgsm/jc3server/_default.cfg @@ -0,0 +1,177 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="619960" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Just Cause 3" +engine="avalanche3.0" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./Server" +servercfgdir="${systemdir}" +servercfg="config.json" +servercfgdefault="config.json" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/jk2server/_default.cfg b/lgsm/config-default/config-lgsm/jk2server/_default.cfg new file mode 100644 index 0000000..4d49e4e --- /dev/null +++ b/lgsm/config-default/config-lgsm/jk2server/_default.cfg @@ -0,0 +1,187 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## SteamCMD Login | https://docs.linuxgsm.com/steamcmd#steamcmd-login +steamuser="username" +steampass='password' + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27960" +defaultmap="ffa_bespin" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+set sv_punkbuster 0 +set fs_basepath ${serverfiles} +set net_ip ${ip} +set net_port ${port} +exec ${servercfg} +map ${defaultmap}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="6030" +steamcmdforcewindows="yes" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-quake3" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Jedi Knight II: Jedi Outcast" +engine="idtech3" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/GameData" +executabledir="${systemdir}" +executable="./jk2mvded" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgdir="${systemdir}" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backups" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/kf2server/_default.cfg b/lgsm/config-default/config-lgsm/kf2server/_default.cfg new file mode 100644 index 0000000..9ca4a09 --- /dev/null +++ b/lgsm/config-default/config-lgsm/kf2server/_default.cfg @@ -0,0 +1,184 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +queryport="27015" +defaultmap="KF-BioticsLab" +gamemode="KFGameContent.KFGameInfo_VersusSurvival" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="\"${defaultmap}?Game=${gamemode}?ConfigSubDir=${selfname} -QueryPort=${queryport}\"" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="232130" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Killing Floor 2" +engine="unreal3" +glibc="2.3.2" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}/Binaries/Win64" +executable="./KFGameSteamServer.bin.x86_64" +servercfgdir="${systemdir}/KFGame/Config/${selfname}" +servercfg="LinuxServer-KFGame.ini" +servercfgdefault="LinuxServer-KFGame.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/kfserver/_default.cfg b/lgsm/config-default/config-lgsm/kfserver/_default.cfg new file mode 100644 index 0000000..4aa1288 --- /dev/null +++ b/lgsm/config-default/config-lgsm/kfserver/_default.cfg @@ -0,0 +1,193 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## SteamCMD Login | https://docs.linuxgsm.com/steamcmd#steamcmd-login +steamuser="username" +steampass='password' + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +defaultmap="KF-BioticsLab.rom" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="server ${defaultmap}?game=KFmod.KFGameType?VACSecured=true -nohomedir ini=${servercfg} log=${gamelog}" + +## Server Parameters for Objective mode +#defaultmap="KFO-Steamland" +#startparameters="server ${defaultmap}?Game=KFStoryGame.KFStoryGame?VACSecured=true -nohomedir ini=${servercfg} log=${gamelog}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="215360" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-unreal2" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Killing Floor" +engine="unreal2" +glibc="2.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/System" +executabledir="${systemdir}" +executable="./ucc-bin" +servercfgdir="${systemdir}" +servercfg="${selfname}.ini" +servercfgdefault="Default.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" +compressedmapsdir="${rootdir}/Maps-Compressed" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${logdir}/server" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" +gamelogdate="${gamelogdir}/${selfname}-game-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/l4d2server/_default.cfg b/lgsm/config-default/config-lgsm/l4d2server/_default.cfg new file mode 100644 index 0000000..676a723 --- /dev/null +++ b/lgsm/config-default/config-lgsm/l4d2server/_default.cfg @@ -0,0 +1,185 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="c5m1_waterfront" +maxplayers="8" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game left4dead2 -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="222860" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Left 4 Dead 2" +engine="source" +glibc="2.3.6" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/left4dead2" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/l4dserver/_default.cfg b/lgsm/config-default/config-lgsm/l4dserver/_default.cfg new file mode 100644 index 0000000..cf1f641 --- /dev/null +++ b/lgsm/config-default/config-lgsm/l4dserver/_default.cfg @@ -0,0 +1,185 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="l4d_hospital01_apartment" +maxplayers="8" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game left4dead -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="222840" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Left 4 Dead" +engine="source" +glibc="2.3.6" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/left4dead" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="server.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/mcbserver/_default.cfg b/lgsm/config-default/config-lgsm/mcbserver/_default.cfg new file mode 100644 index 0000000..586575d --- /dev/null +++ b/lgsm/config-default/config-lgsm/mcbserver/_default.cfg @@ -0,0 +1,171 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="" + +# Version (latest|1.18.33.02) +mcversion="latest" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="5" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="minecraftbe" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Minecraft Bedrock" +engine="bedrock" +glibc="2.27" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="${serverfiles}/bedrock_server" +servercfgdir="${systemdir}" +servercfg="server.properties" +servercfgdefault="server.properties" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/mcserver/_default.cfg b/lgsm/config-default/config-lgsm/mcserver/_default.cfg new file mode 100644 index 0000000..b6f923a --- /dev/null +++ b/lgsm/config-default/config-lgsm/mcserver/_default.cfg @@ -0,0 +1,178 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +javaram="1024" # -Xmx$1024M + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="nogui" + +## Release Settings | https://docs.linuxgsm.com/game-servers/minecraft#release-settings +# Branch (release|snapshot) +branch="release" +# Version (latest|1.16) +mcversion="latest" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="5" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="minecraft" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Minecraft" +engine="lwjgl2" +glibc="null" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +preexecutable="java -Xmx${javaram}M -jar" +executable="./minecraft_server.jar" +servercfgdir="${systemdir}" +servercfg="server.properties" +servercfgdefault="server.properties" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/mhserver/_default.cfg b/lgsm/config-default/config-lgsm/mhserver/_default.cfg new file mode 100644 index 0000000..846aed0 --- /dev/null +++ b/lgsm/config-default/config-lgsm/mhserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="7777" +beaconport="15000" +queryport="27015" +# Maps: FFA_Camp, FFA_Contraband, FFA_Grad, FFA_MountainPeak, FFA_Taiga, FFA_ThePit, FFA_Tourney, SKM_Camp, SKM_Contraband, SKM_Grad, SKM_MountainPeak, SKM_Taiga, SKM_ThePit, SKM_Tourney, TDM_Camp, TDM_Contraband, TDM_Grad, TDM_MountainPeak, TDM_Taiga, TDM_ThePit, TDM_Tourney +defaultmap="FFA_ThePit" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="Mordhau ${defaultmap} -log -MultiHome=${ip} -Port=${port} -BeaconPort=${beaconport} -QueryPort=${queryport} -GameIni=${servercfgfullpath}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="629800" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="MORDHAU" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/Mordhau" +executabledir="${systemdir}/Binaries/Linux" +executable="./MordhauServer-Linux-Shipping" +servercfgdir="${systemdir}/Saved/Config/LinuxServer" +servercfg="Game.ini" +servercfgdefault="Game.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/mohaaserver/_default.cfg b/lgsm/config-default/config-lgsm/mohaaserver/_default.cfg new file mode 100644 index 0000000..a457832 --- /dev/null +++ b/lgsm/config-default/config-lgsm/mohaaserver/_default.cfg @@ -0,0 +1,170 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="12203" +defaultmap="dm/mohdm1" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+set sv_punkbuster 0 +set fs_basepath ${serverfiles} +set fs_outputpath ${gamelogdir} +set dedicated 2 +set net_ip ${ip} +set net_port ${port} +exec ${servercfg} +map ${defaultmap}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Medal of Honor: Allied Assault" +engine="idtech3" +glibc="2.3" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/main" +executabledir="${serverfiles}" +executable="./mohaa_lnxded" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/momserver/_default.cfg b/lgsm/config-default/config-lgsm/momserver/_default.cfg new file mode 100644 index 0000000..c075067 --- /dev/null +++ b/lgsm/config-default/config-lgsm/momserver/_default.cfg @@ -0,0 +1,183 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="7777" +beaconport="15000" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-port="${port}" -beaconport="${beaconport}" -MULTIHOME="${ip}"" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="897590" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Memories of Mars" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/Game" +executabledir="${systemdir}/Binaries/Linux" +executable="./MemoriesOfMarsServer" +servercfgdir="${serverfiles}" +servercfg="DedicatedServerConfig.cfg" +servercfgdefault="DedicatedServerConfig.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Game/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/mtaserver/_default.cfg b/lgsm/config-default/config-lgsm/mtaserver/_default.cfg new file mode 100644 index 0000000..ff40ffa --- /dev/null +++ b/lgsm/config-default/config-lgsm/mtaserver/_default.cfg @@ -0,0 +1,169 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="4" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="3" +querytype="protocol-ase" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Multi Theft Auto" +engine="renderware" +glibc="2.7" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +resourcesdir="${systemdir}/mods/deathmatch/resources" +executabledir="${systemdir}" +executable="./mta-server64" +servercfgdir="${systemdir}/mods/deathmatch" +servercfg="mtaserver.conf" +servercfgdefault="mtaserver.conf" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/mods/deathmatch/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/ndserver/_default.cfg b/lgsm/config-default/config-lgsm/ndserver/_default.cfg new file mode 100644 index 0000000..fcf1caf --- /dev/null +++ b/lgsm/config-default/config-lgsm/ndserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="hydro" +maxplayers="32" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game nucleardawn -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="111710" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Nuclear Dawn" +engine="source" +glibc="2.3.6" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/nucleardawn" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/necserver/_default.cfg b/lgsm/config-default/config-lgsm/necserver/_default.cfg new file mode 100644 index 0000000..993572b --- /dev/null +++ b/lgsm/config-default/config-lgsm/necserver/_default.cfg @@ -0,0 +1,181 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Pre-defined Paramters | https://docs.linuxgsm.com/configuration/start-parameters#predefined-parameters +worldname="MyWorld" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-localdir -world ${worldname}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="1169370" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Necesse" +engine="null" +glibc="2.9" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./StartServer-nogui.sh" +servercfgdir="${serverfiles}/cfg" +servercfg="server.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/nmrihserver/_default.cfg b/lgsm/config-default/config-lgsm/nmrihserver/_default.cfg new file mode 100644 index 0000000..f3b740a --- /dev/null +++ b/lgsm/config-default/config-lgsm/nmrihserver/_default.cfg @@ -0,0 +1,191 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="nmo_broadway" +maxplayers="8" + +## Game Server Login Token (GSLT): Optional +# GSLT can be used for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game nmrih -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +sv_setsteamaccount ${gslt} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="317670" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="No More Room in Hell" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/nmrih" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/ns2cserver/_default.cfg b/lgsm/config-default/config-lgsm/ns2cserver/_default.cfg new file mode 100644 index 0000000..fb4686c --- /dev/null +++ b/lgsm/config-default/config-lgsm/ns2cserver/_default.cfg @@ -0,0 +1,191 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +defaultmap="co_core" +maxplayers="24" +servername="LinuxGSM" +httpuser="admin" +httppassword="admin" +httpport="8080" +mods="" +serverpassword="" +# Add the following line to the parms if you want a private server. Ensuring +# that the password variable above is not left empty. +# -password \"${serverpassword}\" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-name \"${servername}\" -port ${port} -webadmin -webdomain ${ip} -webuser ${httpuser} -webpassword \"${httppassword}\" -webport ${httpport} -map ${defaultmap} -limit ${maxplayers} -config_path \"${servercfgdir}\" -modstorage \"${modstoragedir}\" -mods \"${mods}\"" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="313900" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="6" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="NS2: Combat" +engine="spark" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}/ia32" +executable="./ns2combatserver_linux32" +servercfgdir="${systemdir}/${selfname}" +modstoragedir="${servercfgdir}/Workshop" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/ns2server/_default.cfg b/lgsm/config-default/config-lgsm/ns2server/_default.cfg new file mode 100644 index 0000000..8cca4da --- /dev/null +++ b/lgsm/config-default/config-lgsm/ns2server/_default.cfg @@ -0,0 +1,191 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +defaultmap="ns2_summit" +maxplayers="24" +servername="LinuxGSM" +httpuser="admin" +httppassword="admin" +httpport="8080" +mods="" +serverpassword="" +# Add the following line to the parms if you want a private server. Ensuring +# that the password variable above is not left empty. +# -password \"${serverpassword}\" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-name \"${servername}\" -port ${port} -webadmin -webdomain ${ip} -webuser ${httpuser} -webpassword \"${httppassword}\" -webport ${httpport} -map ${defaultmap} -limit ${maxplayers} -config_path \"${servercfgdir}\" -logdir \"${gamelogdir}\" -modstorage \"${modstoragedir}\" -mods2 \"${mods}\"" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="4940" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="6" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Natural Selection 2" +engine="spark" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}/x64" +executable="./server_linux" +servercfgdir="${systemdir}/${selfname}" +modstoragedir="${servercfgdir}/Workshop" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/nsserver/_default.cfg b/lgsm/config-default/config-lgsm/nsserver/_default.cfg new file mode 100644 index 0000000..c207a0a --- /dev/null +++ b/lgsm/config-default/config-lgsm/nsserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="ns_hera" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game ns -strictportbind +ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="90" +steamcmdforcewindows="no" +appidmod="cstrike" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Natural Selection" +engine="goldsrc" +glibc="2.3.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/ns" +executabledir="${serverfiles}" +executable="./hlds_run" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/ohdserver/_default.cfg b/lgsm/config-default/config-lgsm/ohdserver/_default.cfg new file mode 100644 index 0000000..58a42d3 --- /dev/null +++ b/lgsm/config-default/config-lgsm/ohdserver/_default.cfg @@ -0,0 +1,185 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="7777" +queryport="27005" +servername="LinuxGSM" +serverpassword="" +# Maps: risala, khafji_p, lamdong, montecassino, argonne +defaultmap="AAS-TestMap" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="${defaultmap}?MaxPlayers=${maxplayers}?Password=${serverpassword} -Port=${port} -QueryPort=${queryport} -SteamServerName='${servername}' -log" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="950900" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Operation: Harsh Doorstop" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/HarshDoorstop" +executabledir="${systemdir}/Binaries/Linux" +executable="./HarshDoorstopServer-Linux-Shipping" +servercfgdir="${systemdir}/Saved/Config/LinuxServer" +servercfg="Game.ini" +servercfgdefault="Game.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" diff --git a/lgsm/config-default/config-lgsm/onsetserver/_default.cfg b/lgsm/config-default/config-lgsm/onsetserver/_default.cfg new file mode 100644 index 0000000..b0f0d00 --- /dev/null +++ b/lgsm/config-default/config-lgsm/onsetserver/_default.cfg @@ -0,0 +1,178 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="--config ${servercfgfullpath}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="1204170" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Onset" +engine="unreal4" +glibc="2.24" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./OnsetServer" +servercfgdir="${systemdir}" +servercfg="server_config.json" +servercfgdefault="server_config.json" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/opforserver/_default.cfg b/lgsm/config-default/config-lgsm/opforserver/_default.cfg new file mode 100644 index 0000000..8ba202b --- /dev/null +++ b/lgsm/config-default/config-lgsm/opforserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="op4_bootcamp" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game gearbox -strictportbind +ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="90" +steamcmdforcewindows="no" +appidmod="gearbox" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Half-Life: Opposing Force" +engine="goldsrc" +glibc="2.3.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/gearbox" +executabledir="${serverfiles}" +executable="./hlds_run" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/pc2server/_default.cfg b/lgsm/config-default/config-lgsm/pc2server/_default.cfg new file mode 100644 index 0000000..b554478 --- /dev/null +++ b/lgsm/config-default/config-lgsm/pc2server/_default.cfg @@ -0,0 +1,182 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## SteamCMD Login | https://docs.linuxgsm.com/steamcmd#steamcmd-login +steamuser="username" +steampass='password' + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="--config ${servercfg}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="413770" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Project Cars 2" +engine="madness" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./DedicatedServerCmd.elf" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="config_sample/server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/pcserver/_default.cfg b/lgsm/config-default/config-lgsm/pcserver/_default.cfg new file mode 100644 index 0000000..2c15144 --- /dev/null +++ b/lgsm/config-default/config-lgsm/pcserver/_default.cfg @@ -0,0 +1,178 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="--config ${servercfg}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="332670" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Project Cars" +engine="madness" +glibc="2.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./DedicatedServerCmd" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/pmcserver/_default.cfg b/lgsm/config-default/config-lgsm/pmcserver/_default.cfg new file mode 100644 index 0000000..57838ad --- /dev/null +++ b/lgsm/config-default/config-lgsm/pmcserver/_default.cfg @@ -0,0 +1,176 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +javaram="1024" # -Xmx$1024M + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="nogui" + +## Release Settings | https://docs.linuxgsm.com/game-servers/minecraft#release-settings +# Version (latest|1.16.5) +mcversion="latest" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="5" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="minecraft" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="PaperMC" +engine="lwjgl2" +glibc="null" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +preexecutable="java -Xmx${javaram}M -jar" +executable="./paper.jar" +servercfgdir="${systemdir}" +servercfg="server.properties" +servercfgdefault="server.properties" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/psserver/_default.cfg b/lgsm/config-default/config-lgsm/psserver/_default.cfg new file mode 100644 index 0000000..143a334 --- /dev/null +++ b/lgsm/config-default/config-lgsm/psserver/_default.cfg @@ -0,0 +1,188 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +maxplayers="40" +port="10027" +queryport="10037" +randommap="NONE" +reservedslots="0" +tickrate="50" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="MULTIHOME=${ip} RANDOM=${randommap} Port=${port} QueryPort=${queryport} FIXEDMAXPLAYERS=${maxplayers} FIXEDMAXTICKRATE=${tickrate} NumReservedSlots=${reservedslots}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="746200" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Post Scriptum" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/PostScriptum" +executabledir="${serverfiles}" +executable="./PostScriptumServer.sh" +servercfgdir="${systemdir}/ServerConfig" +servercfg="Server.cfg" +servercfgdefault="Server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/pvkiiserver/_default.cfg b/lgsm/config-default/config-lgsm/pvkiiserver/_default.cfg new file mode 100644 index 0000000..0565f80 --- /dev/null +++ b/lgsm/config-default/config-lgsm/pvkiiserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="bt_island" +maxplayers="24" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game pvkii -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="17575" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Pirates, Vikings, and Knights II" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/pvkii" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/pvrserver/_default.cfg b/lgsm/config-default/config-lgsm/pvrserver/_default.cfg new file mode 100644 index 0000000..c840649 --- /dev/null +++ b/lgsm/config-default/config-lgsm/pvrserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="7777" +# Maps: bridge, datacenter, sand +defaultmap="datacenter" +# Get an API key from https://pavlov-ms.vankrupt.com/servers/v1/key +apikey="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="Pavlov ${defaultmap} -log -MultiHome=${ip} -Port=${port} ApiKey=${apikey}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="622970" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="5" +querytype="" + +## Console type +consoleverbose="no" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Pavlov VR" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/Pavlov" +executabledir="${systemdir}/Binaries/Linux" +executable="./PavlovServer-Linux-Shipping" +servercfgdir="${systemdir}/Saved/Config/LinuxServer" +servercfg="Game.ini" +servercfgdefault="Game.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/pzserver/_default.cfg b/lgsm/config-default/config-lgsm/pzserver/_default.cfg new file mode 100644 index 0000000..5a34c04 --- /dev/null +++ b/lgsm/config-default/config-lgsm/pzserver/_default.cfg @@ -0,0 +1,182 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +adminpassword="CHANGE_ME" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-servername ${selfname}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="380870" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Project Zomboid" +engine="projectzomboid" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./start-server.sh" +servercfgdir="${HOME}/Zomboid/Server" +servercfg="${selfname}.ini" +servercfgdefault="server.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${HOME}/Zomboid/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/q2server/_default.cfg b/lgsm/config-default/config-lgsm/q2server/_default.cfg new file mode 100644 index 0000000..b92c36c --- /dev/null +++ b/lgsm/config-default/config-lgsm/q2server/_default.cfg @@ -0,0 +1,170 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27910" +defaultmap="q2dm1" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+set dedicated 1 +set ip ${ip} +set port ${port} +exec ${servercfg} +set deathmatch 1 +map ${defaultmap}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-quake2" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Quake 2" +engine="idtech2" +glibc="null" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/baseq2" +executabledir="${serverfiles}" +executable="./quake2" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/q3server/_default.cfg b/lgsm/config-default/config-lgsm/q3server/_default.cfg new file mode 100644 index 0000000..534bf24 --- /dev/null +++ b/lgsm/config-default/config-lgsm/q3server/_default.cfg @@ -0,0 +1,170 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27960" +defaultmap="q3dm17" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+set sv_punkbuster 0 +set fs_basepath ${serverfiles} +set dedicated 2 +set com_hunkMegs 32 +set net_ip ${ip} +set net_port ${port} +exec ${servercfg} +map ${defaultmap}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-quake3" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Quake 3: Arena" +engine="idtech3" +glibc="2.1" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/baseq3" +executabledir="${serverfiles}" +executable="./q3ded" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/qlserver/_default.cfg b/lgsm/config-default/config-lgsm/qlserver/_default.cfg new file mode 100644 index 0000000..5d5614a --- /dev/null +++ b/lgsm/config-default/config-lgsm/qlserver/_default.cfg @@ -0,0 +1,179 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+exec ${servercfg}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="349090" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Quake Live" +engine="idtech3_ql" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable=$([ "$(uname -m)" == "x86_64" ] && echo -e "./run_server_x64.sh" || echo -e "./run_server_x86.sh") +servercfgdir="${systemdir}/baseq3" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${logdir}/server" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/qwserver/_default.cfg b/lgsm/config-default/config-lgsm/qwserver/_default.cfg new file mode 100644 index 0000000..63d554f --- /dev/null +++ b/lgsm/config-default/config-lgsm/qwserver/_default.cfg @@ -0,0 +1,169 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27500" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-port ${port} -game ktx +exec ${servercfg}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-quake1" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="QuakeWorld" +engine="quake" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/ktx" +executabledir="${serverfiles}" +executable="./mvdsv" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/ricochetserver/_default.cfg b/lgsm/config-default/config-lgsm/ricochetserver/_default.cfg new file mode 100644 index 0000000..36845b0 --- /dev/null +++ b/lgsm/config-default/config-lgsm/ricochetserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="rc_arena" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game ricochet -strictportbind +ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="90" +steamcmdforcewindows="no" +appidmod="ricochet" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Ricochet" +engine="goldsrc" +glibc="2.3.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/ricochet" +executabledir="${serverfiles}" +executable="./hlds_run" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/roserver/_default.cfg b/lgsm/config-default/config-lgsm/roserver/_default.cfg new file mode 100644 index 0000000..1a95add --- /dev/null +++ b/lgsm/config-default/config-lgsm/roserver/_default.cfg @@ -0,0 +1,189 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## SteamCMD Login | https://docs.linuxgsm.com/steamcmd#steamcmd-login +steamuser="username" +steampass='password' + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +defaultmap="RO-Arad.rom" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="server ${defaultmap}?game=ROGame.ROTeamGame?VACSecured=true -nohomedir ini=${servercfg} log=${gamelog}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="223250" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-unreal2" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Red Orchestra: Ostfront 41-45" +engine="unreal2" +glibc="2.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/system" +executabledir="${systemdir}" +executable="./ucc-bin" +servercfgdir="${systemdir}" +servercfg="${selfname}.ini" +servercfgdefault="default.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" +compressedmapsdir="${rootdir}/Maps-Compressed" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${logdir}/server" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" +gamelogdate="${gamelogdir}/${selfname}-game-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/rtcwserver/_default.cfg b/lgsm/config-default/config-lgsm/rtcwserver/_default.cfg new file mode 100644 index 0000000..d62dcb0 --- /dev/null +++ b/lgsm/config-default/config-lgsm/rtcwserver/_default.cfg @@ -0,0 +1,170 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27960" +defaultmap="mp_beach" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+set sv_punkbuster 0 +set fs_basepath ${serverfiles} +set dedicated 1 +set net_ip ${ip} +set net_port ${port} +exec ${servercfg} +map ${defaultmap}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-quake3" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Return to Castle Wolfenstein" +engine="ioquake3" +glibc="2.1" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/main" +executabledir="${serverfiles}" +executable="./iowolfded.x86_64" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/rustserver/_default.cfg b/lgsm/config-default/config-lgsm/rustserver/_default.cfg new file mode 100644 index 0000000..e045777 --- /dev/null +++ b/lgsm/config-default/config-lgsm/rustserver/_default.cfg @@ -0,0 +1,199 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="28015" +rconport="28016" +appport="28082" +queryport="28017" +rconpassword="CHANGE_ME" +rconweb="1" # values: Facepunch web panel, Rustadmin desktop and Rustadmin Online = 1, Rusty = 0. +servername="LinuxGSM" +gamemode="vanilla" # values: vanilla, softcore ( Doc: https://wiki.facepunch.com/rust/server-gamemodes ) +serverlevel="Procedural Map" # values: Procedural Map, Barren, HapisIsland, SavasIsland +customlevelurl="" # Custom level url. +server.levelurl \"${customlevelurl}\" +seed="" # range: 1-2147483647, used to reproduce a procedural map. +salt="" # range: unknown, used to recover a known setting from an existing map. +maxplayers="50" +worldsize="3000" # default: 3000, range: 1000-6000, map size in meters. +saveinterval="300" # Auto-save in seconds. +tickrate="30" # default: 30, range: 15-100. + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-batchmode +app.listenip ${ip} +app.port ${appport} +server.ip ${ip} +server.port ${port} +server.queryport ${queryport} +server.tickrate ${tickrate} +server.hostname \"${servername}\" +server.identity \"${selfname}\" +server.gamemode ${gamemode} +server.level \"${serverlevel}\" +server.seed ${seed} +server.salt ${salt} +server.maxplayers ${maxplayers} +server.worldsize ${worldsize} +server.saveinterval ${saveinterval} +rcon.web ${rconweb} +rcon.ip ${ip} +rcon.port ${rconport} +rcon.password \"${rconpassword}\" -logfile" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="10" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="258550" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Rust" +engine="unity3d" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./RustDedicated" +serveridentitydir="${systemdir}/server/${selfname}" +servercfgdir="${serveridentitydir}/cfg" +servercfg="server.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${logdir}/server" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" +gamelogdate="${gamelogdir}/${selfname}-game-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/rwserver/_default.cfg b/lgsm/config-default/config-lgsm/rwserver/_default.cfg new file mode 100644 index 0000000..9a798c6 --- /dev/null +++ b/lgsm/config-default/config-lgsm/rwserver/_default.cfg @@ -0,0 +1,178 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="339010" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="unity" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Rising World" +engine="unity3d" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./RisingWorldServer.x64" +servercfgdir="${systemdir}" +servercfg="server.properties" +servercfgdefault="server.properties" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/sampserver/_default.cfg b/lgsm/config-default/config-lgsm/sampserver/_default.cfg new file mode 100644 index 0000000..1dbeaac --- /dev/null +++ b/lgsm/config-default/config-lgsm/sampserver/_default.cfg @@ -0,0 +1,169 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="7777" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="3" +querytype="samp" + +## Console type +consoleverbose="" +consoleinteract="" + +## Game Server Details +# Do not edit +gamename="San Andreas Multiplayer" +engine="renderware" +glibc="2.3" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}/samp03" +executable="./samp03svr" +servercfgdir="${systemdir}/samp03" +servercfg="server.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/samp03" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/sbotsserver/_default.cfg b/lgsm/config-default/config-lgsm/sbotsserver/_default.cfg new file mode 100644 index 0000000..ef33b7f --- /dev/null +++ b/lgsm/config-default/config-lgsm/sbotsserver/_default.cfg @@ -0,0 +1,179 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +port="7777" +queryport="27015" +defaultmap="StationKappa" +servername="LinuxGSM" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="Port=${port}?QueryPort=${queryport} -startup_map ${defaultmap} -server_name \"${servername}\"" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="974130" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="StickyBots" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}/blank1/Binaries/Linux" +executable="./blank1Server-Linux-Shipping" +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/sbserver/_default.cfg b/lgsm/config-default/config-lgsm/sbserver/_default.cfg new file mode 100644 index 0000000..6032abe --- /dev/null +++ b/lgsm/config-default/config-lgsm/sbserver/_default.cfg @@ -0,0 +1,185 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## SteamCMD Login | https://docs.linuxgsm.com/steamcmd#steamcmd-login +steamuser="username" +steampass='password' + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="211820" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Starbound" +engine="starbound" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}/linux" +executable="./starbound_server" +servercfgdir="${systemdir}/storage" +servercfg="starbound_server.config" +servercfgdefault="starbound_server.config" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/storage" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/scpslserver/_default.cfg b/lgsm/config-default/config-lgsm/scpslserver/_default.cfg new file mode 100644 index 0000000..f00574b --- /dev/null +++ b/lgsm/config-default/config-lgsm/scpslserver/_default.cfg @@ -0,0 +1,183 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +## All server settings except the server port are done in the config file: +## Docs: https://en.scpslgame.com/index.php?title=Docs:Server_Config +port="7777" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="${port}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="996560" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="7" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="SCP: Secret Laboratory" +engine="unity3d" +glibc="2.27" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}" +executable="./LocalAdmin" +servercfg="config_gameplay.txt" +servercfgdefault="config_gameplay.txt" +servercfgdir="${HOME}/.config/SCP Secret Laboratory/config/${port}" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${HOME}/.config/SCP Secret Laboratory/LocalAdminLogs/${port}" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/scpslsmserver/_default.cfg b/lgsm/config-default/config-lgsm/scpslsmserver/_default.cfg new file mode 100644 index 0000000..bb26d6c --- /dev/null +++ b/lgsm/config-default/config-lgsm/scpslsmserver/_default.cfg @@ -0,0 +1,183 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +## All server settings except the server port are done in the config file: +## Docs: https://en.scpslgame.com/index.php?title=Docs:Server_Config +port="7777" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="${port}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="786920" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="7" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="SCP: Secret Laboratory ServerMod" +engine="unity3d" +glibc="2.27" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}" +executable="./LocalAdmin" +servercfg="config_gameplay.txt" +servercfgdefault="config_gameplay.txt" +servercfgdir="${HOME}/.config/SCP Secret Laboratory/config/${port}" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${HOME}/.config/SCP Secret Laboratory/LocalAdminLogs/${port}" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/sdtdserver/_default.cfg b/lgsm/config-default/config-lgsm/sdtdserver/_default.cfg new file mode 100644 index 0000000..61cd85a --- /dev/null +++ b/lgsm/config-default/config-lgsm/sdtdserver/_default.cfg @@ -0,0 +1,183 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-quit -batchmode -nographics -dedicated -configfile=${servercfgfullpath}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="294420" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="8" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="5" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="7 Days To Die" +engine="unity3d" +glibc="2.27" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./7DaysToDieServer.x86_64" +servercfgdir="${systemdir}" +servercfg="${selfname}.xml" +servercfgdirdefault="${serverfiles}" +servercfgdefault="serverconfig.xml" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${logdir}/server" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/secrets-common-template.cfg b/lgsm/config-default/config-lgsm/secrets-common-template.cfg new file mode 100644 index 0000000..d8ded6a --- /dev/null +++ b/lgsm/config-default/config-lgsm/secrets-common-template.cfg @@ -0,0 +1,5 @@ +################################## +######## Common Secrets ########## +################################## +# PLACE GLOBAL SECRET SETTINGS HERE +## These settings will apply to all instances. diff --git a/lgsm/config-default/config-lgsm/secrets-instance-template.cfg b/lgsm/config-default/config-lgsm/secrets-instance-template.cfg new file mode 100644 index 0000000..5446d37 --- /dev/null +++ b/lgsm/config-default/config-lgsm/secrets-instance-template.cfg @@ -0,0 +1,5 @@ +################################## +####### Instance Secrets ######### +################################## +# PLACE INSTANCE SECRET SETTINGS HERE +## These settings will apply to a specific instance. diff --git a/lgsm/config-default/config-lgsm/sfcserver/_default.cfg b/lgsm/config-default/config-lgsm/sfcserver/_default.cfg new file mode 100644 index 0000000..40c5a0c --- /dev/null +++ b/lgsm/config-default/config-lgsm/sfcserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="sf_astrodome" +maxplayers="32" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game sfclassic -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="244310" # Source 2013 SDK +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="SourceForts Classic" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/sfclassic" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/sfserver/_default.cfg b/lgsm/config-default/config-lgsm/sfserver/_default.cfg new file mode 100644 index 0000000..4beb002 --- /dev/null +++ b/lgsm/config-default/config-lgsm/sfserver/_default.cfg @@ -0,0 +1,184 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +queryport="15777" +beaconport="15000" +port="7777" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="FactoryGame -multihome=${ip} -ServerQueryPort=${queryport} -BeaconPort=${beaconport} -Port=${port} -log -unattended" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="1690800" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Satisfactory" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/FactoryGame" +executabledir="${serverfiles}/Engine/Binaries/Linux" +executable="./UE4Server-Linux-Shipping" +servercfgdir="${systemdir}/Saved/Config/LinuxServer" +servercfg="GameUserSettings.ini" +servercfgdefault="GameUserSettings.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/sof2server/_default.cfg b/lgsm/config-default/config-lgsm/sof2server/_default.cfg new file mode 100644 index 0000000..59fb837 --- /dev/null +++ b/lgsm/config-default/config-lgsm/sof2server/_default.cfg @@ -0,0 +1,170 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="20100" +defaultmap="mp_shop" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+set sv_punkbuster 0 +set dedicated 2 +set net_ip ${ip} +set net_port ${port} +exec ${servercfg} +map ${defaultmap}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-quake3" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Soldier Of Fortune 2: Gold Edition" +engine="idtech3" +glibc="2.1" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/main" +executabledir="${serverfiles}" +executable="./sof2ded" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/solserver/_default.cfg b/lgsm/config-default/config-lgsm/solserver/_default.cfg new file mode 100644 index 0000000..6010185 --- /dev/null +++ b/lgsm/config-default/config-lgsm/solserver/_default.cfg @@ -0,0 +1,182 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +maplist="mapslist.txt" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-b ${ip} -m ${maplist} -c ${servercfg}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="638500" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="5" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Soldat" +engine="soldat" +glibc="2.1" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}" +executable="./soldatserver" +servercfgdir="${systemdir}" +servercfg="soldat.ini" +servercfgdefault="soldat.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/squadserver/_default.cfg b/lgsm/config-default/config-lgsm/squadserver/_default.cfg new file mode 100644 index 0000000..424d81f --- /dev/null +++ b/lgsm/config-default/config-lgsm/squadserver/_default.cfg @@ -0,0 +1,184 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +port="7787" +queryport="27165" +randommap="ALWAYS" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="MULTIHOME=${ip} RANDOM=${randommap} Port=${port} QueryPort=${queryport}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="403240" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Squad" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/SquadGame" +executabledir="${serverfiles}" +executable="./SquadGameServer.sh" +servercfgdir="${systemdir}/ServerConfig" +servercfg="Server.cfg" +servercfgdefault="Server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/stnserver/_default.cfg b/lgsm/config-default/config-lgsm/stnserver/_default.cfg new file mode 100644 index 0000000..7bf2d72 --- /dev/null +++ b/lgsm/config-default/config-lgsm/stnserver/_default.cfg @@ -0,0 +1,184 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### +maxplayers="20" +# Regions: USA: 0, EU: 1, AUS: 2 +region="0" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +# https://colonysurvival.gamepedia.com/Dedicated_Server#Installation_.28Linux.29 +startparameters="-mc ${maxplayers} -r ${region}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="1502300" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Survive the Nights" +engine="unity3d" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./Server_Linux_x64" +servercfgdir="${systemdir}/Config" +servercfg="ServerConfig.txt" +servercfgdefault="ServerConfig.txt" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +gamelogdate="${gamelogdir}/${selfname}-game-$(date '+%Y-%m-%d-%H:%M:%S').log" +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/stserver/_default.cfg b/lgsm/config-default/config-lgsm/stserver/_default.cfg new file mode 100644 index 0000000..e245c57 --- /dev/null +++ b/lgsm/config-default/config-lgsm/stserver/_default.cfg @@ -0,0 +1,182 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +worldname="moon_save" +worldtype="Moon" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-LOADLATEST ${worldname} ${worldtype}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="600760" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Stationeers" +engine="unity3d" +glibc="2.34" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./rocketstation_DedicatedServer.x86_64" +servercfgdir="${systemdir}" +servercfg="setting.xml" +servercfgdefault="setting.xml" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${HOME}/.config/unity3d/Rocketwerkz/Stationeers" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/svenserver/_default.cfg b/lgsm/config-default/config-lgsm/svenserver/_default.cfg new file mode 100644 index 0000000..11822d1 --- /dev/null +++ b/lgsm/config-default/config-lgsm/svenserver/_default.cfg @@ -0,0 +1,185 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="svencoop1" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game svencoop -strictportbind +ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} +servercfgfile ${servercfg} +maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="276060" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Sven Co-op" +engine="goldsrc" +glibc="2.24" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/svencoop" +executabledir="${serverfiles}" +executable="./svends_run" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/terrariaserver/_default.cfg b/lgsm/config-default/config-lgsm/terrariaserver/_default.cfg new file mode 100644 index 0000000..0fc6a06 --- /dev/null +++ b/lgsm/config-default/config-lgsm/terrariaserver/_default.cfg @@ -0,0 +1,185 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## SteamCMD Login | https://docs.linuxgsm.com/steamcmd#steamcmd-login +steamuser="username" +steampass='password' + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-config ${servercfgfullpath}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="105600" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="7" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="5" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Terraria" +engine="terraria" +glibc="2.7" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./TerrariaServer" +servercfgdir="${systemdir}" +servercfg="${selfname}.txt" +servercfgdefault="serverconfig.txt" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +#gamelogdir="" # No server logs available +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/tf2server/_default.cfg b/lgsm/config-default/config-lgsm/tf2server/_default.cfg new file mode 100644 index 0000000..7d3164e --- /dev/null +++ b/lgsm/config-default/config-lgsm/tf2server/_default.cfg @@ -0,0 +1,191 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="cp_badlands" +maxplayers="16" + +## Game Server Login Token (GSLT): Optional +# GSLT can be used for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game tf -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +sv_setsteamaccount ${gslt} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="232250" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Team Fortress 2" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/tf" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/tfcserver/_default.cfg b/lgsm/config-default/config-lgsm/tfcserver/_default.cfg new file mode 100644 index 0000000..3334509 --- /dev/null +++ b/lgsm/config-default/config-lgsm/tfcserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="dustbowl" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game tfc -strictportbind +ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="90" +steamcmdforcewindows="no" +appidmod="tfc" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Team Fortress Classic" +engine="goldsrc" +glibc="2.3.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/tfc" +executabledir="${serverfiles}" +executable="./hlds_run" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/tfserver/_default.cfg b/lgsm/config-default/config-lgsm/tfserver/_default.cfg new file mode 100644 index 0000000..86994d8 --- /dev/null +++ b/lgsm/config-default/config-lgsm/tfserver/_default.cfg @@ -0,0 +1,198 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="5001" +beaconport="5002" +shutdownport="5003" +queryport="27015" +adminlabel="true" # Enable admin icon. +allowsensitivewords="true" +altsavedirectoryname="${defaultmap}" +anticheat="true" +damageself="true" +damangeallies="true" +gamemode="0" # 0 = PvP; 1 = PvE +greenhand="true" +maxplayers="40" +maxqueuesize="50" +queuevalidtime="120" +saveinterval="300" +serveradmins="" # Use 17-digit Steam IDs separated by commas to grant admin privileges to players. +servername="LinuxGSM" +serverpassword="" +servertags="LinuxGSM" +steamsocket="0" # Use Steam Socket. 0 = off; 1 = on. Use Steam Servers for network penetration. Enable this if you don't have a public IP but you want to allow players from outside your network to join your server. If disabled, only you and other players on your LAN can join. If you have a public IP, you do not need to enable this. + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="ProjectWar_Start?DedicatedServer?MaxPlayers=${maxplayers} -server -game -log -MultiHome=${ip} -Port=${port} -QueryPort=${queryport} -BeaconPort=${beaconport} -ShutDownServicePort=${shutdownport} -ConfigServerName='${selfname}' -OutIPAddress=${publicip} -ServerTags='${servertags}' -UseSteamSocket=${steamsocket} -UserDir='${serverfiles}/${selfname}' -ServerName='${servername}' -EnableParallelCharacterMovementTickFunction -EnableParallelCharacterTickFunction -UseDynamicPhysicsScene -Game.PhysicsVehicle=false -ansimalloc -Game.MaxFrameRate=35 -MaxQueueSize=${maxqueuesize} -QueueValidTime=${queuevalidtime} -QueueThreshold=${maxplayers} -ServerFightModeType=${gamemode} -IsCanSelfDamage=${damageself} -IsCanFriendDamage=${damageallies} -SaveWorldInterval=${saveinterval} -GMOverlapRatio=2 -GreenHand=${greenhand} -SensitiveWords=${allowsensitivewords} -UseACE=${anticheat} -ServerAdminAccounts='${serveradmins}' -IsShowGmTitle=${adminlabel} -ServerPassword='${serverpassword}'" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="5" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="2334200" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="The Front" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/ProjectWar" +executabledir="${systemdir}/Binaries/Linux" +executable="./TheFrontServer" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/tiserver/_default.cfg b/lgsm/config-default/config-lgsm/tiserver/_default.cfg new file mode 100644 index 0000000..dd3e1dd --- /dev/null +++ b/lgsm/config-default/config-lgsm/tiserver/_default.cfg @@ -0,0 +1,183 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="7777" +defaultmap="/Game/TheIsle/Maps/Game/Isla_Spiro/Isla_Spiro" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="${defaultmap} -Port=${port} -log" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="412680" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="evrima" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="The Isle" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/TheIsle" +executabledir="${systemdir}/Binaries/Linux" +executable="./TheIsleServer-Linux-Shipping" +servercfgdir="${systemdir}/Saved/Config/LinuxServer" +servercfg="Game.ini" +servercfgdefault="Game.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/ts3server/_default.cfg b/lgsm/config-default/config-lgsm/ts3server/_default.cfg new file mode 100644 index 0000000..36c0d2b --- /dev/null +++ b/lgsm/config-default/config-lgsm/ts3server/_default.cfg @@ -0,0 +1,169 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="inifile=${servercfgfullpath} pid_file=ts3server.pid" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="5" +querytype="teamspeak3" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="TeamSpeak 3" +servername="TeamSpeak 3 Server" +engine="null" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./ts3server" +servercfgdir="${systemdir}" +servercfg="${selfname}.ini" +servercfgdefault="ts3server.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/tsserver/_default.cfg b/lgsm/config-default/config-lgsm/tsserver/_default.cfg new file mode 100644 index 0000000..05189f9 --- /dev/null +++ b/lgsm/config-default/config-lgsm/tsserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="ts_neobaroque" +maxplayers="32" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game ts -strictportbind +ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers} " + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="90" +steamcmdforcewindows="no" +appidmod="cstrike" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="The Specialists" +engine="goldsrc" +glibc="2.3.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/ts" +executabledir="${serverfiles}" +executable="./hlds_run" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/tuserver/_default.cfg b/lgsm/config-default/config-lgsm/tuserver/_default.cfg new file mode 100644 index 0000000..086968e --- /dev/null +++ b/lgsm/config-default/config-lgsm/tuserver/_default.cfg @@ -0,0 +1,188 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="7777" +queryport="27015" + +## Game Server Login Token (GSLT): Optional +# GSLT can be used for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-log -MultiHome=${ip} -Port=${port} -QueryPort=${queryport} -TowerServerINI=${selfname}.ini" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="439660" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Tower Unite" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/Tower" +executabledir="${systemdir}/Binaries/Linux" +executable="./TowerServer-Linux-Shipping" +servercfgdir="${systemdir}/Binaries/Linux" +servercfg="${selfname}.ini" +servercfgdefault="TowerServer.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/twserver/_default.cfg b/lgsm/config-default/config-lgsm/twserver/_default.cfg new file mode 100644 index 0000000..6f9c2ad --- /dev/null +++ b/lgsm/config-default/config-lgsm/twserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## SteamCMD Login | https://docs.linuxgsm.com/steamcmd#steamcmd-login +steamuser="username" +steampass='password' + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-f ${servercfg}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="380840" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="4" +querytype="teeworlds" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Teeworlds" +engine="teeworlds" +glibc="2.14" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/tw" +executabledir="${systemdir}" +executable="./teeworlds_srv" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" # Teeworlds can also auto load any config if an autoexec.cfg file is present in the server dir +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${logdir}/server" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/untserver/_default.cfg b/lgsm/config-default/config-lgsm/untserver/_default.cfg new file mode 100644 index 0000000..e76aefb --- /dev/null +++ b/lgsm/config-default/config-lgsm/untserver/_default.cfg @@ -0,0 +1,192 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +maxplayers="20" +defaultmap="PEI" +servername="LinuxGSM" +perspective="first" # values: first, third, vehicle, Both. +gamemode="normal" # values: normal, easy, gold. + +## Game Server Login Token (GSLT): Required +# GSLT is required for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-nographics -batchmode -bind ${ip} -port ${port} -maxplayers ${maxplayers} -perspective ${perspective} -mode ${gamemode} -name ${servername} -map ${defaultmap} -gslt ${gslt} +InternetServer/${selfname}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="1110390" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Unturned" +engine="unity3d" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./Unturned_Headless.x86_64" +servercfgdir="${systemdir}/Servers/${selfname}" +servercfg="Config.json" +servercfgdefault="Config.json" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${logdir}/server" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/ut2k4server/_default.cfg b/lgsm/config-default/config-lgsm/ut2k4server/_default.cfg new file mode 100644 index 0000000..709b985 --- /dev/null +++ b/lgsm/config-default/config-lgsm/ut2k4server/_default.cfg @@ -0,0 +1,172 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +defaultmap="DM-Rankin" +ip="0.0.0.0" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="server ${defaultmap}?game=XGame.xDeathMatch -nohomedir ini=${servercfg} log=${gamelog}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-unreal2" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Unreal Tournament 2004" +engine="unreal2" +glibc="2.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/System" +executabledir="${systemdir}" +executable="./ucc-bin" +servercfgdir="${systemdir}" +servercfg="${selfname}.ini" +servercfgdefault="UT2004.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" +compressedmapsdir="${rootdir}/Maps-Compressed" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${logdir}/server" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" +gamelogdate="${gamelogdir}/${selfname}-game-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/ut3server/_default.cfg b/lgsm/config-default/config-lgsm/ut3server/_default.cfg new file mode 100644 index 0000000..cdadca6 --- /dev/null +++ b/lgsm/config-default/config-lgsm/ut3server/_default.cfg @@ -0,0 +1,187 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="7777" +queryport="6500" +defaultmap="VCTF-Suspense" +game="UTGameContent.UTVehicleCTFGame_Content" +# Example: mutators="UTGame.UTMutator_Instagib,UTGame.UTMutator_LowGrav" +mutators="" +isdedicated="true" +islanmatch="false" +usesstats="false" +shouldadvertise="true" +pureserver="1" +allowjoininprogress="true" +# Required: GameSpy Username and password +# https://docs.linuxgsm.com/game-servers/unreal-tournament-3#server-gamespy-login +gsusername="" +gspassword="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +# List of game types and mutators: https://docs.linuxgsm.com/game-servers/unreal-tournament-3 +startparameters="server ${defaultmap}?Game=${game}?bIsDedicated=${isdedicated}?bIsLanMatch=${islanmatch}?bUsesStats=${usesstats}?bShouldAdvertise=${shouldadvertise}?PureServer=${pureserver}?bAllowJoinInProgress=${allowjoininprogress}?Mutator=${mutators}?ConfigSubDir=${selfname} -login=${gsusername} -password=${gspassword} -port=${port} -queryport=${queryport} -multihome=${ip} -nohomedir -unattended -log=${gamelog}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Unreal Tournament 3" +engine="unreal3" +glibc="2.3.2" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}/Binaries" +executable="./ut3" +servercfgdir="${systemdir}/UTGame/Config/${selfname}" +servercfg="UTGame.ini" +servercfgdefault="UTGame.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${logdir}/server" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +gamelog="${gamelogdir}/${selfname}-game.log" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" +gamelogdate="${gamelogdir}/${selfname}-game-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/ut99server/_default.cfg b/lgsm/config-default/config-lgsm/ut99server/_default.cfg new file mode 100644 index 0000000..f4a3d8e --- /dev/null +++ b/lgsm/config-default/config-lgsm/ut99server/_default.cfg @@ -0,0 +1,170 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +defaultmap="DM-Deck16][" +ip="0.0.0.0" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="server ${defaultmap}.unr ini=${servercfgfullpath}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-gamespy1" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Unreal Tournament 99" +engine="unreal" +glibc="2.1" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/System64" +executabledir="${systemdir}" +executable="./ucc-bin" +servercfgdir="${systemdir}" +servercfg="${selfname}.ini" +servercfgdefault="Default.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" +compressedmapsdir="${rootdir}/Maps-Compressed" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/utserver/_default.cfg b/lgsm/config-default/config-lgsm/utserver/_default.cfg new file mode 100644 index 0000000..0ffdd82 --- /dev/null +++ b/lgsm/config-default/config-lgsm/utserver/_default.cfg @@ -0,0 +1,173 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +# For CTF: defaultmap="CTF-Face" gametype="CTF" +ip="0.0.0.0" +port="7777" +defaultmap="DM-Underland" +gametype="DM" +timelimit="10" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="UnrealTournament ${defaultmap}?Game=${gametype}?TimeLimit=${timelimit} -port=${port}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="1" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Unreal Tournament" +engine="unreal4" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/LinuxServer" +executabledir="${systemdir}/Engine/Binaries/Linux" +executable="./UE4Server-Linux-Shipping" +servercfgdir="${systemdir}/UnrealTournament/Saved/Config/LinuxServer" +servercfg="Game.ini" +servercfgdefault="Game.ini" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/vhserver/_default.cfg b/lgsm/config-default/config-lgsm/vhserver/_default.cfg new file mode 100644 index 0000000..4e3d239 --- /dev/null +++ b/lgsm/config-default/config-lgsm/vhserver/_default.cfg @@ -0,0 +1,218 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +servername="LinuxGSM" +# Minimum password length is 5. +serverpassword="" +port="2456" +worldname="${selfname}" +public="1" +savedir="$HOME/.config/unity3d/IronGate/Valheim" +logFile="" +saveinterval="1800" +backups="4" +backupshort="7200" +backuplong="43200" +# If crossplay is empty, it's off. Fill with any text to make true +# Crossplay is currently not working on Linux dedicated servers, so for now the default is false (empty) +crossplay="" + +# INSTRUCTIONS FOR WORLD MODIFIERS (from Valheim Dedicated Server Manual.pdf located in serverfiles) +# World modifiers can only be set in the start parameters and can be a combination of the following +# PRESETS: +# Setting a preset will overwrite any other previous modifiers. +# Command line parameter: -preset +# Valid values: normal, casual, easy, hard, hardcore, immersive, hammer. +# MODIFIERS: +# This is set as a combination of key and value, if combined with a preset should be set after. +# Command line parameter: -modifier +# Valid keys and possible values: +# combat: veryeasy, easy, hard, veryhard +# deathPenalty: casual, veryeasy, easy, hard, hardcore +# resources: muchless, less, more, muchmore, most +# raids: none, muchless, less, more, muchmore +# portals: casual, hard, veryhard +# KEYS: +# Sets a world modifier checkbox key. +# Command line parameter: -setkey +# Valid values: nobuildcost, playerevents, passivemobs, nomap +# Example of a combination of modifiers where we set no raids, very hard portals and no map run: +# worldmodifiers="-modifier raids none -modifier portals veryhard -setkey nomap" +# NOTE: removing world modifiers will NOT reset them to default. the modifiers are stored in the world save file (.fwl) +# To go back to default you need to launch the server with the following parameter at least once: +#. worldmodifiers="-preset normal" + +worldmodifiers="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-name '${servername}' -password ${serverpassword} -port ${port} -world ${worldname} -public ${public} -savedir '${savedir}' -saveinterval ${saveinterval} -backups ${backups} -backupshort ${backupshort} -backuplong ${backuplong}${logFile:+ -logFile '${logFile}'}${crossplay:+ -crossplay}${worldmodifiers:+ ${worldmodifiers}}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="5" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="896660" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Valheim" +engine="unity3d" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +executable="./valheim_server.x86_64" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/Saved/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/vintsserver/_default.cfg b/lgsm/config-default/config-lgsm/vintsserver/_default.cfg new file mode 100644 index 0000000..1b64ae2 --- /dev/null +++ b/lgsm/config-default/config-lgsm/vintsserver/_default.cfg @@ -0,0 +1,173 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="--dataPath ${servercfgdir}" + +## Release Settings | https://docs.linuxgsm.com/game-servers/vintagestory#release-settings +# Branch (stable|unstable) +branch="stable" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="5" +querytype="" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Vintage Story" +engine="vintagestory" +glibc="2.17" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}" +preexecutable="" +executable="./VintagestoryServer" +servercfgdir="${serverfiles}/data/${selfname}" +servercfg="serverconfig.json" +servercfgdefault="serverconfig.json" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${servercfgdir}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/vpmcserver/_default.cfg b/lgsm/config-default/config-lgsm/vpmcserver/_default.cfg new file mode 100644 index 0000000..09d6bf9 --- /dev/null +++ b/lgsm/config-default/config-lgsm/vpmcserver/_default.cfg @@ -0,0 +1,177 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +javaram="1024" # -Xmx$1024M + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="" + +## Release Settings | https://docs.linuxgsm.com/game-servers/minecraft#release-settings +# Version (latest|3.1.1) +mcversion="latest" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +# 12: shutdown +stopmode="12" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="minecraft" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Velocity Proxy" +engine="lwjgl2" +glibc="null" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +preexecutable="java -Xmx${javaram}M -XX:+UseG1GC -XX:G1HeapRegionSize=4M -XX:+UnlockExperimentalVMOptions -XX:+ParallelRefProcEnabled -XX:+AlwaysPreTouch -XX:MaxInlineLevel=15 -jar" +executable="./velocity.jar" +servercfgdir="${systemdir}" +servercfg="velocity.toml" +servercfgdefault="velocity.toml" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/vsserver/_default.cfg b/lgsm/config-default/config-lgsm/vsserver/_default.cfg new file mode 100644 index 0000000..0195393 --- /dev/null +++ b/lgsm/config-default/config-lgsm/vsserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +defaultmap="vs_frost" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game vs -strictportbind +ip ${ip} -port ${port} +clientport ${clientport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="90" +steamcmdforcewindows="no" +appidmod="cstrike" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="9" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Vampire Slayer" +engine="goldsrc" +glibc="2.3.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/vs" +executabledir="${serverfiles}" +executable="./hlds_run" +servercfgdir="${systemdir}" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/wetserver/_default.cfg b/lgsm/config-default/config-lgsm/wetserver/_default.cfg new file mode 100644 index 0000000..4c37389 --- /dev/null +++ b/lgsm/config-default/config-lgsm/wetserver/_default.cfg @@ -0,0 +1,165 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+set net_strict 1 +set fs_homepath ${serverfiles} +exec ${servercfg}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-quake3" + +## Console type +consoleverbose="yes" +consoleinteract="no" + +## Game Server Details +# Do not edit +gamename="Wolfenstein: Enemy Territory" +engine="idtech3" +glibc="2.2.4" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}" +executable="./etded" +servercfgdir="${systemdir}/etmain" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/wfserver/_default.cfg b/lgsm/config-default/config-lgsm/wfserver/_default.cfg new file mode 100644 index 0000000..80ff4ba --- /dev/null +++ b/lgsm/config-default/config-lgsm/wfserver/_default.cfg @@ -0,0 +1,184 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="44400" +httpport="44444" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="+exec ${servercfg} +sv_http_ip ${ip} +set sv_http_port ${httpport} +sv_ip ${ip} +sv_port ${port}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="1136510" +steamcmdforcewindows="no" +appidmod="warfork" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-quake3" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Warfork" +engine="qfusion" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/Warfork.app/Contents/Resources" +executabledir="${systemdir}" +executable="./wf_server.x86_64" +servercfgdir="${systemdir}/basewf" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/wmcserver/_default.cfg b/lgsm/config-default/config-lgsm/wmcserver/_default.cfg new file mode 100644 index 0000000..f38976d --- /dev/null +++ b/lgsm/config-default/config-lgsm/wmcserver/_default.cfg @@ -0,0 +1,176 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +javaram="1024" # -Xmx$1024M + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="nogui" + +## Release Settings | https://docs.linuxgsm.com/game-servers/minecraft#release-settings +# Version (latest|1.16.5) +mcversion="latest" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="minecraft" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="WaterfallMC" +engine="lwjgl2" +glibc="null" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${serverfiles}" +preexecutable="java -Xmx${javaram}M -jar" +executable="./waterfall.jar" +servercfgdir="${systemdir}" +servercfg="config.yml" +servercfgdefault="config.yml" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/wurmserver/_default.cfg b/lgsm/config-default/config-lgsm/wurmserver/_default.cfg new file mode 100644 index 0000000..5405be8 --- /dev/null +++ b/lgsm/config-default/config-lgsm/wurmserver/_default.cfg @@ -0,0 +1,218 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +# https://www.wurmpedia.com/index.php/Server_administration_(Wurm_Unlimited) + +# Game mode (Creative|Adventure) +gamemode="Creative" + +# The kingdom the server belongs to. +# If you're using the Adventure base, use 1, 2, or 3. +# If you're using Creative, use 4. +# Kingdom numbers: +# 0 - No kingdom +# 1 - Jen-Kellon +# 2 - Mol-Rehan +# 3 - Horde of the Summoned +# 4 - Freedom +homekingdom="4" + +# Unlocks the admin commands from within the game, that can be used to change +# the gameplay settings of the server, such as skill gain rate and field growth time. +adminpassword="ADMINPASSWORD" + +# If true the server will follow the rules from the Epic servers in Wurm Online. +# For instance it will use the skill curve. +epicsettings="false" + +# If the server is a home server (belongs to a single kingdom). +homeserver="true" + +# Defaults to true, should only be set to false if the server is intended to be +# connected with another server that is going to act as a loginserver. +loginserver="true" + +# Used for server to server communication. +rmiport="7221" +rmiregport="7220" + +maxplayers="200" +servername="LinuxGSM" +serverpassword="" +ip="0.0.0.0" +port="3724" +queryport="27016" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +# Parameters are edited in the game server config file. +startparameters="start=${gamemode} adminpwd='${adminpassword}' epicsettings='${epicsettings}' externalport='${port}' homeserver='${homeserver}' homekingdom='${homekingdom}' loginserver='${loginserver}' maxplayers='${maxplayers}' queryport='${queryport}' rmiport='${rmiport}' rmiregport='${rmiregport}' servername='${servername}' serverpassword='${serverpassword}' ip='${ip}'" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="402370" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="false" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="2" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="" +consoleinteract="" + +## Game Server Details +# Do not edit +gamename="Wurm Unlimited" +engine="wurm" +glibc="2.14" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}" +executabledir="${systemdir}" +executable="./WurmServerLauncher" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${serverfiles}/Logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/zmrserver/_default.cfg b/lgsm/config-default/config-lgsm/zmrserver/_default.cfg new file mode 100644 index 0000000..1bcd5d4 --- /dev/null +++ b/lgsm/config-default/config-lgsm/zmrserver/_default.cfg @@ -0,0 +1,186 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="zm_docksofthedead" +maxplayers="16" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game zombie_master_reborn -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="244310" # Source 2013 SDK +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Zombie Master: Reborn" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/zombie_master_reborn" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/config-default/config-lgsm/zpsserver/_default.cfg b/lgsm/config-default/config-lgsm/zpsserver/_default.cfg new file mode 100644 index 0000000..f449778 --- /dev/null +++ b/lgsm/config-default/config-lgsm/zpsserver/_default.cfg @@ -0,0 +1,191 @@ +################################## +######## Default Settings ######## +################################## +# DO NOT EDIT, ANY CHANGES WILL BE OVERWRITTEN! +# Copy settings from here and use them in either: +# common.cfg - applies settings to every instance. +# [instance].cfg - applies settings to a specific instance. + +#### Game Server Settings #### + +## Predefined Parameters | https://docs.linuxgsm.com/configuration/start-parameters +ip="0.0.0.0" +port="27015" +clientport="27005" +sourcetvport="27020" +defaultmap="zps_deadend" +maxplayers="20" + +## Game Server Login Token (GSLT): Optional +# GSLT can be used for running a public server. +# More info: https://docs.linuxgsm.com/steamcmd/gslt +gslt="" + +## Server Parameters | https://docs.linuxgsm.com/configuration/start-parameters#additional-parameters +startparameters="-game zps -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}" + +#### LinuxGSM Settings #### + +## LinuxGSM Stats +# Send useful stats to LinuxGSM developers. +# https://docs.linuxgsm.com/configuration/linuxgsm-stats +# (on|off) +stats="off" + +## Notification Alerts +# (on|off) + +# Display IP | https://docs.linuxgsm.com/alerts#display-ip +displayip="" + +# More info | https://docs.linuxgsm.com/alerts#more-info +postalert="off" + +# Alert on Start/Stop/Restart +statusalert="off" + +# Discord Alerts | https://docs.linuxgsm.com/alerts/discord +discordalert="off" +discordwebhook="webhook" + +# Email Alerts | https://docs.linuxgsm.com/alerts/email +emailalert="off" +email="email@example.com" +emailfrom="" + +# Gotify Alerts | https://docs.linuxgsm.com/alerts/gotify +gotifyalert="off" +gotifytoken="token" +gotifywebhook="webhook" + +# IFTTT Alerts | https://docs.linuxgsm.com/alerts/ifttt +iftttalert="off" +ifttttoken="accesstoken" +iftttevent="linuxgsm_alert" + +# Pushbullet Alerts | https://docs.linuxgsm.com/alerts/pushbullet +pushbulletalert="off" +pushbullettoken="accesstoken" +channeltag="" + +# Pushover Alerts | https://docs.linuxgsm.com/alerts/pushover +pushoveralert="off" +pushovertoken="accesstoken" +pushoveruserkey="userkey" + +# Rocket.Chat Alerts | https://docs.linuxgsm.com/alerts/rocket.chat +rocketchatalert="off" +rocketchatwebhook="webhook" + +# Slack Alerts | https://docs.linuxgsm.com/alerts/slack +slackalert="off" +slackwebhook="webhook" + +# Telegram Alerts | https://docs.linuxgsm.com/alerts/telegram +# You can add a custom cURL string eg proxy (useful in Russia) in "curlcustomstring". +# For example "--socks5 ipaddr:port" for socks5 proxy see more in "curl --help". +telegramapi="api.telegram.org" +telegramalert="off" +telegramtoken="accesstoken" +telegramchatid="" +curlcustomstring="" + +## Updating | https://docs.linuxgsm.com/commands/update +updateonstart="off" + +## Backup | https://docs.linuxgsm.com/commands/backup +maxbackups="4" +maxbackupdays="30" +stoponbackup="on" + +## Logging | https://docs.linuxgsm.com/features/logging +consolelogging="on" +logdays="7" + +## Monitor | https://docs.linuxgsm.com/commands/monitor +# Query delay time +querydelay="1" + +## ANSI Colors | https://docs.linuxgsm.com/features/ansi-colors +ansi="on" + +#### Advanced Settings #### + +## Message Display Time | https://docs.linuxgsm.com/features/message-display-time +sleeptime="0.5" + +## SteamCMD Settings | https://docs.linuxgsm.com/steamcmd +# Server appid +appid="17505" +steamcmdforcewindows="no" +# SteamCMD Branch | https://docs.linuxgsm.com/steamcmd/branch +branch="" +betapassword="" +# Master Server | https://docs.linuxgsm.com/steamcmd/steam-master-server +steammaster="true" + +## Stop Mode | https://docs.linuxgsm.com/features/stop-mode +# 1: tmux kill +# 2: CTRL+c +# 3: quit +# 4: quit 120s +# 5: stop +# 6: q +# 7: exit +# 8: 7 Days to Die +# 9: GoldSrc +# 10: Avorion +# 11: end +stopmode="3" + +## Query mode +# 1: session only +# 2: gamedig (gsquery fallback) +# 3: gamedig +# 4: gsquery +# 5: tcp +querymode="2" +querytype="protocol-valve" + +## Console type +consoleverbose="yes" +consoleinteract="yes" + +## Game Server Details +# Do not edit +gamename="Zombie Panic! Source" +engine="source" +glibc="2.15" + +#### Directories #### +# Edit with care + +## Game Server Directories +systemdir="${serverfiles}/zps" +executabledir="${serverfiles}" +executable="./srcds_run" +servercfgdir="${systemdir}/cfg" +servercfg="${selfname}.cfg" +servercfgdefault="server.cfg" +servercfgfullpath="${servercfgdir}/${servercfg}" + +## Backup Directory +backupdir="${lgsmdir}/backup" + +## Logging Directories +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +gamelogdir="${systemdir}/logs" +lgsmlogdir="${logdir}/script" +consolelogdir="${logdir}/console" +lgsmlog="${lgsmlogdir}/${selfname}-script.log" +consolelog="${consolelogdir}/${selfname}-console.log" +alertlog="${lgsmlogdir}/${selfname}-alert.log" +postdetailslog="${lgsmlogdir}/${selfname}-postdetails.log" + +## Logs Naming +lgsmlogdate="${lgsmlogdir}/${selfname}-script-$(date '+%Y-%m-%d-%H:%M:%S').log" +consolelogdate="${consolelogdir}/${selfname}-console-$(date '+%Y-%m-%d-%H:%M:%S').log" + +## Log Parameters +logtimestamp="off" +logtimestampformat="%Y-%m-%d %H:%M:%S" diff --git a/lgsm/data/alert_discord_logo.jpg b/lgsm/data/alert_discord_logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..db94b295ec44b542b47851a8254025daad0e375a GIT binary patch literal 34529 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/almalinux-8.csv b/lgsm/data/almalinux-8.csv new file mode 100644 index 0000000..561b3c1 --- /dev/null +++ b/lgsm/data/almalinux-8.csv @@ -0,0 +1,136 @@ +all,bc,binutils,bzip2,cpio,curl,epel-release,file,glibc.i686,gzip,hostname,jq,libstdc++,libstdc++.i686,nmap-ncat,python36,tar,tmux,unzip,util-linux,wget,xz +steamcmd,glibc.i686,libstdc++.i686 +ac +ahl +ahl2 +ark +arma3 +armar,libcurl,openssl-libs +ats +av +bb +bb2,libcurl.i686 +bd +bf1942,ncurses-libs.i686 +bfv,compat-libstdc++-33.i686,glibc.i686 +bmdm,ncurses-libs.i686 +bo +bs +bt,libicu,dos2unix,libxml2 +btl +cc +cd +ck,xorg-x11-server-Xvfb +cmw +cod,compat-libstdc++-33.i686 +cod2,compat-libstdc++-33.i686 +cod4 +coduo,compat-libstdc++-33.i686 +codwaw +col +cs +cs2 +cscz +csgo +css,ncurses-libs.i686 +ct +dab +dayz +dmc +dod +dodr +dods +doi +dst,libcurl.i686 +dys +eco,libgdiplus +em +etl +ets2 +fctr +fof +gmod,ncurses-libs.i686 +hcu +hl2dm +hldm +hldms +hw,zlib-devel +ins +inss +ios +jc2 +jc3 +jk2 +kf +kf2 +l4d +l4d2 +mc,java-17-openjdk +mcb,libnsl +mh +mohaa,compat-libstdc++-33.i686 +mom +mta,ncurses-compat-libs,libxml2 +nd +nec +nmrih,ncurses-libs.i686 +ns +ns2,speex,tbb +ns2c,speex.i686,tbb.i686 +ohd +onset,mariadb-connector-c +opfor +pc +pc2 +pmc,java-17-openjdk +ps,GConf2 +pvkii +pvr,libcxx +pz,java-11-openjdk rng-tools +q2 +q3 +ql +qw +ricochet +ro +rtcw +rust,zlib-devel +rw,java-11-openjdk +samp +sb +sbots +scpsl +scpslsm +sdtd,telnet,expect,libxml2 +sf +sfc,ncurses-libs.i686 +sof2 +sol +squad +st,libxml2 +stn +sven +terraria +tf +tf2,libcurl.i686 +tfc +ti +ts +ts3 +tu +tw +unt +ut +ut2k4 +ut3 +ut99 +vh,glibc-devel +vints,aspnetcore-runtime-7.0 +vpmc,java-17-openjdk +vs +wet +wf +wmc,java-17-openjdk +wurm,xorg-x11-server-Xvfb +zmr,ncurses-libs.i686 +zps,ncurses-libs.i686 diff --git a/lgsm/data/almalinux-9.csv b/lgsm/data/almalinux-9.csv new file mode 100644 index 0000000..64a9e06 --- /dev/null +++ b/lgsm/data/almalinux-9.csv @@ -0,0 +1,136 @@ +all,bc,binutils,bzip2,cpio,curl,epel-release,file,glibc.i686,gzip,hostname,jq,libstdc++,libstdc++.i686,nmap-ncat,python3,tar,tmux,unzip,util-linux,wget,xz +steamcmd,glibc.i686,libstdc++.i686 +ac +ahl +ahl2 +ark +arma3 +armar,libcurl,openssl-libs +ats +av +bb +bb2,libcurl.i686 +bd +bf1942,ncurses-libs.i686 +bfv,compat-libstdc++-33.i686,glibc.i686 +bmdm,ncurses-libs.i686 +bo +bs +bt,libicu,dos2unix,libxml2 +btl +cc +cd +ck,xorg-x11-server-Xvfb +cmw +cod,compat-libstdc++-33.i686 +cod2,compat-libstdc++-33.i686 +cod4 +coduo,compat-libstdc++-33.i686 +codwaw +col +cs +cs2 +cscz +csgo +css,ncurses-libs.i686 +ct +dab +dayz +dmc +dod +dodr +dods +doi +dst,libcurl.i686 +dys +eco,libgdiplus +em +etl +ets2 +fctr +fof +gmod,ncurses-libs.i686 +hcu +hl2dm +hldm +hldms +hw,zlib-devel +ins +inss +ios +jc2 +jc3 +jk2 +kf +kf2 +l4d +l4d2 +mc,java-17-openjdk +mcb,libnsl +mh +mohaa,compat-libstdc++-33.i686 +mom +mta,ncurses-compat-libs,libxml2 +nd +nec +nmrih,ncurses-libs.i686 +ns +ns2,speex,tbb +ns2c,speex.i686,tbb.i686 +ohd +onset,mariadb-connector-c +opfor +pc +pc2 +pmc,java-17-openjdk +ps,GConf2 +pvkii +pvr,libcxx +pz,java-11-openjdk rng-tools +q2 +q3 +ql +qw +ricochet +ro +rtcw +rust,zlib-devel +rw,java-11-openjdk +samp +sb +sbots +scpsl +scpslsm +sdtd,telnet,expect,libxml2 +sf +sfc,ncurses-libs.i686 +sof2 +sol +squad +st,libxml2 +stn +sven +terraria +tf +tf2,libcurl.i686 +tfc +ti +ts +ts3 +tu +tw +unt +ut +ut2k4 +ut3 +ut99 +vh,glibc-devel +vints,aspnetcore-runtime-7.0 +vpmc,java-17-openjdk +vs +wet +wf +wmc,java-17-openjdk +wurm,xorg-x11-server-Xvfb +zmr,ncurses-libs.i686 +zps,ncurses-libs.i686 diff --git a/lgsm/data/appmanifest/ahl/appmanifest_10.acf b/lgsm/data/appmanifest/ahl/appmanifest_10.acf new file mode 100644 index 0000000..0c90238 --- /dev/null +++ b/lgsm/data/appmanifest/ahl/appmanifest_10.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "10" + "Universe" "1" + "name" "Counter-Strike" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688984402" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "11" + { + "manifest" "4720911300072406946" + "size" "292616113" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/ahl/appmanifest_70.acf b/lgsm/data/appmanifest/ahl/appmanifest_70.acf new file mode 100644 index 0000000..9eb708d --- /dev/null +++ b/lgsm/data/appmanifest/ahl/appmanifest_70.acf @@ -0,0 +1,41 @@ +"AppState" +{ + "appid" "70" + "Universe" "1" + "name" "Half-Life" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688984404" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "1" + { + "manifest" "5928322771446233610" + "size" "429833890" + } + "71" + { + "manifest" "9183617604528345869" + "size" "15302314" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/ahl/appmanifest_90.acf b/lgsm/data/appmanifest/ahl/appmanifest_90.acf new file mode 100644 index 0000000..421982e --- /dev/null +++ b/lgsm/data/appmanifest/ahl/appmanifest_90.acf @@ -0,0 +1,49 @@ +"AppState" +{ + "appid" "90" + "Universe" "1" + "name" "Half-Life Dedicated Server" + "StateFlags" "4" + "installdir" "Half-Life" + "LastUpdated" "1688984267" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "76561200949853436" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "4" + { + "manifest" "8690279432129063737" + "size" "25737094" + } + "1006" + { + "manifest" "6912453647411644579" + "size" "72573740" + } + } + "SharedDepots" + { + "1" "70" + "11" "10" + "71" "70" + } + "UserConfig" + { + "mod" "cstrike" + } + "MountedConfig" + { + "mod" "cstrike" + } +} diff --git a/lgsm/data/appmanifest/bb/appmanifest_10.acf b/lgsm/data/appmanifest/bb/appmanifest_10.acf new file mode 100644 index 0000000..6043947 --- /dev/null +++ b/lgsm/data/appmanifest/bb/appmanifest_10.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "10" + "Universe" "1" + "name" "Counter-Strike" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688984405" + "SizeOnDisk" "03" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "11" + { + "manifest" "4720911300072406946" + "size" "292616113" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/bb/appmanifest_70.acf b/lgsm/data/appmanifest/bb/appmanifest_70.acf new file mode 100644 index 0000000..36f34d2 --- /dev/null +++ b/lgsm/data/appmanifest/bb/appmanifest_70.acf @@ -0,0 +1,41 @@ +"AppState" +{ + "appid" "70" + "Universe" "1" + "name" "Half-Life" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688984407" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "1" + { + "manifest" "5928322771446233610" + "size" "429833890" + } + "71" + { + "manifest" "9183617604528345869" + "size" "15302314" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/bb/appmanifest_90.acf b/lgsm/data/appmanifest/bb/appmanifest_90.acf new file mode 100644 index 0000000..c56dda5 --- /dev/null +++ b/lgsm/data/appmanifest/bb/appmanifest_90.acf @@ -0,0 +1,49 @@ +"AppState" +{ + "appid" "90" + "Universe" "1" + "name" "Half-Life Dedicated Server" + "StateFlags" "4" + "installdir" "Half-Life" + "LastUpdated" "1688984269" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "76561200402315446" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "4" + { + "manifest" "8690279432129063737" + "size" "25737094" + } + "1006" + { + "manifest" "6912453647411644579" + "size" "72573740" + } + } + "SharedDepots" + { + "1" "70" + "11" "10" + "71" "70" + } + "UserConfig" + { + "mod" "cstrike" + } + "MountedConfig" + { + "mod" "cstrike" + } +} diff --git a/lgsm/data/appmanifest/cscz/appmanifest_10.acf b/lgsm/data/appmanifest/cscz/appmanifest_10.acf new file mode 100644 index 0000000..c5afe8b --- /dev/null +++ b/lgsm/data/appmanifest/cscz/appmanifest_10.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "10" + "Universe" "1" + "name" "Counter-Strike" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1666731530" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "11" + { + "manifest" "4720911300072406946" + "size" "292616113" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/cscz/appmanifest_70.acf b/lgsm/data/appmanifest/cscz/appmanifest_70.acf new file mode 100644 index 0000000..a4157d7 --- /dev/null +++ b/lgsm/data/appmanifest/cscz/appmanifest_70.acf @@ -0,0 +1,41 @@ +"AppState" +{ + "appid" "70" + "Universe" "1" + "name" "Half-Life" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1666731530" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "1" + { + "manifest" "5928322771446233610" + "size" "429833890" + } + "71" + { + "manifest" "9183617604528345869" + "size" "15302314" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/cscz/appmanifest_80.acf b/lgsm/data/appmanifest/cscz/appmanifest_80.acf new file mode 100644 index 0000000..ec35c44 --- /dev/null +++ b/lgsm/data/appmanifest/cscz/appmanifest_80.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "80" + "Universe" "1" + "name" "Counter-Strike: Condition Zero" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1666731530" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "81" + { + "manifest" "3601230779843470737" + "size" "415387682" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/cscz/appmanifest_90.acf b/lgsm/data/appmanifest/cscz/appmanifest_90.acf new file mode 100644 index 0000000..184a92b --- /dev/null +++ b/lgsm/data/appmanifest/cscz/appmanifest_90.acf @@ -0,0 +1,50 @@ +"AppState" +{ + "appid" "90" + "Universe" "1" + "name" "Half-Life Dedicated Server" + "StateFlags" "4" + "installdir" "Half-Life" + "LastUpdated" "1666731360" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "76561201630089482" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "4" + { + "manifest" "8690279432129063737" + "size" "25737094" + } + "1006" + { + "manifest" "6912453647411644579" + "size" "72573740" + } + } + "SharedDepots" + { + "1" "70" + "11" "10" + "71" "70" + "81" "80" + } + "UserConfig" + { + "mod" "czero" + } + "MountedConfig" + { + "mod" "czero" + } +} diff --git a/lgsm/data/appmanifest/css/appmanifest_10.acf b/lgsm/data/appmanifest/css/appmanifest_10.acf new file mode 100644 index 0000000..0c9b528 --- /dev/null +++ b/lgsm/data/appmanifest/css/appmanifest_10.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "10" + "Universe" "1" + "name" "Counter-Strike" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688984302" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "11" + { + "manifest" "4720911300072406946" + "size" "292616113" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/css/appmanifest_70.acf b/lgsm/data/appmanifest/css/appmanifest_70.acf new file mode 100644 index 0000000..0a417f8 --- /dev/null +++ b/lgsm/data/appmanifest/css/appmanifest_70.acf @@ -0,0 +1,41 @@ +"AppState" +{ + "appid" "70" + "Universe" "1" + "name" "Half-Life" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688984304" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "1" + { + "manifest" "5928322771446233610" + "size" "429833890" + } + "71" + { + "manifest" "9183617604528345869" + "size" "15302314" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/css/appmanifest_90.acf b/lgsm/data/appmanifest/css/appmanifest_90.acf new file mode 100644 index 0000000..3710f97 --- /dev/null +++ b/lgsm/data/appmanifest/css/appmanifest_90.acf @@ -0,0 +1,49 @@ +"AppState" +{ + "appid" "90" + "Universe" "1" + "name" "Half-Life Dedicated Server" + "StateFlags" "4" + "installdir" "Half-Life" + "LastUpdated" "1688984230" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "76561201379539094" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" 0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "4" + { + "manifest" "8690279432129063737" + "size" "25737094" + } + "1006" + { + "manifest" "6912453647411644579" + "size" "72573740" + } + } + "SharedDepots" + { + "1" "70" + "11" "10" + "71" "70" + } + "UserConfig" + { + "mod" "cstrike" + } + "MountedConfig" + { + "mod" "cstrike" + } +} diff --git a/lgsm/data/appmanifest/dmc/appmanifest_10.acf b/lgsm/data/appmanifest/dmc/appmanifest_10.acf new file mode 100644 index 0000000..2ce041b --- /dev/null +++ b/lgsm/data/appmanifest/dmc/appmanifest_10.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "10" + "Universe" "1" + "name" "Counter-Strike" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688984403" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "11" + { + "manifest" "4720911300072406946" + "size" "292616113" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/dmc/appmanifest_40.acf b/lgsm/data/appmanifest/dmc/appmanifest_40.acf new file mode 100644 index 0000000..11cf694 --- /dev/null +++ b/lgsm/data/appmanifest/dmc/appmanifest_40.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "40" + "Universe" "1" + "name" "Deathmatch Classic" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688984402" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "41" + { + "manifest" "2010889186716175170" + "size" "48239254" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/dmc/appmanifest_70.acf b/lgsm/data/appmanifest/dmc/appmanifest_70.acf new file mode 100644 index 0000000..1b33e84 --- /dev/null +++ b/lgsm/data/appmanifest/dmc/appmanifest_70.acf @@ -0,0 +1,41 @@ +"AppState" +{ + "appid" "70" + "Universe" "1" + "name" "Half-Life" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688984405" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "1" + { + "manifest" "5928322771446233610" + "size" "429833890" + } + "71" + { + "manifest" "9183617604528345869" + "size" "15302314" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/dmc/appmanifest_90.acf b/lgsm/data/appmanifest/dmc/appmanifest_90.acf new file mode 100644 index 0000000..3fe759c --- /dev/null +++ b/lgsm/data/appmanifest/dmc/appmanifest_90.acf @@ -0,0 +1,50 @@ +"AppState" +{ + "appid" "90" + "Universe" "1" + "name" "Half-Life Dedicated Server" + "StateFlags" "4" + "installdir" "Half-Life" + "LastUpdated" "1688984269" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "76561201891266584" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "4" + { + "manifest" "8690279432129063737" + "size" "25737094" + } + "1006" + { + "manifest" "6912453647411644579" + "size" "72573740" + } + } + "SharedDepots" + { + "1" "70" + "11" "10" + "71" "70" + "41" "40" + } + "UserConfig" + { + "mod" "dmc" + } + "MountedConfig" + { + "mod" "dmc" + } +} diff --git a/lgsm/data/appmanifest/dod/appmanifest_10.acf b/lgsm/data/appmanifest/dod/appmanifest_10.acf new file mode 100644 index 0000000..afe7cb8 --- /dev/null +++ b/lgsm/data/appmanifest/dod/appmanifest_10.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "10" + "Universe" "1" + "name" "Counter-Strike" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688988451" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "11" + { + "manifest" "4720911300072406946" + "size" "292616113" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/dod/appmanifest_30.acf b/lgsm/data/appmanifest/dod/appmanifest_30.acf new file mode 100644 index 0000000..c4acdb3 --- /dev/null +++ b/lgsm/data/appmanifest/dod/appmanifest_30.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "30" + "Universe" "1" + "name" "Day of Defeat" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688988451" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "31" + { + "manifest" "3826716661969602728" + "size" "391387184" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/dod/appmanifest_70.acf b/lgsm/data/appmanifest/dod/appmanifest_70.acf new file mode 100644 index 0000000..fb91ddb --- /dev/null +++ b/lgsm/data/appmanifest/dod/appmanifest_70.acf @@ -0,0 +1,41 @@ +"AppState" +{ + "appid" "70" + "Universe" "1" + "name" "Half-Life" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688988452" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "1" + { + "manifest" "5928322771446233610" + "size" "429833890" + } + "71" + { + "manifest" "9183617604528345869" + "size" "15302314" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/dod/appmanifest_90.acf b/lgsm/data/appmanifest/dod/appmanifest_90.acf new file mode 100644 index 0000000..c57a3f6 --- /dev/null +++ b/lgsm/data/appmanifest/dod/appmanifest_90.acf @@ -0,0 +1,50 @@ +"AppState" +{ + "appid" "90" + "Universe" "1" + "name" "Half-Life Dedicated Server" + "StateFlags" "4" + "installdir" "Half-Life" + "LastUpdated" "1688988429" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "76561201442771088" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "4" + { + "manifest" "8690279432129063737" + "size" "25737094" + } + "1006" + { + "manifest" "6912453647411644579" + "size" "72573740" + } + } + "SharedDepots" + { + "1" "70" + "11" "10" + "71" "70" + "31" "30" + } + "UserConfig" + { + "mod" "dod" + } + "MountedConfig" + { + "mod" "dod" + } +} diff --git a/lgsm/data/appmanifest/hldm/appmanifest_10.acf b/lgsm/data/appmanifest/hldm/appmanifest_10.acf new file mode 100644 index 0000000..de7355e --- /dev/null +++ b/lgsm/data/appmanifest/hldm/appmanifest_10.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "10" + "Universe" "1" + "name" "Counter-Strike" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688984411" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "11" + { + "manifest" "4720911300072406946" + "size" "292616113" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/hldm/appmanifest_70.acf b/lgsm/data/appmanifest/hldm/appmanifest_70.acf new file mode 100644 index 0000000..0f4b415 --- /dev/null +++ b/lgsm/data/appmanifest/hldm/appmanifest_70.acf @@ -0,0 +1,41 @@ +"AppState" +{ + "appid" "70" + "Universe" "1" + "name" "Half-Life" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688984413" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "1" + { + "manifest" "5928322771446233610" + "size" "429833890" + } + "71" + { + "manifest" "9183617604528345869" + "size" "15302314" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/hldm/appmanifest_90.acf b/lgsm/data/appmanifest/hldm/appmanifest_90.acf new file mode 100644 index 0000000..d9bfbaa --- /dev/null +++ b/lgsm/data/appmanifest/hldm/appmanifest_90.acf @@ -0,0 +1,47 @@ +"AppState" +{ + "appid" "90" + "Universe" "1" + "name" "Half-Life Dedicated Server" + "StateFlags" "4" + "installdir" "Half-Life" + "LastUpdated" "1688984301" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "76561199593999446" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "4" + { + "manifest" "8690279432129063737" + "size" "25737094" + } + "1006" + { + "manifest" "6912453647411644579" + "size" "72573740" + } + } + "SharedDepots" + { + "1" "70" + "11" "10" + "71" "70" + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/ns/appmanifest_10.acf b/lgsm/data/appmanifest/ns/appmanifest_10.acf new file mode 100644 index 0000000..edffb84 --- /dev/null +++ b/lgsm/data/appmanifest/ns/appmanifest_10.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "10" + "Universe" "1" + "name" "Counter-Strike" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688984412" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "11" + { + "manifest" "4720911300072406946" + "size" "292616113" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/ns/appmanifest_70.acf b/lgsm/data/appmanifest/ns/appmanifest_70.acf new file mode 100644 index 0000000..f186681 --- /dev/null +++ b/lgsm/data/appmanifest/ns/appmanifest_70.acf @@ -0,0 +1,41 @@ +"AppState" +{ + "appid" "70" + "Universe" "1" + "name" "Half-Life" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688984414" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "1" + { + "manifest" "5928322771446233610" + "size" "429833890" + } + "71" + { + "manifest" "9183617604528345869" + "size" "15302314" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/ns/appmanifest_90.acf b/lgsm/data/appmanifest/ns/appmanifest_90.acf new file mode 100644 index 0000000..f709c9b --- /dev/null +++ b/lgsm/data/appmanifest/ns/appmanifest_90.acf @@ -0,0 +1,49 @@ +"AppState" +{ + "appid" "90" + "Universe" "1" + "name" "Half-Life Dedicated Server" + "StateFlags" "4" + "installdir" "Half-Life" + "LastUpdated" "1688984290" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "76561199772965246" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "4" + { + "manifest" "8690279432129063737" + "size" "25737094" + } + "1006" + { + "manifest" "6912453647411644579" + "size" "72573740" + } + } + "SharedDepots" + { + "1" "70" + "11" "10" + "71" "70" + } + "UserConfig" + { + "mod" "cstrike" + } + "MountedConfig" + { + "mod" "cstrike" + } +} diff --git a/lgsm/data/appmanifest/opfor/appmanifest_10.acf b/lgsm/data/appmanifest/opfor/appmanifest_10.acf new file mode 100644 index 0000000..8a3a4fb --- /dev/null +++ b/lgsm/data/appmanifest/opfor/appmanifest_10.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "10" + "Universe" "1" + "name" "Counter-Strike" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688984434" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "11" + { + "manifest" "4720911300072406946" + "size" "292616113" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/opfor/appmanifest_50.acf b/lgsm/data/appmanifest/opfor/appmanifest_50.acf new file mode 100644 index 0000000..83b939a --- /dev/null +++ b/lgsm/data/appmanifest/opfor/appmanifest_50.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "50" + "Universe" "1" + "name" "Half-Life: Opposing Force" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688984434" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "51" + { + "manifest" "789184054796507140" + "size" "286265390" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/opfor/appmanifest_70.acf b/lgsm/data/appmanifest/opfor/appmanifest_70.acf new file mode 100644 index 0000000..da3db24 --- /dev/null +++ b/lgsm/data/appmanifest/opfor/appmanifest_70.acf @@ -0,0 +1,41 @@ +"AppState" +{ + "appid" "70" + "Universe" "1" + "name" "Half-Life" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688984437" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "1" + { + "manifest" "5928322771446233610" + "size" "429833890" + } + "71" + { + "manifest" "9183617604528345869" + "size" "15302314" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/opfor/appmanifest_90.acf b/lgsm/data/appmanifest/opfor/appmanifest_90.acf new file mode 100644 index 0000000..1ae893b --- /dev/null +++ b/lgsm/data/appmanifest/opfor/appmanifest_90.acf @@ -0,0 +1,50 @@ +"AppState" +{ + "appid" "90" + "Universe" "1" + "name" "Half-Life Dedicated Server" + "StateFlags" "4" + "installdir" "Half-Life" + "LastUpdated" "1688984298" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "76561198622612838" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "4" + { + "manifest" "8690279432129063737" + "size" "25737094" + } + "1006" + { + "manifest" "6912453647411644579" + "size" "72573740" + } + } + "SharedDepots" + { + "1" "70" + "11" "10" + "71" "70" + "51" "50" + } + "UserConfig" + { + "mod" "gearbox" + } + "MountedConfig" + { + "mod" "gearbox" + } +} diff --git a/lgsm/data/appmanifest/ricochet/appmanifest_10.acf b/lgsm/data/appmanifest/ricochet/appmanifest_10.acf new file mode 100644 index 0000000..8eb50b2 --- /dev/null +++ b/lgsm/data/appmanifest/ricochet/appmanifest_10.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "10" + "Universe" "1" + "name" "appid_10" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688999004" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "11" + { + "manifest" "4720911300072406946" + "size" "292616113" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/ricochet/appmanifest_60.acf b/lgsm/data/appmanifest/ricochet/appmanifest_60.acf new file mode 100644 index 0000000..9fcb75c --- /dev/null +++ b/lgsm/data/appmanifest/ricochet/appmanifest_60.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "60" + "Universe" "1" + "name" "appid_60" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688999004" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "61" + { + "manifest" "4560730344969588055" + "size" "17605146" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/ricochet/appmanifest_70.acf b/lgsm/data/appmanifest/ricochet/appmanifest_70.acf new file mode 100644 index 0000000..a9173d9 --- /dev/null +++ b/lgsm/data/appmanifest/ricochet/appmanifest_70.acf @@ -0,0 +1,41 @@ +"AppState" +{ + "appid" "70" + "Universe" "1" + "name" "appid_70" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688999004" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "1" + { + "manifest" "5928322771446233610" + "size" "429833890" + } + "71" + { + "manifest" "9183617604528345869" + "size" "15302314" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/ricochet/appmanifest_90.acf b/lgsm/data/appmanifest/ricochet/appmanifest_90.acf new file mode 100644 index 0000000..cb48442 --- /dev/null +++ b/lgsm/data/appmanifest/ricochet/appmanifest_90.acf @@ -0,0 +1,50 @@ +"AppState" +{ + "appid" "90" + "Universe" "1" + "name" "Half-Life Dedicated Server" + "StateFlags" "4" + "installdir" "Half-Life" + "LastUpdated" "1688999004" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "76561198882404437" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "4" + { + "manifest" "8690279432129063737" + "size" "25737094" + } + "1006" + { + "manifest" "6912453647411644579" + "size" "72573740" + } + } + "SharedDepots" + { + "1" "70" + "11" "10" + "71" "70" + "61" "60" + } + "UserConfig" + { + "mod" "ricochet" + } + "MountedConfig" + { + "mod" "ricochet" + } +} diff --git a/lgsm/data/appmanifest/tfc/appmanifest_10.acf b/lgsm/data/appmanifest/tfc/appmanifest_10.acf new file mode 100644 index 0000000..71c7c40 --- /dev/null +++ b/lgsm/data/appmanifest/tfc/appmanifest_10.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "10" + "Universe" "1" + "name" "Counter-Strike" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688998186" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "11" + { + "manifest" "4720911300072406946" + "size" "292616113" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/tfc/appmanifest_20.acf b/lgsm/data/appmanifest/tfc/appmanifest_20.acf new file mode 100644 index 0000000..07594e9 --- /dev/null +++ b/lgsm/data/appmanifest/tfc/appmanifest_20.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "20" + "Universe" "1" + "name" "Team Fortress Classic" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688998186" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "21" + { + "manifest" "7841127166138118042" + "size" "124989202" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/tfc/appmanifest_70.acf b/lgsm/data/appmanifest/tfc/appmanifest_70.acf new file mode 100644 index 0000000..0ed30ae --- /dev/null +++ b/lgsm/data/appmanifest/tfc/appmanifest_70.acf @@ -0,0 +1,41 @@ +"AppState" +{ + "appid" "70" + "Universe" "1" + "name" "Half-Life" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688998186" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "1" + { + "manifest" "5928322771446233610" + "size" "429833890" + } + "71" + { + "manifest" "9183617604528345869" + "size" "15302314" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/tfc/appmanifest_90.acf b/lgsm/data/appmanifest/tfc/appmanifest_90.acf new file mode 100644 index 0000000..0bb518b --- /dev/null +++ b/lgsm/data/appmanifest/tfc/appmanifest_90.acf @@ -0,0 +1,50 @@ +"AppState" +{ + "appid" "90" + "Universe" "1" + "name" "Half-Life Dedicated Server" + "StateFlags" "4" + "installdir" "Half-Life" + "LastUpdated" "1688998186" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "76561201883029803" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "4" + { + "manifest" "8690279432129063737" + "size" "25737094" + } + "1006" + { + "manifest" "6912453647411644579" + "size" "72573740" + } + } + "SharedDepots" + { + "1" "70" + "11" "10" + "71" "70" + "21" "20" + } + "UserConfig" + { + "mod" "tfc" + } + "MountedConfig" + { + "mod" "tfc" + } +} diff --git a/lgsm/data/appmanifest/ts/appmanifest_10.acf b/lgsm/data/appmanifest/ts/appmanifest_10.acf new file mode 100644 index 0000000..e04a2f2 --- /dev/null +++ b/lgsm/data/appmanifest/ts/appmanifest_10.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "10" + "Universe" "1" + "name" "Counter-Strike" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688983936" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "11" + { + "manifest" "4720911300072406946" + "size" "292616113" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/ts/appmanifest_70.acf b/lgsm/data/appmanifest/ts/appmanifest_70.acf new file mode 100644 index 0000000..d7d0228 --- /dev/null +++ b/lgsm/data/appmanifest/ts/appmanifest_70.acf @@ -0,0 +1,41 @@ +"AppState" +{ + "appid" "70" + "Universe" "1" + "name" "Half-Life" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688983937" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "1" + { + "manifest" "5928322771446233610" + "size" "429833890" + } + "71" + { + "manifest" "9183617604528345869" + "size" "15302314" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/ts/appmanifest_90.acf b/lgsm/data/appmanifest/ts/appmanifest_90.acf new file mode 100644 index 0000000..b560cb4 --- /dev/null +++ b/lgsm/data/appmanifest/ts/appmanifest_90.acf @@ -0,0 +1,49 @@ +"AppState" +{ + "appid" "90" + "Universe" "1" + "name" "Half-Life Dedicated Server" + "StateFlags" "4" + "installdir" "Half-Life" + "LastUpdated" "1688983870" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "76561202249148738" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "4" + { + "manifest" "8690279432129063737" + "size" "25737094" + } + "1006" + { + "manifest" "6912453647411644579" + "size" "72573740" + } + } + "SharedDepots" + { + "1" "70" + "11" "10" + "71" "70" + } + "UserConfig" + { + "mod" "cstrike" + } + "MountedConfig" + { + "mod" "cstrike" + } +} diff --git a/lgsm/data/appmanifest/vs/appmanifest_10.acf b/lgsm/data/appmanifest/vs/appmanifest_10.acf new file mode 100644 index 0000000..71c7c40 --- /dev/null +++ b/lgsm/data/appmanifest/vs/appmanifest_10.acf @@ -0,0 +1,36 @@ +"AppState" +{ + "appid" "10" + "Universe" "1" + "name" "Counter-Strike" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688998186" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "11" + { + "manifest" "4720911300072406946" + "size" "292616113" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/vs/appmanifest_70.acf b/lgsm/data/appmanifest/vs/appmanifest_70.acf new file mode 100644 index 0000000..a470329 --- /dev/null +++ b/lgsm/data/appmanifest/vs/appmanifest_70.acf @@ -0,0 +1,41 @@ +"AppState" +{ + "appid" "70" + "Universe" "1" + "name" "Half-Life" + "StateFlags" "68" + "installdir" "Half-Life" + "LastUpdated" "1688983882" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "0" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "1" + { + "manifest" "5928322771446233610" + "size" "429833890" + } + "71" + { + "manifest" "9183617604528345869" + "size" "15302314" + } + } + "UserConfig" + { + } + "MountedConfig" + { + } +} diff --git a/lgsm/data/appmanifest/vs/appmanifest_90.acf b/lgsm/data/appmanifest/vs/appmanifest_90.acf new file mode 100644 index 0000000..ae33387 --- /dev/null +++ b/lgsm/data/appmanifest/vs/appmanifest_90.acf @@ -0,0 +1,49 @@ +"AppState" +{ + "appid" "90" + "Universe" "1" + "name" "Half-Life Dedicated Server" + "StateFlags" "4" + "installdir" "Half-Life" + "LastUpdated" "1688983843" + "SizeOnDisk" "0" + "StagingSize" "0" + "buildid" "0" + "LastOwner" "76561200857512115" + "UpdateResult" "0" + "BytesToDownload" "0" + "BytesDownloaded" "0" + "BytesToStage" "0" + "BytesStaged" "0" + "TargetBuildID" "0" + "AutoUpdateBehavior" "0" + "AllowOtherDownloadsWhileRunning" "0" + "ScheduledAutoUpdate" "0" + "InstalledDepots" + { + "4" + { + "manifest" "8690279432129063737" + "size" "25737094" + } + "1006" + { + "manifest" "6912453647411644579" + "size" "72573740" + } + } + "SharedDepots" + { + "1" "70" + "11" "10" + "71" "70" + } + "UserConfig" + { + "mod" "cstrike" + } + "MountedConfig" + { + "mod" "cstrike" + } +} diff --git a/lgsm/data/bo_header.jpg b/lgsm/data/bo_header.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d63ee5c3da594ffd9b7d71080bccd535ba662795 GIT binary patch literal 19790 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/ahl-icon.png b/lgsm/data/gameicons/ahl-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f4e5cb5350f81161641de88914ba7e229c354d5a GIT binary patch literal 2983 zcmV;Y3t04tP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/ahl2-icon.png b/lgsm/data/gameicons/ahl2-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..04d35d040388534d61e8105973403e2c533cb1c0 GIT binary patch literal 2532 zcmV004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/arma3-icon.png b/lgsm/data/gameicons/arma3-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0bb0bc64c7c2f0a43ece0073ff799bf46aebc3ba GIT binary patch literal 954 zcmeAS@N?(olHy`uVBq!ia0vp^3Lwk@BpAX3RW*PVOS+@4BLl<6e(pbstRTr`k04(L zhAK4%hK3dfhF?ITh8GMBr3MTPuM!v-tY$DUh!@P+6=(yLU`q0KcVYP7-hXC4kjGx) z>Fdh=oJ&BEQ+adk*&9IlL!K^-#IJz(^||wE-kAmf4J83*3Un8<{50U(~Bj;MgG#@sJw37d+P$6H!peIOnoJ7YIpKn#o2hKI|FWt}YonvjakVi> z%3QM(*%+xg?b7Kar?743)R-K#TV=D{UmtCm5$>HGJMr3v>?{9yZ~b3+GB07Kk8_PS z&x!BGn)Py_X@5GO{QF?{^Y^!gw7~U`_e}1aVy?^XwD;=Q$uFPPEVsF{>%QKuWsdfy zp4O97cBJ?5MB0D&a=ibr%IVK}{NubpfrReo=o z{&%LCe}6{an$D-i?zBYB!es5w&)4);#qKNL_oz{)OHJ%DpZ?mL%y-W{-nY0la`W$i zy=@Z@i;BhmKe?1WdUgG#*sg7D`p;%+Nh;4tV!L#T^nQ`H@m3x2f{iTy1|Nh09+Vv}!Rem<|deh$<`0`CT zPv+4DM?#(leOFKyudNOII{9MEvSqXX9+h6aTKj9o%g*)ork}&@c5lnI`B=R9c=NT5 zk*j#0O)@{Vb%k}wre6xS@A7!-e_emv=4E|P)O}yOK!O9qFR!n+^Y_$!Y(C~L$Z$-; z@jz{t%?-z()fmf7)K-_uPgd*m!W_sx7s@M8(BCv-)C>0J8vtYKdz^NlIc# zs#S7PDv)9@GB7gMH8jvQGz~E_wlXxdGPTq;Ft9Q(V0yE$8%0BIeoAIqC5i?kkOmVA Wh=wD-ZUZwG1B0ilpUXO@geCw^O`j_O literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/armar-icon.png b/lgsm/data/gameicons/armar-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ea79ba0885fc86e817240157a80e72d5ada7dd1c GIT binary patch literal 722 zcmeAS@N?(olHy`uVBq!ia0vp^3Lwk@BpAX3RW*PVOS+@4BLl<6e(pbstRTr`k04(L zhAK4%hK3dfhF?ITh8GMBr3MTPuM!v-tY$DUh!@P+6=(yLU`q0KcVYP7-hXC4kjGx) z>Fdh=oJ&BEQ+adk*&7TDjJG^p978Nlzn#1{D>P7`b^px0-*=i%*JjzeVbX$#=p|bO z&ip!=`2C~^S3;Ij{;Qi`1GN@=?X22z_3!;? z<2dh0zZ}nd)bC`RAsC^1O6pkP)8lA2a-E<7rz$zoBcDC4`kaxI(Cr_(*2u07|r zPMUBaD|O=1AeG#IQYNn+_l2}QjWwMmzE5;Tg<`ght=a?4p;f*)z0%LrI&_2)yx zs%E`dn>CBSyf_;qrLy+u`t#@cVtt=J~eaBfwCb5IevIp+$Iohr1GQ&-#gY)x=E>n&f$v%r2 zS=hN5nRWaO?=Z|Zv0gco>wzD8i)XM~flia-7lw_hcNMpt-F(g1W{Z2lo}&^!nA=3Z zo!usP@jEc$RZCnWN>UO_QmvAUQh^kMk%5u1uAzahp=pSbv6Z2rm8qq+fq|8Q0n?j} n-6$Gz^HVa@Dp52Tfi##{Kr|frbsL!A7#KWV{an^LB{Ts5ag!e3 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/ats-icon.png b/lgsm/data/gameicons/ats-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6495b10737417b00113e735c641e9e5c7a62f2f5 GIT binary patch literal 2037 zcmY*ac{mhm7k_6nW*F{JlPpCjS!#$dElg%)H`Z!OWNd>Xj4U&uMVc5UiHzkYZEm<^ zxyhEOF;tdhOZIg6BzK6!%$=U^ulvV&f6rNd=bYz#&U4OniqlaHS{V%hz}VW5TqUUf zOQd0vmsHGtB>{LK(UAy1MY_!T8N@Fq&BoOcfViCiBwhhvO=3#?0ssRKz^o4dgd702 zgy+?{90UNmL2+;=yVyG5l(xd)FbEPE&5SyAnuxXV+tCw{EWe_@Se(SM_HZ(Vl#foy>A^@BQ$;KuF6ktt>n3Hq;>#Y04-B!4e(ieZOQv8A*K{km(L&VOGVts?fEx2XzTo#*KUSHJS(cL}qadk~B60cmjn*3F` z;supH2LmM#xKL412!V=G(k}sGRkYsG-p*jfp7x-stLpJ`xb)ET>mt!rD6|QHAx&%- zfK8+1d(oKA?`zdHHRLR@o~|KiAk{lR1M_1yUX5&g9*_FJMaEseLX*VP(aXeA0N6E09~P>PngUX zN$GXD#dk3Z_v+g`ju05p7h*%B1J7KI2(|0#xi~2L{>sRx%0$1>`b;17Q~*rMnL_dP zqt!M%6MXw}x2|^O$I83J*!sAO)pNspRM0eS-Jcsv*V)&T;*xsAGxPJavtO5c+66v{ zO=Tg+8>&mHii-Z=rd@%TVZgl?B)0ydV!KgLfsJEv-tLj<)z1)hY<$5Njk00KR z2@Cc-=6NkAWpZjBgTd_Bv19Mvy{sr>nq*cXzV=5+^!kw2Dv5%OvUMaQXVAZ4QJPO# zZw4geylhJ%x|?-qyQ7Y~du(bHCa%Pog?%<$ITX`*CoLAOfmgnD+ejTH7m~Uu&0MJ~ z`QEsvpS2y7YGzgRK8KhhwV6jf*XxV>z54-TerwizQK_u9*SZ{ZRQ8kKgex1gU7N#iw{y9qo`U7tT-DaKllP&hV3O4{2U}7Ol1^?_PlmWl z+gBcB0$aL~5w4UXp(uc>)6}pHR9|UXO<| zFTv|y+~ohGFrdFri2`eX4JRro{h1qZx+BuIz2D0s?UObC zm@e!I%Pr(SYvyLXgSx{3Q`*y`Pj+_^wit~w#|>(&?<>TynMZKk zOw^6tg3jKlQO`#a26e285wH4I=F#i9h=^LnPMwt9S1UUYEZ8*-N4;y9wvRm6aeH)& zp~a_W8xVkf_`4D(((?&_U)ibZ;N@JC6^jfn^NknP@}rB^@rdCMv# z+r26cn;z7hb6fvBX10_wzqn=~%PW$x+Nr4-AIVfvDHs^~tF$6I-i@F6w5XtDWg(_c zp!&)ZlG{@8fg$Jp=51gwkEcQ{I9t6i)Ke2LESMQO(9-E-dn0DojfTzd!dT;NPTuxb zfyXX5^V$464M7WsS&w=%ppVQ5ssh!Y-b0K3Bwa?znY>p!tPtZrT0nn(*}F7hp20C7 z8(PEi8Bt$nmrOZo@xs!^j}Jr~4uoatJs7=iqgCFQ2$s<-9QrO z`+ipQ=*V-Q=>rRIKWKOvcbI>gi*NeCJ(R-}zG#2U^?0}>vV48*`C+Ps@%o}~u_5kC zZ8B5AOZazSVZx%nx2KEPayYTkv`ggC|2Cj-uY7(@!l9^$sVe%(Nz>N-q1$!!enxAV z$GUY7b#Cfh}Y=?ibr3*konVQ1T3=Ih;=6ZNM0gs3Nuj0mk2xr6m=mD|+AsGE47@Pf{(7HA( Qxyb<7lATCpM|>{*3s-`Tg8%>k literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/av-icon.png b/lgsm/data/gameicons/av-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4bce455adcc406311e72d4ed220da36f7f567079 GIT binary patch literal 1983 zcmY+DX;hQv633tS%?2R^kR{4?;gBF<2?>Y-1q4knxw5ZeF(!}&kPry*#eji?MNJS; z_8xPb`h)gp*Xu~h+=+9PsZDsEV5_1B`lp!*^bl)2UEeVSZ17M)eWKn?m`k2X%iv*z96##W501Jka`V9cv z=>WXt0}$8>04cxyVr&oq@Ryi~1Qu-QFc<_w02l_q5Nv|M;2_8t03$RCK)}cdi$OtX z0Pq;d@UfK%&Kd_|lj~&2g9jC(8ssm%@b5Z4rUOjcej)E`hENAv8*`C&iI~BLJ}4%6QF6(-=>? z^L0CyejaNr66j>9x;%benXI|GxV5&dVV6>xnQV#zWD}G>$%MDgWu#HPJpV{3P827z z%ZqcW%Zn(sR{Fy9CzrYqK4%-3Er@5=?MAffLLwIJV2<;&HD$YzN>ev>X{EJ0GBvWy z%I*1`^;O*PU`rT~OmR-;xFB2e2C1-P*Y*}!=Kcb~eif1{O4d{%^|htVm5So@I7cIl z9TDq9Ky7ecc|cRBRpyi{Bo(B1li_CG(5mSm@=F>F1vv@uAyX}+79`4vBN%XL^ zi2i42jV$?OiL|3sPIt1~k`&XNFFIHtJgSl_lA_jlxb|w~)si%8b3&U^e5p?T?VjR; zs;uwoDhJfa$NN{>w+Yke)G9tV+Rb@+d3j7h$oRVa8JjmTmwp7-;tdH-!HHzyX7T10 z#x7@7lMewvUFI;u68y(A`Fx=;BSR<_h%#rNy?p+9Mlky-b7poXBjY&?hl{cOuo!ET zgg{}=0)Yh-%P5FNc*dOY6Rr33^hm0=hbMI^Ge>5SS3hwp*0NC=UY z=(pW8(u*Q>*b+=sAvQKxPG=AkLV0)SG>7*OXiw^gs=Ay0RntF;$FVVN$b}76pVl3` zRB^OHf3~`(yQ%5G@TeCKXTtVP*MPfdvuJPGKele&n!Mh@!a_wv_E|(YVF(1zB^c6# zU3ESzm?`Z`O0w7=i(go4V>*I3KBNj;hU%c@(UE?ln05u!eO zHDh^u0zYy4=H$4y(OIgeJB{jvn!bwnaXg`}icV#Jf2Duq$l$44-4|VlE}rijb;ftW zZz8ZXY$>vKW+Hs(*z4v8=jWSmwAswo-lny}Sgg2|hgdu7-yM4T*7p7A{F3pjFP7iA zM$%9od=Z}y{(Z%@iMmeo_S`QRUvcV0+vz8=7m_FIa5?4V3bNVo<`lgfllA({0PiBQr7?sJ-96Ag z;_jZI37%V*`}mx4{DJgQ(aYSlvxQUdf(vs~$m*v;(KBJ}eqHmUVcD{#!g)7hA0q#$ zq-Jv9$qz-;ipNHS?38RF_S_#H>4CW*!KBlFiy?*Cx+5w`NN;@SMBD7j8N z2X(1iB1N@ZdLPW`KW%QHbpSG3txJIdpikG#1!H2geN4QZ<~6*T2cDvj`z(^ z+XFg3{;6$&+JzcCIVIqzonP(FrT@H|`*0Isl;65#zpym2I6-jo28nd~=6w7q9`EyS zb5rlvw+%Knu@Z8pKl`T)IsYCigFm!)<~+aSwZ3$5K_xqQ&0a+;LrSsXt|x-%_S|Xo zpzDPD(uWH(hhVxz{_lf@KB%)EB&K7dGG!VqBJiHx()}1e!~fL62eZjZw0^u;jOB+& z8qZrdH@^nE2xhCj8_<@PbQ|Y@7QKEI=-q=o#I3*o)^Obv1&gZ?3KXKiOu5J)z=!VR z>&2jZG5ivId;=MbK)(PFIz5n1hkqTY{u>~b3A4q@zX3j90big013A$(cMJgFu%eiK I8~Ek_1Nwjlr2qf` literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/bb-icon.png b/lgsm/data/gameicons/bb-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2c6b7ec88310b2fed7a1e0be13ea9758f007ff3e GIT binary patch literal 2837 zcmV+w3+nWVP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/bb2-icon.png b/lgsm/data/gameicons/bb2-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..56716418c160e2be5713b2440d6f2abda66fde1e GIT binary patch literal 2082 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/bo-icon.png b/lgsm/data/gameicons/bo-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..53f5577d8d99b4e01270e07e377ca50788311c2f GIT binary patch literal 2030 zcmY*ac|6p67ykZc{mqP7Ff$DX!(hl@W*Ej?>oB$&B$Y}el_FHva#7uKwU;cRRo$eL z=-Seygk;|ukuGm3GD+DACFPyo_pkfMInP->&-t7`p3gbQeZAd@cuhP2favMr>Ze53 zPlJ(4?|S`2qY_YI&N62JO3n}#L(o5)p&ouR01}M=IG6&!g0gh*9RRUB0N!r~Kzt5> zWxFp`t+E3E34B-jOV@h&Q&~(D21NiE2!%sq@c<1_NGt}0#-ULtG9HJ90UkruW~^E1 zqp!vOxeXFv2oOpc03;qJ0p$NefIvV)1^gI8T|lO>;fITC8{@@XXXQ<^Tj9 zs7SD+c7nw`(z=gi*^T43k$G)uf=;@yi!FT05%rkb_44hOEd9P1$xdsSK^RnkirOef z{2A?#LpNt4F$^rM4H1n9h$)A);hNeiD(C(*`7mNtAdD@&eL zu!hzTu6u`;eI3c%$w4wRGd=qD-Q3)l+S^=sJ; zzaD9*Z_2-Zv+(8}O-=3XRDCjx*9C}bn&`ywlM2NcjKh(LswxDPHEY(r9(Gww}RX#pQQy-@Q%c_o|EhVO6QRZXBKO=eye0M%+jhKcm>1Lztr5 zB{^9a&Ya4$#*$N#5C6VDnaj0c!r&2(KR|SLl}M9db|c2(DAAyk=w<~`GF8l+0bC06 zT5;BLw0$*3*o+q&pm1CW?!Y@d#0r~mwylI;p5Seo2%-+M{SCk=M+hFl)-_mR6qzHF zc`q$3eb}LSRw-m?%L;ebrF`tn6J>&p@svri3Oq#>$1dC7(XZ6`xTmYLzo^ZuCnA8l zhJl?L4mz?aCp^{i!}%AsA63fQwmpAv@oGpxR;rc zut2KZsau{xlc}p4luD`t(l^@>C=KRmXUbY96R!N~aB046$!?NR%Q)a{;UPg$ohj)bhwzCmOX_4)=0{%$L$lf7^uysmTutUHc^ zk#I4GoHEn(ah*)1#xylG=|;~Z^&g$$bUY6 z3v)eoEfu-ljfM;BOk^z&pSy$Ay)()xQ(4Xa+r?ruwXaIv!a!CghYx+7$NMK*cgE;pV(T{;tJA?a@u zL}y1A`O??aRBT`8r{6sjJ$Wzk#p;U6s;V19mm@1GzJ*6bw6@K2YBp-rj60RPMEw>$ zU!O7W=uuc$eAl$FIOJVq*90$(1MfzhOPj3Dyhj?wgAZ54*_`=9Shf2G&W&@+<-u z-RfF`iEQsE9-*U2YhdGseXka3zP(gL_=NqoAb&!j3(-uK5B+;`Me@OC`j09{mZn0J zh8L~`5F!d7%zBf%ggN5w=62+$I|hqAdh~nKQVF$b^%QDIbiz6N*q4a-hSNcN%stY&jo%$4 znWVWg_~T(2e<$R|x9#*$;U`D=!s*Nn6X~yT7@rC{ZOEI4> x7TTKfcw!z8@uB48zX*}hTX$|x_!mL&lVBzKKcQh^K>3UT@RWMH7E3lK{}=Hf9rOSI literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/bs-icon.png b/lgsm/data/gameicons/bs-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..712f8d43012a97b4fbfd720e22a1822046a54f41 GIT binary patch literal 1916 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 bQ6B{{>i-MQzP;u7$pNsM(v173&1(4*av`BP literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/btl-icon.png b/lgsm/data/gameicons/btl-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..615ba7cb9aa4528ef3d2c5351b2e1a170c1e73bc GIT binary patch literal 2334 zcmV+(3E}pMP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 uLgbZ>Oz;TM6rG* zaEEkO%DyT^H#1Cl-k>(r=R8va*IQ&-fAia%jN9Z|Px9~%|n`_V|% zh$h)4E<}mtRfa^D?!l2~O4QtOiLO931JODTB@HSV7TVWc%^)H>iHTBpUz&BI36|+atN8bml8Q}r{!pMCkAZ-pPc-g9Gzp6M2};D&j$DB>N+15< za3Coa9S@D+IYC||vK03$wG{vg-Iu&bB{HCYY&_> zFU+Zugk&{HqmEQue$WCxlb%2J{8Fhf^LeMC`?xras#ye^EgAav!C6tg@T~AaQN0>7lZ0L?-;PI!V2H*)7j_ zkt|vJC&y)sUtMT+o%acc)Cjob6vT19c+CCK7|2OG<(ah!R{u)#>57kfaF8&Tzh|#J zhGBoJm-#YVp{ll4y}5V&tQNKN5pD8|U5h$wC=NW3ofx|k0y~Okv8p405a~EvRZEl^ z6eJvE%A%W8bcoh7;;8og{!PM+#l zYJoxTS?1g&wjI?El;4;p#7=GYaEjVypO&NAVt@B!<<$(|At~X>4ZcIUQZ>offAm|% z3h8}TnJgI5h+8hWh1U%7cMHt0(&-n63Iij5%&ZGHMg%fbjcujq+((}EJ~phEasfIf ztu~MJAk^*~b;VkzJb()s!>y*(hH!(`5L!o}&ijt5L0w(nm$%cd!^q0YU>OjxxYaWP z4*gqF7XrD@RMofkooc(ui0+Wt+e!~`F{?0q$6q>PuBORG#zo9Nbr+s^L7|{ySEtZw zGbQ)}mfnG^6yVMho6Vkb^$UkuF9$cKl1})LnAtrqv3dmM*mTPX+6}5qeAa{Z^I=CApC&mXX=f;MDl>eOuy{phxoPhyFOsF(#kEixHBw z_X4_p+Mqcn3u2J&f15Ettm2)=GPp9JTz!Rt=t8W0F%(Kx@oN7B?Z&HaWrM!8QkdsDR7y|up375Ue9lXqbo8G?TFghV6m(2Q~a zzR$u2>S(odRFrsp@qAZ|fUDw7QtV%aX_)ur%JvOC`P||u8r*c5ADOJrh>-D74Dm&+ zjI3>^aZXlv7}NU=?;i)pL_`nk=NqqWwbwb$*eao|4j>)C$|~My<(Ah2-8VEm2Gc9$Tw1+fbuQf{GCAY33g_>J2Gnf>FtHGQ`DHz zP>DCW*x~|n5a3_8*%f!qOv$PGHiz?mt_wcWs|2AbID$ala2hE17PU+~0PZ%9;?OCS zn!Bj4!07_qowlIv4r)CBd3`g;1VbyxlNC~$hq(=X8T*Dc-VR= z{UH9Q5)5!h+$`C`asZwoA?2K_6y}-LTH5t$y z^OkQv>Q=cj|JYOWum}3Boi_pK^{|VIjQqAfp!H+VFKL8A-HO0Jb_Z8C)W$W`*E{r* z#l`EFb`3xwP-r70!U*}RGt$%oVQzsoIfg)3AP_kJ)-V54pa=P0p+)`wf{Ceu<8A>U M*bs65vG$7pFA`tQga7~l literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/cd-icon.png b/lgsm/data/gameicons/cd-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..dddd49f7c40781aa78c47fbbdb28e6d889e41c2a GIT binary patch literal 2819 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 Tt|?&kn>i?BOJt#uYs7y6+R9E? literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/ck-icon.png b/lgsm/data/gameicons/ck-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a22d81480c1fcb53f9e432919ce47d9a98a0a56f GIT binary patch literal 2828 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/cod-icon.png b/lgsm/data/gameicons/cod-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7af55bf2c24d0627de8dfe4b41fc758d0efe028c GIT binary patch literal 2050 zcmY+FXH*l|62~v;g%~&+5NtH*#Xv$81SCixw1g0figa~xeM(thaOwMyvPw;Y$f}6a zbU}&~1tb_s2t*K3K{`l?f{5)cAo${WpZ3GOzjJ5qf6mM~GxuhCd%EB-yD$I%oGX>W zkWu}|LP2Fa<#tw&46u`q9*zLi{vCh~nJIY*fH)!mZ-W7_ zDFR^Uxsr!;TL2(i-tJ6i27{rYp^3#}F=z}Pr+`JvV=(gaI6Ml4l>v=L$>XpXECP*& z$>UHvcE~QGwKUaz7+wfCLJlGag8~Q?3WGo)01Ac3GJwFK2p9~4$KxOnfIz@x2>>|& zg~8x(nGe|8Tg%A+pz`tPu4 zO&$_IX0hlPw5%>LKlQYPleR2*VW6*zLLjjiJQ9g&ZLFRi6BculhX-19bkqzDb)6`7 zP+4IB@CxIHpFT7;RO1w6T3DE1usE4jaR->65lxPDUggFQiJSabP6h^hn7%G5DvBwo zzljC}!^6GPlfyGp12a>-v(w!(6MTt8xFQuB8mo}awet&-`uiSQsbge3%Z&l3nSh9O7TF=fUvr+=dY{0R09KL4lkMI=fHnb!{wx1!Jy{NCP z{Lk-69&S`edk0$^%Y#-HC7jF82l$d1@ygP(Vs661oJhJf;veADEvWD6YIrmIA|%Mq zl6=7F5XFK-HrCe;^zk_2WK~tpo172|dt1`e;!lPjH_+8Yqi}vqkA7kE(9?Fw;@Dr+ zrK&2*NF;o}wmOMq;_v6_$8tS>%q{9v2!lbjwKLAR6n)g6&hKb8G2BlwGeW?zNR%9} zI4QR<#-HgO7{~}b=2BP`bN6mh0E?A%Dfz?+uZrp%=}Lb`*Pq<{y!?U`CW~58eYsau zeK9_g$#g&cbKv6ANbIj69Bz7Lbpc;+XHhypHZ=L!+;+-}mp|Gcv_1Kl(G2=0e$i2D*G?2V|_Phci-wQBXu{H6#qalFb;zmEy>> z5-Itx{h7Xd+KJ}7pDa#XymWB&JX`c3on2eRCM~*egad7Au7K}eq^M{{s3MLKT}8LN z-Do$J>fK4ayn2PoGxU77`az3qi|oesKBIS=@mooWl7o_OVmWn<;oMU#Gl$EBXUGBf zTrI8{TX#o#)Rza2+&e8Ta7f*&DZf`$;HrWeb9bXF_lBWN1uEksDV(yxkEqZc*tVtq zBMOIgHS#GF`TMPL>X#zyOjycf_8S<7J%uTUMVm)h}ymlCyVy6?229^DX#N~bMXl;ECzGf??7vLh_t@vjYk9BF;h=7z>$?{&?`O&wdSf0tFs))gR*IrsQPt~8@A_%nQcCWU6X~H!hXe}#U5jQ;= zkFq%Xwq^7B;I*jciHp;$>s^5Q#d~6GG~qiGf9UfEExQ%-_Ne&RYLj1Iwe>b%sPm6G z>QHaQ-tt<0wZ2eO(SLDq`Mp$cf)w{;Dq(F!DFfpfXMev{<;L`wxp7BBZQTdy=R>~)`2z^3o^Xb_x&ECq&H!ByWj z-+q4A`Ld#?W4&otl@0W;6&;WH$yY^f-{$*RQRgWgJCbx$E%BT5XGewRe}=SvDiS@rpi9~Nr8q29Gvl+8o6fo1#l35;8ImvNYx^ciu`C-B z)jgYDokNx@q2&~Eob%75P|CWCLmN~fd0Tl>ZnB2%gBEe&ht(vsqI!_`^;#?01EC%3 z>>nE*5*uL?79Al2Fe93gj7^EgrshmDl8vdUjk&cUk!V9CLYC{Y{~`G0U*V@C+5Zrj a{Sc6?{x1-0yq0~?0Ju7PQfdwdr~VHLrE2T| literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/cod2-icon.png b/lgsm/data/gameicons/cod2-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..dfd6ee7de82588901d0d4accf5477ffb11b11b50 GIT binary patch literal 2707 zcmV;E3T*X>P)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 KMNUMnLSTXo^c5Na literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/codwaw-icon.png b/lgsm/data/gameicons/codwaw-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..10f06601ddff3f5abfb2ac14cf7e68f1cdfb8066 GIT binary patch literal 2819 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 LF$Ps(=o0l`hlM^N literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/col-icon.png b/lgsm/data/gameicons/col-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fbd91f9ef1e2c703dc445cd4a86526519d83f2af GIT binary patch literal 2411 zcmZ`(X*k9#Y~f; zma#_Bw5nBG%@}K>rLVD#sJ4V^Cu0}1Uj6ufc<+7AJ%2B0noUd|IF*mj~x@My)z>NIxVZmfTkxgo;!;fdr z4oQ}=0qZT2R>snXc@APU9YJy~j?6GHxG9fu`(VExE`Z(sJHETLgK)v2L>}x?n&6(v zEw6ee`+bvJUkW2K`Wikay(kzjiKmmTXZSl6EU7qNeKM_~hNlI5ETcYV6w}8vCqhgY zinYEOd&qDR(GFJgFLld?hKvtnYU*N;8=CmXQY)vTfnhS7t!4*)A925zFvHVb`$&Bp z6Yjx`UKo5*xOs`~74vz%aJ!U0xxN~oLg`$-b7%Xh^s`N-Ua~*$WWf6RNOc`!N#%I2 zIE&Ak&kzp@_;z>&Db_JiIhgIiT$!8u%bGYnS(qF*x2UnXYKs#`xC?4@7g81XRZ_Jb zC2wbH;y;Wg+HO2$F8ylhk?)#nm}$~8=(j7%C;y-dN3#dxYoJzo>vpM5u-n~$%JXcU zGfhFl;>hmjGC$=OUiLs{@1Lw%XX7janOquLPa2UU3}+i6!DWseoCWviKiebf(v;ic z=vr@5@8|8oq_+F&{fN45xH-$^%BJKMI4g5B`t*o@@%9x_n3K(89)MJuPfdYxkaG!+Od$tzz&H2=kLZ=X$Ac_O@vL1D^r8^kYkY~a{Hq`tR?v%vzx}ZYfh3ap5~7O?h8qt%` z>{0#XSUR1KF3diB*z|egKVpivudihu#W}*1x6C|+6uPobvjfoF#}1CS$v*^xw~#U;hJj|Gw*ZPe+#$cqy~@INL+^Yf3QmhTty7Zr`ZTobYMi zi5klz!XEMX9EZEV%oSJM6Sst)I+R11VcsG2QkvJ=Wes$jg``%^7;O>>7u-gZ)TZXx zqDSk;${?Vg?Z6&LjPg0}TvapQDou@Hj2jK;Z!aHJ)k(S!H-$C6T*rYjH88uW2ke@z zvD$rMp33m6=hr{yT={V}tLwtnbX^i#*enou4X@OUvTtOuyno@jh_0^xV(1jwipx=& zL1;c7^vm=dD(1qdEYSgqwhi#_ad=6i#5$?!FA#is7k|iR?Y*ZNK`|`hm6@GyjGkVe zdj#v0%~F1tBc8?D9g=~3sBj30 z^cRLnM9n9#zsW%;%%Np_CB}ifRdq)N5t(Rt7-Rs`CWyi(&$e*;xd~cl@F8JgvqGU7 zG%7?4B-Y)n3uqZTpY^VJ4Yu^UrJDr2k>?|18YgMWg0>UnIcE9 zl65Xz|LUT`>?j(8IptxGCzpjvOB~41fNQ_9O3B*xRu{2fYv=6RTH0e9K}xX{cSQA% zyrbfOg#pyvq1`rGsk;&%eA$MOC*fcR- zy$@Iu=Q*$o4027x15Fj~pH_$4ZWbF_NQ|>h=+yGEToaNrk+NRQY?|1wv9KK}k1M?O z>l@bM%L3c&sRsJERNQ#68{799nzT-wnYL{<3v3gy38&|0IG;#E`7y?2m7&I@w6%}o zbhrqOHb~*CW6WJhxa^o?#$~ypd}er`?zoSSrQ|;a+pkkK0)M0mu1r8ks;%;eRDKmt z9fHvPNc&#<-jf^=9zZ4I>zGZgBFIeMXvy9l>j^cYwl zaCMBNIxv`%AVm7>Z2GBfpsOM;_x+%S7)`t&4C{+JDKW7e*2w;|@lgdhwt*^)a=q(} zx2qgH_Pp<%adUnOJ|nkGv+*^buh&H-&_tscbRu5i*2;>*xchMJq+LgO#C`U~z$*i0 zkJZI~!tBvz-yZ)k=D2$%MT#6Xy@$J3;(BsE~-Tg#RBfx7_Ek697a9 LcYLi~(6#>p?uSyD0Kh>U7K0Zk zVvpiNf_q0{`R3jy5Q}#JfD108GjOK%Q9rz{O0^5Dl=m z#Q?i|Rl}+)7C8HeSg$yN2L0l1)ZQ7vLyUxTuohc_NlL+#m=^D<1(prT+LMI$Pe2f3 zV?xeF1|vvhVlcv=NJQxZuwMd0`~u1Vrmt^gV5nypU}Ow}AWA@e0R=GprLe-J0Kr5t z863va75nUxdsM!!o1AY1J&wCE2#%lAHfUF}lFNa-RC$sHv6Pn4q8^fk3CZ!VL%wB; zO5O~Uad=ry0bE?bG{Uh%)`7@A4}1o63JWc{tSxlo9?fw(adkFfbz(q?sYjD#EWLTb zGL4|!eKY$R-r~b-VKA)o4y|8cxi`KF(??cRAVp8X?zq(J7K)hX0w;Bi(<@vb?c1Lw zyyyqEv^f5m8MXz1_n_iL38JfKWLmKI@iz|0c-;D2WkXYGP0 z7#P?CsOfr$B)Z6oNx;i#w8KiP%hR2Djt+a!_I*J5`mUGeSU0sSM1h_mkosic^XcnV zP@#@5xrOwkl?kaL=!tyG5=Hxv}BE)Rvo zMgBtU9`1~PY}1kSFL2Rda_o<A=s%2@>?xUU2b3;%gnc`5y^^RC(b0zCVj%G zwRC9)JAJkt zZe=fyo6^aDZ-%C_Qyx!hZ&(lzI0gS|?$2Fg&f~(UM$4hW8Hh!Az!x9x^v-oX$9}Qk zL!Q)R?}Y~utrondyRYd9=e7Myty{+gzko~=w*b-<_l#N zqVL6Dr|{all&+o}OJ-jLK2S0dkLLcpJL#c$d`?`s7+w#T2sscESF^tYd&ET;hN0kT zVrk+7RPDF~yqjGM5MqVgXHjzgt%(W*7{N(%u2y5mDh(oljtt_Pz8Td{Q$l=OTWZ?Y zbkA9?Qj<>*>uCu4`>BhuGXU@q(T<3-iw|<9zzuJG1mW)SY`Q zx63b43V12bm{U2WB5KW!6^0+_Bi7e(PYVM!y0^x(UZV&r0C9mC(_-aORK=WR3P2h{l@fxb+8l%NgZYCnr*{K-$+!E;E7bKZiphnl3Y_s7L803c%{BX6NPpJvdZo{v8V3r~+K&V;+ti zK1p(_^>m^ZRU?yF1xX@h{nIR+cxo^Yz7lQa&X6_NV1J}`{St3$hjY_F-I_F{;Dwyso12SlyTW1yfAc>R{N?k!HG6dIl2f$s&bAR3=$&BQU6axv+h{ITk5apXz5V)@ z+imHIOP>;;jY3jZ#mKpvqhX-J7cQI4U6r?%+U9d+SxJh`r@ze;J3baGDv=|n8jrJt zicJSk+nto9>5giQ1Q;B3~uxp<`)|F%e547YoxD`9wW@Y{BBi*M4( zTB+vky0X)ba07ITYglbh0YyEn)U0tsRY>FI66MDR?Re^{DYuz_k+-OLMdcLrQVHI! zK|QyU@TSFgnm8-cDLQ^8@2N>%<>3&oDxm<8;XY(~F3=;zQdYFI$wL07uYrRcjk}E1 zxT-avJIqUAvqOikDJ-Ny(7)#~Gjpce1PfPnZ{Y^{lY&hGV}k_(=z_X>+9*&PW$21B tG69WE^b9mX&;$fA;rDs}6NrilIu}Cz{{aId2`51Sz*#$DTC51^{{Sl$&?o=^ literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/cs2-icon.png b/lgsm/data/gameicons/cs2-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3cda210bb4f7e6fc29c4af21e013648f359b5664 GIT binary patch literal 2397 zcmV-j38MCiP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x010qNS#tmY4s-wj4s-!)B(v5400>`6L_t(Y$5mEauU%CY z{>GSd&2`yp?|tsq(o<=r)FLPmjHpE61@OrS5=H$7YT_U8$v26SC<&MtU(p9mNH8TB z6RF&)h!mkfFO>GQ=hAb|K4-7J)?RDP%kbfxwqayEjHfZj?fbq-{CMh~AGm1#)az&e^ukO3IQ`${g_E0GO=2cTrHx|4 z3{MT<(}bI*biUP^HG4oJP=Jt7004mDvpn-v14Y8dN@sTdSbpaTs0hHfAG&vG?%35& ze}4IsPqWT^C)3WiS;v%RA)#%WF^g$inA;3puYE01#FJ1?T-BaH+ak%e}Sj zv}mT0%tDMfXyEgQv-|Hkxj564c6W2_V}!jM8yB*~t5CCV7H8+WNq01;67FgCIYKPt zK>-971^{^HOHrwZZuGRum&6=Ho4~s$MPsqPIw*FpwBz;IM8=qa-O0sXQLax-^!vR# zKK|&VH0dr(&(>8<_K$Z85Qv35xYXo0D29a@SHWzT%e|$C`bQr|?>Mq!K(}pc)9Cu;}|UcI`mRnVS-un+7Q3{e~aVrzq#T=kav zhwj7DgP?i11S&Ea5NtInW~L_v@PG|iUEB1ctfjm&wXuO`fAia7&t>Ukx6{=G2NF;a z3PBhk2q0Xy#>dnB#e1=QA9$`Vqu3-wEG<(MXPvYx5XXSV%YS|M>0dq5SP?|!sO|OV zhr6NMU2MiklAJ*es14*G%%UhLfFY?ecT{!`=@F!dKt1ksVYqEAnP@aBLC88Fg&??m zd84f0ee8T3CH-+7^4?Tytx)jdbl`$@>>UTMjENO7d>bflWpQccTR8kxguLY_5E=_o z()gm&Gahh))`BA(K6;m^*ozWSAO-~|6(T0hRvO(%X_$=8g|#MjHaIIznTfl;iIs04 zU1_;niE|#Ymn<;?-l@h!aT4R%=U-Yma`M!vS9LsB)eVFL;kFS#K?`{xXdwh52*i8E zF6v?Si!evwdR9kp91PrxFaCS4IJ3Pyo}OLyApimdPyqHF z05qE{fMFf`0Ii4s6Cvwk;t2Fy;D{LlFd!mLLz9z-|NNIdURfSj zt=y{mvw?Q#Qh@SK34xge4O0c4r~=YRGzhT1(L$Lv9(ewDe{hJ3s-0b02ogE(_loO6 zP)gk@{2;k70Bv1L5)8&r0&(I)&8h+wZ5umShE|B66Ri+%=8f}b-h8i<&W_5~L_VMu zu)u=^Ob6M80j8i?0>JD-56DOn(8551;4MU?^^2#8rxz~%EB&;0s%*CxKr z<7lcXLlWmA((7kQ!URjO1WyPm>|cCLA?7s1h9f8eTG+-)qVuEu`TKyx0ZJSrluhu2 zKv-K_V=}>05_cviW}2oIkKu4smE(iS3s^vM5U_yr#zsvukSfe|$8loKQX4&xFMTKQ zOmIk;G(v5-BrLDYf8~LD+EC~?|$O3N1A46A`a3r zlXH%UoDBd$G=M-50`^ae0>envjC}37$yDG@ODUWJV59|htLy*Tx%?V-KIkP4(1_rN zKYDUuZnCa+yLsx`x~{8Enp^9!Pn2MQ0SG}@guqbFB*xnin_g)*yT^5&R7_SIYJG6KZ`ufW3bG(%WIUwU4Kn8N`VS!4nBHi-`9gLIBIY zn$T_MBumFOxOmb`ADcb-D6%C`1KP#rSwH-w8*@?Y#U0()Au}O>8RtIS-Pzg}`0=Q; z*7iENZT+o^KTAnqC~iYEXnQj!AAy>I%77BZrRu^PvELb$d$Y?cTV=g;88`nspEUxAeSp)Qbm|1m64E}XLA8O^|JlLST-!*?-nijxK3+Hu ziF9NJJ9z!|x7OCTiehBajF~;WF$T2Hr~5C-?G8#SfqD~*_d_oN7GYhkoxO4KT~+U~ zt3w!DqJ=xZhN%;95g4cc`OfD0@N-A*j&v$PMNtG`Jg$HMINFE7O|~FmwvtdX-Cg_w zq8>1`8}ARUzvs$pd8Q%~jiA`1{T0|8K6W);c;UsOa71xqQMWb_6Oq<@Q)=X96Z@C| zBbx0_97bmr5DYGsSI*eo3lmujTOqiVb*eM;7HgX#oqYeJjrENp&u4CI4zrdXRRzEU;6UWbI<+qCqMmJmUR>xCT)yy&INHd^%5+%b^sC(@P9LN zm_c%>w08gi03~!qSaf7zbY(hYa%Ew3WdJfTGBYhPFfB4SR53X^GdVgmF)J`IIxsLK z7CT)4001R)MObuXVRU6WZEs|0W_bWIFfubOF)%GMH&ih>Ix{&sG%+hMFgh?WRZD~6 P00000NkvXXu0mjfr_4_L literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/cscz-icon.png b/lgsm/data/gameicons/cscz-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..490174b30705f8feebca4c6d4cc8423c99a83c06 GIT binary patch literal 2362 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 pO{5wej)KDtJe#=xBk=OMxg} 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/dmc-icon.png b/lgsm/data/gameicons/dmc-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0d3dad7099550acc5267fa6b6e655a92d2252106 GIT binary patch literal 2774 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 G_xgW)bdTHs literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/em-icon.png b/lgsm/data/gameicons/em-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2c98840b272e90dee3fe5b69e6aa02745b3da947 GIT binary patch literal 2442 zcmZ`*dpy&7A78Gk9OfwfNX-hzJj%vmNZBuQS)?tO%q7PvF_#>-Gv#tz5@wyl$Wt?# zmY2iGsaYtF%QKbRiGw8f_;p$%b`T9`J^wv_JfF|&^L>B6pU><4&*%2~=A1p_^35*& zT`(Bz8#h-ciUJM48eBgco z+Itu*9s`4Y2!_GzN?@>kS2<1OAMS1(i$BU$KqFI$|hT3jM51%S2=MZs5=D{7gs`|!{ z=CmADeoAzGaWU(4S|&Tf5LDTT+HJ&E&A{m~OhA@WA5fuj&_?QVGBB{te+`?blT<=| z+*IAvC*jIUk;#AYZ_nWSe(M2d@hpfzB>%__6$poSq43Z!b#g5WL8W)?Wm|?gKD+VKO zSq$~F1~k$ie*BVBU?c|6#;E(xjZv8h9y@pTJX$sA7olb%@Y+)B_#BQB1MF&_>LW*v z1U|V+p!WijI6LI^Piajc_<5LKu>XxQf?A(t3cr*(W2C$f&5Grns=nm*?f{vV3RdfpF`)0v}1C z=ZVpYi6|kpWznBrXtdt@@zlAqHfpU{@z2>1gH**cHRY44Ha9n~tt~jLzNT5UeCA=r zK!+{Fx!pb2oVb`G>$Mpi9K1P&_W)>=moZuS*eT|Dx;Ds(eHc_dgomhfzSkb&+TvvP ztTfJ!R7I(JEE0`GiTG?Hxu>TGBW@6hT*xZ($NP78JoGXnbczAB?+T$th_RA%0EM%+ z|1#)#(vQw(QzfOPrRLqv722GjI}iTN=0ZDB1GobkY9zEf{6S`jb)P4?2(krlx}j|$ z@aBsbFPtluo*%v?m&^JK3k#(Q{_tNQ1{aErjV&T&QOvx_0-p}d-^aCR9EicEVFO7n&ENqNBg_vja3Tp`z}&waL`hZ+#G;Wj{b0rjpQY_s1kbE!Wq@ z`TNg$tDQ69M+m8+sBx;lzw)p5!(Q5|uX=cT`c@Aq8uqt8UdC|R+S=rDc{VcT^%dL< z{()jZ9|}9B&(Z^r-nOx}Ht70ks}r*?Tk}9TPM=Cg^M$%%o@wr@EAJRw_HR@{5_bft z$)>O*mSX1$G8Z~`?i>cop#WheuwdW15!%gQT11fRbmP9G0VNzxC*W(gm(La^L`Fu2 zhlkVYlGpV#o2a*+<16zKW<{jbB&jeK>J!w}jY#4JD~XfIi68!~s&KibR30_)l(D(7 zVhCSdThqJRL6tNu3=9n9=zPb-GA;dFv+YCsxkPwmM8wmTVSiGUq9nAQnVFg1yEYw| z>nlUP9T+x+douAvFQtD40lM9J`|O&CQuX(jWRyw;yZsMm@X3(-p>!6%kwgO zwzVOt{;wo1yv2&2)SgEF2e2?V|5Iy78}utCypM1Xqf1Ne6HWPCXuV}}aZNpA$EWpo zFABf5hCWS$|M%3Cp<97-MSWvq7}FMyf1l7Sq<&3sY^-doHKn<^dH0_)9INuj*vpZT z(gFTy3W@I}8uKV{qL+5Y+Jq`>d&^yM{fJEm_*%1*87FTH-Zbh(e=bvpMqz% zT1`z}^G+3>EBfK4xg}{ozsUT?W}Ai9)@Ip-hKEF-{ekj^R|k1TSmx5g!qMNAm3Av%5ta_s>xLeXU&T4^qN2hx;|B2 zb}91D?d@RQhz^KnS=rm?A>NFQDI@)g+h*Jc_vjkO8dRF@dSYLE3cQKYkgRM>cVv5V z@b#^&Wkx&8*%Uhi&E(0{xgy_#sq!VoUJVl{o}Z=&T&Q(K3xTr|rx~QH|E%6QAX(ui zua2%wT=PU9)6aKI{V0|0M5P;^SIj+?+LR!DBOMcU>FUwg152PYyuKa|RPQw`K!A#C z{nBV?*-*HUXNre9rZFCa{-UU3cRiRfm4oYBUl#8j&f@`jhyKXXifpRA3)wzVJ$tGV z0oF=%iC71RURxWn3IXQ!djgN$Kow+;Q2I4CgO@K&dN%8>c+v%XG$3cZTX0FteSMc3IU@ws36OP$vdMXGoH{uzmS}-{MACtnCQ~&?~ literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/etl-icon.png b/lgsm/data/gameicons/etl-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d81c43fb57730c0465e1d3ea6c10f1ef16613de0 GIT binary patch literal 1774 zcmV004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 AMgRZ+ literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/fof-icon.png b/lgsm/data/gameicons/fof-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c9e17c4ff444aafb6a4acf4651f94819afca78f6 GIT binary patch literal 2491 zcmV;s2}JgZP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/hcu-icon.png b/lgsm/data/gameicons/hcu-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f265a5853349142db415ec9d95ec1101e834546a GIT binary patch literal 2241 zcmZ{lS5%XU7KMLGAX0;hbb&CG2!Rv{Qk0fJ=tY_ofzVNE07X|I1R|kH3so43BM2fO zNT{J#4JZN@q^Oio_1<9wg{Xs%_u;Oy_StKFd+nF=a?%rKymYjMajz*_9yNmVdu@Ku32 z-UZrJYue1RQ8D|&bGQO9Q?mPK17Q^G=0cumaLZb>4u0RE7l2Uc`1Q-C6 z)QwWPFaH5LfuxQ%obQ+@O<9yG+lw4<4XY3Qy00<2VTlo(9XD8~`|ik{aB|i@HSpxJ zGg*=V!jJIFo6zcB;Al#EB=#INsG4j)p9E-{q5MYah?g7KRN5^{3ts_^~i5k(O_ zZaWVhVV^#j3BSY+-gALg@0H`R*p7jp`$}EJi2?YTpSd_b7bd+lNpJMxe+J={<@xTO zwzpAm5p0U20u*|mSkCof(ikhMRglI!2u&8{(MGp0!nwKZjr5ua1#%e$CGp;J&E{ro zCYkG%s2LiK;TGev#0D~^d;I>6iMslRTTuK4(OP?3>1@v<= zmQS%%<#3=7sDG7)pTIDOWQb(3iTOLsfru~Urd97>NG4}%=ef@O@#Tsib2vd6hCP_! zC3yqA-E{r!A)la8-sF-Jsh{n$Vp5er^7SDB0U*5S+E-edRQWrqyBnk0J4!rwL*;27e$r>JgvVIU+ zp}Vt3=v>tqP3Y~3PnuWsbYx|3;iZGRH7(xDFLm(%e9qcRPf_p1-ma1VxJJ3jQveb`?99aPB z>jFi$a-WjyFNDEgU4Nu|Wvf)C`eHp3HPE5H>Nv9!BN>!6uS120i+Vy>oq$e&05&%wHs~Ln5S^)TV^ZsqDVQ zy^?Hs=AJy$Fw&U)6xk{akor}9Sf$p^%WRwvAh5SWlJ<82%}qC{Gg%FmNv+r08(>3MY=hM0?Aru~gAGDKq3*=kn(N`al(>l0u-c71gs-*1{=N?^b!@dp zwk57k0SM$GrHtTAFGSl{qjc>a&hk7nl2#N0VUl7A0(m^ogwC|%kbyE>v=XcM(mY`c zFM`BJew(v4Ywr~`L-5KTIjp?7$k#)+X0_b{qbTlm?p!0i>VylIOBh+xdz-ipQn`mK+1-d-b8&cY|!v#-JkG{(C8r!DV80|zAw{KP)$|! z&M6p$#d=Bb2S4lNy}@W%@~y&q>cMgLx-#OuucKre+Rs69jgg8)c~l1>0E;3zPz(2T z^Ms;aA)78^&%TVk#h~cF8e1PqW3Lq+IDHViCV%MZ)PIuKrH~4+-DJtKt?{n87M3tJ zODK@v4;MnaQ-|FvoR0k-*GJOd?KEXJZYPS&Y=&!y#Ew*jG-%1`qLTw?v>RbCF)76SB}BC#rXTi1nBui z2OJxKLZHxaBm$1aI3acP5W0G3ZFK}f4}rjjGWPzb5EkJd5*Yvg3)(s&cE<(40%wbD IH1VPQ3s4~QUH||9 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/hl2dm-icon.png b/lgsm/data/gameicons/hl2dm-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5bf5720ac2623da53e36251b2ec90f7a2a010453 GIT binary patch literal 2549 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 DwgK*+ literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/hldms-icon.png b/lgsm/data/gameicons/hldms-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..37e2a20b8031ad54ec534ac430a97179267e07a1 GIT binary patch literal 2834 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

3uqR&|} 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 NurRfSHyC>){1>I5JYN6+ literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/jc2-icon.png b/lgsm/data/gameicons/jc2-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..782edabc314ebfd05b6e4ce09c91abe073d132dc GIT binary patch literal 2983 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 DlL1HN literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/kf-icon.png b/lgsm/data/gameicons/kf-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..516bf8d6f1759770e47360c8ecf2f3360108d857 GIT binary patch literal 2687 zcmV-_3V`*AP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 JM$h%}e*qqL2l)U1 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/l4d-icon.png b/lgsm/data/gameicons/l4d-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..319f644f86f719f32533a42bf19416265779380f GIT binary patch literal 2487 zcmV;o2}t&dP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/mc-icon.png b/lgsm/data/gameicons/mc-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ad6904d9cb10e5776dd8c5ba8c85beb2a8a16162 GIT binary patch literal 2423 zcmV--35fQIP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x00(qQO+^Ri3J?(qBeQ+Y*Z=?sdr3q=R9M5c*Gr6DN14F! zf7Llv=W!o>`*z#0)9J)9atIJ9VgwQ+q9{>VzzWzQMPdVNvta>(1cBHvMr_zHi-|N6 zlLbLUvzutp3}_e@tUwVW!A@+eZTHiCU+11@y=HOa7MV_zU_q_xobOlP_noR!5%)MQ zeP&&J;ai`0dh4-KcI7t*$M^akaWBt&>Bs-@Oxv|D^m_RdX_~g%gRP%me`Ejhzdrx# zKLO$I1rT5U$)}!?v3NlUp70?^YaId@57(I%^IG`m=Zn4i^1pxo_a7MYzJLplpA}#H z_9vfl!9Jg&o=lY%L4b9RNi`#jQ>M!~GLoceigHn-I`wjSY%c%vH-7oPkoN?9_Un(y z(L>48NvdAZiGI>{R&1_~Ar^F1OJy6*_BU|Ou|GXx(C;zsjkvRzV6CI>nxDcIx8D;~n9o`^G6SmjS6MW#- zY@bL*XfIhGj+r)dih7BZQPY;)&yH>^e)yk1dgB!21n{LFd`hlw^`DY5yb$~7DJ>#e zXDEG5nr7$_<7>-kJff}}_KQPwlJMa8e&%Jtw3;y*t>e9?Z5qnDCOAhDCHN3{VDo$v z+VJv?D+mAd)9?Q8>vtj1+wtY&pL_7te5Aie;KJ7U9BG9K-$^Yx#g%M|)(k=7G)g+&tdJ z7{j^E`$!{AwhPR7K78*AMZ^@!+HP5tP7q zLmF!$DH&!1bfhSnB}KKQm*l8Kv9vWuJ6B0W%GtF|vOJ|QCA~Q3t=${kxlwRKH$^M%~n0``s=sHJrULA{)kxvk{396s%1m7A9(AxQ@YmBbrvDO&n)aaP5~zWbAa5~qN^=SS7UE=g!?21Z_XL6 z4`91w7<*&^S)8ytJ-|6f+jXQW3_OUrc*>K zxc>Sc)7_GX9zILlhgfRnI}2|8@c`*0^^KbNydqT4IYZ-G{8W+4h%}2yRD|>XG~nTL zV}5^im!`A0(s3rFlyyf@Tk5h#dquCGv7DDorZe{T59#%LOm-@S6=<(9!4O=)S02|` zOwqw25GM&9kMja!1&y(%0RiY`nz}J~Js^=5Up5Rf&FqbuV;xzdSRZ6)6>~HzX}i_R>(-nG_z;kh zVCQhkAW!H^kJm9D+S;UP4TrNOwG|*E#wO#=YZYmxSj+<23ATp=W<`UH1yTwwoLi@; zTFS=ISx*S7RZA(z5_JNQe|az@I%cw{m=!g~IuL@J2U7yj&k`OUYjo%k2y_$?2SLvn z5@BeKL+C!O@gypyYz?h-M3JQF3>(9ojnM$1dQ{E3WPkw1dN$X3^is|4@q!QnZRb!b zqUkJa{ggb_80YBcnlo#C_NKc?3D$X3uTM-&RW-E6k|hdj9o`3A2y_-Y=V>}~Is@}% z&Ag}yA<)Y-n`=D=c}g!;Sm)VT%URYft+9jh*n#y^{eL0MqD_fIhYm< z@`TPfb`EEZ`Wc;dEUK1BO5#WmN0Kw69@7SD4^7oz-KsD8nWpY6;V*tkPD-Fu#IkDf zepS!?<5e*0JR(-is~RZt2p$2_ zHYAi~NgyDFM5`F*R}E;Yg2l3=a~^9P&aZl-GnRnBI*$|rA0U!~0JDQh@#6Kv#aA2S zUIF|&G5}CCX7c*YJO8m*Rb%cWP2HK<{-pSqH}_^=n^)bx0q?j)y#sLaNmk}~=VFFS zoBc}{&ySzearEpUPe#^x`foSrwf!kgYuQ}Ou|9A-uVyo+U%Gw!_K$(9-0Q{U-R7Pd zB$qyZ>Hg=&!~9um+{goalO?H&soHL~Hz{7)IVwI-;Clg_JacxKT)K4s=5w9%&l=~s zGh4oNYf}DIf&Ugm=s3D41Q+jdApraz+ep5RoFx^f0000bbVXQnWMOn=I%9HWVRU5x zGB7eTEio`HF*Z~&HaaslIx{ybFfckWFlLHF(*OVfC3HntbYx+4WjbwdWNBu305UK# pGc7SNEipD!F)}(dFgi3jD=;uRFfggHhIs%0002ovPDHLkV1h-Md1L?p literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/mcb-icon.png b/lgsm/data/gameicons/mcb-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9634220307042b92eab42c05a91ceb2656ef5dfc GIT binary patch literal 2737 zcmV;i3QqNjP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x010qNS#tmY3labT3lag+-G2N4000McNliru=L!%J3Lm#W z;+y~g37|YN0aAI+3(W)VLshk?ts;t4rK(&)>jW2aPi<`P&ED(GnREZ$zI;CL z`cE!-*HnX`t@kCTvfJ!sjY_zgb$Rq;#8SuoQLS?mHdATg%+p+u-n~bAoJQfe0qnQQqjeiUrjeC0)hi|yNYx1o?bCSW<$1TohgH6*Ec zYaWy6@%N(`&CTBVoQ2=!A40^Qzj1Af_U)hjH*x04O)rg!r9kb+?^Lb!G)N+CX;_00 zq-~kt-Xq%DlY;3KeF7K}8WoH%6D$q{%ukc{z)`?dO4&m)B>EIkHcQ$?=rt9{Bw~=t zMl4%`A6y>bAQD%=&dexf=#m9KJ4O&E+o+JFtR_%5q#%QQ4e4dNJxTy8NHS zdVln1vaQYdmmx9a?8cB5;r)fvwUsQmgkOwR87pdfV}eoy(rJO$R#2fWDsL3p2J|3w zS@0CFL+Qdcj*dCg`_7drVp7+>&`4uk%EEwGh3|N5g6Z-iBDQF-OJr@}XFvE_5ZR+0 z3p`9#JHp4CYkfxSPyg*>;qyQK(lb>t-#$EHQPNbkmi*q60$kugN$?J-jndVt&*emK z?ftu=>1e8I;(znOF;ZMxj-g`Idk2&-3_Jwojr0{(Gj5AOP->NBnN(a-;_I@b7<08{ ztR$hL!3t`)H`oXnIBQFqoLXX8$AfN-BZM|hlXNuSD@=BHe0n4)Hp{ESDDLjhP8i2? zt9@*8$w}+z&a5hfaMnsj`?djqwaJP#b+4Pu@^a@_|KV9QI@@=yeX{?Uak@1f19dMv zdx06xgK4yu1UOJ_JwI8rAe6VklVULFaV4wTwpERkNX7;AhLHeRatH*xD?Rg+Sw?)s-pi(qLtgFH~q1GyKI1L$NgdWxgX-T%I1(RZ!h1cXoK?W$DTfKfKdZ{QSnM zVsQQQXA|mc1aTWq|9{%goomrWk+c+0cJU%)iasT0y+}8(OOMOx{ z@$yC!$itHd=QpqJogAwEVAuCko`mTa_7|sX>r;Z}_igA(V0!r^&*|pZh~)R0w9d2P z(x|bnjzKT^qPsH79j=W8A;-Q>dy-umBp;sUpZn6EHl49clBaIGl+(`oo3=fljYUTy`yZrl)m?y|9$r6wfU@Aoo*Uq_Vyp9T@^2n7K@^>v@MH`GpqOS-#@c4 zJ)O-2O?on!|NevQc=zs6_SJ8`wi*`0`40T`pIkgxw0ny-Gf>uTAgFcRv{oYH8fsG- z8-T_TFzqN3THvg1e9WS@@mkB)F1$dXb|`xyj-Ou_Jr#a__s|h>Ya`j3bU89HNj)-dfz0)Tl<2?m)Un$?l60umNQglk4(=a-a1;y^~3^<%}5KqaK* z3f}zTEoAcG__QdhUMF@3;h<6#y%@& z2&s^(hRA|c#C3`pq_8a8o@nB+NL`k7v3cBCKdvYZ-9dL`nwdRWmL;uO4FII7WE;5a`4Ceb0&N{%A|$4S(GUm|rAMg(BQ2?eh%1_c zAwh_Sc|Xr87nPbiMFWSxD0rZ%lP-)mTyhWtTU6ip%8jO;KYp_70Rlk?`q6GKvDTqz zF^fXOX&CmC{%CFQ(Y$KO$Dhn%#$W!Z zqiY2+bd@7@3({hUS*sm5?ii0-1C%;XsP};pUt`SZNg|RC)QMoNacw{fPI|_2|h2XqG^>9r18c(VAK;JAdJJtg#eOJ&8s#>=7A9% z>hHb!Gz8p!cm$Nk{o#;C#7W>JzIvDa0~zd03~!qSaf7zbY(hYa%Ew3 zWdJfTGBYhPFfB1QR53R?FgZFiH7hVMIxsLqYPRzL001R)MObuXVRU6WZEs|0W_bWI rFfubOF)%GLHdHY;IxsmpGc_wPFgh?WH8&1V00000NkvXXu0mjfFSIYI literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/mh-icon.png b/lgsm/data/gameicons/mh-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1f1621f1576c206a38cee743696027f9121ec19d GIT binary patch literal 2638 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/mohaa-icon.png b/lgsm/data/gameicons/mohaa-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0acd3dcf39d8fbd564eb4078eac8748d412e98d9 GIT binary patch literal 2845 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/mom-icon.png b/lgsm/data/gameicons/mom-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..317b6010a9e19865cb56eb507aef10d03ce9ece6 GIT binary patch literal 3025 zcmV;?3oi7DP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 TH8&1V00000NkvXXu0mjfy342o literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/mta-icon.png b/lgsm/data/gameicons/mta-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..25f89c9d86612df2fdff6167f52686fb8936a1a2 GIT binary patch literal 2147 zcmZ`)dpOe#8~%~Qh|DP_z06stS<0E2dCi<9InHsYy`gBbRo^NV8AYb#P|k0(q?+>~ z@(w9N$m?un4rvq1oZ2^ket&%Tb3M;}UH5a{|2_BhqJ;w|^&8bZ;4s_HqRPq7DF%lL25$AdwdU;1Ub~mO=o);t>ES z#pO48S_u|nVa|>yfWKEyTPhw16p1*rUpxRD)!b{L%Vo9%fheBfKk_5|2s@2)f z0j83G94bLQ1#%BE^dTvcQ3}kE%IEh56pwx{r2k}KK=Sd_|e+%pT)nENTXL)OZ zzn0xb>e^zjl4$pUNbVNHZ2N(^B_BO6a~F zq_j}v%QP{njn6H+a5QMD)&`T6pSirDGa0vrU|>EBelhhIy> zRa~yBo}6&4_td^{M2WG-IP|iu-Y0g}ztKvVB58M*$ipX++VzH4p$QDBe-(OV=I5t& ze{B#5gvK0;+^zz%4X1Ih=iG$MjL<1ba~>~4s)$rk)fP`(H|!5!egud1oYas<>)WAzAI+Lb(jV`Y~m6dYxdxzU*{9BoS67}w0e|!%$3PB>xELB3g*u(J~W{(4EVja9L# z!a=&OUDhAU+rs@?LX6iXG8M$JebD!Sv# zTa@nt@y=AyM&4g6WLa8T?q2&(R8-WrZ_aEfZ3ILJfpC-ngaC!V8|ti)`KM*)#YDL$ zHM*}&dA7! ziHYg^@IgvO22Xo!n8y4-_>SrVjBs$zy2%z(O>bP6S~`SJxKk%-4v>D{&7=ZzKP^qC)tw(xF> zo9$Sz4X`XAR187X)ZB->LB??StLEkj_Qrh^38fe#Q&v`1FxT5dLMTFHEvM&n%(IxfLkX?I~jlg8a#V-1;Hl~1jNo~j*9CjxC)pcm#bBhWHF15SA-=+` zz&{`WPxnu$k4go|#y$}anYhFs6N_A8emqo!n1zFcQ{sQmwBJlmPp=H1mXbo=ddi?d zBY)bzJ9Y*eif#U~FcRXC?#l`Ui$wM1=N1&4H&GGfK*%6eLXHEF5k@b`z77$poX5wq zS3&uw*r_v6dt}OUnQ^Q*Is$KB-ktcDVQ%&CIciC9{#5~tFHBEWhWF+ZabKMuo&>zYIoU9oVNZHW0X{qAK%xoWC}+9m~1+uaEqP; z_Ofoa;1?m$o|bR!tv{`Oq5-EhUJHhQ<{V)T;-S3N9)^4QXYZ1#^>kIR} zc3|(trP+6Ps;a6KQ_0RK1WG+y4wV2P-lor2j~X2=%d_5>>+<&C&FfJ;*9xC*wSQO` zRmnU1xH9B<(G#^?vk5j&@D zes9uQo?pdvRBhk-q`m5ES7fVwz^Fv!OkNq|4{4s8Y@4eY;u5WUUs0)wKnl}WA4f}P z)~np$Klr<{57NRTSjk?py~gJpvz^3Fr9Pd`m=4=sAO~%2nTKQW>#?>&qdtSHJxtx{ z&806j`jMwg2BPWyr@IxAaeW4PJ_C(+TSPoy8f81Pi+UWQp~vyq_Q{+=)x%q36y2z! z@?xBaGHt5^YBoVxALBpThi0i{nm86y-7;}wgM))}b75eSo9*g%HSk6yGgbiN7OF*} zG{t^%d*k+jFp`qJn$8r7bJW~sn;JZ^V`}yCBA!>X$rL9dca*^0Gu4$P%n@n GH~tHF4)IU` literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/nd-icon.png b/lgsm/data/gameicons/nd-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..dbc6a689100adf77227ae5a8cdcfc9b2057dfdd8 GIT binary patch literal 2520 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/nmrih-icon.png b/lgsm/data/gameicons/nmrih-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..02631268fda286ab42ef67094bea2a7093e2ed2c GIT binary patch literal 1100 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 DUH$8a literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/ns2-icon.png b/lgsm/data/gameicons/ns2-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4894b0fa4997d6ca618cf69404c0ebccfbb17d2d GIT binary patch literal 2859 zcmV+`3)J+9P)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x010qNS#tmY4%h$y4%h()NRg%h000McNliru=L!%J3Lm#W z;+y~g3K~g7K~zY`CDr+lTz6pr@bCTZH*aQkc4l_g$L?kwM{#g$V>uyC(vS#9K_MUn z5(05ZAhjy36!izhZy;zTq^jbl7NJH}lcLfBq7)JZnt(YHFp1+N_SzfoZp>b@JI9;j zy?Mv?Ai3KHEsm@}XF-#G}5cK;) zn=$NpE&#ywT!gW0TLwX641f^9yi&Ct<`|A^zH@8=g-(G)vEsJ?{-dMzZ|tIWr=At2 z;F-@NLO`YBA|O47*ft@UgkG4YGd$O*GsZm6BLszENG)pHR^a=L8rLH>Wj=MGm{h&| zL}xx5q*+%y@v+u)WAoCSItXnekrBk&Tcske^&V#(6%Sr1iOWo=budf&?>0 z05lM3Af!c5C3K}g7-cpx0nxVWE`&IMbl$e^eOKUguRMEcp?Na(s;j-xy6fJ)&?x<| zqJUv;ZJbSdJGWb%6NNO>tV9Muj4@`^wwV+qFA~Eu3b;oBHP}Mh$YHDMc501jZ>Q5L z&dmS*xi^-h6U|}v&NRz|8a~%-eDR6={(F}K$~__ji$#IY2puQWdZR{+hDs@8G-FIb z>07>UvwG+vn5Pretof$oIy>L6ZYKs#&-LTWB>j1 zYf>YOtYORzAaNWQGhXPF004v#S(Z5rAfp4%aS6gk+IHDE+J>rx)Tvgg^{5g>rgP5x z^H19DaHyMi(1cml@q=yW?xpPiemkFO5LRkj+6VofAJhUX5NNC?Q&J-CVwb02iZmb! z+k)r90?0ykP}zf}Z|mH*qq!EkKcITM`(W)kY7-1!5@nkTa z0LD@c(xh8*=};SiQZodN$4$;-NH(4( z0JW;ZtCO>ZdU6gJA{acyjM9AWs~wtU;e?y`e?r1b`?CoQa$(38VI94Hr|5cS5oW-v1!kO zRW)x_TDTnnnjDa_fb zJJ+|i=bLjbAD=jR{KJm{u=sJApO(?XkA2cAoRSjfzBu0BKK%aw{0rxSHd5LO0SuYz zdX?(&m6L?}5czY>li&E}(;K@x{fW7;o8KG-H~KAJoV|Q03oNT~j36OC@r4#R<`?wy zKYyXH%p7Aj5?(&V-R();U;M|feKkH*c@}UPky$o!J+Ipx-Fkb=Mr;&Mf@+OA;iv!l zuP%M}CzYjocX#t=I6U+C^`E}577{wx9zOB-1Aa67_4dm88_y(%aqr4AKmsJFqRUQg z$sE6{*L&Hqcsz*

JJFbeU34d%E0|T7&m92nQ84cRuHO0b-|^v)--dL5a>R5Y^VM5|Jqnot9!RU{s1_p{!M!2+7O(CGka#c zz4E4YX$`uvc9johIA5a-Y>y5B{de^v$`Ahl+Q2(^(Jx&C5}ji#=m1Z*7)looosM`l zik;0#`2G16F$hJ_Xx%V=KaTo~M-0>*Vo`=TT3*%tv4=$N^&dTNnP<2ES?5S2V=KP z+dqGfa!W5v82-*lFx^{a?Blh`nfRyX!2bc5p|>^TbbzvI!Nd1{$G`b!*45ud7hiaP zeE4jl<{smQdu;NkudjJ5bgD|oK5Fi5DC=qLVLVd(Ic8d;Gj}q)d?zeRVf5a6MF8*U zVT>Yo2N?Q(*VJ+vuel93Vdss3g8)b+{>fj{a~EBpeZF9gFw zABs1gU1l1tv21re_G16)oFDIbD?7Np3oCrAIGTES;S1N(KiRRf_>msi5%2a{zs3@0 zd{6&9?O9#diP*wD>IM0M>xsUJlV9ig5o(d@K2&@6&c{8d;s>ZAsvK z^{c2kNw@ra{rjh$-biNgVI)_8@JZZl^fk8+VnXUp;+TM^Ra4&tV5~y?f!bPKZrQiY|962w_}$$zc}!GaScE%*owtBuN4s4s{1&t`Lg5v zC_fq@vx|egYEd(8Q)R z%aYK8@8pi-M<}L69x~Ji1_l5f4HFIPf0-6Z*+f{C422ylTm2Pd`!`N==l+Li5yiy_ zBAvqU@5iPhn(;f61`|R_moV@GrqyzX*LTfqprUrZ%c?gj=$Uz+usX?G-f`W71sK?C z_`e~KRvw)|z zmO-~O$y%%&GF#dv7{}JJ>=`tUX!F+qMB-7Bd+i-3<>vbI`k`(^a`sVQDORG=ieRbL*l+P5 zc(y%Dq1h=IIm+B4A6k=CVzEdN7Qau{Nc4!AsHIF0PaQxC#(K7WDNP$^1B=2k+pWT* zv{BJwHC6%s_=9Dol=iC4Y#yG{z>`1&m@^~=EnU1Acb#z8|ALK7IUwx_t`eK=r%!~x zGjE+JYw_F%_y}ADAqb8jR>ptLHax25H5_tMUH)oJoXg3-!4EWe_BB#jsEW@o{zgB7C{8hV?fy3ZK8)$;78i{F@Kt8VonePW~2OP_XBB7mRraZ2)fyY`kjh*AF zyf)g)ctNo;NoU4wD1i=oL#OHK19~2?6*w?gzgn+mfl3l=*ZXxDHqu28g*zn!Q%G<53HUQKgvwt4> zw1>&DtB=u#3+a}{uGzlxf+nTdx9to!3K}zWRI2U;$drqweaULMELdq(z-Bh{BMcu*kt}r%8^7|_}hWTWdYqvT&EiK0I|> z9y650x*KsZtIfZ9DWZAdytyvw@%%$`?c@dQW2HM+L2-P`)g^X|LM#jZ;9J9EUX5uC zE_>pdpQ=XHqd{@60h@r%;2scE6OSf1Lv#Vh`tS^+F3Ry zb~MKN<=8-64f%bm5^b0Qsf=?n!@Q1{zoU|l!WTEcFlxAtp{ z@alcq@a~l>YyGa%k2m#`*6gUR zBU{v#7=4E@Hj_GKvEC|fa$wF&bC#A#IN52l3QNr$htJwc zm6|0GsojMK<%YsZU72efwl^>!8bg9YRlHeG+0bsIQHMFE1a^dM{n%+R+w#I+{m@oI zo5(WejdFXf+MU++96R-$WY^a(*8+$?W^ks(;S^(Tp*OJq*#>#%hNWL1 zG4cc2HXaf(EI6*OO7h-dKoZ-`7vW$HV92bQnykw3GI1ULC|FBv`PRf|ooCdb>e(hv zm+eRcV{w6OX4g!bwEeT@cc%54cB3B%V#EowUB6+Vby!MgP7}T%O=e>Oj>{iQOD1Dj zHXs;Y1XWbh9-RF?m))#4=)&YYd7+HStDq;ZEL^HTtGys#IhI%B)N0h7r3CYrpC0iV z5%`ma^kmF@Rso%h59xsWi9@QrbT#ok2tqIe(V1c#2N59xw5)tY+p&fuj^!@Kp@2ah zA`-{8F?6em8TJ;%0WAoCB=rCj&A$>Z$!!eT_OKE5p%t4dpkkE#pp~897(hFRluy`e z#QDnApxbwyN}z6~t<}s|6l-P7Bh5jYzGj)ey2A(AS48Q?}EWc$ussp{^kJZr;o{ z*P7NLZpi>hYJ}^Ua9y09bWF$=+hFWkGQWO|JMcVzr`T>1x`K}DV`6Kn%Jeep-8s>O zuIM{!oV5i8=m;4b` zjM*Sd9>7K=o+cs_hlY+Sg{ag5OC25u4s>LELCxG9u{T;zMOu zcEeGalRy^kembss8Uq{gR@Z5}wJsl~^dq>|Cy<&B*ifO4hskk^C{T|!&iW0FR-@=cd9_qb(G0fG$U&qYw zRvr_VLU$6X5{F~x6PZ^#)*azv0}I%hRCrdChuWM#DfT)x&3qRiy>W^M0ROrxzWs?0Vr zKRtICZ@YQ#zi`JeK2tYGCb*7l(lOZ)z&U5@f`d*Au5)ozTV;~K!pQA#y=73MVK|Zg+60=L6}h0y%kz- zNr?DT92=g(m9I+RLI8Ly++ivbk@AL$#S4Y&jUK5@ zuXKLn6VSPzDfUJp0?AcW_Y}2fc`70TB>+k_#2XAxT4Y2$J5T0n+q9_)!3@W~+~mf) z;$BJ(i&ftw9V@H*S^kpsXbhET7x5-bN#s3X4hkBq&a_X>a<%fryF6YYRCdZEDvjUB2Ii=;RgJV0BX2UP;8GAM9_ z<&!z0-qH$bww6mJx#9oTteGY4(fKL@XvmBHfuwCzfMo|7&ML1SDArqJ(n4M}-o^yp zuz()$vjv0<8YZGIWznF2(SrCsvphkUrhxQ{(>r8*@g>fkf9{Ff#GyR;dPd`qwEpYY zqafXvVz2JHB~BrYHrt$CXzkcQ<8@EM-PW7tMUdMVur+#w>lshwMP?mo%D#y@z04hJ z+~XkHEa;p{>1ozFb>SZ%Z_B7W&?f<8K@yiHdU{8z8j1g?yUYlRz6Nd2-1Bco2|YQG zuL!7@y5`um1))CCF@m&hMAv82#mBK{h;Otlw1GB_1cvBo?2BPeNpkIOq%`;@)-3Pb z?HxPP%0DQwSWs1A@l0T~YVGLiO*_ryS+o(ob+I(e2+!`1YQ0ym&wpa{n*!yIZm~3q z$_V}gTzQ)+5|}5Dzc)J#dXNQ!NFSY>Pu)%lN&4?%8f0+`|AHQ$Zj7$$mb3Ko+(Ge2 z(LGYO?oZBjorQL`O;f`8Ij&)emGQ27j#6ZPo~*6Uwx~XtKza<4!W@cOhKS`S$$uCa zlB0@vM5^#~U9xj|St<_|E{;Mi=Fml3Ph>;|fu~H!YbvGk|Cup3_k+|%dCt~Z_97to z{62E0PH2_F>}%OOj`3BTZQS-Vl0_L*ZJ7U!I#smiU+pY~DbSGcqEr?A$$iKf03!kL ziHuAE72kocQc>+l0(aP10?LJPU59<#I``+6(cB{|aI3@OYdw+cbA=}8VC4N0uw@-HQ6XYJpe3L^t zQQITfSef=~3sDldFl?;DMDgJ=R3o48vp9XZ_VQ&+3K;0Yf@Ynyqd)w=6ZU`plBMR! zZ)Rk4(;4Lkf#~(Z>^_k@`)Xd|Oz_j~sq@;Oo8i@}UoOV!;PbRIWHXwccIVq(+(Ul7 z4Wp$l#e>srk|4s-<`(bl$YwJ`5e#+7)gv7?p{8WYi*ZD8pg43*}@6h)mUSApI`Ozom zUnC0OfL$Io71Gc)LAt@L)0@{W1h@fTGP)aW7Nz#;vb|Jm-zk1!uf^TrQD<^Jj-1TQ zwMvwvnUf&Fc|9t$@Wr@k^z*41r2W*sQK96X8yUT!@DFgNaPr@eDcsv9O8>@x5G3;7 z8jb?r&Y+AER*Rr@L6vGNf!N0~!8h-#kFf>JQEI1KiI|x8!Km7~Ig2g5qm#3X$JT0o zKCYhDW6Nv8xvVh(NC7g6m_T_&g7d9(+it1y7?grBaA6Q3mTNV9fYU+QVi^z9?{MtN ztF$Uq`ju_4hM;Pst+!9LPr0H<~)O-H{r0(OQD&nW%L)c=pODwz2E^GIJw>M8W z*hC_T%XU-{>nEv--^0-7_>eulZ2BfQC>8A0wU)dd-F|xgl6o9h2;d_;R5Djj2$W9GUSx&nOwSd{DWT!O2nQ=SVT5eKr72#XVd7=kg zt;0WJ@mBGFU?}va>ZLkOUZqCKAM=!QF9?5+B!%CAVLJN?uD}QlewbhXhJQ(ttaL)* z?nmm=uOrx}utmP1r-Xq}vi`I6Ruhhu^Atwv4;vW{$L^!p@&lxBKe{Sr&WL31p_n<( z_!E1S601*0O=MajYjo)pZ*j8@Ghw*ns>I-6bQG@bs|OG6o6IRX-$^7TiTC5zVb95* zgaM)6mCB}G+bb%Q`y8|>OOu~a{ey^Zz9J2*zU9VQNa2lunV-wdnp z{&JtldfNxMN*QE|KiieSakh_NS?YxjBv@fxD><-{gO_O%;uBcL?&JPez131SZGG?^ zE<^FlWk1VktIl`>UR1b;H=Ui~t+US~drU>c8|v~D4{`5kQ z{4c-$fEz0Admj}8jl{W4H->b@e>fnEtq<545Uo;#gaDro zBPmi`!9oOgVPHa&dOMSesAT240vpN~DsXRYW44^|qx54maM_^io`yE+Rs_$M5*>!XhKFdx z1A+~hP}x4VWKL*+KwsU#UBXc#l3FNb)u#e%#!&RG>t*J%ZTiyea;STf#f))dfR7-s zSP#TKTB^ST3Ki4;vnD_EWWV(f&|0Eb$fvVEIRimB>E@*;(a;_UryIuh zh0w=~Q#NJQo-N`H9nfdGyAh;asq<*j{xtP`wp@>A>E_s^mdtJ3%)GPrzVUMb6i244 z{!I1t?n5wpb=P_;a9E=ii&qNTA3G+So{$`^crvR{kTU{bxjCcp_I!Mto|W{Y_blH& zBlEm{h=%S9IDT85oWm7o9u#z1|H)QGp&9O+@FzdRWHShTQ|J#9CL-(o!@wqnzgu@k zkc3?1dWJNnY_dXcJPXH5?8%JlT*L`S{ZC>o3wl>|n`v^Ps|Vct4^)}e@+$VKqmV-N zcWltx>&G2~jAx!U3JOQ2U{7GGQDx8vub2>xx_I?qT_mGsEwJ=CAHe z;3wz6X1WuW?Ike^%OdsIto3kQ>>=b9o;baf4-LWC3C?IU5pXX`xqI7_AQyj8_VM+=dI#-&zY<^g+m`t|XF99wm^Yd0 zTuO8yX@z2JVElgRnb1wrM0#g>t%P60#TuT>{#<=kjFw0(DS0+raVl^l_SQHY6N%+3 z=g@6OEU(`^>lh0Opx9B;%8_@%vNc&_0Mi{6^HlP>)$8yd(&AXk(Vsb;3~cNY-}p1@ zhLQ%XZ`}@$8dZK{D9uTbmPu7G!SYHqC!)g|(p7}j@)>*4Vr{FU)|Sw!-Y~+V)#wu@ z2lkF9$=b-)PT(rjB$l>68uSv@3M%kIF24*bsF4s!GZb@<+GyCqwF((e+R+e74~)O*2tfhU@J(q9({w1_bpm9@e=S`yEotE-MmnieW}t!1AHO^W9ZRXh(M6q&2FIy; zU4ua3)-RG_k^*DMhG%_}98;_y?brbEIcA@<N`clt4dpc(&$)`6MECQ&dq7JG&z zlFC%-o4+}b^H#WDE)EtX7&#t=`2*(sanh7YabU;y_lhKLaV(G6<}`^BdTWTkZF!)j zG%he{9e23v!QukjCJ=2mcUY^Cq{21TFAhd4F0l;A8&(ZwpRg6d_8E3u=0l%fI-yo( zh`@Y(Lype7~imnv^)9 z6S#sj8nBl$MzORpmt+0Xfpi6TYrY8er8qgNZxDdc80!05tpK zJ5cu2-?i5jprN-#^FhK!mZ{x8{mz`EL9CQ=!Bw=?YGmhSPZ4;NdX9k%+=uYy zB?wPg3dG{W`{HC>@8k`3746BDy?hlBL(l$;_0wRH_p#CZ#&0(yn5&mPRcBc?mr>d5 z9?v@^;Yt^e7(qGuZL)vI@AOGdu%&sZZD(Mu9HP;-vw0RoxK?P-&K)5b=(56l4ug_! zc{TUYAK^?3@^|5D_iCw%d@$t0II!L|)#92TAU0fMBVadc*XgqHc2sAfjYw@pYBCQ? zgED>}bEk;enAj}Ewo5|iLmb=Dv*ULHF6`BN%OUDyZbAUIz z6bF&<;WmDN*pZyC<&P{3`swg z1A_F5+VHJxud)BGTciszfh8x5bL3SvO&sx5KbDL-@!waIj6AnSvT0*lrCw5F6B9%h zyRrEwR~zSzb;j*feHGDnT}){e%2kzD(dx6(@Tn23LM#ShNr}_YM{7N5Y%x~^WqehZ z<{+9#-_7e$ugROS!!QoK9kko>Q8Q{$DpreiNL4kaq(E5cw+Z!AU8yql5pN*ihDjUI ze!K$5CUbO-LgASr&(25vL-4dQ>9aDm8+7NTMBes81beXGQVPU|{wF&3|3aZCEc8Fs zIh5=iN_6i3K%tKQ!m+uhm92CAiW_JDgN361hlQTvYHZ-XR(a2nWJc$&mOz48NEnnI z&}v6jl)#FoLu5!@ku5B`CAbu9Ac?({O5h<~#iyD+WKbJcL`D5DZXHL(tfvf(H}o!~ z9{8dP!DmCC4n-_IL1HQ|1+H-$Is87S9N4cICbRm#T}+|M+JaeJ<;y6rS|Hp;&~!!gDi&`& zZI$C zUmp>PMTaYYq}TwOy;kH<|0tuH%10Fs3guDLjT@HPTnMO<7;HJJu6pMqw8`M*Vl)&k z_in~O^vLFgGLt36l7 z)vl{!Ib})$>hB1Tu8YVE#_JrZjGB})Cu7l}u@K2v*z&jw?8U4T5g89;J*GlL!{xbu zY1>JlQH|Ca&ys`)rRFQCw}ab745zz{Ory{~xfFHD4dY%s+KJ@f#eLoQ(3yZQlExI+ zHBL3o0oN8s!XH0?CS=<3{2{?@2TfY>`cTuI4401sY)H7x1G-q&iK*f<|%k33cU zB{jeMSMLxV;IA;{yOMI5;3qgO@EmjaNgp}?jGL(i+{Yehf1GL&^oo&C&R9!ZZRIa9 zLH4&y@SUenYp)WmXYuj3_pwn|>}eMguEo=i(%f+pzCWRf@q)n#MxT!fBj}Xc!pIC{ z`!l`L*s%vmsxt&`1`&<#*e5mdkvzkmeuH%Qu}U<(TgFC+A;s19TQH?O^N_Xc${QT_ z$H~i~-h9MbD@#z!CfUeYGZwZ%snd56F~T_q^pqye8x|7(QwT-gCo`<5^dwH5wH!Sa zclyC~gDL^zwEm((LK_PydK1gV&6uo-2o6E;Kp1JzBd4u)qqe2dK?>`f0eT8T$O*f` zGcYmtPIrW15W6`PJttO7o8t_x1Fy~>OKB>6YRWmp&oA-W0Qs*z^va~gbz|BP%m@p` z1Uc-DqLMSnP%61e<2zPmDR7srW+Clf3p&v`y6o8UIwo|Ykq}nZQl0PxAs=e}VIwuq zJjJFJD3+l;B=9)IqvvSxRT)hZuN_&zhJG+R-#3`42i=}vk0b6MLr+ykzAylqown^H z1+)95UJKq9N;nl>(!Yu~XTsUEx&+d0B>1V&tcRKqsqp)SN@?cRysLj@Ak1#G4&41U z)41=?LC$Q-H_&P!@&&W3w35#?ZXwk`-o*Aj7yM zaVj@DHfdT}q5=kp)v>xeb)#<*>2X?RA%dg)d;$sa1_K@Yjg1Zc6F-)w1Tp7tF>m2+ zl?hcA%k&M-@m<<*)>p05sa_kh8$zO-$Xf#z{L_H}*5(FD@=v*Vh6t#Qg(U1l?>t$X zk`Pd~Fum%v9Ck$&_L8L0fG4X&SrQ;iz3tG*i%9Wvp_iQew8#Nt#(J=gf+6g{U@Wq1 z&sD_NLfeZ_hzdF+vd+PW~W7$f_|?$-|oxsdB(H zH0W%o5I{ONJQXV7I;>91s+byFwk6hqcvkgA8b1O^dSG--xhB#jR{ytfleZ1uI%in7 z@e>v)jkC}A%f(87@2mP?6&?Ij{*27c%y6fV0xG5d6V#eEo{bs{EbLF~h{1pL`#Z zpuoF8%{;JDrpkaJg$#({egNYUaWf>YJz|=kIMsK@V&m~yB@Gq+O4O&=r!3UzSKm*6 z79WVbwyZ$4IKTg^ahrXc(=7<&4mnSpSS#p*L$8a*ncK6Za@jA zA5S}X9TKjhIyR-@u_%Jn*f@(L7MC~ejgcW zyY7>Pi1mGD6R=A6CW9n?nq}wKyfUbsztww7xA;KouPJ^R8^}sxSQ+2U|4GI@tU7C|u z8BVh2B5oDr#8{FT42!AV|HL|_7bl>WuEqOS|sf8yfekem(*Pn%_g~wn{rwbQ!Uibga1A` zf?BZJ!vPHaTv{lj?X%(O#X((LSqK#9btJ0AfI%nwvjdR~C26WThVyx`B``!x2_{xDsgV3?|Ie*#yc6xUX-PkY_qyA^zyoj;BNp#RF%XR zfVGnt5zvn-cRY=#Sc}|*7G}-M9Pj$D0(!-=v9_;$eZM9p{Y)dZmP8ww=O?RVehN@3 zb1hH?0ou@w0c^(xA!sRL{j1eY4wA6W_a9~HDyGPuZOClk56Gk)uz6LciS-M@_yTMX zL{^#AHA`|*zsx*~N!1-{<2F?=+}2eKDP%NWvY=tK*TNEDU{ z!-v|AXRv(s5yZZiiEkh=sr{J_u4M~W>@fQzXzt9Qap1*0k7LpHi5U-y$FYMnPbtA>>z@kbqmaq(jrer~yry7tpeDVeyTC}`zdHsTqD z!6Xg2rdkjZ=-YEv4}73(bnWTk;3`pDw@yVy4;mIe@6qM>K!}UNPQkEBK{lH|Utvdl{Or{WZ$fGf!$z=*6U{Yy?Z+}G3jL(cIzWoP!)7G1VC zCU;ps_CJ$yd-0C-Ex<0GO`Zk;P9Qm+016%SBUcrpk2(DfA6oGo1Wm2c)B1QIJ`pWx ztS0wmzkT0yp^FVl1Xv&}tb7E!CDQusY9^m}jq_pzP3nzMFXkTMSwL!C_7Yc{BIW+2 zzN(78a|`u1S&j*T7LAMYH;8(p_oi9pbra|g!>i$>ZX8)!g?wqa*3ULgj_~_&slAq^ z$6aFS{DlYwTeBO7#|!Y0Q9I*5dvnH)#b*gEL_l1Pd zCw;=bz_+ngPUCP--Ul^qc!Af48_TrIW>O?ndrYI22BaJ}-2(mYhj&qg@yFIFX(d%v z+?KBWuct@zj>$^3h8+tfslB8U|J($&wfoR+o~=&#)7V9AMW29x923a}8{02MG=SW_iY%!}hP;KFh1F>tv!g5Dux*7_Fr!Z< zG$OFPoK6PKG};l|i0@svePY?WkwV+0raQ6Xw0{@A|BUiDAUuphVG~RjM|Mjr!j=pw zXb4j*GVH&F1r)mbqzyV zCSw<}^oz)u)`uaV*U`-clIS(#pW7Z?Bo)&vc`_w!BRAVFz5JSO9D-nkvJhEfAK6Ru4S6D$zm4wY!;fMcxe}v6U5ZD z{f~FEk4J;!CgULi5BcQexVlq$vx4o7uhEYa*_h;Q_c6wj|Uuj=pY4s~zg{zfS_t#$P>0;A{LuirWt_K7Ib%3_fBcE8#xw0M8(lIIhf(~AHni)>6K~w_c z;mMD&YnVayz82qGAK*taR*~=p9!{%Gp~2I~L1San05Ly<%l~?4-Tbo0xG&0)Tz3ZQ zh#q&;ZrW>QFka&EUAZ~B`v(|&QhSU}eu!I`k9q{b?}tURmi=G3S5_mQP>i}9@T}kB z7tQ5HYr#tGBuW?vAh6CfR`T1do$V=2tZ5EV7iq;uz1Y{)?xCIH2m=aJu`@jMuOXsx z=lfq;yb*b!UtH9u%xX<$U0|X}8Twk^>zu5XOKit#6CsVmG8eIRH9~ZyQ=J9gF&8`Zc zNV!JE=-5;{1vBMi;D^#o75P($=-BY2|L`A?`ia6)xB8mfGDM{`t#RmY5GlSS33_0E zqS?dJo3JRVCX_BUH?dX1WsjK2HZ?-4{C@_KA_5jfl?(shQM5k(m`t~o?_DE#j8(OZ zgFg)j1%31m(?GFg>rqB?Sh(1&T^Mj*g7~BTFVf0qBcObbwpvaNrOmPb0HOWBy!@j+ z(Myu@8oqJZMVhpr1V%#h8 zPo8aJ$S=6ErRBdOw(e(A`g_6#;lKB@&+(q{o?0KTC*#mSo!XZ`01N1%2lVHrq#W_k z0;)eYfjy2+Cfa{Tm==RGaqMqV3n?~c|Cs+#@u7EZ9bb=+oG3GxmO8HjtOs)iKRk6Z{TSn z5QxQRM7p)Jmm7{2ut%C{P|wXsl1H@j(dcc0{XlfR%hTb`D9N91KG7<_M=zslB4&=F zEHo}<%YQ4_M0@^`OtV4L=)ArUxjC(itt4@)dwP6wXk}gfL11qA)5dO=FMo;4tD4a{ zK}6XY=n^7-?vD*Q#D&D*bK9I{eoibMo+{a)aK_FL!Tcyl7_DMd!Rb9Ne`_QC+mX6m z`@jYsBz<7RLZ*YaD1mKC3ye0sNI!T=Xo-It9f&dzlLcjM1uvEVmd$m`84d^(mzRmBfE(TWKVwm)3bZ=uDA$M(KikELtLnT;Q^)e#o}x*dKOIoUQa!$@Kte98 z)(=ZDaF7e*nhy?1?|;ahIp>{(GTbRK>pDn8aeNncAj;jAd*4ICbJYv8@{QMCO# z;8e8Tj{VSZ8CZPZ`(ftmW0V8npxbn9mzWwj+0^hb)A|_YSok#rmEzDy%Y>zQ#?FSb zU406EdSRo1qC;;}J!+nUkHEh%XYav%Q}zx2{L~NpuixRNY+(Mi(~?A&@5*XB>dbrN z=e_86Ut!M(Xcv}WPTYMd_q=-;<;CK{*;;#H3gk2wXEC{RBnx+=VM6CvATQUsb3ArK zs?hUBzY}_2X-HoHB(KqibbssqhM!>R0-14QDlR)g(VC?ko+mm@rV`tcP;-iAK1_0C z-LyZ#erq^`JXPzWgTx;uYE@peK8jrte@dMJ6?xu5q*8~xTqmVBe9U9C3X|mvd*Gx% z;pc(9R6v3httn3uIUHg>JVNvL8wLwWwBqR*^@d6BvOd}oDR!z<-hiD1*u2=1{gA>t zY2Ca*R33sl!h`E+==S1cVT<5%sMbF~>BUu8bdZ2+w8ZEs&VBLQC;-a=WBj3_+Rk@8 zg&vI`cpaFvi?cBwuf4xdTC&7&-$8v(KS$^4Ur2@e`TYYl@6r7JVb7fU^xnb6Q<`XV zM_IHRC^Oxn`Zj@UqTW1izJUYnkcP^}bf^~d#otZTD|-@TD~aF|9ae>Yk@U^BmQHhyLH7!RSBB zNj9c>l(a;|y~3v;#V}DI&%C(6z&0?kZ#}@-6v|<8;SlOnW1oHkN+lu&2QF%F6_B3s z*#}B{Pg2L8dIZbDVUVGVpdB!nR#Qa?H&8tVqC?_CBc-7D*PCfgcXa#y~mX*I&16>cq^fSY1h7-pe4okNi!|(Ek91JgY^(eg6Qj-T(mMl}lKFI*Chidc%bXcO6GYA6y~`>TJNH3fauxQrfck zg0&6Gf{^(^yj0MGa_TI<1`eaxY>$aO#vTSeM^fd$bpgQyA#5Opqq)XOON9#{qNA_5 z4I~zc6@wTH=5fyx4p>7b*i?_WWv%@EAFsdX#8jmI96!eY0C~zRL?yOc`FHqf@%Drd zZ_DHTpm3nj9-}W8kruH-kjcqtiA~F$PFU+X@_kNXsFh&doeN>8lBVt$E>~7*u@;V@_1B?}m! z54H99eSfKOPuZ{Mm{aJrb@(6pzbH5<#iq)_g;_w z{`&fciZH@)7{rFKO_p3zhW0BT%9Zlob3G8Pq z3swSk9Q8Sr2zCraDnj7}k~P`_=!mIqIJu#n zoT{R#4)rJu_b)H*bY*4OzYlpZ!Z7l3VV4ubsCF57805(zfa8gAj9ty(O=E)zXdzOj zq8M))i`?Z_2n)O#h?MGZ#yEN)9guK47Z)!^hjTTr&1O!%*#;HK=aQv1$QUESi-kA!7k3=626` z;Ypz?1e-&$$iX(odQt8+(KunrW!YEz!zyU<-G-zH zUB}o}_<=_M0C*$E1Y<6C1|kPG&cNGp$=I5%7^D=l<|`KM9SW2TBM4%2LqPChmnZ5l zz|kz8gTw0q2_F-YMrw%K#v1psIXBV9g7Pqg4Wm$rwWp7NMJ$46Q+qKJjwq znXHk991}>Zms^#6pC(n*R8tf2Hi$GOV{g<(uiUVRG$LL`Y~0|gjR^XOBx+F&l*N}| z{{Rsb{{VzqdQBr_K&+{xxYu<%#f$=7=CN=J7ZM(bC9P_81pfdGLROv5j5eg+={4jepy+**yLz}!^^r7e1dA-0;EY9|B+&9F&n z3E0N`r6nT((*RVp@AQ0=F)1}cP3PC;SCTdRw$ zYE%e2n?KYI6jofQeZ;WKg$RP}HKsJI>THFt@eC8+jX~*}mr~9`Rj|Uf8mLN=e({?< zN))|=10wcf2N}y9upGz3-g$tX{W3Y{=rF?gCxkTxw+tIA08Rar^(j1viYKU9XRv#k zo9IA<6z+A=sD~s*%&|*cHz9Y^%C9FH3;IRdDYl}^jQk_h14%s4&&kgV8%{3*kGgJjX<|~ zQTa|-_%WALzAU+Tad5}H^A+WDq&!Yt$}uwSM*N^g2L-Z$^A*Ijy+#jMoRMg@4g}i(SjPaIf@-GP+8dWUD{w~c zQRC_t(J6Z@t9>vlCU3#TrhWeaDd0 zT8|bJ--#J;l`9TRR6zlCJB;F$l=+>3Phzl=H5dnZ_l60j+zHz>@-S@NY^X4Vs7jS9 z3cYx$Be3AB(W_R9omEOWF%sh;HJvH1-D49BKk` zJ7*@=k9u_&QZKO`IB4{^x{A$1PZ#2NULP9qxZosx#rF|AE;PcaWj%-7qYf%CBX!if zq^jgWiCx0j1R<9MK?9Ej9?d7HY7>&htSjymUCMmQe84@x@rqld(~P#%sO(&!dYx)C zX(JjT7t~1I%Lh=8wtHQgRgeczPs|@gBah-!gsb``1v@?A5;VgZSvf3Xbiwwys9P46 z!4gqEq7_jHo~+T9fer2@+broj5L8=Du8^W!3<7H^0S2VdlSbnc$Sz+R#dzGgb=h+8 z=A{q_V!W6*X5~bIIn)oFdxrD4?@^~E8)q`dQ5NnhbF$qx3*Vw?T}shzZqq8Xav>mW zwJRwFvQb+IX^0nyhi~l~7w%hB+-RVMTkJvHRTEbLF9fYaaT-BQx;;t-hz>*0B0N{z zTqRmG#<68XHa8m-Fb4<=jS8qSx%kR^B|9sOUvPe|59(i462<9-ZYl+`hMq+Tp?D-C zeiT(^HrqE)a&!zSEP;7|skrEYhZmR1rAmn_^v4biRJn=Ef-s42)V~XtStAl{EBJmV ztu_a7p;t8k+%38z?L~b?Dsol)U{SYlK}RCcE?ZhK*e75Em<_D4$e>nyD$0G-vF<9v z(`YVyFzCf$WENk6d@dBla zAd#1-?@%@@R))yjS5es^O46(I61>0*uq|*!JE%m zul@%WD>aIhmj)QL>Id9q<;cOeJu}%}4`R-nm-N+2w5cD2axu$Mb-dAr;4U$1(v>gm00cAQT0yqu^@&myFH8_hf!I!fl<13a zP7wrPB3}~wvSG1fhy%h4Z2Bst1Q{iwRl;EmLIYD{UsJ|S8#Ce}L1zFNhsQQ`8CAFt zZD3Xn&DqopUsW#SghF(126I^P9JQ(|5m;)Ll~(J_S|7-cZ$~y(np6J75n5XUERW1G z>>N6;4?2`Nn;OX|BCdl+=I%4AKx&rmqD2J{I^5Up6LvO+3?Wl$)Y3ZwaMv@6E~*5^ z5sD}QWvZ0ulypjTN_2fhoF7u15nu-?+Q(L6gL*I8o@TP8uG{E=a6~q}pAjulYF(e) z1R_^pZvB|l_R~mntaFHVTCyz|$I)Lgh^Z(_{lu4M+{yt(Ixbg*Fwqt*Vbrz;c`;62 zCQRH5;1CrtgysUT$|dxso{|3mEU~pMwVOb43JFGv_iQ2+MM6N;T`&Mjw@xKul;}B@ z$f4pV5}w(lAV++49l=eIJ(EY6G|ILZpW_jz65&f)_OtG5`>+b;e_wIQ7;|;8e=>o; zKX5|9C&qse_CzI#QmoCTQvmsT8JrI>-Fja45}fK&!5ydYz8J|bIO?NjEwtL8wS~fB zmcu~vETpg&9pVa0uu~O^m21H=)*;MB3zms;VrMZhu>~K+EU7_d>nln|>M%L=tS0v! znUrtP45KMramx_zG{k#n-uAv=h2G#dnRB{`3Mr+mL0T&d0hX)8OfG3;F-Z4^?pn(3 z2|*)YZxIl66?im9S0A+lZx6F9QtjmzXVhR@e(@=aWwvVo6;!6;{wgObffQDOQ?`j* zz~iT$m`bJP!a%}{rAnvyBw8(pROkD{7Z{#V#`4}^rGP8uW6ivHn28Hzq#U9rn)V{6 z$eoJ^{pM9gWz26i@tI@=R;61F)fVr0m*jh#K?`Ac_=A0r91k+sh#x410LaRJ$r}jN zyoCtz7PneL7f|OH`$trUlkgFoL3wx+1qGUAml9P9-8p^c>JyG2s9Ko2i(+Z2*O$a4 zYrBF2qf-gz(7rBXk3p%-$*dD8IicNyaU?)CEo|R&6tq|7$M}pZRyCok{{S+K4L}|b z^9&V>t`lSR1uC>YF&|9S*&UJ6ZRlWU7tF)2h`zTfZV2npt9h2eY|I3tN^G4>0L8$W zjjE_Z8*X1&nO(rfs%9aS)7(5k!7ZwkpU%Q&H6EHJ7RZg_qo|^TP_em27I|(V2i!!< zA9qm*gyH0YMqs3B@9I&l3@fL(bWX4|lIj6w&VFUM(6s^_6lm3M{{RsD(4GJn@o_?x zt2#?rtgKr900ex+g<2V6Dvd+BhZ7(TP`qEvEbK;|FU-qDU^Lgf$TuSP7i0FppcSpL zr1N0sasir)YEmANl(0RC^0gn+fIW9AcKvxN` z%qOU6^(a)UPMo#-g>T?6%AjPmgv9}-w=jcT^D>UO0bhdG;yBfvGWqy}NN6m+{h)S1 zy0|T?APqMS%(&L2FQAMK?jo2z;30phU*RqQJr%b!{-gQA2kZ3$1sU;3{^1fgfO8T6 zxcG?6ExU61kbMe|4Byb)qcSMWOixmXFikEiE>gOvbts4?n9f=tO3nuur{a7_<&BJD z@raB;oKGl5u39k-6iUMqxAU@G?ooD(7he?-62snEV#>o9Dzzs>YY&Tvi!F1bDx-7Z zn}VXvx+Xi9E9zt1VSrq;N?St^QObCi(Lm)pne2FSd&4uW1t?W-oJ<&kyqDalz-opf z9oNioqNjrr#ybF~*v_dIo;#YCO6*4swIe;nvqhG@6 zAz&>6utJhl$UHz5imySye5PKD;;J@S0dm4b>s8P~?_$<7&ZVT(O*OOs03+#$Diy4q zltZPyuY~Ra$Q&4A5-E93(x5pDG=o4~?j%HHi0sV9n~lJ|ZX;K-5L*^J!~t03VwhN2 zLMCkX2h0O@C7Qk65$mh~cp3;RyYm!Yx`tX{vbc@rAU6mSpCmHH$C%1=FC{h$gb1~z zhaYf(mNl9okoQ#o00JE-xW8!Rj0kjy!X!({0Da=w2$p&!##goquST0+68A#p*`buz zrCbIJ;#%lzHQY_4PcU>}nVHQ?lEpm5QCu%kc*J?}DnXf=L2w0AD}4U|@JfN4#4$yM z%4=-A!C@;4Ya5$5auR-+HHTGI)IeFp;?Dm7xWrIbvGE$aigAAu$8pRdKJdkuw-#<* zu;L|pH-^moOyU9YTT!MBM5VgO~eL*}^cDRNpQ~|rh1zyUH9wnAsH@L(-4DeIkexOTjGXQty9&K&hZ|p;-*L6l9xuyq4Qx}QTd3)dU6v{a^p|`01CNc zS7tM;rH%TIrQ}pY8$d1jm82U5(6XLQ%hN_4U7zA0Cu~b7DE5ooDH~vf2s5A%E*p8G zS5KENaNo>Ar!v8$0I`=Gz-e2xc!-cv=;k>k)*w1&F?Wvbjy|>A32hMjEt0mihCsP|-R?*Z|FhI9Q zyb7pvTOJndmj{tx;%Sm2NhO_KaCww)8-n!5K$X>;`;#icN)*0dGoid~Dx>>_9@6lz zzT&d9SXg*FU?HU!fL3eX8l+)VPnMbvG1PoIz z6#}K9l#BNhEpDMILOICJqbxtc7-p+@P{yc7+967B62 zBF^K(72FF(n7??b?JOK%g%)$vNz#k6L)kHux@p1F{Z7E~Ofof++OIdLz>;WORb$vj z7qS4}nY@R9<%=@J#&E%uTVt!13o?r5%hW z5HP+1^9WR~fXOL<88=@9SuMgeU8VH@08w`;#oO6(_zPjNKg^>#qZS#@)KH}jDhuri z2Au`JB)@Rvr5L5_xS$UZQDx^OU{R>=*qJamc=E+tG#hEfd*&kKGfiLoHSrL9V3@r7 zb3BeiDaG(F2NJo4IJ`C<&Sjy98pC~FHMcjVgMK66nhvpK%PA80k_iz@g9LxJ|JL9#W6@BG{2nw>M zSJ?(?4|NbGlofr-hs^mOP~3Mi`YN-iR!MPAeGVA3q;oCCOQHfHRfddX@42_Q#dkG1 z^p;U5BwV^H-vE06f0-*+S^4uaMw8}LrI)hTJDeN)n3?dI==8@b(MzSaU)MFMd++GHV z7Fl{y>&3-rR=gvH;{B!EpO#<-NKJ!LiM)9u1t94i@K=0xEm9h z#}E~i-1&(A0Fq@p{7oqsuwh^BI(EgOwv+HbGjd#tw1J8YhPL$yXIO)h+&Ypa0Kq5= z1b6}+DFedJt1)N+=rZ5?rI0M0lz&9AjS2VJ{{V8fcY^Q1@gGJ10FbBk6dO!Eo0vs> zS!Z|ny)W&zKK`L&sP1I{08vh%K=CVCk99rRq0B^WmtJGJ3zmi8%{r7JmS~E0e8)!j z8Rj{615nu=Fk<5+6Yiem3OI_2Wp!*^W?*I$lOE;7UO`)%PCUx2VXQR+V708qrv|x< z>e}vIa@9A!rXU=`QlbNgMez~=%!~P$7GY4X@C+S-U2#wywL7uy;wAtARSOI&Gt4s> zONVBDq8ZNvH|d(dY#6+@F}L%{k0m+j8A7qQhd2SyPn}rM^9-3LZhQ zI`I%`%yld)yr-Di2QPG2nA8weif)Lb{QBhLV1@1tpTI+Df(A-Ba3cCLDZui?BvGu^ zcNYO*9O454GgX~UBZv)$41C#iz+5~_s7+Ylf8r=bg`+t>r3ATca3{Pu&rr*BAU1t> zF)|dGruF%mds}ee?1f!W@w2a#rkQNv;o$tR4d791Y6K{*BIJ%?70SiFgn8;#@C^w? zMFj@~n}zb`0IO99)qKTqxZ7*C8Pf&3PL~J}#n~G-0opNi+^;QRKgw8Hv$dYg+5{+} zT71BAy-dwqh2^5!^HT?jVadOsflyRB7yKdXC~-FN80)<@o`1M%a#;D8p$7}=h^#(+ z2BZ8kd`ip>%_>{oT42m5YA7Q&uO1?`3Kp(UFpOeb)7j?`R2B>-;xd>znRIQfhfSKKDkbgUb!vf_}c+#!BY+>lT^3$ixiJe z8*c5K1^HoYu3`+q%)4+^N?q{{vNZ#t<}{WRSPTGuV`+@u?k@;8AxEG2gG2xg9Q<(r zmN1J+_ZS39v9EbnoXmZojg{sZJqdQOy6;x6pY<(EE7cmBV#pA*hxz`Im4!fvSmFY=p~Ao~CG&A;JVO<|N^(BNpc5>2iZ=$Vz$*gz zkC!Qq!?f<0SgD4eVyxo+3xjA|!c!hK0Ikb`0i#UP(WtnJSop{4IBQCLOR;X{CTQ_1 z7wNxIvKoA5Y8K*Pzv2R97O$A9ZA4P8wMjVk=YFqaHjg{M46 z0TX}5GzYxQk-@1%a_$!AdQ}sX!=RUDV_nOe=tKnUzxM8xEe{VO8^G7PAr9)7b%F zs>SXpV^P(af-v#w8*?hKw7kAzKwJfUOt6J$#`DFg(ga4%tis*A?$^)u>-*wZOow zn!ZvyqQVKAHKHx*k_4gi)WRup1zGy#f_FlV<=@l_ErOd0bksrzk*(J0h~64i{^2aU zDZss;FwL*!gK-t$00mjxbbL(-XBr_)eZK%pQy&B>>Gl#LaUIrw74Onez85N#Rilg}kM29Vjp2RYh^f|7 zv3x|mMJB1`t<_h|z8@0Iq%E^7wE4`i_a0>%x`BCIUjpVN;ir$q8qL%SSIe%f@>(+2??_pCXC!| zK}H=Q(7ehRh0@>}>{X9xYQt*7)VX+;IEt{_2QOwLRyWi>;3zzV_QX_;iG=DlDExB; zbVFfl5~=YJ9m@nOt4pKJOOgcNT_C{Jt71xlYQb@QZ~2K(!ormsxP)2@<|!l=mcF2n zkqbfVsL1(ZVBSNik9L~XdrH_AEs0S`Zvr~<^Ba(C6IEe>#xK-Q}V~1zF9xP>7>?O*`X`EL3>H z%vrD^xy0e4Ms0L?nHY_^{j0fBxo1n*{-PQP6_1905ei0u=Ah}ow3{Qq99=nm#dml+1tR`sv^WikbC%%;6f{3H zKvFiip2eSwxM_COHl03+k5xh^rQsmvIIv@wG(#<;F{%>EV~{yw2AHbYy^*6H7c68) zHD3{zzjFo5y2!Bm`YnzGUgreZH4X$E&wNx*ra7CLf|U!2$pJ&N!%)DwWFgeH3}rpo z+KZqVzKC?B9>xkGYDLdd>%qy7s2)bsk@ksJAl<^?D^y`z_wP2r$%|;!a~U^?=2#WH znfsX)D6Np*!#Rj$hmdvOw7v}NQoX{%Jr_A*opA<~H!AQ9>N9{{;`1(<%C#@N{3Nf4 zVUG4eNL&87i(;nRPNfYo+{;|X0Nk{ymx8|gOW=p8Qm~eo=b3wD?a2f;D~uAg7?b2m zjXs!Y$!|gKazfO(R)vW2pbAP`mIzw8&c305Bt4#C7FMKF5P%dfEw=zGEUJLfzf=WU z2$lm}x`tdK(Ds*0UiL*=>O(c#sdZlqAXBi5H+70@RGW?6plEKtT*O2d0I?GLpfyY1 z`6>}5pr2rbw}XX!vfC=7vu3{}R4@F@YAVWyw&p-Zqs+9mUL`2c#42dqc7ZSm0=+G- zh-)x0(}`>CpP8$N;ut?rpEBv+qOC;XiG%p5YlT$Idql`RRx&Vy4@LJ(q^l?@*r&~3 z<^&xdP_8l0)Kg4baRR5C#%^QH>)&Jceq$~~0LUjPG~vV*tgXK<+$Ky zeHV~|+qiBPbBRwtaKV=ng^3p;7#(g={lS(a4kBHIs4D6I01@Cqjphfyv>H!&Ufj12 z5t>zuG?pKA<8|bSZ!t(I`ilnlfhc?0%nZN8b)sacMebUGyNW5ZOuB~@V6GW#TSD%S zm{k`7MEQ6sU+pXGoks^)Xvp9uRl$9$Zr3w~*$d zghhe1`GzL`zDK`_c$v@`UcYk!PF8NXm-N;N>#2AYQKAyc6+dxua`T(HRkG;|vQ$!J zyA{SIMe$kA7HVhM-oNrv5k$dOG3F)Jg3L;%^9-xDz1x)#QJrh4R^k;GyJHpszWSJk znP+1GlZxCB>TyX1fzLoC7<`t_9%!J`w$NCm1_7a8`3w+FIqB-#c3QWNZ1#MUjts04o^Z+B)AgtTWcE=>P z9ZD2q3#OX<=i)t>3ku_YSOFcjO`@_e3c*Y9OkbxxHzvx^2LjW<)m#@526oDSc%SESL)0({{X;1iU=E(XPd=>lXjq1fHF!)O{xd9 zi)XpL2Y(R@3t6Y>me-G6y}ZSveVSoZH7=?7L^iJN{$}aSUoIu$1Dk+24Xj=uyIE{T z-vrof=%`ST<(0iLHk*31=K-}9gDcdcZ1aY;Q~kx8LUmHB5LlOwD6K3owY9YO8MrZ6 z4_(DL4W?`S%kHO7~DOUrR=@LKxjFrZ@S8tv!Zgji$RJ| zmG3S&btT~yy8)nyXeBsQ*lKOHH}4V^OXGvQe~G^fYl?fuB8Ee2Ik{9gQ1guZVkDS_ zJ(QS8@CV`uUH-a65Vq9>sRpw~C zb#c{l9O5oktbx=L;LmB!Wv|*(XvG^B z7mH-NqvR@|ea!G}qraMuDb3!6c=G^U7G0mXmrOS2pg3?u%L0+#u@f`pytqgLq=|_&CqPGQdLIeoc7mEx))8J`ZtAI7dvw7^9 z@^B^44NEjGS8O=^6`AJ$0JsezEep%yGNna&^1Il=qSiLAGR8{k=p`!L3fqMu2oLEj<+;^Dbj%3pG1810|EP&B<>`P)SiDkG`uQ3HS zXD+@xOCnI;WvxERMg=)EWr_nrBg@nV{{V=nOJH%-L1u?TF&thXuS(&$aBW$D1>R%- z013oUJi(}-GD}ojVc(dYm6+5OiGc4qpPhyco_xR(&@p_(fUq*?lM~acWH(Jh;2|*2 zmZgh8o8SH>_5cg$59(8Icyo(XFqc+qebHQWUu4O@OOJ;7{85}Ze(6{J*>0*sMrEW{;HqF?>Y zrdF_Az$+kImJ$#K%18V_*j&m;cv|4gW_PHzBS<;(4O1W%HfVKT@Rbv=>m6LO4Tc2k z;fT0U(qK(e*tB|4zHEO-{r#5J^asqjkoWi`m$5MHbg zNFZ*Jd_)9sad3B4e02+cQwUa3Fe(7aXP8Lm>5bJb^2Kx!Ly+K?W_wkf6AW$Cys{YQ zScujjn6~ZWjKY--Jd%FAM=bVTJr+{61qu#<8wpWX$Xg@3^6n4YEGK9$h^j!dU>SrR z5rIcv=2HEq-eJh4w=qINd_cr2Bn$Uo6Gn=|B-o2GQAhcRnV7?*2_5Dl(F?NK zT5hghQoj)sGKh0-{{V4rFnf2&D!wWTuV@$N=ou$7QL;SdIV5!Wm=nwm7l688Edb?V zT7!Fsm^F7#@h?F;0x{KDp_yu8c}9}U8`b6x7%HM(MFOyUqBEJ{jkOOasA#Ex#h5!c z+{Whc3-JIGKxKwol(l<*_^89x3OPpz{w@#`6G|V3ta@VN4Nhhv?5-yKbauxP)xy%o zA8_<0IS5G}uHc1^c(Nf-(B=I?ZKWA$s3;3wpb!BiYvTmQ3gj>9SkZT!9xf0k7C3|0 z4g~|U<3I-t+ynv*d(8vZh91b~2bgh7SZ*~3i*GFDj~amt4?i;UD|A=%ID;z7Af*Cl zlhWqXbsAEXC&|y$u>=~uA#xJww6BP!GGPtepwAq>?aGC013~tM#pMwU4&M2Vl4nt~ zsA`p65R`ALxE!0?g^6q`t{!Ix0Ua)&C6w|oC=0l$BG+{;R2mzKRtZH96uE*D$FC3( zp#IYzwNz9dR#aQpC39X0RE1T;xofiJ*g`wA9@;t!J0F}tHY$!ruj&B#K zQ1UY1W}VBTH^p}{Mopj8Bw#i;lnT{mGO=;Mfo2*3iuR2wgaz2d3RP8(V=+qx>M7K( zGO1S^mm`>*oW^rhJ(m9fxFPU9B)9eGE0zdnX%S9@e^FaAqs&TDX5Ujo%nJx+5ZXGG zX|`9Wm4d-)yca8rUL{6+uH^)xjYE~Vuv#9`3ptnB)klRrH!n!=xD>V7;Ddz~nh=|{ z8nZIS)Hn=G3oipZLA~Ci9$iv3K=v>Wn^j8@(7FizS_FspSeTu+-}b=f&zTfs8@mm+NvI@U#NF3z7tHbJn&IoHsT$MS2ZDX)Xeb_bxV>L$tois?FoLqYMnZ zViIc=lW#KRqO68~VsfV;&we5XVwM5!q7^pM+;YUXye3f+H)5_5LlqiNB+jb%%GPEq zfkm<7HoM@iSd~Kz;@qRQW?<8SZeXQRMR37IT{i1ag@Cyws0*kR2L%b@0$>SvIjCua zK}UnVRBW<_kTb5>rdr6nP@-a71Y8g*H2z{C5Oglt`l!?_vvE-wpy8wn-eowbV7_Un zwgq33D=w}WAw@S5{RM%5XE2Ku=g&Hu^$u7vd!aprDeSGpsb|dXySL z6sz+2hAOR(t@S?VZpw_M8`cuNMQP_#jaN`=;#2}05gEsB)RllA`q%(RpD4PT@48lc|a5{;^` zI1drtATmspz?NIyBtb!^#J{3m%S*t!A*Gj9yJgodA;%G&KT$kDyGSlnz%B#CTG=zU z^Ts?(s9RQ1R~WhhI?EWeuLM0kM{?B+F&6=$f-b%kv$ z2!Q2AtycM{;f1bIN8&EqVqG*rfi2Zv`-MV_hcx*h6`-n_bg)nh0>jC2>Bjl@R~ z)QXpuv4NMfm4CRTQ%Fm9UL``D+DdUMvQPu(?aZZ6?M7SJ-zPCUX|-DqEkhf(>Qe3_f~LV0?F6Ee$vvmyB+cH_jQ2A! z>OI`MgZBmR@_?&!MdncP5Vsviady2UG7A^3rA1Wg<_TkJVdc2Gn|_kAT82Cg`@(ca zQc{(vK&vw&)y{tLRtrw)Y5l?qh50~VyNK7%R9ka~VTH3c9#wF^c?x|vOc{+MrX~Dl zWW@reLF3U#rQhZ~-_3 z=0X8@it`JNO04*RBL;>H{Iv{NIluEAtMHhmY(@^oLiu-?B7v+k}Ya>J{oLe$7D-Zx&-$cuOj z@#0bdXe!+KmQ^nI;xmRx4ksZ3)~M=Qsa6}=7Std@Wq(qti4%RU_wh3}Wo^WwSX!*? zGYGFhvm#LeNT)s_&5^1awN*-Sl14}H&9S5-%ShTClc)#d?T^Xfw{vayppwtj!5pLl3`~}~G z{{V^?6#F@g zUCwguZ3gyNUknNgw!Z9ptOFz8kI$n20MbAu9B;S}>T&d2^kr)h+!}A2`xV0&5^cwZJCfF0dvMGhU%0^m_LIfO=esz==Wqxf91 zUghVV+gQ_+Y7=luAT|?f|#9BJXF~H6N)pHR}yinlFE4(dw z^juyAHDbVdt|G>i1uM=Nl(i{WW4h4?CEJ2w*&8!ixke9_u z2TrPNU$i=0bjr4lCA-T8bCrU8f6v4r@DIXf+|)bB{{Rz+wN)LS>iZ+4O7*Va9)oc3 z)E25`^5!Jnm3160vD|u0vaVV})}?Sa>y8=k`3iF_+;uhs{{YXXC7B=y0bw5AV+ozA zapHZ;8Xsw!A?UXaE1u!Ce&G3vIGWW)-NNQM@jHcc3MHQF4T6r>a=IWMCCxFnRW2bT z^ObKhrtqpDIfZ`WI}~+^PSv%~5Ksw#Vl@OdF$)E)*@odF>$z$+E5SVMtT4nh48EM(X@pCA;%V?~8~9gY7uUeDYLLYnA3Q zRnr>X7u*|Qx{XGVSXA5=XR!Cs@JlOE!QwS4rUESF7{3SbB{8g296fQ&xxX*sw=BfG z!Es2K7^Wd9wfssF{{S$cijMrm7R&QeonGR!a-fDmLrEq}TuEYC+{vfD&JiP{`u%*GKu5yY?h8agkxdx`%Iui(SfY}Fy!xeoF98Y!N%!jXc)JfOz}*{PxSH~ZLBMzqu6bcaog4PL46(XJ zVh@HY{)fGKv6Knr7=9(droxVUn}EJ6aocTMn+ZjEmI~H?5`$$u%%hr$LQ{w~%o9q~ zDWbFx)C3Oh?T*r;X1TYR<5I>zbig31dX^%v+B+|t%6UZH-OeS)a5R-hsq-;mj3%F% zW}g)Tg)qLCkU5l@1*u$$_BOyGgn;fxmEsepYIa82gatdSf5ffi$Ba# za52fX@0KZjumIijEO&uPft6hiMm~U*@DXPmJxjvN)KD1y;a*HHEE3(eI3T{zZY9KH z9l@j1R4vr131)o>=hJWH$C+!K5Kzl7`bD`=E-e256s57{fiR$gkLpuS}R#(Rko8jOVksbM-|(v%KpFhg%hXnMI|hCIa&FA+6cusVc8 zY|R^cK>Zz1c#TuP5{M~tgeG_hu=<3mIR+T0v(N-V(hkt<;$8yA1g~-?VXm6JK&b6Q zAzN*YRt>1>?38LuXok@;V7$RAmKGp+@iif8)|z0IHaA0NA%Ih9#ku^(G=pP^&6WTm z8ZjzeN+i5WBUaVR0JnnkH!By224Lec8D=F)xNbdq)f_y|k6MNwGXU7a@PsR^k?{kh z7j^Lqx0i{E76Gui1+My(LL=6`Alf`a{ZdLj(EOv#fv1Q%qAq89f|{#UR*XTf#L*>u zyqmk3%n3}74a!(}YB5ARmI4KyX8i_I?5ILB-QTYYjL%9aR*HRqZy zgTGW-1>7PpkI5?KR^{IHZYqU`0%L|5aimY-mEbeaQp9Wp;wNBY=u)3+>d0TgKpyKf z3ioxy7-nZ=TaTRu!^}Z#kXz;f8Yk2)AM<#Rhjb;rQTL+(A< zlPn=%4#k#vCWOs9JqK?WDQg>uF37WYs^$u$?J0ar47Z40l}X&b5gR&%+NUmg{-S(` z!!5~+reQVqhOZTb9xfwtkN{n)4{JWfS6>~>hZ7Kg+uCMa84DbTb=*kvS5;k9;^kz@S0f%^QsjF^gftx_dn$$) zxL(epHF2UInWK64fnTwXX*RZeTlkbW9DX2@#mWeF&<}Pt(!kGlk`l3$77fH;tOOjd z!7`>+N7&S!Oh(%40IZfM-{?_?i5jyX8J`STLJT9aXa4{u4$QK?!4q?T&k~(sY9RbX zy>3xaHq5Z$gIh(Y01VySTE*v>!oW%B_6)=#^;P{s>Ls8@rdlht=H-%xky%r7lq zfHQPQyqXE7nlLZ&FsKUDQm9`eadJcS=WjWAT`E6lG(#(?lbNqS@%Fhdw2Z zi28-Wi>9I*BkdbtDDmogE_ek9J-XS^+R3PQ0pcQ16jZG4JtEwcP%tO zF{#yPmkUtH!$KpxZXtjU3_v)BYen%8m;umw{)T(0Ocx$sMEiSKBYuVUfsf%r)+?gY zmv$@6bhIta7A@2#X)1}$8mEpdU6yb_3ZB+uJWxM?0}4*Z;uKV*@U$AOB0Vr=FbbBt zm2*`M%TO$r{w^&V97HJ@c|zWm+vd^YqUIrLP-M6$;lxUg9Wve2jnQ-a7MzL#1_c0d zKk;zaQMdsH5UV2GUB#; z?Q4<-PznP<>ixVojt{BsqPF$4vaKId%j3Z-{8Cr`0Q&VI>V1Huei*mud55lD3H#&%I)7-lbH!+ky1lNmX-`3@Z!$VN{ozPF* zJA)f;DX19itlM_WMK^uQUCq@!ObFna_C6x8vG;+-uDjYS#w0#oAkFz(?KZC~=x}2brB6&)zaq!cu@)_d zqW1VAR)b%j$k2fnzXE9qihn7TiBukdbzeqm1oaBGht+|lkq*R2=*AdA zs;6DV@rYFj`&xiCT5X(Eq`bh zKy1DMzY2?(+$2)4`$j@zt98}0iyKn1W*2Seai8=un5K<$hC5>71-GcTHk*GIvZ{ST z{{W5Rq80pT_k`4q5@-O*t|}N{24n!iKt8_>ofh z^gv_cJ%KFt1JDS%3yhY=tl^^270UHh{fI0(xTKhL7JxK7Hb#LU$St5@T%c+gSy%9j zOvRcQX8||Z^2Xq?&SFDXmlEIv4qj!!(b)mA_g3$;>mHyAjwx9UmSqa3uQ?yXa_IQO0X@bM^DKO7CK$c*{JW(YI8Y@ zewFET8g*ruPu!%7pW2Ck5ds0ENWBBw&^PL}>xGuQN+vjjD6ttuld$FG{s6A8`U7q5 zmO2jq0EbjJSXeu6aCh>WDOBOlrBje+QqBD6X94B4T|TD(AxM@aX3j~2@hzSK#57oK zm3WVt-IT{EFDnIq$&aH`7PY}#z)?_sB50OYsDKPTr?Sq88E~6Bkl6Sgm?!(P#+~UpRl>^ zj23jX6c) zjyJ^;-0D~E3l>Rsk{_3*<4ep;=$S6Hpkb=Z`o{z21wMw@++OdYGo>vCgwBLh(treP zawHsRG`E5CLVHUy6Kflp$bx&s3qY~TIc_$~YrtB)3<_eFisihb%Yz%8enJ&JpPsNS z`}C^Ybctr}7_T!Y4*vjGY-5a)F7V^xE5J=)5AO%eEMYV_6i@CWY6vY^kLajT8>_4+ z%3I(P*!@}e6k^BP)BK_E5kSlzK)9d54@J2D0LaE+JwbwkUqrAbhQ-+o)#;$=@7zje zrNFUZTNc(BA_p?v5pE&?Hi(-*wyIco=pzspC zYzBOIYyG1x<3q)d>(dyb*uO$4rQ^h~@whT`$0~ayu{?U@Y8qq>7tpogfoF%MkSAg> z7mhIs2^auzVzAJcT%O-XqSoIqULi`suTIIFviE#Iwlx*|{{TnwKd8-EMm(alC)?D( zDzMq)ug}yX)u12DBBi1Si8*sC9S38^_*`fhvAB52-B(m0DrHe zSwQP^t6n+993^Qg5i+E029Ab(@6c%h6G4ph>Gz8x7}cpCl2}%%Ip+8Np8l5PCT-2v zTQOUC7N*ttfHn^r4E&GNa((*+&uCh7!=pHiwyfwgPZKw>}b?qII zRV~MGP?#+L0N&BW(^_2?cuOA(4;h`u=tQyfc@z`}Vml&XCaKKbjk~fa3+U3h>a%o* zEU5yy49gMZhtVpL4)UMU5`~Vgh?m*+dTJFQyZ-9Wx#*1?EUjtKZIzR^4+8V)st)@v zJg!_W(lX&QhxRb1q8Ic3}QVU|4~2Sg(kb(8-_t z)K-0(0+;a;6jIvCm`|oxNqHd!TI0}l5aLuqy%zmyJ{_TJ-w;~MQdK*N#0ZjX@-L=f z?mLVcQ|x0^9T41i=5rL=KRApZby zaM{r6-TtCRN=g>k43;i}>8}tJ8(yjX_@gY zr-0CSF(^9??zz(IPZQ5`unGJ05{A|qAKVo~;N#VGbmxD=7OZ{G)2aUef3KpgTGe85 zh-Q!Xijo1{?pp6-+PR4!&#?;=(vsylj9(N_pO{ga6#!5l5eyyL0JUQ_P-#0yYd+Nh z232a)S%ETNK?*_ozn?|Y5ndqJM36@%$503dX0WUkjp>+{qJRh)3;WJNYTtdxT@p!C z$0>+378PN?EF8B_HLUn6@X#>a(WFk!SGnqdM6uzONQiEbFdmdU;Q~v#;d2kk&!oLF z^29Dk{ut&3Y!&u*g!^8gfJVodEuiZfkvc{O&+R`LXFgD_4H^OWi<~uyz`8uTAo#o% z!Y2Bs&AzMv1RNwZTnrQ#qY+d0lv#LU7`$;RstsBkp7kwKk?hCy76laBD#zhs$Yvnej4bq2;tm;gabfEY|DM>4Q?GsKT{nTi`8x3?+1&rkwt4etmEwY>X_P!$*V6MvAp9Sb+I})b2x4 z>L~j?3J2mc=>4bUiZWgJ<|KPaLbhG)yN8iErk9=<$5Ah$vIiED{6;9h#3p53TyfSq zfJAskn~L5e#ev6w*U9y`Q#`jcK5^`@{{Xl2xdM1b6P*diGN}k<@jv8s^swP{&;mfX zHhdAw8W&weG*f+$a&rp30p@;JdOwl(MUk zS^3Lm$+b^==)v)SO9^Z~B8~@3uuuB^eFXqbSh5B4=1_|`B?404m*Lsrdi1eK*k;?W zObH`7;P-Oz?=5Ksx45<5SS9@;yGiUd{S)ug0A4)uAKZ3-8Z2qI;tQO&3M~5{a2<4E zZlH3GfFG09SQE1{^3?P}NTS;@eF4;TG&~|ogRlTLt*f>};fzTa_%IKzR?#!Tm@nW+ zYyb?jk7Q3)U-WxHpr}zAtfeh&-K*rmZzrEYur*O_x3N$4^lFtnyg!3-0I+lqS%y2i zmQ)l8`;1XS*i4ytxkoE{d+Fe~A(a3%F1-cN{{W;_Eq@N{QQ+lN;||e8o2XOFcRKkLpl{{{XocW7k5Z6-@+jKks(>G^e-kDZHxno$kT)rc#%#0|6Dw zZ2thC*U%3)Uq)G3+weGrkGaer3yBZaahb1N5Jd zU_^_O><;ifHlP)q@6RFo-rx)5{aj2K8ryT0 zuKxfeRs&%lQK?Xa(^!EJ>}Cm&iAO1VeWoJ~I)JD?vgKpuWpz~NP%LT) zVMi>>TzWcs4ITwl@Lypc9;z)0wJRQSQ2B8a5HmHAq*n0tGhg9CpW#K#@M7&tFVChf zag;-dK*rVXv_6JOAk@M;KqdK_1NcU55&?c}(3C2J63S3wxg#5A?U5egSI?>l1x8$6 z(%0NdiI(6sa|jT$Q`zQ!*z4#rdR8`q{xZP+*eEzSn!$FPi3lb)((wyx55x)4!m97k z{EzA&!(Ze}2)FKf_%_L-N{e&;*Keohzj&}3YtxD~Y<7r$sL)_B}mhfA&nTvac%H!I2I_VfY>21kgv@ed;( zt5qGr%QW*W=rqVdo^2*ZNgsOj5E&WCp!_5x+H(3I^m|8%+5DoaB`oXiC>GS|-M@qU zBGCygez!x-!uahfvrvb3sa*jUE(8`{7y%=jh`nZ4GQenYIB-K?*g5kMa@Bc{cq^I{ zHT5z*P~4zJxSZu7tk4!?Ix;<+o|^t#!!Y972a4(>)WRscu2|kf17{@h5O-j?oJcPx z6KR1-7;`lf1SM*LfuZvOL>L+aUZzM^@<6B0xN&n8{{YRG@kRO?o3Pj;Bnp-7`t(Y?MYeL`9FM$C^K1R__<&b-b9ZNFd~xcGlnv(+9SXx_8>wj9(w`bWeFuo_ znQcB+UIEP8$a)b&tU_REH%|{qr1VReLFf0HJ|7S+@u|WeCm#zbDG;vD4~} zu~vIn#pFlK)mA+>kZa*#WCvS(02kdNHsytwgMfLQ<@8HttdVD;;J8+6g6;4!_9J`I zVT88e?p~H#HT95Rgi*l3FYJlBHG{jW7$3!kkv2`F9Pzj?cw|$J1W7oVB!T-sP>!(R_D+zfWm75{gB@TIaDXv(dC+79KcZ& z3bY$o_BKrP1F*>X?iHOErV8^5J^Oh1_w;6A2E-{Cu?n}9$?aq6JwVcitAZBpGgW@X z!aEihrP&p3cYh<=zms91bGEC3Vl^HhH{qSY$p>&Z(Dn!a0Kdp18BsuXu{xuCsn0U_ zJ&zaSJM;_wk7;3pf|j{)649}#LbQXPqC!Y_F`;N0k5ZfK?Fh^qp0g@SDFTa2nS37v zQC2}7GZkDxZC4i>54mny0eRwB1qF{7KM@3Q1m@6xsfi471DEN<9b+*r_`Yc!dHZ3U0rShTP+ge$8V#P(HEwKH!VvAqa}OO{l2U(M+CNQ zv+aquxqHc=c~AUo{{Y6%{A~XK#?Sn0{{Y6%{A~XK%+LJH{{Y6uLgNLSVS1E>aylJX zyk)dwcY=N!)Q)8}-Jj|NELTwf0PQ48t#trDks>wuk{%o7H8Ayl8<*9z#t{g!#*;$>(B%614~x7Q7CMUrSlct5T>$<%uLK1A6s12>wb-@#sqd3 zbWDU>Sf-&6oe;YJ036D>P*UD#3-)35&PhJQ^9d_i2Jb7sr3dxGQ?1=kIPoriL8@^Z zQ(OE*;noA8$^hHjLhB;ZpiW#2K39orCCAU{Q0|Ieo+FeyXJv)d#HFUa2sX(C21n1##b`wgt#~Q z2lX8Al8vVi%&>T#ZK##CflAgHgdiQi+W?mi8x5bEiA*4s!H%;_iMKbIgWsZAex~K< zG;WM>Ff1xlJ^^pkMavu_#iiyum2-?7!N`Q8r1t!EBAK(@{VkLA>KfmOof5 zU)z@cVj{+`wh_ty0L%vr=YT@>-$ zex%j+iHs1Tj$%6zGOjYdUqUZ2+#s=+FczHW2d6%ZO~p*RcN4vT0Myo_Y23OoPnfe$ zpeu=1^$-opqAMD@g_Q;IFW|DM$73Amu9ChxxlvhT7YhKM_c+-Vuy6Z-4rm@~&&e$Y zEw71}B~u<(XZH!!IW}Cr)%$@RmFZY33@jYNQ9TWb96q9pXsVb}fXsBR40Pi0CA;ql8#7PJ zqW++Dtjd$+o1O4`E#175s4m=Vh&jHTJc`UUg0`-L-k_L4yLUpayJFI(CH1iUkp7Wn zKJ$`=uLN$q!XIg10ePSgOeG=#Ioy?L(n813vP1C?m^bt;0FTq@S%dGsLM<6}DgqiT z2-ru#HbFq&UYQl>w$Un}?6~R}xNo^~rMQKfm(40R#m`55L@gEKB0#nU3q`6KW;;sv zf(FLugGL$Pg%HWBo7Qf8!Bn-@3|z1kPWg#}DqbLLG&o2F%m~RjH#dfIG!m*EnH)z8 zx4QIGpLl410(=mW5N@jwG2kRa3plwvJ-b|A{k!oAlpvK(#SwNhHsa&;IY^s#N z?ok7|O5DK4nMZz#PCa`dp@2J7Xv+`+Rp`{m(hA;!VUx1F{KMOo)l-1Ca^Dko!j0sa z!0D>BU&Kiuc@Hsgh|{y}jneD8qG5dvTNG)Q4NGSG$CLg&rhWea-?V(R*HwhAk_R_= zhS_#7Yn4tinhM4L01@lwN4u9u^`W=~XtCtNWR=Y|pw8VErMVJEv$_%zpUjpIXJx{zDBw=-5GNV$uyT45vV41`0r;n%sX%1{5!39E_>F_03{FE)%PA2Ia~o zY9jL2KQR^?v^Y1~0IMLn$v3##H@Mu!Kjuc)F8n5mQ{>aJBwWf;^P%KVVYqh*vRv!ql&{3 zXYxR>N^2+%A<`4WD$-3NrR|5aR;z22s}!uW9HC9j3wId1)FwtTl%Z&s=z?4W+$&j? z{{UHc{{V5jMNEJ!0k!~+TFDTwGI*6EZ?wi6wNXbC+cN9w2{F815|k(^u-s-B!e8bh z0;Se|h)58za=&B)1-6czuMtVqm@d8uvs*M*IpkOcpq3!t%r2ee1y8AvH~(BJS1o)An{ zJ;j5!a_7pZ*iXd{fB6N`1V#$gh1qBfw740J^c(%sflG zM|qhT;p$)08=*n=g@98j^q5&vf~Bpd`3SaF%|hPLN_t?gf~-ZdLw9pm4hrnq-(OZIy9NcnTN(9_qBCJHHvhX2E{vtBy zEr!?{vbW8|%hkJt#Z$r=K)7a-%b~+AeX5|LOcviO--xK|MWuS-sPY7~GzXkZx`l*$ ze~6)!#|-y`Nv7o`p49^)SpiUEKvY4m!~XyfqkqTzOrOyI020++K)N-DP^CkZ9gSl# zZ}tBG#NJE++#OzTWVVKmUU47A3mk6$01%qddLF&^aVye}w@i6hw)$c|hUKnYxk`M? zsJ+CrivjZ%;kfPE$9{`MhTvjnc!2ya;J6*I03ZAo>nu>EIVM~G0KeWfEo;B>#@8yX z$2on!_zkNG!^Fhu#(~ z2gEJqdxu@+Dlth{Efg1X1B*G2iI7?gtz*d!7Qfl{6SXZ?F#vZlAs|8pfEt1OW=1hlspo{A%Nhg#3F?8D6T`cW3-&9 z#ILzkE-g?g&GwskiJ5&RR2f!@qlo)Q7{R}o1W~g`>SnV{ORB1v1g>Y`085Cku^(tf zgaJ~EZ_F$j!U*j|dfI{y zmCUsf0_IG1nOL}N@SPlPIei@ynTrhI7cC4G_EYo!0K(_#AJ3_;YySX-LM4h&{5X50 z%i4ca2HyVwtTlfup$s8Xub6Rg(pll+X!hnHvA3IvIn3U*a~w7*AeNta`pV0{{FZmO zK~jjoobt=*=Vx>M3AQnfe8x!cw!QQwy@fks5nz>6+*{P%OSxd7!0Hq|qqSCJn5pmbapoJkw(4_E#14{$YivxKXZ*N_hytiLL~8zsEur%-*P!YJdL_oW>T7?sf2gp4 z7OJ8c@hhzQTWlTHKZ41pfEfe!%xAb@47khjP`rCTh@oupcfkFmAmA{o$DQJJASHDQg_B_JIZ9b(7+ZaA92P5qB2WSx6vOclXcehj;%vm|PhkH|;EV%u_H_E-muL3VV`_cFB#jbjpXI$&+}N7-HlLY2OhVmJeYa32%m4 zAg!v9Ke>v5e2GzYVpYm8h6dJ%Qy05y<{tMEPVOdl&~27X4R;ke%p8r}85^`(RV}QC zxish&Tsc?frw}ewFw3|NabAn*wR&#Y%a;z6gNr|%464J314WHkB>M5g8yDR}fSKZ%ntQ22%e7T9y> z&5gwNO?^VNOOwQR9^SuKC+O_<{%Q(&X{YF-mNU3E7P9zX&!nm`aC$fN?qs>ZVEoGd zV4~~p@2P!joUxNsMwvXvom9J8sFdhysP3iBye_}Qwz+FAe9HiB#ly=mHy@ zgoi9dv;!GlULm8jH%FMs5QL$*ssm{9SxnR?nfecHS@&PIjR91H#4<4v}pe(wpl(Me;dL?=-@ljwR zg4FBLSo%1q9JfdlVld~(YytTu7kLhm^mYb?_<${I*ovwSQd~wLV7a_X6rcqH9|*F?nY&E{bDD`r z1WV=tc08vN)fkb{KWhL-GQ}r?W^t9GmE-)t3O$1MXE8wAqmXe6HE}@OrXw=o4G6N> z`JlD*0l$QzsDpjSV?3E)1D$gg;s-A(5p1ffPe~n$AQ!+tsMnTcg4snzE176e3ZaW6 zXjrSy4M-7rW*3g$*&?)wWLNBiG((wo8IkGFp_H)maMB*84NljHmk()#E=co>`-Mj3 z4X>UFeQc{zhW`N6YYCcb3s94vaXqcq@Hva$+vIQ4oh?Lmf_vj0RK*B)yf2m2v&iR$pXm0nP^Aw;ijD}C` zo(*L}p&{lBDAi#Ym1SZUV&K*h+H5uGHR_c5Q^R9wOs*?>EyHld`#{3dPqaN{uxaA5HUBS7wpqv|DIg00Ea0wzb9PG=+P zdgp=!^IzbGF~y#2;ie4i7MYPy;JYo+Zxx#ZG;~4IpH$SE$GS zdt(3&&xxM~NY?QQ+o^(4<%&J6bt&kG)2X_21teEMqXN29{Rfv*JCgsskF5!yz5v1sfliE7@oS?+BxbZ~7p`n*- zNNC z{{R;-0w!3o6!&M~C5ULmDQQo#2gTBs4>1I`rb1nfQngVHKt*Enh+aZRa`)ftpY(Z@ z7+Zod@dv+T{DN$lxAhngm-jYewdt0A>?%$b3xTNPFz6Xjnl2HA?F9Y7hZ<9NPyu4A zWsKBjQwn0Cb+9|;C>>sEC5}DF9W}1vG3jE3$LK2C%sH;g9&oL}F?+lpYW=4y1m~A1cdGRkg zF$1W3l}jv{!IVYj@fB;K)Cg$iiw1tZwB&U-*W88Wr1hpU- zJPe;#6|z;Q<{T`Xzf${hO>)`&&5;Gz-{v21<1{pR+!jK-aM0wGQ&$CWRZ747U-0tu zST+1k-X%x)Zx<}1y-VxSQin2@>R`sZ_L~#hITw}$@RhhkxTL!HV)>Mnc}sr<3G~26 z%sNJ*@h&E+pUi)K4|3|dg2mARCV$d75G|$@=9T+lvS(S6h*Ga}V~j>i4h!=S1yQDG z#ckUC&BvGK8Zx#@s-Kulk;R{qAB{74lu%w^b)p0qI*yh$$|o`-aVybG7;v1i zYW7PR2EiDor|LVq)M3>&z7505y2ti6tBg!;Hwu>Bsk$4dOk^VAiCx1@a&Zj@%Cdj~ zdzB?Ojj&EP?;PqO1+t+qZa(E#wkuGW%jimXOtP*im_K4Ri>s-MfqgGvQx7vk)oyF*ZOpUT9r_-9DqpMP&`y&jJWmlRWUSdL zqs-y}+0)RsK8+Sz+^lw7-VIEHs+5O97MDc?!l=J67>a`B@}3%+6)=_m02mOX-u|U~ zlI&c^Ui2ZB^DG>K%$v1>uImT53kE+#Iv9q|We(O+ayNZK;EP8?o2<)|f}J3nDN2~W zt}4=+`30wCLmFzz0964LGs(#VOVzOnG#;@9;^}YkFz_1x3VZ}@c_Lr79uXwsdtm_F0odMg-*DLNLEcJm-m~ewW z`Hua$+1%uyckdL2%;gbC$Xc$y5$Gi?s%|93JB;q1>RL*v6Bf&CpFv>#socx1))_;50wQ zZV0jxDli!Gfdd)b@URF0)q zEK2)?Kyq$6yHE}yjV8A#??_vQ$*ZWM@%_Xoa@7jOVkF30DnuSWHpZY1)vK#&pCn5F zx1B{26XjH>t&LMqFEE`mVccK&iRgl!<<~m4uvYufCT>u_2G<-i&;qE6OAhnfco3?>MzB^#? zdC|PLF@%c&K3v2bF8o9Rk_s;qAGf`sP&DSMD}zDxM8XnCsUl0>fDq~Z|Bl(#9ogs1E zM-aC%Xe&s{dK`X$7XG3GN>&pYKR;2;mO`dehpCcP0$u@9yQH!GpAl#Y?G=xk6L6JG z5P)kX)Jun7a^!Ru7X3!E7Tm)Rv|D`^Zf*QOKm0aUxFv#X9$fNc>%%X3nKx~Uq~ zZFzkQ2g$~~N<)>hISFTQfw^Z>Sy&)IQReCjrq6ii2%#qPFGZ=QrqswA95EL$wGIkS2ynRAwCp)O zp@$~0!K>37XO*s=V+gty?db6lT8}|QU=o<34k-knM>v}jk!y{Vy}(%2Kt0ZP4M8nf zT3fEA@&5CVx^y7twIgi+HPRY?CD3N>?}I-UwBb_X$WFcGK9$ zW6m$?D*ph35d)`ktTipl%a~+dA}Tb+oy%3V^2QgSwD@A&)Md0Ad(;-44%)qBmrv zc~*$-rbjhC(2NTX-bi-L{1Pmy-Du1`B1NRWYjUNca-VSVFGXuxh9P}u7jWk4XDPD3 z14MRPz&llvyZD0COg1nBNzA&jx~AIA>Rh4OvDivTM`}LD4~W&oCJ(}ZENCu4%X9#6Pb0fyFvf}U_! z_*KNj(){`l7w9eYT^^g2xbN54M9Nm6W6*{-FxA2He(_kkD-1%0?=haqxmcHq<|>tS z5~HG3GY$Q+&mfHzQFL;~`7N_(idzL>zc6(p3RU=xhJz>F#3xe#dwGT+6oiD5Tvm@@ zR4u)V3;B3r;Vr-sI0*2-nP{!(CW?naRsJJnL2W=ODPmcudxb~M<$x^mCI`&3aE*h( zK6M>NprHKj7!(Rvvw!B}*J7@qODjtNJ%oEc+0pH&?Fa>bb-@l1ZLrt<%rZW07B{%+ zsF;no%X!44{p#}_4yDir#}FQNXW)%iV#cPEwkn50=IvcdQU!v}ej)Irb7zV6iyQcZ zLe=-14=}ZBnD~}0rawSm95q*{7Fcx_NXC;=q*R272?<8w%y_?Mm{QA@}5gtmd-fyuhUrz@`rN!Xm*zJ}v}Z z`s{s5djVEgCb5k~>Rqyqv-eO1D=paf{@9CMFBiI+dUhN3WsAO8zvI;2stu9Xsc0cc z1aS-rLW_VMHx^1%m2%ts$A+E(>6J>NFxC$e!e~EihV!psJE{8!{9h_NF{Jcdyz&wUC0^l#Jh;XT36{r_18jEmm z8aL^~)hp%bmFZ|?^9+>|p}28y+Lk*aRJXsYm!Q;NLu5Aw2eB4)raHU7cunzVY-B6& zr7)r1VQ|{15}@E>Gi-Pl4u}HDXEO`x3yI?l9(uVd`p%&E1S=K!buSo$DznUNTqps| zM^`&fGustP+n`0PYz-b&R~`voZDV{z%Efjlj2L3+6Fq4_JxY;^9Rw(^f)s7OCB>dt zt4`wg=EsZWZ=T@Vt_I3~aGM>LiF?1qLZg|Yrb`yxK$v3CTAQl)kMUKZfZ!kk3h2L|4`@mbj#bVW_P1&giWi%OTNGHff7cn* zIn3>!6&{{o&V7)9zfj&dUM0K*CZ`sEh!`2=z7RED09Q!=0GYt*3(^QvoI>?qz*j+f zw=o$IvSzA`fP51cTx^9Nqjno}ccpS_TZ+o3xSU4{GsSr&txni_Ip@S!Mz^5yfU<3& z@!=4t!6>@FnTh>aS&YH$VC*#h<>EFEW=WSG8-&|z*FW`$ZO_6%Q*08kL6H?i_ks)XNlvjmyQ|kb@P43VDvZz%v(d zVu7t%oQEvko~FY12s&9>ivIu!^YOzR4J1N4BQ1N4MRP8@a&d@F;ze3>nAEabsrL4R z4=RO1oV}=wkLoK1sE7_)%c$I7mjr=}itg?B?kJSkJ+GOv-Q2n=CRz=d#ARTRq4t8k z#C23u*xv5z;ss0_x`2YkA!>}Ws>>ExR!8_)Qk1R1=?8%-(^)2W@ilp%=!gLTfnF!L zQ5#pAp9x7w4=^{V-L`~LkOjJTc30*LNHPM|9;CXeD1|T#8ii3VvP{=eAs_%%$T;tD z<%2~EdZ?($a+j5tQ(0o(S6LFfftR6XQA;AYzL`11<^@VXUKsxXoM_8tm6)VJYN?9f znPvBMKsfn>#u2Xb^9|r?f;aNERBN~|7v=%fY$uTO7J#sp+Re+`yo9Xgui{~VGN$Cd?#*lQpoyM>MMS-kUbe6}y`U^D_-|7G@^!3zSyhKaTqe03iFo=6A zh)DvijGQvxBfz2rC@60llth&W(``V^w1syEgvKipfITY-a9KNCd_}pCL0gRC-}eRM zT!e1z4}NC^w@>j^8H^2Vy`idxY)aU5b=*@VH4fk~iu06qnpfdmhA+fvn+A!x&VA5D`ci#{e*S{ zP)05xU|xX_W6Wa()z+I9)*D7e^4&8awG3B_TVM$E(bu}c;?-!btskj zEk0V?Frxe8?)HM%c3?GTx;#L@th66Efe|d5vXgdh0Q-Bnt)f*yZE=0)h$WKgQvSP- zrWGMPtxDl&5~}>wq4s{J@BpW8Br=MC825^bFFNS_)GK3Q7dRLr z64K2aKT_}zBGHoE<6ki)ZBcKk%sLKs92G}Hi`)uE&%#X^6Jn+-UaFd7qBT(UHyy#K z0%vnxftOIG$hYYF18$7P5K_H{?&yyu&@kJ@M&E8`{BVqIr#(bS^mr9|!vUuX>=0K>L9<*T6(k5mnwCAe+V#JuJG z8xRv#rxZ!;5DT~8%;2%4T`X7PZYE;oL;@D(3*X$a)Il71iHid5k85f+XXXa0cwqcW zh~zBiDb0LJ;1#&j%xw|^4?ZI$A;Wq3fZmPXVk!+;h@p}YB+{x})@88xT9h<;y3_8Q z%cZ{zY&^thFJ}J$gix=-7Ac!o1yJhPv{?guSNV)*nkyI0U9kct=D4d|+o;+VWI`>5 z7F?@$jcWTma~*+;!JMT->sD2l?H}$AkctOq6?*xU{S2vo)rmv`s+xTI7H0Ajz9Pb9 zrz|+eLlM`TGJVR6FjTZ08-y)ku8NyH#J?1>tRY6_AZ&mO&qFXVqo^1Hs?DHh)M|Ze z*)@mVgn&tq?c$gr!&K!++5!#QwzG=nC@tlD{!eL4YGpn({^N31QsmA@gY^hTz^XRs zxK>aGL`L|8%Pu7$#s2_NU{PQe;^a{oJtOsYMXU=i1qb9QKQSDzMV7e%<$$F~-c2?< z7ZV^sfCInGqAJ>IyRIyZ0p{bpLYDfAoY0(c5K(J@41P+Dlye7l%*90?m@SqJ+1H_j zfo!LxO1Vs?Q!ORmt&F>kap_6Kx1f8)a24!CO5Q)$cnZ1N7PkvuY-w%oH(dAW(yH9akN8ix{ifzr5dbK;I66#Mh1c6 zWxHIg13(S??gD1uTk^4cS;D9Bwq#M`U=M;=wj<2G+Tt2s>H)U#8d-UTrt6zvuW*q? z%WVeXK+2(9O_J^j5ehL?M75zu5oAKPyF*7(Vv8#S-tCGAt$3L7vFhsGiT4$P*RRcVAW*Toq=mI($1sU?p|*DhW)2Ry^C%b*ARb0>Es#Wk-qg6<>{5W`%bS}t zY2NA#Rw8<~_Dg;X-~{5|X+}n%7&B|H1h+udkYdWB zwJws=ZoIxBE?&};mic4e6jZ}*KLmf@E!C9%E*AR-O)^J2f=kHbKQZOCTb0i;{61i? zTul&EO?*dW#aqll2qmxVo$xgdqlXYBmj%EtEkQXffI4bYTe)xWr>G`pRhTnX1%6|_ zzXTS~!Vq}w;w}x=C9}&4C~?%pE-BkHcE!(#intcy4OC3gWKG`@8&*9Hk|NA?uo%kr z7l>yHc!3HrLAB~Tc`+Fq#0*ggzWg$miGWnmA3Jt1^+QG)_KJXF*u!f%j*cbUDTzSN z@D(>Op_U#4{g|7ZD3XQc!45fNU`!cW_^H+91^FEipUyG{_03&e!i2B~LtnV%JvvFn zYnR^>HH_gU5{x+i0CMsZfJU;*?+e;aEG{YE%su^B1y_vif=C34`*}x(8aGR~mZ8{6 zrA5KPGuLunICSrr*ae4W;TE5BF(ZtuCs@equ;y$ffHqZyx#tr!|6dGrY z?jTZe!^#fg6(Ac2y!>Jlu9^T}35KQyAcf(+Z~BP=1sLS#-{v%7;5dU|pklVl_93k? zXimT|$}Sw>ghf|Ln6YH-bslQiyARY$nHdcsLyBQgIUZP|7YVO@_&i1WI05z^NU0eV zhR*SKGY~o$6HdCy!h1Ei3D<_D;|y!d+9@g^8XC#&5|X^r+xIJ9yu>LkQ$|;Gw#;;M zD|nbTN|hqu3-cJ)Nc-Mm!sJ#Zrrvx(kQoq`)`4pUEph3aH;F|j{>;4yisEa(MG(Zr z>QyNsWou3Q%l5|#{Q8WS@hpZn2H37AGiv(w&f=*91KcnrFEMrN ztUoHs_Lx9>NXF5u$2362m3SQ1s}{rvwPI9k8W9x+tw_~0FVr$#uwZ$o9ZM;oAXEB` zfxU}ncLw>$N>L~mKJlQGY#vHu@fv(cO(UY)vvn4nrfbHHejw7=Hoj&apxv!LqLMZ- zMcfLSvVXWB3LVxi9@n-6qsO0_NA9)@dtBf=06oif`;IvsRgihd2_Ez#OTzit7-)^I zx;cro;RT`_4dx(b7iu%3P4vc;t`kt+Ss(hMt?D?#k)?aXphohqs_r2hfCFvwtbEH3 zP^wnyrXU5aywd@Nad%(%j7g;fvn2`l9m;@Ojvm~`8ko%VYf)K_FzXtqVZbOmjN=7` zXN^G6*+-nq5yi?&^sB*m9L)X|z-8VKGjOu;8aR#f=!oa}U-A!Xj_ROSs8m4X(8@X> zDm`8x(7}>p?fN67cN8(m0W<>3{SQz<9U)eaEJV$b&o=^qloc=@e8v!7Hv^jHRW8`% zTg2!^4aa3yw6R=8TPa_}N158{rdnWWNLU&a{`yfVV3~j4)wk>FBXtc#xJ*7feKW4 z2_J}!(B|3D>b>G^ogs^R3<@QBF(|dTs&fa!C=ZZUe8K0auCEz+^8pwZC{>+8d`>hk zCh+`9Fd-n<7A(M^0%X8%iw#zdJr5HW~q9R&&RQ)mB?? z#u?0@Rp2rlBe>;_k$?92g-{wTC0^3N*}bK#G+bL(_W?#g!P0hI5%~=N0Ky@7OsnS< zkF-tDt|aU!RAz2IPy^?0)FK&0C=51Qe^J6Lt-G1R-}{Mriy2Gk8mQ7PXbG-+tV(fv zLk;p8_L=2n8sXuv{6fxt!;;baz|?QErA!x*8^=3?+-B;|SD-XNL1MUUHxtaezREe3 zKLYm44N6RYw(a=DR94&Ey|Tee@f9|e>bO7h59kxxBV@ZWs9Epb2p+2t9;cmMzZ literal 0 HcmV?d00001 diff --git a/lgsm/data/serverlist.csv b/lgsm/data/serverlist.csv new file mode 100644 index 0000000..1dd6dda --- /dev/null +++ b/lgsm/data/serverlist.csv @@ -0,0 +1,135 @@ +shortname,gameservername,gamename,os +ac,acserver,Assetto Corsa,ubuntu-22.04 +ahl,ahlserver,Action Half-Life,ubuntu-22.04 +ahl2,ahl2server,Action: Source,ubuntu-20.04 +ark,arkserver,ARK: Survival Evolved,ubuntu-22.04 +arma3,arma3server,ARMA 3,ubuntu-22.04 +armar,armarserver,Arma Reforger,ubuntu-20.04 +ats,atsserver,American Truck Simulator,ubuntu-22.04 +av,avserver,Avorion,ubuntu-22.04 +bb,bbserver,BrainBread,ubuntu-22.04 +bb2,bb2server,BrainBread 2,ubuntu-22.04 +bd,bdserver,Base Defense,ubuntu-22.04 +bf1942,bf1942server,Battlefield 1942,ubuntu-22.04 +bfv,bfvserver,Battlefield: Vietnam,ubuntu-22.04 +bmdm,bmdmserver,Black Mesa: Deathmatch,ubuntu-22.04 +bo,boserver,Ballistic Overkill,ubuntu-22.04 +bs,bsserver,Blade Symphony,ubuntu-22.04 +bt,btserver,Barotrauma,ubuntu-22.04 +btl,btlserver,BATTALION: Legacy,ubuntu-20.04 +cc,ccserver,Codename CURE,ubuntu-22.04 +cd,cdserver,Crafting Dead,ubuntu-22.04 +ck,ckserver,Core Keeper,ubuntu-22.04 +cmw,cmwserver,Chivalry: Medieval Warfare,ubuntu-22.04 +cod,codserver,Call of Duty,ubuntu-22.04 +cod2,cod2server,Call of Duty 2,ubuntu-22.04 +cod4,cod4server,Call of Duty 4,ubuntu-22.04 +coduo,coduoserver,Call of Duty: United Offensive,ubuntu-22.04 +codwaw,codwawserver,Call of Duty: World at War,ubuntu-22.04 +col,colserver,Colony Survival,ubuntu-22.04 +cs,csserver,Counter-Strike 1.6,ubuntu-22.04 +cs2,cs2server,Counter-Strike 2,ubuntu-22.04 +cscz,csczserver,Counter-Strike: Condition Zero,ubuntu-22.04 +csgo,csgoserver,Counter-Strike: Global Offensive,ubuntu-22.04 +css,cssserver,Counter-Strike: Source,ubuntu-22.04 +ct,ctserver,Craftopia,ubuntu-22.04 +dab,dabserver,Double Action: Boogaloo,ubuntu-22.04 +dayz,dayzserver,DayZ,ubuntu-22.04 +dmc,dmcserver,Deathmatch Classic,ubuntu-22.04 +dod,dodserver,Day of Defeat,ubuntu-22.04 +dodr,dodrserver,Day of Dragons,ubuntu-22.04 +dods,dodsserver,Day of Defeat: Source,ubuntu-22.04 +doi,doiserver,Day of Infamy,ubuntu-22.04 +dst,dstserver,Don't Starve Together,ubuntu-22.04 +dys,dysserver,Dystopia,ubuntu-22.04 +eco,ecoserver,Eco,ubuntu-22.04 +em,emserver,Empires Mod,ubuntu-22.04 +etl,etlserver,ET: Legacy,ubuntu-22.04 +ets2,ets2server,Euro Truck Simulator 2,ubuntu-22.04 +fctr,fctrserver,Factorio,ubuntu-22.04 +fof,fofserver,Fistful of Frags,ubuntu-22.04 +gmod,gmodserver,Garrys Mod,ubuntu-22.04 +hcu,hcuserver,HYPERCHARGE: Unboxed,ubuntu-22.04 +hl2dm,hl2dmserver,Half-Life 2: Deathmatch,ubuntu-22.04 +hldm,hldmserver,Half-Life: Deathmatch,ubuntu-22.04 +hldms,hldmsserver,Half-Life Deathmatch: Source,ubuntu-22.04 +hw,hwserver,Hurtworld,ubuntu-22.04 +ins,insserver,Insurgency,ubuntu-22.04 +inss,inssserver,Insurgency: Sandstorm,ubuntu-22.04 +ios,iosserver,IOSoccer,ubuntu-22.04 +jc2,jc2server,Just Cause 2,ubuntu-22.04 +jc3,jc3server,Just Cause 3,ubuntu-22.04 +jk2,jk2server,Jedi Knight II: Jedi Outcast,ubuntu-22.04 +kf,kfserver,Killing Floor,ubuntu-22.04 +kf2,kf2server,Killing Floor 2,ubuntu-22.04 +l4d,l4dserver,Left 4 Dead,ubuntu-22.04 +l4d2,l4d2server,Left 4 Dead 2,ubuntu-22.04 +mc,mcserver,Minecraft,ubuntu-22.04 +mcb,mcbserver,Minecraft Bedrock,ubuntu-22.04 +mh,mhserver,MORDHAU,ubuntu-22.04 +mohaa,mohaaserver,Medal of Honor: Allied Assault,ubuntu-22.04 +mom,momserver,Memories of Mars,ubuntu-22.04 +mta,mtaserver,Multi Theft Auto,ubuntu-22.04 +nd,ndserver,Nuclear Dawn,ubuntu-22.04 +nec,necserver,Necesse,ubuntu-22.04 +nmrih,nmrihserver,No More Room in Hell,ubuntu-22.04 +ns,nsserver,Natural Selection,ubuntu-22.04 +ns2,ns2server,Natural Selection 2,ubuntu-22.04 +ns2c,ns2cserver,NS2: Combat,ubuntu-22.04 +ohd,ohdserver,Operation: Harsh Doorstop,ubuntu-22.04 +onset,onsetserver,Onset,ubuntu-20.04 +opfor,opforserver,Opposing Force,ubuntu-22.04 +pc,pcserver,Project Cars,ubuntu-22.04 +pc2,pc2server,Project Cars 2,ubuntu-22.04 +pmc,pmcserver,PaperMC,ubuntu-22.04 +ps,psserver,Post Scriptum,ubuntu-22.04 +pvkii,pvkiiserver,Pirates Vikings & Knights II,ubuntu-22.04 +pvr,pvrserver,Pavlov VR,ubuntu-22.04 +pz,pzserver,Project Zomboid,ubuntu-22.04 +q2,q2server,Quake 2,ubuntu-22.04 +q3,q3server,Quake 3: Arena,ubuntu-22.04 +ql,qlserver,Quake Live,ubuntu-22.04 +qw,qwserver,Quake World,ubuntu-22.04 +ricochet,ricochetserver,Ricochet,ubuntu-22.04 +ro,roserver,Red Orchestra: Ostfront 41-45,ubuntu-22.04 +rtcw,rtcwserver,Return to Castle Wolfenstein,ubuntu-22.04 +rust,rustserver,Rust,ubuntu-22.04 +rw,rwserver,Rising World,ubuntu-22.04 +samp,sampserver,San Andreas Multiplayer,ubuntu-22.04 +sb,sbserver,Starbound,ubuntu-22.04 +sbots,sbotsserver,StickyBots,ubuntu-22.04 +scpsl,scpslserver,SCP: Secret Laboratory,ubuntu-22.04 +scpslsm,scpslsmserver,SCP: Secret Laboratory ServerMod,ubuntu-22.04 +sdtd,sdtdserver,7 Days to Die,ubuntu-22.04 +sf,sfserver,Satisfactory,ubuntu-22.04 +sfc,sfcserver,SourceForts Classic,ubuntu-22.04 +sof2,sof2server,Soldier Of Fortune 2: Gold Edition,ubuntu-22.04 +sol,solserver,Soldat,ubuntu-22.04 +squad,squadserver,Squad,ubuntu-22.04 +st,stserver,Stationeers,ubuntu-22.04 +stn,stnserver,Survive the Nights,ubuntu-22.04 +sven,svenserver,Sven Co-op,ubuntu-20.04 +terraria,terrariaserver,Terraria,ubuntu-22.04 +tf,tfserver,The Front,ubuntu-22.04 +tf2,tf2server,Team Fortress 2,ubuntu-22.04 +tfc,tfcserver,Team Fortress Classic,ubuntu-22.04 +ti,tiserver,The Isle,ubuntu-22.04 +ts,tsserver,The Specialists,ubuntu-22.04 +ts3,ts3server,Teamspeak 3,ubuntu-22.04 +tu,tuserver,Tower Unite,ubuntu-22.04 +tw,twserver,Teeworlds,ubuntu-22.04 +unt,untserver,Unturned,ubuntu-22.04 +ut,utserver,Unreal Tournament,ubuntu-22.04 +ut2k4,ut2k4server,Unreal Tournament 2004,ubuntu-22.04 +ut3,ut3server,Unreal Tournament 3,ubuntu-22.04 +ut99,ut99server,Unreal Tournament 99,ubuntu-22.04 +vh,vhserver,Valheim,ubuntu-22.04 +vints,vintsserver,Vintage Story,ubuntu-22.04 +vpmc,vpmcserver,Velocity Proxy MC,ubuntu-22.04 +vs,vsserver,Vampire Slayer,ubuntu-22.04 +wet,wetserver,Wolfenstein: Enemy Territory,ubuntu-22.04 +wf,wfserver,Warfork,ubuntu-22.04 +wmc,wmcserver,WaterfallMC,ubuntu-22.04 +wurm,wurmserver,Wurm Unlimited,ubuntu-22.04 +zmr,zmrserver,Zombie Master: Reborn,ubuntu-22.04 +zps,zpsserver,Zombie Panic! Source,ubuntu-22.04 diff --git a/lgsm/data/ubuntu-16.04.csv b/lgsm/data/ubuntu-16.04.csv new file mode 100644 index 0000000..e91bec2 --- /dev/null +++ b/lgsm/data/ubuntu-16.04.csv @@ -0,0 +1,136 @@ +all,bc,binutils,bsdmainutils,bzip2,ca-certificates,cpio,curl,file,gzip,hostname,jq,lib32gcc1,lib32stdc++6,netcat,python3,tar,tmux,unzip,util-linux,uuid-runtime,wget,xz-utils +steamcmd,lib32gcc1,lib32stdc++6,libsdl2-2.0-0:i386,steamcmd +ac +ahl +ahl2 +ark +arma3 +armar,libcurl4 +ats +av +bb +bb2,libcurl4-gnutls-dev:i386 +bd +bf1942,libncurses5:i386,libtinfo5:i386 +bfv,libncurses5:i386,libstdc++5:i386 +bmdm,libncurses5:i386 +bo +bs +bt,libicu-dev,dos2unix,libxml2-utils +btl +cc +cd +ck,xvfb,libxi6 +cmw +cod,libstdc++5:i386 +cod2,libstdc++5:i386 +cod4 +coduo,libstdc++5:i386 +codwaw +col +cs +cs2 +cscz +csgo +css,libtinfo5:i386 +ct +dab +dayz +dmc +dod +dodr +dods +doi +dst,libcurl4-gnutls-dev:i386 +dys +eco,libgdiplus +em +etl +ets2 +fctr +fof +gmod,libtinfo5:i386 +hcu +hl2dm +hldm +hldms +hw,lib32z1 +ins +inss +ios +jc2 +jc3 +jk2 +kf +kf2 +l4d +l4d2 +mc,openjdk-8-jre +mcb +mh +mohaa,libstdc++5:i386 +mom +mta +nd +nec +nmrih,libtinfo5:i386 +ns +ns2,speex,libtbb2 +ns2c,speex:i386,libtbb2 +ohd +onset,libmariadb-dev +opfor +pc +pc2 +pmc,openjdk-8-jre +ps,libgconf-2-4 +pvkii +pvr,libc++1 +pz,openjdk-8-jre,rng-tools +q2 +q3 +ql +qw +ricochet +ro +rtcw +rust,lib32z1 +rw,openjdk-8-jre +samp +sb +sbots +scpsl,mono-complete +scpslsm,mono-complete +sdtd,telnet,expect,libxml2-utils +sf +sfc,libtinfo5:i386 +sof2 +sol +squad +st,libxml2-utils +stn +sven,libssl1.1:i386,zlib1g:i386 +terraria +tf +tf2,libcurl4-gnutls-dev:i386 +tfc +ti +ts +ts3 +tu +tw +unt +ut +ut2k4 +ut3 +ut99 +vh,libc6-dev +vints,aspnetcore-runtime-7.0 +vpmc,openjdk-8-jre +vs +wet +wf +wmc,openjdk-8-jre +wurm,xvfb +zmr,libtinfo5:i386 +zps,libtinfo5:i386 diff --git a/lgsm/data/ubuntu-18.04.csv b/lgsm/data/ubuntu-18.04.csv new file mode 100644 index 0000000..c890739 --- /dev/null +++ b/lgsm/data/ubuntu-18.04.csv @@ -0,0 +1,136 @@ +all,bc,binutils,bsdmainutils,bzip2,ca-certificates,cpio,curl,distro-info,file,gzip,hostname,jq,lib32gcc1,lib32stdc++6,netcat,python3,tar,tmux,unzip,util-linux,uuid-runtime,wget,xz-utils +steamcmd,lib32gcc1,lib32stdc++6,libsdl2-2.0-0:i386,steamcmd +ac +ahl +ahl2 +ark +arma3 +armar,libcurl4 +ats +av +bb +bb2,libcurl4-gnutls-dev:i386 +bd +bf1942,libncurses5:i386,libtinfo5:i386 +bfv,libncurses5:i386,libstdc++5:i386 +bmdm,libncurses5:i386 +bo +bs +bt,libicu-dev,dos2unix,libxml2-utils +btl +cc +cd +ck,xvfb,libxi6 +cmw +cod,libstdc++5:i386 +cod2,libstdc++5:i386 +cod4 +coduo,libstdc++5:i386 +codwaw +col +cs +cs2 +cscz +csgo +css,libtinfo5:i386 +ct +dab +dayz +dmc +dod +dodr +dods +doi +dst,libcurl4-gnutls-dev:i386 +dys +eco,libgdiplus +em +etl +ets2 +fctr +fof +gmod,libtinfo5:i386 +hcu +hl2dm +hldm +hldms +hw,lib32z1 +ins +inss +ios +jc2 +jc3 +jk2 +kf +kf2 +l4d +l4d2 +mc,openjdk-11-jre +mcb +mh +mohaa,libstdc++5:i386 +mom +mta,libncursesw5,libxml2-utils +nd +nec +nmrih,libtinfo5:i386 +ns +ns2,speex,libtbb2 +ns2c,speex:i386,libtbb2 +ohd +onset,libmariadb-dev +opfor +pc +pc2 +pmc,openjdk-11-jre +ps,libgconf-2-4 +pvkii +pvr,libc++1 +pz,openjdk-11-jre,rng-tools +q2 +q3 +ql +qw +ricochet +ro +rtcw +rust,lib32z1 +rw,openjdk-11-jre +samp +sb +sbots +scpsl,mono-complete +scpslsm,mono-complete +sdtd,telnet,expect,libxml2-utils +sf +sfc,libtinfo5:i386 +sof2 +sol +squad +st,libxml2-utils +stn +sven,libssl1.1:i386,zlib1g:i386 +terraria +tf +tf2,libcurl4-gnutls-dev:i386 +tfc +ti +ts +ts3 +tu +tw +unt +ut +ut2k4 +ut3 +ut99 +vh,libc6-dev +vints,aspnetcore-runtime-7.0 +vpmc,openjdk-11-jre +vs +wet +wf +wmc,openjdk-11-jre +wurm,xvfb +zmr,libtinfo5:i386 +zps,libtinfo5:i386 diff --git a/lgsm/data/ubuntu-20.04.csv b/lgsm/data/ubuntu-20.04.csv new file mode 100644 index 0000000..e66eb7d --- /dev/null +++ b/lgsm/data/ubuntu-20.04.csv @@ -0,0 +1,136 @@ +all,bc,binutils,bsdmainutils,bzip2,ca-certificates,cpio,curl,distro-info,file,gzip,hostname,jq,lib32gcc1,lib32stdc++6,netcat,python3,tar,tmux,unzip,util-linux,uuid-runtime,wget,xz-utils +steamcmd,lib32gcc1,lib32stdc++6,libsdl2-2.0-0:i386,steamcmd +ac +ahl +ahl2 +ark +arma3 +armar,libcurl4 +ats +av +bb +bb2,libcurl4-gnutls-dev:i386 +bd +bf1942,libncurses5:i386,libtinfo5:i386 +bfv,libncurses5:i386,libstdc++5:i386 +bmdm,libncurses5:i386 +bo +bs +bt,libicu-dev,dos2unix,libxml2-utils +btl +cc +cd +ck,xvfb,libxi6 +cmw +cod,libstdc++5:i386 +cod2,libstdc++5:i386 +cod4 +coduo,libstdc++5:i386 +codwaw +col +cs +cs2 +cscz +csgo +css,libtinfo5:i386 +ct +dab +dayz +dmc +dod +dodr +dods +doi +dst,libcurl4-gnutls-dev:i386 +dys +eco,libgdiplus +em +etl +ets2 +fctr +fof +gmod,libtinfo5:i386 +hcu +hl2dm +hldm +hldms +hw,lib32z1 +ins +inss +ios +jc2 +jc3 +jk2 +kf +kf2 +l4d +l4d2 +mc,openjdk-17-jre +mcb +mh +mohaa,libstdc++5:i386 +mom +mta,libncursesw5,libxml2-utils +nd +nec +nmrih,libtinfo5:i386 +ns +ns2,speex,libtbb2 +ns2c,speex:i386,libtbb2 +ohd +onset,libmariadb-dev +opfor +pc +pc2 +pmc,openjdk-17-jre +ps,libgconf-2-4 +pvkii +pvr,libc++1 +pz,openjdk-17-jre,rng-tools +q2 +q3 +ql +qw +ricochet +ro +rtcw +rust,lib32z1 +rw,openjdk-17-jre +samp +sb +sbots +scpsl,mono-complete +scpslsm,mono-complete +sdtd,telnet,expect,libxml2-utils +sf +sfc,libtinfo5:i386 +sof2 +sol +squad +st,libxml2-utils +stn +sven,libssl1.1:i386,zlib1g:i386 +terraria +tf +tf2,libcurl4-gnutls-dev:i386 +tfc +ti +ts +ts3 +tu +tw +unt +ut +ut2k4 +ut3 +ut99 +vh,libc6-dev +vints,aspnetcore-runtime-7.0 +vpmc,openjdk-11-jre +vs +wet +wf +wmc,openjdk-17-jre +wurm,xvfb +zmr,libtinfo5:i386 +zps,libtinfo5:i386 diff --git a/lgsm/data/ubuntu-22.04.csv b/lgsm/data/ubuntu-22.04.csv new file mode 100644 index 0000000..ffc637a --- /dev/null +++ b/lgsm/data/ubuntu-22.04.csv @@ -0,0 +1,136 @@ +all,bc,binutils,bsdmainutils,bzip2,ca-certificates,cpio,curl,distro-info,file,gzip,hostname,jq,lib32gcc-s1,lib32stdc++6,netcat,python3,tar,tmux,unzip,util-linux,uuid-runtime,wget,xz-utils +steamcmd,lib32gcc-s1,lib32stdc++6,libsdl2-2.0-0:i386,steamcmd +ac +ahl +ahl2 +ark +arma3 +armar,libcurl4 +ats +av +bb +bb2,libcurl4-gnutls-dev:i386 +bd +bf1942,libncurses5:i386,libtinfo5:i386 +bfv,libncurses5:i386,libstdc++5:i386 +bmdm,libncurses5:i386 +bo +bs +bt,libicu-dev,dos2unix,libxml2-utils +btl +cc +cd +ck,xvfb,libxi6 +cmw +cod,libstdc++5:i386 +cod2,libstdc++5:i386 +cod4 +coduo,libstdc++5:i386 +codwaw +col +cs +cs2 +cscz +csgo +css,libtinfo5:i386 +ct +dab +dayz +dmc +dod +dodr +dods +doi +dst,libcurl4-gnutls-dev:i386 +dys +eco,libgdiplus +em +etl +ets2 +fctr +fof +gmod,libtinfo5:i386 +hcu +hl2dm +hldm +hldms +hw,lib32z1 +ins +inss +ios +jc2 +jc3 +jk2 +kf +kf2 +l4d +l4d2 +mc,openjdk-17-jre +mcb +mh +mohaa,libstdc++5:i386 +mom +mta,libncursesw5,libxml2-utils +nd +nec +nmrih,libtinfo5:i386 +ns +ns2,speex,libtbb2 +ns2c,speex:i386,libtbb2 +ohd +onset,libmariadb-dev +opfor +pc +pc2 +pmc,openjdk-17-jre +ps,libgconf-2-4 +pvkii +pvr,libc++1 +pz,openjdk-17-jre,rng-tools5 +q2 +q3 +ql +qw +ricochet +ro +rtcw +rust,lib32z1 +rw,openjdk-17-jre +samp +sb +sbots +scpsl,mono-complete +scpslsm,mono-complete +sdtd,telnet,expect,libxml2-utils +sf +sfc,libtinfo5:i386 +sof2 +sol +squad +st,libxml2-utils +stn +sven,libssl1.1:i386,zlib1g:i386 +terraria +tf +tf2,libcurl4-gnutls-dev:i386 +tfc +ti +ts +ts3 +tu +tw +unt +ut +ut2k4 +ut3 +ut99 +vh,libc6-dev +vints,aspnetcore-runtime-7.0 +vpmc,openjdk-17-jre +vs +wet +wf +wmc,openjdk-17-jre +wurm,xvfb +zmr,libtinfo5:i386 +zps,libtinfo5:i386 diff --git a/lgsm/data/ubuntu-23.04.csv b/lgsm/data/ubuntu-23.04.csv new file mode 100644 index 0000000..65e17bf --- /dev/null +++ b/lgsm/data/ubuntu-23.04.csv @@ -0,0 +1,136 @@ +all,bc,binutils,bsdmainutils,bzip2,ca-certificates,cpio,curl,distro-info,file,gzip,hostname,jq,lib32gcc-s1,lib32stdc++6,netcat-openbsd,python3,tar,tmux,unzip,util-linux,uuid-runtime,wget,xz-utils +steamcmd,lib32gcc-s1,lib32stdc++6,libsdl2-2.0-0:i386,steamcmd +ac +ahl +ahl2 +ark +arma3 +armar,libcurl4 +ats +av +bb +bb2,libcurl4-gnutls-dev:i386 +bd +bf1942,libncurses5:i386,libtinfo5:i386 +bfv,libncurses5:i386,libstdc++5:i386 +bmdm,libncurses5:i386 +bo +bs +bt,libicu-dev,dos2unix,libxml2-utils +btl +cc +cd +ck,xvfb,libxi6 +cmw +cod,libstdc++5:i386 +cod2,libstdc++5:i386 +cod4 +coduo,libstdc++5:i386 +codwaw +col +cs +cs2 +cscz +csgo +css,libtinfo5:i386 +ct +dab +dayz +dmc +dod +dodr +dods +doi +dst,libcurl4-gnutls-dev:i386 +dys +eco,libgdiplus +em +etl +ets2 +fctr +fof +gmod,libtinfo5:i386 +hcu +hl2dm +hldm +hldms +hw,lib32z1 +ins +inss +ios +jc2 +jc3 +jk2 +kf +kf2 +l4d +l4d2 +mc,openjdk-17-jre +mcb +mh +mohaa,libstdc++5:i386 +mom +mta,libncursesw5,libxml2-utils +nd +nec +nmrih,libtinfo5:i386 +ns +ns2,speex,libtbb2 +ns2c,speex:i386,libtbb2 +ohd +onset,libmariadb-dev +opfor +pc +pc2 +pmc,openjdk-17-jre +ps,libgconf-2-4 +pvkii +pvr,libc++1 +pz,openjdk-17-jre,rng-tools5 +q2 +q3 +ql +qw +ricochet +ro +rtcw +rust,lib32z1 +rw,openjdk-17-jre +samp +sb +sbots +scpsl,mono-complete +scpslsm,mono-complete +sdtd,telnet,expect,libxml2-utils +sf +sfc,libtinfo5:i386 +sof2 +sol +squad +st,libxml2-utils +stn +sven,libssl1.1:i386,zlib1g:i386 +terraria +tf +tf2,libcurl4-gnutls-dev:i386 +tfc +ti +ts +ts3 +tu +tw +unt +ut +ut2k4 +ut3 +ut99 +vh,libc6-dev +vints,aspnetcore-runtime-7.0 +vpmc,openjdk-17-jre +vs +wet +wf +wmc,openjdk-17-jre +wurm,xvfb +zmr,libtinfo5:i386 +zps,libtinfo5:i386 diff --git a/lgsm/data/ubuntu-23.10.csv b/lgsm/data/ubuntu-23.10.csv new file mode 100644 index 0000000..65e17bf --- /dev/null +++ b/lgsm/data/ubuntu-23.10.csv @@ -0,0 +1,136 @@ +all,bc,binutils,bsdmainutils,bzip2,ca-certificates,cpio,curl,distro-info,file,gzip,hostname,jq,lib32gcc-s1,lib32stdc++6,netcat-openbsd,python3,tar,tmux,unzip,util-linux,uuid-runtime,wget,xz-utils +steamcmd,lib32gcc-s1,lib32stdc++6,libsdl2-2.0-0:i386,steamcmd +ac +ahl +ahl2 +ark +arma3 +armar,libcurl4 +ats +av +bb +bb2,libcurl4-gnutls-dev:i386 +bd +bf1942,libncurses5:i386,libtinfo5:i386 +bfv,libncurses5:i386,libstdc++5:i386 +bmdm,libncurses5:i386 +bo +bs +bt,libicu-dev,dos2unix,libxml2-utils +btl +cc +cd +ck,xvfb,libxi6 +cmw +cod,libstdc++5:i386 +cod2,libstdc++5:i386 +cod4 +coduo,libstdc++5:i386 +codwaw +col +cs +cs2 +cscz +csgo +css,libtinfo5:i386 +ct +dab +dayz +dmc +dod +dodr +dods +doi +dst,libcurl4-gnutls-dev:i386 +dys +eco,libgdiplus +em +etl +ets2 +fctr +fof +gmod,libtinfo5:i386 +hcu +hl2dm +hldm +hldms +hw,lib32z1 +ins +inss +ios +jc2 +jc3 +jk2 +kf +kf2 +l4d +l4d2 +mc,openjdk-17-jre +mcb +mh +mohaa,libstdc++5:i386 +mom +mta,libncursesw5,libxml2-utils +nd +nec +nmrih,libtinfo5:i386 +ns +ns2,speex,libtbb2 +ns2c,speex:i386,libtbb2 +ohd +onset,libmariadb-dev +opfor +pc +pc2 +pmc,openjdk-17-jre +ps,libgconf-2-4 +pvkii +pvr,libc++1 +pz,openjdk-17-jre,rng-tools5 +q2 +q3 +ql +qw +ricochet +ro +rtcw +rust,lib32z1 +rw,openjdk-17-jre +samp +sb +sbots +scpsl,mono-complete +scpslsm,mono-complete +sdtd,telnet,expect,libxml2-utils +sf +sfc,libtinfo5:i386 +sof2 +sol +squad +st,libxml2-utils +stn +sven,libssl1.1:i386,zlib1g:i386 +terraria +tf +tf2,libcurl4-gnutls-dev:i386 +tfc +ti +ts +ts3 +tu +tw +unt +ut +ut2k4 +ut3 +ut99 +vh,libc6-dev +vints,aspnetcore-runtime-7.0 +vpmc,openjdk-17-jre +vs +wet +wf +wmc,openjdk-17-jre +wurm,xvfb +zmr,libtinfo5:i386 +zps,libtinfo5:i386 diff --git a/lgsm/modules/README.md b/lgsm/modules/README.md new file mode 100644 index 0000000..de008ec --- /dev/null +++ b/lgsm/modules/README.md @@ -0,0 +1,17 @@ +# LinuxGSM - Modules + +These modules are scripts that are called upon by the primary script linuxgsm.sh + +## Module Names + +Modules have been named to give an idea of what the function does. + +- core: Essential modules that will always run first. +- command: Primary command function. +- check: Runs checks that will either halt on or fix an issue. +- dev: development modules. +- fix: Applies a game server specific fix. +- info: retrieves information from a source such as config file or the OS. +- install: modules related to the installer. +- monitor: modules related to monitor. +- update: modules that update the game server. diff --git a/lgsm/modules/alert.sh b/lgsm/modules/alert.sh new file mode 100644 index 0000000..e885a74 --- /dev/null +++ b/lgsm/modules/alert.sh @@ -0,0 +1,359 @@ +#!/bin/bash +# LinuxGSM alert.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Overall module for managing alerts. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Generates alert log of the details at the time of the alert. +# Used with email alerts. +fn_alert_log() { + info_distro.sh + info_game.sh + info_messages.sh + if [ -f "${alertlog}" ]; then + rm -f "${alertlog:?}" + fi + + { + fn_info_messages_head + fn_info_messages_distro + fn_info_messages_server_resource + fn_info_messages_gameserver_resource + fn_info_messages_gameserver + fn_info_logs + } | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" | tee -a "${alertlog}" > /dev/null 2>&1 +} + +fn_alert_test() { + fn_script_log_info "Sending alert: Testing LinuxGSM Alert. No action to be taken" + alertaction="Tested" + alertemoji="🚧" + alertsound="1" + alertmessage="Testing ${selfname} LinuxGSM Alert. No action to be taken." + # Green + alertcolourhex="#cdcd00" + alertcolourdec="13487360" +} + +# Running command manually +fn_alert_stopped() { + fn_script_log_info "Sending alert: ${selfname} has stopped" + alertaction="Stopped" + alertemoji="❌" + alertsound="1" + alertmessage="${selfname} has been stopped." + # Red + alertcolourhex="#cd0000" + alertcolourdec="13434880" +} + +fn_alert_started() { + fn_script_log_info "Sending alert: ${selfname} has started" + alertaction="Started" + alertemoji="✔️" + alertsound="1" + alertmessage="${selfname} has been started." + # Green + alertcolourhex="#00cd00" + alertcolourdec="52480" +} + +fn_alert_restarted() { + fn_script_log_info "Sending alert: ${selfname} has restarted" + alertaction="Restarted" + alertemoji="🗘" + alertsound="1" + alertmessage="${selfname} has been restarted." + # Green + alertcolourhex="#00cd00" + alertcolourdec="52480" +} + +# Failed monitor checks +fn_alert_monitor_session() { + fn_script_log_info "Sending alert: ${selfname} is not running. Game server has been restarted" + alertaction="Restarted" + alertemoji="🚨" + alertsound="2" + alertmessage="${selfname} is not running. Game server has been restarted." + # Red + alertcolourhex="#cd0000" + alertcolourdec="13434880" +} + +fn_alert_monitor_query() { + fn_script_log_info "Sending alert: Unable to query ${selfname}. Game server has been restarted" + alertaction="Restarted" + alertemoji="🚨" + alertsound="2" + alertmessage="Unable to query ${selfname}. Game server has been restarted." + # Red + alertcolourhex="#cd0000" + alertcolourdec="13434880" +} + +# Update alerts +fn_alert_update() { + fn_script_log_info "Sending alert: ${selfname} has received a game server update: ${localbuild}" + alertaction="Updated" + alertemoji="🎉" + alertsound="1" + alertmessage="${selfname} has received a game server update: ${localbuild}." + # Green + alertcolourhex="#00cd00" + alertcolourdec="52480" +} + +fn_alert_update_request() { + fn_script_log_info "Sending alert: ${selfname} has requested an update and needs to be restarted." + alertaction="Updating" + alertemoji="🎉" + alertsound="1" + alertmessage="${selfname} has requested an update and needs to be restarted." + # Blue + alertcolourhex="#1e90ff" + alertcolourdec="2003199" +} + +fn_alert_check_update() { + fn_script_log_info "Sending alert: ${gamename} update available: ${remotebuildversion}" + alertaction="Update available" + alertemoji="🎉" + alertsound="1" + alertmessage="${gamename} update available: ${remotebuildversion}" + # Blue + alertcolourhex="#1e90ff" + alertcolourdec="2003199" +} + +fn_alert_update_linuxgsm() { + fn_script_log_info "Sending alert: ${selfname} has received an LinuxGSM update" + alertaction="Updated" + alertemoji="🎉" + alertsound="1" + alertbody="${gamename} update available" + alertmessage="${selfname} has received an LinuxGSM update and been restarted." + # Green + alertcolourhex="#00cd00" + alertcolourdec="52480" +} + +fn_alert_backup() { + fn_script_log_info "Sending alert: ${selfname} has been backed up" + alertaction="Backed Up" + alertemoji="📂" + alertsound="1" + alertmessage="${selfname} has been backed up." + # Green + alertcolourhex="#00cd00" + alertcolourdec="52480" +} + +fn_alert_permissions() { + fn_script_log_info "Sending alert: ${selfname} has permissions issues" + alertaction="Checked Permissions" + alertemoji="❗" + alertsound="2" + alertmessage="${selfname} has permissions issues." + # Red + alertcolourhex="#cd0000" + alertcolourdec="13434880" +} + +fn_alert_config() { + fn_script_log_info "Sending alert: ${selfname} has received a new _default.cfg" + alertaction="Updated _default.cfg" + alertemoji="🎉" + alertsound="1" + alertmessage="${selfname} has received a new _default.cfg." + # Blue + alertcolourhex="#1e90ff" + alertcolourdec="2003199" +} + +fn_alert_wipe() { + fn_script_log_info "Sending alert: ${selfname} has been wiped" + alertaction="Wiped" + alertemoji="🧹" + alertsound="1" + alertmessage="${selfname} has been wiped." + # Green + alertcolourhex="#00cd00" + alertcolourdec="52480" +} + +fn_alert_info() { + fn_script_log_info "Sending alert: ${selfname} info" + alerttitle="LinuxGSM Alert - ${selfname} - Info" + alertaction="Queried" + alertemoji="📄" + alertsound="1" + alertmessage="${selfname} info." + # Blue + alertcolourhex="#1e90ff" + alertcolourdec="2003199" +} + +# Images +alerticon="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/data/gameicons/${shortname}-icon.png" + +if [ "${alert}" == "permissions" ]; then + fn_alert_permissions +elif [ "${alert}" == "monitor-session" ]; then + fn_alert_monitor_session +elif [ "${alert}" == "monitor-query" ]; then + fn_alert_monitor_query +elif [ "${alert}" == "test" ]; then + fn_alert_test +elif [ "${alert}" == "update" ]; then + fn_alert_update +elif [ "${alert}" == "update-request" ]; then + fn_alert_update_request +elif [ "${alert}" == "check-update" ]; then + fn_alert_check_update +elif [ "${alert}" == "config" ]; then + fn_alert_config +elif [ "${alert}" == "wipe" ]; then + fn_alert_wipe +elif [ "${alert}" == "info" ]; then + fn_alert_info +elif [ "${alert}" == "started" ]; then + fn_alert_started +elif [ "${alert}" == "stopped" ]; then + fn_alert_stopped +elif [ "${alert}" == "restarted" ]; then + fn_alert_restarted +elif [ "${alert}" == "update-linuxgsm" ]; then + fn_alert_update_linuxgsm +elif [ "${alert}" == "backup" ]; then + fn_alert_backup +else + fn_print_fail_nl "Missing alert type" + fn_script_log_fail "Missing alert type" + core_exit.sh +fi + +alerttitle="${alertemoji} ${alertaction} - ${servername} ${alertemoji}" + +# Generate alert log. +fn_alert_log + +# Generates the more info link. +if [ "${postalert}" == "on" ] && [ -n "${postalert}" ]; then + exitbypass=1 + command_postdetails.sh + fn_firstcommand_reset + unset exitbypass +elif [ "${postalert}" != "on" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_warn_nl "More Info not enabled" + fn_script_log_warn "More Info alerts not enabled" +fi + +if [ "${discordalert}" == "on" ] && [ -n "${discordalert}" ]; then + alert_discord.sh +elif [ "${discordalert}" != "on" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_warn_nl "Discord alerts not enabled" + fn_script_log_warn "Discord alerts not enabled" +elif [ -z "${discordtoken}" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_error_nl "Discord token not set" + echo -e "* https://docs.linuxgsm.com/alerts/discord" + fn_script_error "Discord token not set" +fi + +if [ "${emailalert}" == "on" ] && [ -n "${email}" ]; then + alert_email.sh +elif [ "${emailalert}" != "on" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_warn_nl "Email alerts not enabled" + fn_script_log_warn "Email alerts not enabled" +elif [ -z "${email}" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_error_nl "Email not set" + fn_script_log_error "Email not set" +fi + +if [ "${gotifyalert}" == "on" ] && [ -n "${gotifyalert}" ]; then + alert_gotify.sh +elif [ "${gotifyalert}" != "on" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_warn_nl "Gotify alerts not enabled" + fn_script_log_warn "Gotify alerts not enabled" +elif [ -z "${gotifytoken}" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_error_nl "Gotify token not set" + echo -e "* https://docs.linuxgsm.com/alerts/gotify" + fn_script_error "Gotify token not set" +elif [ -z "${gotifywebhook}" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_error_nl "Gotify webhook not set" + echo -e "* https://docs.linuxgsm.com/alerts/gotify" + fn_script_error "Gotify webhook not set" +fi + +if [ "${iftttalert}" == "on" ] && [ -n "${iftttalert}" ]; then + alert_ifttt.sh +elif [ "${iftttalert}" != "on" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_warn_nl "IFTTT alerts not enabled" + fn_script_log_warn "IFTTT alerts not enabled" +elif [ -z "${ifttttoken}" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_error_nl "IFTTT token not set" + echo -e "* https://docs.linuxgsm.com/alerts/ifttt" + fn_script_error "IFTTT token not set" +fi + +if [ "${pushbulletalert}" == "on" ] && [ -n "${pushbullettoken}" ]; then + alert_pushbullet.sh +elif [ "${pushbulletalert}" != "on" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_warn_nl "Pushbullet alerts not enabled" + fn_script_log_warn "Pushbullet alerts not enabled" +elif [ -z "${pushbullettoken}" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_error_nl "Pushbullet token not set" + echo -e "* https://docs.linuxgsm.com/alerts/pushbullet" + fn_script_error "Pushbullet token not set" +fi + +if [ "${pushoveralert}" == "on" ] && [ -n "${pushoveralert}" ]; then + alert_pushover.sh +elif [ "${pushoveralert}" != "on" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_warn_nl "Pushover alerts not enabled" + fn_script_log_warn "Pushover alerts not enabled" +elif [ -z "${pushovertoken}" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_error_nl "Pushover token not set" + echo -e "* https://docs.linuxgsm.com/alerts/pushover" + fn_script_error "Pushover token not set" +fi + +if [ "${telegramalert}" == "on" ] && [ -n "${telegramtoken}" ]; then + alert_telegram.sh +elif [ "${telegramalert}" != "on" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_warn_nl "Telegram Messages not enabled" + fn_script_log_warn "Telegram Messages not enabled" +elif [ -z "${telegramtoken}" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_error_nl "Telegram token not set." + echo -e "* https://docs.linuxgsm.com/alerts/telegram" + fn_script_error "Telegram token not set." +elif [ -z "${telegramchatid}" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_error_nl "Telegram chat id not set." + echo -e "* https://docs.linuxgsm.com/alerts/telegram" + fn_script_error "Telegram chat id not set." +fi + +if [ "${rocketchatalert}" == "on" ] && [ -n "${rocketchatalert}" ]; then + alert_rocketchat.sh +elif [ "${rocketchatalert}" != "on" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_warn_nl "Rocketchat alerts not enabled" + fn_script_log_warn "Rocketchat alerts not enabled" +elif [ -z "${rocketchatwebhook}" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_error_nl "Rocketchat token not set" + #echo -e "* https://docs.linuxgsm.com/alerts/slack" + fn_script_error "Rocketchat token not set" +fi + +if [ "${slackalert}" == "on" ] && [ -n "${slackalert}" ]; then + alert_slack.sh +elif [ "${slackalert}" != "on" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_warn_nl "Slack alerts not enabled" + fn_script_log_warn "Slack alerts not enabled" +elif [ -z "${slacktoken}" ] && [ "${commandname}" == "TEST-ALERT" ]; then + fn_print_error_nl "Slack token not set" + echo -e "* https://docs.linuxgsm.com/alerts/slack" + fn_script_error "Slack token not set" +fi diff --git a/lgsm/modules/alert_discord.sh b/lgsm/modules/alert_discord.sh new file mode 100644 index 0000000..0afb9db --- /dev/null +++ b/lgsm/modules/alert_discord.sh @@ -0,0 +1,153 @@ +#!/bin/bash +# LinuxGSM alert_discord.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Sends Discord alert. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +jsoninfo=$( + cat << EOF +{ + "username": "LinuxGSM", + "avatar_url": "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/data/alert_discord_logo.jpg", + "file": "content", + "embeds": [ + { + "author": { + "name": "LinuxGSM Alert", + "url": "", + "icon_url": "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/data/alert_discord_logo.jpg" + }, + "title": "${alerttitle}", + "url": "", + "description": "", + "color": "${alertcolourdec}", + "type": "content", + "thumbnail": { + "url": "${alerticon}" + }, + "fields": [ + { + "name": "Server Name", + "value": "${servername}" + }, + { + "name": "Information", + "value": "${alertmessage}" + }, + { + "name": "Game", + "value": "${gamename}", + "inline": true + }, + { + "name": "Server IP", + "value": "\`${alertip}:${port}\`", + "inline": true + }, + { + "name": "Hostname", + "value": "${HOSTNAME}", + "inline": true + }, + { + "name": "More info", + "value": "${alerturl}", + "inline": true + }, + { + "name": "Server Time", + "value": "$(date)", + "inline": true + } + ], + "footer": { + "icon_url": "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/data/alert_discord_logo.jpg", + "text": "Sent by LinuxGSM ${version}" + } + } + ] +} +EOF +) + +jsonnoinfo=$( + cat << EOF +{ + "username": "LinuxGSM", + "avatar_url": "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/data/alert_discord_logo.jpg", + "file": "content", + "embeds": [ + { + "author": { + "name": "LinuxGSM Alert", + "url": "", + "icon_url": "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/data/alert_discord_logo.jpg" + }, + "title": "${alerttitle}", + "url": "", + "description": "", + "color": "${alertcolourdec}", + "type": "content", + "thumbnail": { + "url": "${alerticon}" + }, + "fields": [ + { + "name": "Server Name", + "value": "${servername}" + }, + { + "name": "Information", + "value": "${alertmessage}" + }, + { + "name": "Game", + "value": "${gamename}", + "inline": true + }, + { + "name": "Server IP", + "value": "\`${alertip}:${port}\`", + "inline": true + }, + { + "name": "Hostname", + "value": "${HOSTNAME}", + "inline": true + }, + { + "name": "Server Time", + "value": "$(date)", + "inline": true + } + ], + "footer": { + "icon_url": "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/data/alert_discord_logo.jpg", + "text": "Sent by LinuxGSM ${version}" + } + } + ] +} +EOF +) + +fn_print_dots "Sending Discord alert" + +if [ -z "${alerturl}" ]; then + json="${jsonnoinfo}" +else + json="${jsoninfo}" +fi + +discordsend=$(curl --connect-timeout 10 -sSL -H "Content-Type: application/json" -X POST -d "$(echo -n "${json}" | jq -c .)" "${discordwebhook}") + +if [ -n "${discordsend}" ]; then + fn_print_fail_nl "Sending Discord alert: ${discordsend}" + fn_script_log_fail "Sending Discord alert: ${discordsend}" +else + fn_print_ok_nl "Sending Discord alert" + fn_script_log_pass "Sending Discord alert" +fi diff --git a/lgsm/modules/alert_email.sh b/lgsm/modules/alert_email.sh new file mode 100644 index 0000000..6833d96 --- /dev/null +++ b/lgsm/modules/alert_email.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# LinuxGSM alert_email.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Sends email alert. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_print_dots "Sending Email alert: ${email}" + +if [ -n "${emailfrom}" ]; then + mail -s "${alerttitle}" -r "${emailfrom}" "${email}" < "${alertlog}" +else + mail -s "${alerttitle}" "${email}" < "${alertlog}" +fi +exitcode=$? +if [ "${exitcode}" == "0" ]; then + fn_print_ok_nl "Sending Email alert: ${email}" + fn_script_log_pass "Sending Email alert: ${email}" +else + fn_print_fail_nl "Sending Email alert: ${email}" + fn_script_log_fail "Sending Email alert: ${email}" +fi diff --git a/lgsm/modules/alert_gotify.sh b/lgsm/modules/alert_gotify.sh new file mode 100644 index 0000000..2ab6e9e --- /dev/null +++ b/lgsm/modules/alert_gotify.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# LinuxGSM alert_gotify.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Sends Gotify alert. + +module_selfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +jsoninfo=$( + cat << EOF +{ + "title": "${alerttitle}", + "message": "Server Name\n${servername}\n\nInformation\n${alertmessage}\n\nGame\n${gamename}\n\nServer IP\n${alertip}:${port}\n\nHostname\n${HOSTNAME}\n\nMore info\n${alerturl}\n\nServer Time\n$(date)", + "priority": 5 +} +EOF +) + +jsonnoinfo=$( + cat << EOF +{ + "title": "${alerttitle}", + "message": "Server Name\n${servername}\n\nInformation\n${alertmessage}\n\nGame\n${gamename}\n\nServer IP\n${alertip}:${port}\n\nHostname\n${HOSTNAME}\n\nServer Time\n$(date)", + "priority": 5 +} +EOF +) + +if [ -z "${alerturl}" ]; then + json="${jsonnoinfo}" +else + json="${jsoninfo}" +fi + +fn_print_dots "Sending Gotify alert" +gotifysend=$(curl --connect-timeout 10 -sSL "${gotifywebhook}/message"?token="${gotifytoken}" -H "Content-Type: application/json" -X POST -d "$(echo -n "${json}" | jq -c .)") + +if [ -n "${gotifysend}" ]; then + fn_print_ok_nl "Sending Gotify alert" + fn_script_log_pass "Sending Gotify alert" +else + fn_print_fail_nl "Sending Gotify alert: ${gotifysend}" + fn_script_log_fail "Sending Gotify alert: ${gotifysend}" +fi diff --git a/lgsm/modules/alert_ifttt.sh b/lgsm/modules/alert_ifttt.sh new file mode 100644 index 0000000..7793256 --- /dev/null +++ b/lgsm/modules/alert_ifttt.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# LinuxGSM alert_ifttt.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Sends IFTTT alert. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +jsoninfo=$( + cat << EOF +{ + "value1": "${selfname}", + "value2": "${alerttitle}", + "value3": "Server Name\n${servername}\n\nInformation\n${alertmessage}\n\nGame\n${gamename}\n\nServer IP\n${alertip}:${port}\n\nHostname\n${HOSTNAME}\n\nMore info\n${alerturl}\n\nServer Time\n$(date)" +} +EOF +) + +jsonnoinfo=$( + cat << EOF +{ + "value1": "${selfname}", + "value2": "${alerttitle}", + "value3": "Server Name\n${servername}\n\nInformation\n${alertmessage}\n\nGame\n${gamename}\n\nServer IP\n${alertip}:${port}\n\nHostname\n${HOSTNAME}\n\nServer Time\n$(date)" +} +EOF +) + +if [ -z "${alerturl}" ]; then + json="${jsonnoinfo}" +else + json="${jsoninfo}" +fi + +fn_print_dots "Sending IFTTT alert" +iftttsend=$(curl --connect-timeout 10 -sSL -H "Content-Type: application/json" -X POST -d "$(echo -n "${json}" | jq -c .)" "https://maker.ifttt.com/trigger/${iftttevent}/with/key/${ifttttoken}" | grep "Bad Request") + +if [ -n "${iftttsend}" ]; then + fn_print_fail_nl "Sending IFTTT alert: ${pushbulletsend}" + fn_script_log_fail "Sending IFTTT alert: ${pushbulletsend}" +else + fn_print_ok_nl "Sending IFTTT alert" + fn_script_log_pass "Sent IFTTT alert" +fi diff --git a/lgsm/modules/alert_pushbullet.sh b/lgsm/modules/alert_pushbullet.sh new file mode 100644 index 0000000..dedd432 --- /dev/null +++ b/lgsm/modules/alert_pushbullet.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# LinuxGSM alert_pushbullet.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Sends Pushbullet Messenger alert. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +jsoninfo=$( + cat << EOF +{ + "channel_tag": "${channeltag}", + "type": "note", + "title": "${alerttitle}", + "body": "Server Name\n${servername}\n\nInformation\n${alertmessage}\n\nGame\n${gamename}\n\nServer IP\n${alertip}:${port}\n\nHostname\n${HOSTNAME}\n\nMore info\n${alerturl}\n\nServer Time\n$(date)" +} +EOF +) + +jsonnoinfo=$( + cat << EOF +{ + "channel_tag": "${channeltag}", + "type": "note", + "title": "${alerttitle}", + "body": "Server Name\n${servername}\n\nInformation\n${alertmessage}\n\nGame\n${gamename}\n\nServer IP\n${alertip}:${port}\n\nHostname\n${HOSTNAME}\n\nServer Time\n$(date)" +} +EOF +) + +if [ -z "${alerturl}" ]; then + json="${jsonnoinfo}" +else + json="${jsoninfo}" +fi + +fn_print_dots "Sending Pushbullet alert" +pushbulletsend=$(curl --connect-timeout 10 -sSL -H "Access-Token: ${pushbullettoken}" -H "Content-Type: application/json" -X POST -d "$(echo -n "${json}" | jq -c .)" "https://api.pushbullet.com/v2/pushes" | grep "error_code") + +if [ -n "${pushbulletsend}" ]; then + fn_print_fail_nl "Sending Pushbullet alert: ${pushbulletsend}" + fn_script_log_fail "Sending Pushbullet alert: ${pushbulletsend}" +else + fn_print_ok_nl "Sending Pushbullet alert" + fn_script_log_pass "Sent Pushbullet alert" +fi diff --git a/lgsm/modules/alert_pushover.sh b/lgsm/modules/alert_pushover.sh new file mode 100644 index 0000000..c436a4a --- /dev/null +++ b/lgsm/modules/alert_pushover.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# LinuxGSM alert_pushover.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Sends Pushover alert. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_print_dots "Sending Pushover alert" + +# Different alerts are given different priorities and notification sounds. +if [ "${alertsound}" == "1" ]; then + alertsound="" + alertpriority="0" +elif [ "${alertsound}" == "2" ]; then + # restarted. + alertsound="siren" + alertpriority="1" +else + alertsound="" + alertpriority="0" +fi + +if [ -z "${alerturl}" ]; then + pushoversend=$(curl --connect-timeout 10 -sS -F token="${pushovertoken}" -F user="${pushoveruserkey}" -F html="1" -F sound="${alertsound}" -F priority="${alertpriority}" -F title="${alerttitle}" -F message=" Server name
${servername}

Information
${alertmessage}

Game
${gamename}

Server IP
${alertip}:${port}

Hostname
${HOSTNAME}

Server Time
$(date)" "https://api.pushover.net/1/messages.json" | grep errors) +else + pushoversend=$(curl --connect-timeout 10 -sS -F token="${pushovertoken}" -F user="${pushoveruserkey}" -F html="1" -F sound="${alertsound}" -F priority="${alertpriority}" -F title="${alerttitle}" -F message=" Server name
${servername}

Information
${alertmessage}

Game
${gamename}

Server IP
${alertip}:${port}

Hostname
${HOSTNAME}

More info
${alerturl}

Server Time
$(date)" "https://api.pushover.net/1/messages.json" | grep errors) +fi + +if [ -n "${pushoversend}" ]; then + fn_print_fail_nl "Sending Pushover alert: ${pushoversend}" + fn_script_log_fail "Sending Pushover alert: ${pushoversend}" +else + fn_print_ok_nl "Sending Pushover alert" + fn_script_log_pass "Sent Pushover alert" +fi diff --git a/lgsm/modules/alert_rocketchat.sh b/lgsm/modules/alert_rocketchat.sh new file mode 100644 index 0000000..f72e093 --- /dev/null +++ b/lgsm/modules/alert_rocketchat.sh @@ -0,0 +1,134 @@ +#!/bin/bash +# LinuxGSM alert_rocketchat.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Sends Rocketchat alert. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +jsoninfo=$( + cat << EOF +{ + "alias": "LinuxGSM", + "text": "*${alerttitle}*", + "attachments": [ + { + "title": "", + "color": "${alertcolourhex}", + "author_name": "LinuxGSM Alert", + "author_link": "https://linuxgsm.com", + "author_icon": "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/data/alert_discord_logo.jpg", + "thumb_url": "${alerticon}", + "text": "", + "fields": [ + { + "short": false, + "title": "Server Name", + "value": "${servername}" + }, + { + "short": false, + "title": "Information", + "value": "${alertmessage}" + }, + { + "short": false, + "title": "Game", + "value": "${gamename}" + }, + { + "short": false, + "title": "Server IP", + "value": "${alertip}:${port}" + }, + { + "short": false, + "title": "Hostname", + "value": "${HOSTNAME}" + }, + { + "short": false, + "title": "More info", + "value": "${alerturl}" + }, + { + "short": false, + "title": "Server Time", + "value": "$(date)" + } + ] + } + ] +} +EOF +) + +jsonnoinfo=$( + cat << EOF +{ + "alias": "LinuxGSM", + "text": "*${alerttitle}*", + "attachments": [ + { + "title": "", + "color": "${alertcolourhex}", + "author_name": "LinuxGSM Alert", + "author_link": "https://linuxgsm.com", + "author_icon": "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/data/alert_discord_logo.jpg", + "thumb_url": "${alerticon}", + "text": "", + "fields": [ + { + "short": false, + "title": "Server Name", + "value": "${servername}" + }, + { + "short": false, + "title": "Information", + "value": "${alertmessage}" + }, + { + "short": false, + "title": "Game", + "value": "${gamename}" + }, + { + "short": false, + "title": "Server IP", + "value": "${alertip}:${port}" + }, + { + "short": false, + "title": "Hostname", + "value": "${HOSTNAME}" + }, + { + "short": false, + "title": "Server Time", + "value": "$(date)" + } + ] + } + ] +} +EOF +) + +if [ -z "${alerturl}" ]; then + json="${jsonnoinfo}" +else + json="${jsoninfo}" +fi + +fn_print_dots "Sending Rocketchat alert" +rocketchatsend=$(curl --connect-timeout 10 -sSL -H "Content-Type: application/json" -X POST -d "$(echo -n "${json}" | jq -c .)" "${rocketchatwebhook}") + +if [ -n "${rocketchatsend}" ]; then + fn_print_ok_nl "Sending Rocketchat alert" + fn_script_log_pass "Sending Rocketchat alert" +else + fn_print_fail_nl "Sending Rocketchat alert: ${rocketchatsend}" + fn_script_log_fail "Sending Rocketchat alert: ${rocketchatsend}" +fi diff --git a/lgsm/modules/alert_slack.sh b/lgsm/modules/alert_slack.sh new file mode 100644 index 0000000..7dcdb31 --- /dev/null +++ b/lgsm/modules/alert_slack.sh @@ -0,0 +1,193 @@ +#!/bin/bash +# LinuxGSM alert_slack.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Sends Slack alert. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +jsonnoinfo=$( + cat << EOF +{ + "attachments": [ + { + "color": "${alertcolourhex}", + "blocks": [ + { + "type": "header", + "text": { + "type": "mrkdwn", + "text": "${alerttitle}", + "emoji": true + } + }, + { + "type": "divider" + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "*Server Name*\n${servername}" + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "*Information*\n${alertmessage}" + } + }, + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "*Game*\n${gamename}" + }, + { + "type": "mrkdwn", + "text": "*Server IP*\n\`${alertip}:${port}\`" + }, + { + "type": "mrkdwn", + "text": "*Hostname*\n${HOSTNAME}" + }, + { + "type": "mrkdwn", + "text": "*Server Time*\n$(date)" + } + ], + "accessory": { + "type": "image", + "image_url": "${alerticon}", + "alt_text": "cute cat" + } + }, + { + "type": "context", + "elements": [ + { + "type": "image", + "image_url": "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/data/alert_discord_logo.jpg", + "alt_text": "LinuxGSM icon" + }, + { + "type": "plain_text", + "text": "Sent by LinuxGSM ${version}", + "emoji": true + } + ] + } + ] + } + ] +} +EOF +) + +jsoninfo=$( + cat << EOF +{ + "attachments": [ + { + "color": "${alertcolourhex}", + "blocks": [ + { + "type": "header", + "text": { + "type": "mrkdwn", + "text": "${alerttitle}", + "emoji": true + } + }, + { + "type": "divider" + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "*Server Name*\n${servername}" + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "*Information*\n${alertmessage}" + } + }, + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "*Game*\n${gamename}" + }, + { + "type": "mrkdwn", + "text": "*Server IP*\n\`${alertip}:${port}\`" + }, + { + "type": "mrkdwn", + "text": "*Hostname*\n${HOSTNAME}" + }, + { + "type": "mrkdwn", + "text": "*Server Time*\n$(date)" + } + ], + "accessory": { + "type": "image", + "image_url": "${alerticon}", + "alt_text": "cute cat" + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "*Server Time*\n${alertmessage}" + } + }, + { + "type": "context", + "elements": [ + { + "type": "image", + "image_url": "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/data/alert_discord_logo.jpg", + "alt_text": "LinuxGSM icon" + }, + { + "type": "plain_text", + "text": "Sent by LinuxGSM ${version}", + "emoji": true + } + ] + } + ] + } + ] +} +EOF +) + +if [ -z "${alerturl}" ]; then + json="${jsonnoinfo}" +else + json="${jsoninfo}" +fi + +fn_print_dots "Sending Slack alert" + +slacksend=$(curl --connect-timeout 10 -sSL -H "Content-Type: application/json" -X POST -d "$(echo -n "${json}" | jq -c .)" "${slackwebhook}") + +if [ "${slacksend}" == "ok" ]; then + fn_print_ok_nl "Sending Slack alert" + fn_script_log_pass "Sending Slack alert" +else + fn_print_fail_nl "Sending Slack alert: ${slacksend}" + fn_script_log_fail "Sending Slack alert: ${slacksend}" +fi diff --git a/lgsm/modules/alert_telegram.sh b/lgsm/modules/alert_telegram.sh new file mode 100644 index 0000000..3b3ec99 --- /dev/null +++ b/lgsm/modules/alert_telegram.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# LinuxGSM alert_telegram.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Sends Telegram Messenger alert. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +jsoninfo=$( + cat << EOF +{ + "chat_id": "${telegramchatid}", + "parse_mode": "HTML", + "text": "${alerttitle}\n\nServer name\n${servername}\n\nInformation\n${alertmessage}\n\nGame\n${gamename}\n\nServer IP\n${alertip}:${port}\n\nHostname\n${HOSTNAME}\n\nMore info\n${alerturl}\n\nServer Time\n$(date)", + "disable_web_page_preview": "yes" +} +EOF +) + +jsonnoinfo=$( + cat << EOF +{ + "chat_id": "${telegramchatid}", + "parse_mode": "HTML", + "text": "${alerttitle}\n\nServer name\n${servername}\n\nInformation\n${alertmessage}\n\nGame\n${gamename}\n\nServer IP\n${alertip}:${port}\n\nHostname\n${HOSTNAME}\n\nServer Time\n$(date)", + "disable_web_page_preview": "yes" +} +EOF +) + +if [ -z "${alerturl}" ]; then + json="${jsonnoinfo}" +else + json="${jsoninfo}" +fi + +fn_print_dots "Sending Telegram alert" +telegramsend=$(curl --connect-timeout 10 -sSL -H "Content-Type: application/json" -X POST -d "$(echo -n "${json}" | jq -c .)" ${curlcustomstring} "https://${telegramapi}/bot${telegramtoken}/sendMessage" | grep "error_code") + +if [ -n "${telegramsend}" ]; then + fn_print_fail_nl "Sending Telegram alert: ${telegramsend}" + fn_script_log_fail "Sending Telegram alert: ${telegramsend}" +else + fn_print_ok_nl "Sending Telegram alert" + fn_script_log_pass "Sent Telegram alert" +fi diff --git a/lgsm/modules/check.sh b/lgsm/modules/check.sh new file mode 100644 index 0000000..1b8796e --- /dev/null +++ b/lgsm/modules/check.sh @@ -0,0 +1,101 @@ +#!/bin/bash +# LinuxGSM check.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Overall module for managing checks. +# Runs checks that will either halt on or fix an issue. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Every command that requires checks just references check.sh. +# check.sh selects which checks to run by using arrays. + +if [ "${commandname}" != "INSTALL" ]; then + check_root.sh +fi + +if [ "${commandname}" != "UPDATE-LGSM" ]; then + check_version.sh +fi + +check_tmuxception.sh + +if [ "$(whoami)" != "root" ]; then + if [ "${commandname}" != "MONITOR" ]; then + check_permissions.sh + fi +fi + +if [ "${commandname}" != "INSTALL" ] && [ "${commandname}" != "UPDATE-LGSM" ] && [ "${commandname}" != "DETAILS" ] && [ "${commandname}" != "POST-DETAILS" ]; then + check_system_dir.sh +fi + +allowed_commands_array=(START DEBUG) +for allowed_command in "${allowed_commands_array[@]}"; do + if [ "${allowed_command}" == "${commandname}" ]; then + check_executable.sh + fi +done + +if [ "$(whoami)" != "root" ]; then + allowed_commands_array=(DEBUG START INSTALL) + for allowed_command in "${allowed_commands_array[@]}"; do + if [ "${allowed_command}" == "${commandname}" ]; then + check_glibc.sh + fi + done +fi + +allowed_commands_array=(BACKUP CONSOLE DEBUG DETAILS MAP-COMPRESSOR FASTDL MODS-INSTALL MODS-REMOVE MODS-UPDATE MONITOR POST-DETAILS RESTART START STOP TEST-ALERT CHANGE-PASSWORD UPDATE UPDATE-LGSM VALIDATE WIPE) +for allowed_command in "${allowed_commands_array[@]}"; do + if [ "${allowed_command}" == "${commandname}" ]; then + check_logs.sh + fi +done + +allowed_commands_array=(DEBUG START) +for allowed_command in "${allowed_commands_array[@]}"; do + if [ "${allowed_command}" == "${commandname}" ]; then + check_deps.sh + fi +done + +allowed_commands_array=(CONSOLE DEBUG MONITOR START STOP) +for allowed_command in "${allowed_commands_array[@]}"; do + if [ "${allowed_command}" == "${commandname}" ]; then + check_config.sh + fi +done + +allowed_commands_array=(DEBUG DETAILS DEV-QUERY-RAW MONITOR POST_DETAILS START STOP POST-DETAILS) +for allowed_command in "${allowed_commands_array[@]}"; do + if [ "${allowed_command}" == "${commandname}" ]; then + if [ -z "${installflag}" ]; then + check_ip.sh + fi + fi +done + +allowed_commands_array=(DEBUG START UPDATE VALIDATE CHECK-UPDATE) +for allowed_command in "${allowed_commands_array[@]}"; do + if [ "${allowed_command}" == "${commandname}" ]; then + if [ "${appid}" ]; then + check_steamcmd.sh + fi + fi +done + +allowed_commands_array=(CHANGE-PASSWORD DETAILS MONITOR START STOP UPDATE VALIDATE POST-DETAILS) +for allowed_command in "${allowed_commands_array[@]}"; do + if [ "${allowed_command}" == "${commandname}" ]; then + check_status.sh + fi +done + +allowed_commands_array=(DEBUG START INSTALL) +for allowed_command in "${allowed_commands_array[@]}"; do + if [ "${allowed_command}" == "${commandname}" ]; then + check_system_requirements.sh + fi +done diff --git a/lgsm/modules/check_config.sh b/lgsm/modules/check_config.sh new file mode 100644 index 0000000..42892a1 --- /dev/null +++ b/lgsm/modules/check_config.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# LinuxGSM check_config.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Checks if the server config is missing and warns the user if needed. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +if [ -n "${servercfgfullpath}" ] && [ ! -f "${servercfgfullpath}" ]; then + fn_print_warn_nl "Configuration file missing!" + echo -e "${servercfgfullpath}" + fn_script_log_warn "Configuration file missing!" + fn_script_log_warn "${servercfgfullpath}" + install_config.sh +fi + +if [ "${shortname}" == "rust" ] && [ -v rconpassword ] && [ -z "${rconpassword}" ]; then + fn_print_fail_nl "RCON password is not set" + fn_script_log_warn "RCON password is not set" +elif [ -v rconpassword ] && [ "${rconpassword}" == "CHANGE_ME" ]; then + fn_print_warn_nl "Default RCON Password detected" + fn_script_log_warn "Default RCON Password detected" +fi + +if [ "${shortname}" == "vh" ] && [ -z "${serverpassword}" ]; then + fn_print_fail_nl "serverpassword is not set" + fn_script_log_fail "serverpassword is not set" +elif [ "${shortname}" == "vh" ] && [ "${#serverpassword}" -le "4" ]; then + fn_print_fail_nl "serverpassword is to short (min 5 chars)" + fn_script_log_fail "serverpassword is to short (min 5 chars)" +fi diff --git a/lgsm/modules/check_deps.sh b/lgsm/modules/check_deps.sh new file mode 100644 index 0000000..0f8304a --- /dev/null +++ b/lgsm/modules/check_deps.sh @@ -0,0 +1,394 @@ +#!/bin/bash +# LinuxGSM check_deps.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Checks and installs missing dependencies. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_install_dotnet_repo() { + if [ "${distroid}" == "ubuntu" ]; then + # if package aspnetcore-runtime-7.0 is unavailable in ubuntu repos, add the microsoft repo. + if ! apt-cache show aspnetcore-runtime-7.0 > /dev/null 2>&1; then + fn_fetch_file "https://packages.microsoft.com/config/ubuntu/${distroversion}/packages-microsoft-prod.deb" "" "" "" "/tmp" "packages-microsoft-prod.deb" "" "" "" "" + sudo dpkg -i /tmp/packages-microsoft-prod.deb + fi + elif [ "${distroid}" == "debian" ]; then + fn_fetch_file "https://packages.microsoft.com/config/debian/${distroversion}/packages-microsoft-prod.deb" "" "" "" "/tmp" "packages-microsoft-prod.deb" "" "" "" "" + sudo dpkg -i /tmp/packages-microsoft-prod.deb + fi +} + +fn_install_mono_repo() { + if [ "${autodepinstall}" == "0" ]; then + fn_print_information_nl "Automatically adding Mono repository." + fn_script_log_info "Automatically adding Mono repository." + echo -en ".\r" + fn_sleep_time_1 + echo -en "..\r" + fn_sleep_time_1 + echo -en "...\r" + fn_sleep_time_1 + echo -en " \r" + if [ "${distroid}" == "ubuntu" ]; then + if [ "${distroversion}" == "22.04" ]; then + cmd="sudo apt-get install gnupg ca-certificates;sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF;echo 'deb https://download.mono-project.com/repo/ubuntu stable-jammy main' | sudo tee /etc/apt/sources.list.d/mono-official-stable.list;sudo apt update" + elif [ "${distroversion}" == "20.04" ]; then + cmd="sudo apt-get install gnupg ca-certificates;sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF;echo 'deb https://download.mono-project.com/repo/ubuntu stable-focal main' | sudo tee /etc/apt/sources.list.d/mono-official-stable.list;sudo apt update" + elif [ "${distroversion}" == "18.04" ]; then + cmd="sudo apt-get install gnupg ca-certificates;sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF;echo 'deb https://download.mono-project.com/repo/ubuntu stable-bionic main' | sudo tee /etc/apt/sources.list.d/mono-official-stable.list;sudo apt update" + elif [ "${distroversion}" == "16.04" ]; then + cmd="sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF;sudo apt install apt-transport-https ca-certificates;echo 'deb https://download.mono-project.com/repo/ubuntu stable-xenial main' | sudo tee /etc/apt/sources.list.d/mono-official-stable.list;sudo apt update" + else + monoautoinstall="1" + fi + elif [ "${distroid}" == "debian" ]; then + if [ "${distroversion}" == "12" ]; then + cmd="sudo apt-get install apt-transport-https dirmngr gnupg ca-certificates;sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF;echo 'deb https://download.mono-project.com/repo/debian stable-bookworm main' | sudo tee /etc/apt/sources.list.d/mono-official-stable.list;sudo apt update" + elif [ "${distroversion}" == "11" ]; then + cmd="sudo apt-get install apt-transport-https dirmngr gnupg ca-certificates;sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF;echo 'deb https://download.mono-project.com/repo/debian stable-bullseye main' | sudo tee /etc/apt/sources.list.d/mono-official-stable.list;sudo apt update" + elif [ "${distroversion}" == "10" ]; then + cmd="sudo apt-get install apt-transport-https dirmngr gnupg ca-certificates;sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF;echo 'deb https://download.mono-project.com/repo/debian stable-buster main' | sudo tee /etc/apt/sources.list.d/mono-official-stable.list;sudo apt update" + elif [ "${distroversion}" == "9" ]; then + cmd="sudo apt-get install apt-transport-https dirmngr gnupg ca-certificates;sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF;echo 'deb https://download.mono-project.com/repo/debian stable-stretch main' | sudo tee /etc/apt/sources.list.d/mono-official-stable.list;sudo apt update" + else + monoautoinstall="1" + fi + elif [ "${distroid}" == "centos" ] || [ "${distroid}" == "almalinux" ] || [ "${distroid}" == "rocky" ]; then + if [ "${distroversion}" == "8" ]; then + cmd="sudo rpmkeys --import 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF';su -c 'curl https://download.mono-project.com/repo/centos8-stable.repo | tee /etc/yum.repos.d/mono-centos8-stable.repo'" + elif [ "${distroversion}" == "7" ]; then + cmd="sudo rpmkeys --import 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF';su -c 'curl https://download.mono-project.com/repo/centos7-stable.repo | tee /etc/yum.repos.d/mono-centos7-stable.repo'" + else + monoautoinstall="1" + fi + elif [ "${distroid}" == "fedora" ]; then + if [ "${distroversion}" -ge "29" ]; then + cmd="sudo rpm --import 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF';su -c 'curl https://download.mono-project.com/repo/centos8-stable.repo | tee /etc/yum.repos.d/mono-centos8-stable.repo';dnf update" + else + cmd="sudo rpm --import 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF';su -c 'curl https://download.mono-project.com/repo/centos7-stable.repo | tee /etc/yum.repos.d/mono-centos7-stable.repo';dnf update" + fi + else + monoautoinstall="1" + fi + + # Run the mono repo install. + eval "${cmd}" + + # Did Mono repo install correctly? + if [ "${monoautoinstall}" != "1" ]; then + if [ $? != 0 ]; then + fn_print_failure_nl "Unable to install Mono repository." + fn_script_log_fail "Unable to install Mono repository." + else + fn_print_complete_nl "Installing Mono repository completed." + fn_script_log_pass "Installing Mono repository completed." + fi + fi + + # Mono can not be auto installed with this distro. + if [ "${monoautoinstall}" == "1" ]; then + fn_print_warning_nl "Mono auto install not available for ${distroname}." + echo -e "Follow instructions on Mono website to install." + echo -e "https://www.mono-project.com/download/stable/#download-lin" + fn_script_log_warn "Unable to install Mono repository. Mono auto install not available for ${distroname}." + fi + + else + fn_print_information_nl "Installing Mono repository." + fn_print_warning_nl "$(whoami) does not have sudo access." + echo -e "Follow instructions on Mono website to install." + echo -e "https://www.mono-project.com/download/stable/#download-lin" + fn_script_log_warn "Unable to install Mono repository. $(whoami) does not have sudo access." + fi +} + +fn_deps_email() { + # Adds postfix to required dependencies if email alert is enabled. + if [ "${emailalert}" == "on" ]; then + if [ -f /usr/bin/mailx ]; then + if [ -d /etc/exim4 ]; then + array_deps_required+=(exim4) + elif [ -d /etc/sendmail ]; then + array_deps_required+=(sendmail) + elif [ "$(command -v yum 2> /dev/null)" ] || [ "$(command -v dnf 2> /dev/null)" ]; then + array_deps_required+=(mailx postfix) + elif [ "$(command -v apt 2> /dev/null)" ]; then + array_deps_required+=(mailutils postfix) + fi + else + if [ "$(command -v yum 2> /dev/null)" ] || [ "$(command -v dnf 2> /dev/null)" ]; then + array_deps_required+=(mailx postfix) + elif [ "$(command -v apt 2> /dev/null)" ]; then + array_deps_required+=(mailutils postfix) + fi + fi + fi +} + +fn_install_missing_deps() { + # If any dependencies are not installed. + if [ "${#array_deps_missing[*]}" != "0" ]; then + if [ "${commandname}" == "INSTALL" ]; then + fn_print_warning_nl "Missing dependencies: ${red}${array_deps_missing[*]}${default}" + fn_script_log_warn "Missing dependencies: ${array_deps_missing[*]}" + else + fn_print_dots "Missing dependencies" + fn_print_warn "Missing dependencies: ${red}${array_deps_missing[*]}${default}" + fn_script_log_warn "Missing dependencies: ${array_deps_missing[*]}" + fi + + # Attempt automatic dependency installation + if [ "${autoinstall}" == "1" ]; then + sudo -n true > /dev/null 2>&1 + else + sudo -v > /dev/null 2>&1 + fi + autodepinstall="$?" + + if [ "${monoinstalled}" == "false" ]; then + fn_install_mono_repo + fi + + if [ "${dotnetinstalled}" == "false" ]; then + fn_install_dotnet_repo + fi + + if [ "${commandname}" == "INSTALL" ]; then + if [ "${autodepinstall}" == "0" ]; then + fn_print_information_nl "$(whoami) has sudo access." + fn_script_log_info "$(whoami) has sudo access." + else + fn_print_warning_nl "$(whoami) does not have sudo access. Manually install dependencies or run ./${selfname} install as root." + fn_script_log_warn "$(whoami) does not have sudo access. Manually install dependencies or run ./${selfname} install as root." + fi + fi + + # Add sudo dpkg --add-architecture i386 if using i386 packages. + if [ "$(command -v apt 2> /dev/null)" ]; then + if printf '%s\n' "${array_deps_required[@]}" | grep -q -P 'i386'; then + i386installcommand="sudo dpkg --add-architecture i386; " + fi + fi + + # If automatic dependency install is available + if [ "${autodepinstall}" == "0" ]; then + fn_print_information_nl "Automatically installing missing dependencies." + fn_script_log_info "Automatically installing missing dependencies." + echo -en ".\r" + fn_sleep_time_1 + echo -en "..\r" + fn_sleep_time_1 + echo -en "...\r" + fn_sleep_time_1 + echo -en " \r" + if [ "$(command -v apt 2> /dev/null)" ]; then + cmd="echo steamcmd steam/question select \"I AGREE\" | sudo debconf-set-selections; echo steamcmd steam/license note '' | sudo debconf-set-selections; ${i386installcommand}sudo apt-get update; sudo apt-get -y install ${array_deps_missing[*]}" + eval "${cmd}" + elif [ "$(command -v dnf 2> /dev/null)" ]; then + cmd="sudo dnf -y install ${array_deps_missing[*]}" + eval "${cmd}" + elif [ "$(command -v yum 2> /dev/null)" ]; then + cmd="sudo yum -y install ${array_deps_missing[*]}" + eval "${cmd}" + fi + autodepinstall="$?" + + # If auto install passes remove steamcmd install failure. + if [ "${autodepinstall}" == "0" ]; then + unset steamcmdfail + fi + fi + + # If automatic dependency install is unavailable. + if [ "${autodepinstall}" != "0" ]; then + if [ "$(command -v apt 2> /dev/null)" ]; then + echo -e "${i386installcommand}sudo apt update; sudo apt install ${array_deps_missing[*]}" + elif [ "$(command -v dnf 2> /dev/null)" ]; then + echo -e "sudo dnf install ${array_deps_missing[*]}" + elif [ "$(command -v yum 2> /dev/null)" ]; then + echo -e "sudo yum install ${array_deps_missing[*]}" + fi + fi + + if [ "${steamcmdfail}" ]; then + if [ "${commandname}" == "INSTALL" ]; then + fn_print_failure_nl "Missing dependencies required to run SteamCMD." + fn_script_log_fail "Missing dependencies required to run SteamCMD." + core_exit.sh + else + fn_print_error_nl "Missing dependencies required to run SteamCMD." + fn_script_log_error "Missing dependencies required to run SteamCMD." + fi + fi + + else + if [ "${commandname}" == "INSTALL" ]; then + fn_print_information_nl "Required dependencies already installed." + fn_script_log_info "Required dependencies already installed." + fi + fi +} + +fn_check_loop() { + # Loop though required depenencies checking if they are installed. + for deptocheck in ${array_deps_required[*]}; do + fn_deps_detector + done + + # user will be informed of any missing dependencies. + fn_install_missing_deps +} + +# Checks if dependency is installed or not. +fn_deps_detector() { + ## Check. + # SteamCMD: Will be removed from required array if no appid is present or non-free repo is not available. + # This will cause SteamCMD to be installed using tar. + if [ "${deptocheck}" == "libsdl2-2.0-0:i386" ] && [ -z "${appid}" ]; then + array_deps_required=("${array_deps_required[@]/libsdl2-2.0-0:i386/}") + steamcmdstatus=1 + elif [ "${deptocheck}" == "steamcmd" ] && [ -z "${appid}" ]; then + array_deps_required=("${array_deps_required[@]/steamcmd/}") + steamcmdstatus=1 + elif [ "${deptocheck}" == "steamcmd" ] && [ "${distroid}" == "debian" ] && ! grep -qE "^deb .*non-free" /etc/apt/sources.list; then + array_deps_required=("${array_deps_required[@]/steamcmd/}") + steamcmdstatus=1 + # Java: Added for users using Oracle JRE to bypass check. + elif [[ ${deptocheck} == "openjdk"* ]] || [[ ${deptocheck} == "java"* ]]; then + # Is java already installed? + if [ -n "${javaversion}" ]; then + # Added for users using Oracle JRE to bypass check. + depstatus=0 + deptocheck="${javaversion}" + else + depstatus=1 + fi + # Mono: A Mono repo needs to be installed. + elif [ "${deptocheck}" == "mono-complete" ]; then + if [ -n "${monoversion}" ] && [ "${monoversion}" -ge "5" ]; then + # Mono >= 5.0.0 already installed. + depstatus=0 + monoinstalled=true + else + # Mono not installed or installed Mono < 5.0.0. + depstatus=1 + monoinstalled=false + fi + # .NET Core: A .NET Core repo needs to be installed. + elif [ "${deptocheck}" == "aspnetcore-runtime-7.0" ]; then + # .NET is not installed. + if [ -n "${dotnetversion}" ]; then + depstatus=0 + dotnetinstalled=true + else + depstatus=1 + dotnetinstalled=false + fi + elif [ "$(command -v apt 2> /dev/null)" ]; then + dpkg-query -W -f='${Status}' "${deptocheck}" 2> /dev/null | grep -q -P '^install ok installed' + depstatus=$? + elif [ "$(command -v dnf 2> /dev/null)" ]; then + dnf list installed "${deptocheck}" > /dev/null 2>&1 + depstatus=$? + elif [ "$(command -v rpm 2> /dev/null)" ]; then + rpm -q "${deptocheck}" > /dev/null 2>&1 + depstatus=$? + fi + + # Outcome of Check. + if [ "${steamcmdstatus}" == "1" ]; then + # If SteamCMD is not available in repo dont check for it. + unset steamcmdstatus + elif [ "${depstatus}" == "0" ]; then + # If dependency is found. + missingdep=0 + if [ "${commandname}" == "INSTALL" ]; then + echo -e "${green}${deptocheck}${default}" + fn_sleep_time + fi + elif [ "${depstatus}" != "0" ]; then + # If dependency is not found. + missingdep=1 + if [ "${commandname}" == "INSTALL" ]; then + echo -e "${red}${deptocheck}${default}" + fn_sleep_time + fi + # If SteamCMD requirements are not met install will fail. + if [ -n "${appid}" ]; then + for steamcmddeptocheck in ${array_deps_required_steamcmd[*]}; do + if [ "${deptocheck}" != "steamcmd" ] && [ "${deptocheck}" == "${steamcmddeptocheck}" ]; then + steamcmdfail=1 + fi + done + fi + fi + unset depstatus + + # Missing dependencies are added to array_deps_missing. + if [ "${missingdep}" == "1" ]; then + array_deps_missing+=("${deptocheck}") + fi +} + +if [ "${commandname}" == "INSTALL" ]; then + if [ "$(whoami)" == "root" ]; then + echo -e "" + echo -e "${bold}${lightyellow}Checking ${gamename} Dependencies as root${default}" + fn_messages_separator + fn_print_information_nl "Checking any missing dependencies for ${gamename} server only." + fn_print_information_nl "This will NOT install a ${gamename} server." + else + echo -e "" + echo -e "${bold}${lightyellow}Checking ${gamename} Dependencies${default}" + fn_messages_separator + fi +fi + +# Will warn user if their distro is no longer supported by the vendor. +if [ -n "${distrosupport}" ]; then + if [ "${distrosupport}" == "unsupported" ]; then + fn_print_warning_nl "${distroname} is no longer supported by the vendor. Upgrading is recommended." + fn_script_log_warn "${distroname} is no longer supported by the vendor. Upgrading is recommended." + fi +fi + +info_distro.sh + +if [ ! -f "${tmpdir}/dependency-no-check.tmp" ] && [ ! -f "${datadir}/${distroid}-${distroversioncsv}.csv" ]; then + # Check that the distro dependency csv file exists. + fn_check_file_github "lgsm/data" "${distroid}-${distroversioncsv}.csv" + if [ -n "${checkflag}" ] && [ "${checkflag}" == "0" ]; then + fn_fetch_file_github "lgsm/data" "${distroid}-${distroversioncsv}.csv" "lgsm/data" "chmodx" "norun" "noforce" "nohash" + fi +fi + +# If the file successfully downloaded run the dependency check. +if [ -f "${datadir}/${distroid}-${distroversioncsv}.csv" ]; then + depall=$(awk -F, '$1=="all" {$1=""; print $0}' "${datadir}/${distroid}-${distroversioncsv}.csv") + depsteamcmd=$(awk -F, '$1=="steamcmd" {$1=""; print $0}' "${datadir}/${distroid}-${distroversioncsv}.csv") + depshortname=$(awk -v shortname="${shortname}" -F, '$1==shortname {$1=""; print $0}' "${datadir}/${distroid}-${distroversioncsv}.csv") + + # Generate array of missing deps. + array_deps_missing=() + + array_deps_required=("${depall} ${depsteamcmd} ${depshortname}") + array_deps_required_steamcmd=("${depsteamcmd}") + fn_deps_email + # Unique sort dependency array. + IFS=" " read -r -a array_deps_required <<< "$(echo "${array_deps_required[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')" + + fn_check_loop +# Warn the user that dependency checking is unavailable for their distro. +elif [ "${commandname}" == "INSTALL" ] || [ -n "${checkflag}" ] && [ "${checkflag}" != "0" ]; then + fn_print_warning_nl "LinuxGSM dependency checking currently unavailable for ${distroname}." + # Prevent future dependency checking if unavailable for the distro. + echo "${version}" > "${tmpdir}/dependency-no-check.tmp" +elif [ -f "${tmpdir}/dependency-no-check.tmp" ]; then + # Allow LinuxGSM to try a dependency check if LinuxGSM has been recently updated. + nocheckversion=$(cat "${tmpdir}/dependency-no-check.tmp") + if [ "${version}" != "${nocheckversion}" ]; then + rm -f "${tmpdir:?}/dependency-no-check.tmp" + fi +fi diff --git a/lgsm/modules/check_executable.sh b/lgsm/modules/check_executable.sh new file mode 100644 index 0000000..91db68f --- /dev/null +++ b/lgsm/modules/check_executable.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# LinuxGSM check_executable.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Checks if server executable exists. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# #4241 temporary fix for Satisfactory for upgrade betweern Update 7 & Update 8 - remove this once update 8 is released +if [ "${shortname}" == "sf" ]; then + if [ ! -f "${serverfiles}/Engine/Binaries/Linux/UE4Server-Linux-Shipping" ]; then + ln -s "${serverfiles}/Engine/Binaries/Linux/UnrealServer-Linux-Shipping" "${serverfiles}/Engine/Binaries/Linux/UE4Server-Linux-Shipping" + fi +fi + +# Check if executable exists +execname=$(basename "${executable}") +if [ ! -f "${executabledir}/${execname}" ]; then + fn_print_fail_nl "executable was not found" + echo -e "* ${executabledir}/${execname}" + if [ -d "${lgsmlogdir}" ]; then + fn_script_log_fail "Executable was not found: ${executabledir}/${execname}" + fi + unset exitbypass + core_exit.sh +fi diff --git a/lgsm/modules/check_glibc.sh b/lgsm/modules/check_glibc.sh new file mode 100644 index 0000000..9da491b --- /dev/null +++ b/lgsm/modules/check_glibc.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# LinuxGSM check_glibc.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Checks if the server has the correct Glibc version. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +info_distro.sh + +if [ "${glibc}" == "null" ]; then + # Glibc is not required. + : +elif [ -z "${glibc}" ]; then + fn_print_dots "Checking glibc" + fn_print_error_nl "Checking glibc: requirement unknown" + fn_script_log_error "Checking glibc: requirement unknown" + fn_sleep_time_5 +elif [ "$(printf '%s\n'${glibc}'\n' "${glibcversion}" | sort -V | head -n 1)" != "${glibc}" ]; then + fn_print_dots "Checking glibc" + fn_print_error_nl "Checking glibc: requirements not met" + fn_script_log_error "Checking glibc: requirements not met" + echo -en "\n" + echo -e " * glibc required: ${glibc}" + echo -e " * glibc installed: ${red}${glibcversion}${default}" + echo -en "\n" + fn_print_information_nl "Distro upgrade is required" + fn_script_log_info "Distro upgrade is required" + fn_sleep_time_5 +fi diff --git a/lgsm/modules/check_ip.sh b/lgsm/modules/check_ip.sh new file mode 100644 index 0000000..7671429 --- /dev/null +++ b/lgsm/modules/check_ip.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# LinuxGSM check_ip.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Automatically identifies the server interface IP. +# If multiple interfaces are detected the user will need to manually set using ip="0.0.0.0". + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +info_game.sh + +ip_commands_array=("ip" "/bin/ip" "/usr/sbin/ip") +for ip_command in "${ip_commands_array[@]}"; do + if [ "$(command -v "${ip_command}" 2> /dev/null)" ]; then + ipcommand="${ip_command}" + break + fi +done + +ethtool_commands_array=("ethtool" "/bin/ethtool" "/usr/sbin/ethtool") +for ethtool_command in "${ethtool_commands_array[@]}"; do + if [ "$(command -v "${ethtool_command}" 2> /dev/null)" ]; then + ethtoolcommand="${ethtool_command}" + break + fi +done + +mapfile -t current_ips < <(${ipcommand} -o -4 addr | awk '{print $4}' | grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}' | sort -u | grep -v 127.0.0) + +function fn_is_valid_ip() { + local ip="${1}" + # excluding 0.* ips also + grep -qEe '^[1-9]+[0-9]*\.[0-9]+\.[0-9]+\.[0-9]+$' <<< "${ip}" +} + +# Check if server has multiple IP addresses. + +# If the IP variable has been set by user. +if fn_is_valid_ip "${ip}"; then + queryips=("${ip}") + httpip=("${ip}") + telnetip=("${ip}") +# If the game config has an IP set. +elif fn_is_valid_ip "${configip}"; then + queryips=("${configip}") + ip="${configip}" + httpip=("${configip}") + telnetip=("${configip}") +# If there is only 1 server IP address. +# Some IP details can automatically use the one IP. +elif [ "${#current_ips[@]}" == "1" ]; then + queryips=("127.0.0.1" "${current_ips[@]}") + ip="0.0.0.0" + httpip=("${current_ips[@]}") + telnetip=("${current_ips[@]}") +# If no ip is set by the user and server has more than one IP. +else + queryips=("127.0.0.1" "${current_ips[@]}") + ip="0.0.0.0" + httpip=("${ip}") + telnetip=("${ip}") +fi diff --git a/lgsm/modules/check_last_update.sh b/lgsm/modules/check_last_update.sh new file mode 100644 index 0000000..166d80a --- /dev/null +++ b/lgsm/modules/check_last_update.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# LinuxGSM check_last_update.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Checks Lockfile to see when last update happened. +# Will reboot server if instance not rebooted since update. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +if [ -f "${lockdir}/${selfname}-last-started.lock" ]; then + laststart=$(cat "${lockdir}/${selfname}-last-started.lock") +fi +if [ -f "${lockdir}/last-updated.lock" ]; then + lastupdate=$(cat "${lockdir}/last-updated.lock") +fi + +check_status.sh +if [ -f "${lockdir}/last-updated.lock" ] && [ "${status}" != "0" ]; then + if [ ! -f "${lockdir}/${selfname}-last-started.lock" ] || [ "${laststart}" -lt "${lastupdate}" ]; then + fn_print_info "${selfname} has not been restarted since last update" + fn_script_log_info "${selfname} has not been restarted since last update" + alert="update" + alert.sh + command_restart.sh + fn_firstcommand_reset + fi +fi diff --git a/lgsm/modules/check_logs.sh b/lgsm/modules/check_logs.sh new file mode 100644 index 0000000..036eea5 --- /dev/null +++ b/lgsm/modules/check_logs.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# LinuxGSM check_logs.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Checks if log files exist. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_check_logs() { + fn_print_dots "Checking for log files" + fn_print_info_nl "Checking for log files: Creating log files" + checklogs=1 + install_logs.sh +} + +# Create directories for the script and console logs. +if [ ! -d "${lgsmlogdir}" ] || [ ! -d "${consolelogdir}" ]; then + fn_check_logs +fi + +# Create gamelogdir. +# If variable exists gamelogdir exists and log/server does not. +if [ "${gamelogdir}" ] && [ -d "${gamelogdir}" ] && [ ! -d "${logdir}/server" ]; then + fn_check_logs +fi + +# Create Steam log symlink if missing +if [ ! -d "${logdir}/steam" ] && [ -n "${appid}" ]; then + fn_check_logs +fi diff --git a/lgsm/modules/check_permissions.sh b/lgsm/modules/check_permissions.sh new file mode 100644 index 0000000..572b403 --- /dev/null +++ b/lgsm/modules/check_permissions.sh @@ -0,0 +1,234 @@ +#!/bin/bash +# LinuxGSM check_permissions.sh +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Checks ownership & permissions of scripts, files and directories. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_check_ownership() { + if [ -f "${rootdir}/${selfname}" ]; then + if [ "$(find "${rootdir}/${selfname}" -not -user "$(whoami)" | wc -l)" -ne "0" ]; then + selfownissue=1 + fi + fi + if [ -d "${modulesdir}" ]; then + if [ "$(find "${modulesdir}" -not -user "$(whoami)" | wc -l)" -ne "0" ]; then + funcownissue=1 + fi + fi + if [ -d "${serverfiles}" ]; then + if [ "$(find "${serverfiles}" -not -user "$(whoami)" | wc -l)" -ne "0" ]; then + filesownissue=1 + fi + fi + if [ "${selfownissue}" == "1" ] || [ "${funcownissue}" == "1" ] || [ "${filesownissue}" == "1" ]; then + fn_print_fail_nl "Ownership issues found" + fn_script_log_fail "Ownership issues found" + fn_print_information_nl "The current user ($(whoami)) does not have ownership of the following files:" + fn_script_log_info "The current user ($(whoami)) does not have ownership of the following files:" + { + echo -e "User\tGroup\tFile\n" + if [ "${selfownissue}" == "1" ]; then + find "${rootdir}/${selfname}" -not -user "$(whoami)" -printf "%u\t%g\t%p\n" + fi + if [ "${funcownissue}" == "1" ]; then + find "${modulesdir}" -not -user "$(whoami)" -printf "%u\t%g\t%p\n" + fi + if [ "${filesownissue}" == "1" ]; then + find "${serverfiles}" -not -user "$(whoami)" -printf "%u\t%g\t%p\n" + fi + + } | column -s $'\t' -t | tee -a "${lgsmlog}" + echo -e "" + fn_print_information_nl "please see https://docs.linuxgsm.com/support/faq#fail-starting-game-server-permission-issues-found" + fn_script_log "For more information, please see https://docs.linuxgsm.com/support/faq#fail-starting-game-server-permission-issues-found" + if [ "${monitorflag}" == 1 ]; then + alert="permissions" + alert.sh + fi + core_exit.sh + fi +} + +fn_check_permissions() { + if [ -d "${modulesdir}" ]; then + if [ "$(find "${modulesdir}" -type f -not -executable | wc -l)" -ne "0" ]; then + fn_print_fail_nl "Permissions issues found" + fn_script_log_fail "Permissions issues found" + fn_print_information_nl "The following files are not executable:" + fn_script_log_info "The following files are not executable:" + { + echo -e "File\n" + find "${modulesdir}" -type f -not -executable -printf "%p\n" + } | column -s $'\t' -t | tee -a "${lgsmlog}" + if [ "${monitorflag}" == 1 ]; then + alert="permissions" + alert.sh + fi + core_exit.sh + fi + fi + + # Check rootdir permissions. + if [ "${rootdir}" ]; then + # Get permission numbers on directory under the form 775. + rootdirperm=$(stat -c %a "${rootdir}") + # Grab the first and second digit for user and group permission. + userrootdirperm="${rootdirperm:0:1}" + grouprootdirperm="${rootdirperm:1:1}" + if [ "${userrootdirperm}" != "7" ] && [ "${grouprootdirperm}" != "7" ]; then + fn_print_fail_nl "Permissions issues found" + fn_script_log_fail "Permissions issues found" + fn_print_information_nl "The following directory does not have the correct permissions:" + fn_script_log_info "The following directory does not have the correct permissions:" + fn_script_log_info "${rootdir}" + ls -l "${rootdir}" + if [ "${monitorflag}" == 1 ]; then + alert="permissions" + alert.sh + fi + core_exit.sh + fi + fi + # Check if executable is executable and attempt to fix it. + # First get executable name. + execname=$(basename "${executable}") + if [ -f "${executabledir}/${execname}" ]; then + # Get permission numbers on file under the form 775. + execperm=$(stat -c %a "${executabledir}/${execname}") + # Grab the first and second digit for user and group permission. + userexecperm="${execperm:0:1}" + groupexecperm="${execperm:1:1}" + # Check for invalid user permission. + if [ "${userexecperm}" == "0" ] || [ "${userexecperm}" == "2" ] || [ "${userexecperm}" == "4" ] || [ "${userexecperm}" == "6" ]; then + # If user permission is invalid, then check for invalid group permissions. + if [ "${groupexecperm}" == "0" ] || [ "${groupexecperm}" == "2" ] || [ "${groupexecperm}" == "4" ] || [ "${groupexecperm}" == "6" ]; then + # If permission issues are found. + fn_print_warn_nl "Permissions issue found" + fn_script_log_warn "Permissions issue found" + fn_print_information_nl "The following file is not executable:" + ls -l "${executabledir}/${execname}" + fn_script_log_info "The following file is not executable:" + fn_script_log_info "${executabledir}/${execname}" + fn_print_information_nl "Applying chmod u+x,g+x ${executabledir}/${execname}" + fn_script_log_info "Applying chmod u+x,g+x ${execperm}" + # Make the executable executable. + chmod u+x,g+x "${executabledir}/${execname}" + # Second check to see if it's been successfully applied. + # Get permission numbers on file under the form 775. + execperm=$(stat -c %a "${executabledir}/${execname}") + # Grab the first and second digit for user and group permission. + userexecperm="${execperm:0:1}" + groupexecperm="${execperm:1:1}" + if [ "${userexecperm}" == "0" ] || [ "${userexecperm}" == "2" ] || [ "${userexecperm}" == "4" ] || [ "${userexecperm}" == "6" ]; then + if [ "${groupexecperm}" == "0" ] || [ "${groupexecperm}" == "2" ] || [ "${groupexecperm}" == "4" ] || [ "${groupexecperm}" == "6" ]; then + # If errors are still found. + fn_print_fail_nl "The following file could not be set executable:" + ls -l "${executabledir}/${execname}" + fn_script_log_warn "The following file could not be set executable:" + fn_script_log_info "${executabledir}/${execname}" + if [ "${monitorflag}" == "1" ]; then + alert="permissions" + alert.sh + fi + core_exit.sh + fi + fi + fi + fi + fi +} + +## The following fn_sys_perm_* modules checks for permission errors in /sys directory. + +# Checks for permission errors in /sys directory. +fn_sys_perm_errors_detect() { + # Reset test variables. + sysdirpermerror="0" + classdirpermerror="0" + netdirpermerror="0" + # Check permissions. + # /sys, /sys/class and /sys/class/net should be readable & executable. + if [ ! -r "/sys" ] || [ ! -x "/sys" ]; then + sysdirpermerror="1" + fi + if [ ! -r "/sys/class" ] || [ ! -x "/sys/class" ]; then + classdirpermerror="1" + fi + if [ ! -r "/sys/class/net" ] || [ ! -x "/sys/class/net" ]; then + netdirpermerror="1" + fi +} + +# Display a message on how to fix the issue manually. +fn_sys_perm_fix_manually_msg() { + echo -e "" + fn_print_information_nl "This error causes servers to fail starting properly" + fn_script_log_info "This error causes servers to fail starting properly." + echo -e " * To fix this issue, run the following command as root:" + fn_script_log_info "To fix this issue, run the following command as root:" + echo -e " chmod a+rx /sys /sys/class /sys/class/net" + fn_script_log "chmod a+rx /sys /sys/class /sys/class/net" + fn_sleep_time_5 + if [ "${monitorflag}" == 1 ]; then + alert="permissions" + alert.sh + fi + core_exit.sh +} + +# Attempt to fix /sys related permission errors if sudo is available, exits otherwise. +fn_sys_perm_errors_fix() { + if sudo -n true > /dev/null 2>&1; then + fn_print_dots "Fixing /sys permissions" + fn_script_log_info "Fixing /sys permissions." + if [ "${sysdirpermerror}" == "1" ]; then + sudo chmod a+rx "/sys" + fi + if [ "${classdirpermerror}" == "1" ]; then + sudo chmod a+rx "/sys/class" + fi + if [ "${netdirpermerror}" == "1" ]; then + sudo chmod a+rx "/sys/class/net" + fi + # Run check again to see if it's fixed. + fn_sys_perm_errors_detect + if [ "${sysdirpermerror}" == "1" ] || [ "${classdirpermerror}" == "1" ] || [ "${netdirpermerror}" == "1" ]; then + fn_print_error "Could not fix /sys permissions" + fn_script_log_error "Could not fix /sys permissions." + + # Show the user how to fix. + fn_sys_perm_fix_manually_msg + else + fn_print_ok_nl "Fixing /sys permissions" + fn_script_log_pass "Permissions in /sys fixed" + fi + else + # Show the user how to fix. + fn_sys_perm_fix_manually_msg + fi +} + +# Processes to the /sys related permission errors check & fix/info. +fn_sys_perm_error_process() { + fn_sys_perm_errors_detect + # If any error was found. + if [ "${sysdirpermerror}" == "1" ] || [ "${classdirpermerror}" == "1" ] || [ "${netdirpermerror}" == "1" ]; then + fn_print_dots "Checking /sys permissions" + fn_print_error_nl "Checking /sys permissions" + fn_script_log_error "Checking /sys permissions" + # Run the fix + fn_sys_perm_errors_fix + fi +} + +## Run permisions checks when not root. +if [ "$(whoami)" != "root" ]; then + fn_check_ownership + fn_check_permissions + if [ "${commandname}" == "START" ]; then + fn_sys_perm_error_process + fi +fi diff --git a/lgsm/modules/check_root.sh b/lgsm/modules/check_root.sh new file mode 100644 index 0000000..8fe2076 --- /dev/null +++ b/lgsm/modules/check_root.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# LinuxGSM check_root.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Checks if the user tried to run the script as root. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +if [ "$(whoami)" == "root" ]; then + if [ "${commandname}" != "INSTALL" ]; then + fn_print_fail_nl "Do NOT run as root!" + if [ -d "${lgsmlogdir}" ]; then + fn_script_log_fail "${selfname} attempted to run as root." + else + # Forces exit code is log does not yet exist. + exitcode=1 + fi + core_exit.sh + fi +fi diff --git a/lgsm/modules/check_status.sh b/lgsm/modules/check_status.sh new file mode 100644 index 0000000..906675e --- /dev/null +++ b/lgsm/modules/check_status.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# LinuxGSM check_status.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Checks the process status of the server. Either online or offline. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +status=$(tmux -L "${socketname}" list-sessions -F "#{session_name}" 2> /dev/null | grep -Ecx "^${sessionname}") diff --git a/lgsm/modules/check_steamcmd.sh b/lgsm/modules/check_steamcmd.sh new file mode 100644 index 0000000..5d14bb2 --- /dev/null +++ b/lgsm/modules/check_steamcmd.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# LinuxGSM check_steamcmd.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Checks if SteamCMD is installed correctly. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# init steamcmd functions. +core_steamcmd.sh + +fn_check_steamcmd_clear +fn_check_steamcmd +if [ "${shortname}" == "ark" ]; then + fn_check_steamcmd_ark +fi +fn_check_steamcmd_dir +fn_check_steamcmd_dir_legacy +fn_check_steamcmd_steamapp +fn_check_steamcmd_user +fn_check_steamcmd_exec diff --git a/lgsm/modules/check_system_dir.sh b/lgsm/modules/check_system_dir.sh new file mode 100644 index 0000000..2f57511 --- /dev/null +++ b/lgsm/modules/check_system_dir.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# LinuxGSM check_system_dir.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Checks if systemdir/serverfiles is accessible. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +if [ ! -d "${serverfiles}" ]; then + fn_print_fail_nl "Cannot access ${serverfiles}: No such directory" + if [ -d "${lgsmlogdir}" ]; then + fn_script_log_fail "Cannot access ${serverfiles}: No such directory." + fi + core_exit.sh +fi + +if [ ! -d "${systemdir}" ] && [ -z "${CI}" ]; then + fn_print_fail_nl "Cannot access ${systemdir}: No such directory" + if [ -d "${lgsmlogdir}" ]; then + fn_script_log_fail "Cannot access ${systemdir}: No such directory." + fi + core_exit.sh +fi diff --git a/lgsm/modules/check_system_requirements.sh b/lgsm/modules/check_system_requirements.sh new file mode 100644 index 0000000..6932de4 --- /dev/null +++ b/lgsm/modules/check_system_requirements.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# LinuxGSM check_system_requirements.sh +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Checks RAM requirements. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +info_distro.sh + +# RAM requirements in megabytes for each game or engine. + +if [ "${shortname}" == "ark" ]; then + ramrequirementmb="4000" + ramrequirementgb="4" +elif [ "${shortname}" == "bt" ]; then + ramrequirementmb="1000" + ramrequirementgb="1" +elif [ "${shortname}" == "mh" ]; then + ramrequirementmb="4000" + ramrequirementgb="4" +elif [ "${shortname}" == "arma3" ]; then + ramrequirementmb="1000" + ramrequirementgb="1" +elif [ "${shortname}" == "rust" ]; then + ramrequirementmb="4000" + ramrequirementgb="4" +elif [ "${shortname}" == "mc" ] || [ "${shortname}" == "pmc" ] || [ "${shortname}" == "wmc" ]; then + ramrequirementmb="1000" + ramrequirementgb="1" +elif [ "${shortname}" == "ps" ]; then + ramrequirementmb="2000" + ramrequirementgb="2" +elif [ "${shortname}" == "ns2" ] || [ "${shortname}" == "ns2c" ]; then + ramrequirementmb="1000" + ramrequirementgb="1" +elif [ "${shortname}" == "st" ]; then + ramrequirementmb="1000" + ramrequirementgb="1" +elif [ "${shortname}" == "pvr" ]; then + ramrequirementmb="2000" + ramrequirementgb="2" +fi + +# If the game or engine has a minimum RAM Requirement, compare it to system's available RAM. +if [ "${ramrequirementmb}" ]; then + if [ "${physmemtotalmb}" -lt "${ramrequirementmb}" ]; then + fn_print_dots "Checking RAM" + # Warn the user. + fn_print_warn_nl "Checking RAM: ${ramrequirementgb}G required, ${physmemtotal} available" + echo "* ${gamename} server may fail to run or experience poor performance." + fn_sleep_time_5 + fi +fi diff --git a/lgsm/modules/check_tmuxception.sh b/lgsm/modules/check_tmuxception.sh new file mode 100644 index 0000000..8f1f94c --- /dev/null +++ b/lgsm/modules/check_tmuxception.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# LinuxGSM check_config.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Checks if run from tmux or screen. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_check_is_in_tmux() { + if [ "${TMUX}" ]; then + fn_print_fail_nl "tmuxception error: Sorry Cobb you cannot start a tmux session inside of a tmux session." + fn_script_log_fail "Tmuxception error: Attempted to start a tmux session inside of a tmux session." + fn_print_information_nl "LinuxGSM creates a tmux session when starting the server." + echo -e "It is not possible to run a tmux session inside another tmux session" + echo -e "https://docs.linuxgsm.com/requirements/tmux#tmuxception" + core_exit.sh + fi +} + +fn_check_is_in_screen() { + if [ "${STY}" ]; then + fn_print_fail_nl "tmuxception error: Sorry Cobb you cannot start a tmux session inside of a screen session." + fn_script_log_fail "Tmuxception error: Attempted to start a tmux session inside of a screen session." + fn_print_information_nl "LinuxGSM creates a tmux session when starting the server." + echo -e "It is not possible to run a tmux session inside screen session" + echo -e "https://docs.linuxgsm.com/requirements/tmux#tmuxception" + core_exit.sh + fi +} + +fn_check_is_in_tmux +fn_check_is_in_screen diff --git a/lgsm/modules/check_version.sh b/lgsm/modules/check_version.sh new file mode 100644 index 0000000..5369fd8 --- /dev/null +++ b/lgsm/modules/check_version.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# LinuxGSM command_version.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Will run update-lgsm if gameserver.sh and modules version does not match +# this will allow gameserver.sh to update - useful for multi instance servers. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +if [ -n "${modulesversion}" ] && [ -n "${version}" ] && [ "${version}" != "${modulesversion}" ]; then + exitbypass=1 + echo -e "" + fn_print_error_nl "LinuxGSM version mismatch" + echo -e "" + echo -e "* ${selfname}: ${version}" + echo -e "* modules: ${modulesversion}" + echo -e "" + fn_script_log_error "LinuxGSM Version mismatch: ${selfname}: ${version}: modules: ${modulesversion}" + fn_sleep_time_1 + command_update_linuxgsm.sh + fn_firstcommand_reset +fi diff --git a/lgsm/modules/command_backup.sh b/lgsm/modules/command_backup.sh new file mode 100644 index 0000000..55981e1 --- /dev/null +++ b/lgsm/modules/command_backup.sh @@ -0,0 +1,258 @@ +#!/bin/bash +# LinuxGSM command_backup.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Creates a .tar.gz file in the backup directory. + +commandname="BACKUP" +commandaction="Backing up" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +# Trap to remove lockfile on quit. +fn_backup_trap() { + echo -e "" + echo -en "backup ${backupname}.tar.gz..." + fn_print_canceled_eol_nl + fn_script_log_info "Backup ${backupname}.tar.gz: CANCELED" + rm -f "${backupdir:?}/${backupname}.tar.gz" | tee -a "${lgsmlog}" + echo -en "backup ${backupname}.tar.gz..." + fn_print_removed_eol_nl + fn_script_log_info "Backup ${backupname}.tar.gz: REMOVED" + # Remove backup lockfile. + rm -f "${lockdir:?}/backup.lock" + fn_backup_start_server + unset exitbypass + core_exit.sh +} + +# Check if a backup is pending or has been aborted using backup.lock. +fn_backup_check_lockfile() { + # Remove stale lockfile. + if [ -f "${lockdir}/backup.lock" ]; then + if [ "$(find "${lockdir}/backup.lock" -mmin +60)" ]; then + fn_print_dots "Lockfile found: " + fn_print_checking_eol + fn_print_warn "Lockfile found: Removing stale lockfile: " + fn_print_warn_eol + fn_script_log_warn "Lockfile found: Removing stale lockfile" + rm -f "${lockdir:?}/backup.lock" + fi + fi + + if [ -f "${lockdir}/backup.lock" ]; then + fn_print_info_nl "Lockfile found: Backup is currently running" + fn_script_log_error "Lockfile found: Backup is currently running: ${lockdir}/backup.lock" + core_exit.sh + fi +} + +# Initialisation. +fn_backup_init() { + # Backup file name with selfname and current date. + backupname="${selfname}-$(date '+%Y-%m-%d-%H%M%S')" + + info_distro.sh + fn_print_dots "Starting backup" + fn_script_log_info "Starting backup" + if [ ! -d "${backupdir}" ] || [ "${backupcount}" == "0" ]; then + fn_print_info_nl "Starting backup: No previous backups found" + fn_script_log_info "No previous backups found" + else + fn_print_info_nl "Starting backup: Previous backups found" + fn_script_log_info "Previous backups found" + if [ "${lastbackupdaysago}" == "0" ]; then + daysago="less than 1 day ago" + elif [ "${lastbackupdaysago}" == "1" ]; then + daysago="1 day ago" + else + daysago="${lastbackupdaysago} days ago" + fi + echo -e "* Previous backup was created ${daysago}, total size ${lastbackupsize}" + fi +} + +# Check if server is started and whether to stop it. +fn_backup_stop_server() { + check_status.sh + # Server is running but will not be stopped. + if [ "${stoponbackup}" == "off" ]; then + fn_print_warn_nl "${selfname} is currently running" + echo -e "* Although unlikely; creating a backup while ${selfname} is running might corrupt the backup." + fn_script_log_warn "${selfname} is currently running" + fn_script_log_warn "Although unlikely; creating a backup while ${selfname} is running might corrupt the backup" + # Server is running and will be stopped if stoponbackup=on or unset. + # If server is started + elif [ "${status}" != "0" ]; then + fn_print_restart_warning + startserver="1" + exitbypass=1 + command_stop.sh + fn_firstcommand_reset + fi +} + +# Create required folders. +fn_backup_dir() { + # Create backupdir if it doesn't exist. + if [ ! -d "${backupdir}" ]; then + mkdir -p "${backupdir}" + fi +} + +fn_backup_create_lockfile() { + # Create lockfile. + date '+%s' > "${lockdir:?}/backup.lock" + fn_script_log_info "Backup lockfile generated" + fn_script_log_info "${lockdir}/backup.lock" + # trap to remove lockfile on quit. + trap fn_backup_trap INT +} + +# Compressing files. +fn_backup_compression() { + # Tells how much will be compressed using rootdirduexbackup value from info_distro and prompt for continue. + fn_print_info "A total of ${rootdirduexbackup} will be compressed." + fn_script_log_info "A total of ${rootdirduexbackup} will be compressed: ${backupdir}/${backupname}.tar.gz" + fn_print_dots "Backup (${rootdirduexbackup}) ${backupname}.tar.gz, in progress..." + fn_script_log_info "Backup ${rootdirduexbackup} ${backupname}.tar.gz, in progress" + excludedir=$(fn_backup_relpath) + + # Check that excludedir is a valid path. + if [ ! -d "${excludedir}" ]; then + fn_print_fail_nl "Problem identifying the previous backup directory for exclusion." + fn_script_log_fail "Problem identifying the previous backup directory for exclusion" + core_exit.sh + fi + + tar -czf "${backupdir}/${backupname}.tar.gz" -C "${rootdir}" --exclude "${excludedir}" --exclude "${lockdir}" ./. + local exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol + fn_script_log_fail "Backup in progress: FAIL" + echo -e "${extractcmd}" | tee -a "${lgsmlog}" + fn_print_fail_nl "Starting backup" + fn_script_log_fail "Starting backup" + else + fn_print_ok_eol + fn_print_ok_nl "Completed: ${backupname}.tar.gz, total size $(du -sh "${backupdir}/${backupname}.tar.gz" | awk '{print $1}')" + fn_script_log_pass "Backup created: ${backupname}.tar.gz, total size $(du -sh "${backupdir}/${backupname}.tar.gz" | awk '{print $1}')" + alert="backup" + alert.sh + fi +} + +# Clear old backups according to maxbackups and maxbackupdays variables. +fn_backup_prune() { + # Clear if backup variables are set. + if [ "${maxbackups}" ] && [ -n "${maxbackupdays}" ]; then + # How many backups there are. + info_distro.sh + # How many backups exceed maxbackups. + backupquotadiff=$((backupcount - maxbackups)) + # How many backups exceed maxbackupdays. + backupsoudatedcount=$(find "${backupdir}"/ -type f -name "*.tar.gz" -mtime +"${maxbackupdays}" | wc -l) + # If anything can be cleared. + if [ "${backupquotadiff}" -gt "0" ] || [ "${backupsoudatedcount}" -gt "0" ]; then + fn_print_dots "Pruning" + fn_script_log_info "Backup pruning activated" + fn_print_ok_nl "Pruning" + # If maxbackups greater or equal to backupsoutdatedcount, then it is over maxbackupdays. + if [ "${backupquotadiff}" -ge "${backupsoudatedcount}" ]; then + # Display how many backups will be cleared. + echo -e "* Pruning: ${backupquotadiff} backup(s) has exceeded the ${maxbackups} backups limit" + fn_script_log_info "Pruning: ${backupquotadiff} backup(s) has exceeded the ${maxbackups} backups limit" + fn_sleep_time_1 + fn_print_dots "Pruning: Clearing ${backupquotadiff} backup(s)" + fn_script_log_info "Pruning: Clearing ${backupquotadiff} backup(s)" + # Clear backups over quota. + find "${backupdir}"/ -type f -name "*.tar.gz" -printf '%T@ %p\n' | sort -rn | tail -${backupquotadiff} | cut -f2- -d" " | xargs rm + fn_print_ok_nl "Pruning: Clearing ${backupquotadiff} backup(s)" + fn_script_log_pass "Pruning: Cleared ${backupquotadiff} backup(s)" + # If maxbackupdays is used over maxbackups. + elif [ "${backupquotadiff}" -lt "${backupsoudatedcount}" ]; then + # Display how many backups will be cleared. + echo -e "* Pruning: ${backupsoudatedcount} backup(s) are older than ${maxbackupdays} days." + fn_script_log_info "Pruning: ${backupsoudatedcount} backup(s) older than ${maxbackupdays} days." + fn_sleep_time_1 + fn_print_dots "Pruning: Clearing ${backupquotadiff} backup(s)." + fn_script_log_info "Pruning: Clearing ${backupquotadiff} backup(s)" + # Clear backups over quota + find "${backupdir}"/ -type f -mtime +"${maxbackupdays}" -exec rm -f {} \; + fn_print_ok_nl "Pruning: Clearing ${backupquotadiff} backup(s)" + fn_script_log_pass "Pruning: Cleared ${backupquotadiff} backup(s)" + fi + fi + fi +} + +fn_backup_relpath() { + # Written by CedarLUG as a "realpath --relative-to" alternative in bash. + # Populate an array of tokens initialized from the rootdir components. + declare -a rdirtoks=($(readlink -f "${rootdir}" | sed "s/\// /g")) + if [ ${#rdirtoks[@]} -eq 0 ]; then + fn_print_fail_nl "Problem assessing rootdir during relative path assessment" + fn_script_log_fail "Problem assessing rootdir during relative path assessment: ${rootdir}" + core_exit.sh + fi + + # Populate an array of tokens initialized from the backupdir components. + declare -a bdirtoks=($(readlink -f "${backupdir}" | sed "s/\// /g")) + if [ ${#bdirtoks[@]} -eq 0 ]; then + fn_print_fail_nl "Problem assessing backupdir during relative path assessment" + fn_script_log_fail "Problem assessing backupdir during relative path assessment: ${rootdir}" + core_exit.sh + fi + + # Compare the leading entries of each array. These common elements will be clipped off. + # for the relative path output. + for ((base = 0; base < ${#rdirtoks[@]}; base++)); do + [[ "${rdirtoks[$base]}" != "${bdirtoks[$base]}" ]] && break + done + + # Next, climb out of the remaining rootdir location with updir references. + for ((x = base; x < ${#rdirtoks[@]}; x++)); do + echo -n "../" + done + + # Climb down the remaining components of the backupdir location. + for ((x = base; x < $((${#bdirtoks[@]} - 1)); x++)); do + echo -n "${bdirtoks[$x]}/" + done + + # In the event there were no directories left in the backupdir above to + # traverse down, just add a newline. Otherwise at this point, there is + # one remaining directory component in the backupdir to navigate. + if (("$base" < "${#bdirtoks[@]}")); then + echo -e "${bdirtoks[$((${#bdirtoks[@]} - 1))]}" + else + echo + fi +} + +# Start the server if it was stopped for the backup. +fn_backup_start_server() { + if [ -n "${startserver}" ]; then + exitbypass=1 + command_start.sh + fn_firstcommand_reset + fi +} + +fn_print_dots "" +check.sh +core_logs.sh + +fn_backup_check_lockfile +fn_backup_init +fn_backup_stop_server +fn_backup_dir +fn_backup_create_lockfile +fn_backup_compression +fn_backup_prune +fn_backup_start_server + +# Remove backup lockfile. +rm -f "${lockdir:?}/backup.lock" +core_exit.sh diff --git a/lgsm/modules/command_check_update.sh b/lgsm/modules/command_check_update.sh new file mode 100644 index 0000000..2e6855f --- /dev/null +++ b/lgsm/modules/command_check_update.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# LinuxGSM command_check_update.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Handles updating of servers. + +commandname="CHECK-UPDATE" +commandaction="Check for Update" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +fn_print_dots "" +check.sh +core_logs.sh + +if [ "${shortname}" == "ts3" ]; then + update_ts3.sh +elif [ "${shortname}" == "mc" ]; then + update_mc.sh +elif [ "${shortname}" == "mcb" ]; then + update_mcb.sh +elif [ "${shortname}" == "pmc" ] || [ "${shortname}" == "vpmc" ] || [ "${shortname}" == "wmc" ]; then + update_pmc.sh +elif [ "${shortname}" == "fctr" ]; then + update_fctr.sh +elif [ "${shortname}" == "mta" ]; then + update_mta.sh +elif [ "${shortname}" == "jk2" ]; then + update_jk2.sh +elif [ "${shortname}" == "vints" ]; then + update_vints.sh +elif [ "${shortname}" == "ut99" ]; then + update_ut99.sh +else + update_steamcmd.sh +fi + +core_exit.sh diff --git a/lgsm/modules/command_console.sh b/lgsm/modules/command_console.sh new file mode 100644 index 0000000..a5d49d7 --- /dev/null +++ b/lgsm/modules/command_console.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# LinuxGSM command_console.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Gives access to the server tmux console. + +commandname="CONSOLE" +commandaction="Access console" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +check.sh +fn_print_header + +if [ "${consoleverbose}" == "yes" ]; then + echo -e "* Verbose output: ${lightgreen}yes${default}" +elif [ "${consoleverbose}" == "no" ]; then + echo -e "* Verbose output: ${red}no${default}" +else + echo -e "* Verbose output: ${red}unknown${default}" +fi + +if [ "${consoleinteract}" == "yes" ]; then + echo -e "* Interactive output: ${lightgreen}yes${default}" +elif [ "${consoleinteract}" == "no" ]; then + echo -e "* Interactive output: ${red}no${default}" +else + echo -e "* Interactive output: ${red}unknown${default}" +fi +echo "" +fn_print_information_nl "Press \"CTRL+b\" then \"d\" to exit console." +fn_print_warning_nl "Do NOT press CTRL+c to exit." +echo -e "* https://docs.linuxgsm.com/commands/console" +echo -e "" +if ! fn_prompt_yn "Continue?" Y; then + exitcode=0 + core_exit.sh +fi +fn_print_dots "Accessing console" +check_status.sh +if [ "${status}" != "0" ]; then + fn_print_ok_nl "Accessing console" + fn_script_log_pass "Console accessed" + tmux -L "${socketname}" attach-session -t "${sessionname}" + fn_print_ok_nl "Closing console" + fn_script_log_pass "Console closed" +else + fn_print_error_nl "Server not running" + fn_script_log_error "Failed to access: Server not running" + if fn_prompt_yn "Do you want to start the server?" Y; then + exitbypass=1 + command_start.sh + fn_firstcommand_reset + fi +fi + +core_exit.sh diff --git a/lgsm/modules/command_debug.sh b/lgsm/modules/command_debug.sh new file mode 100644 index 0000000..495417c --- /dev/null +++ b/lgsm/modules/command_debug.sh @@ -0,0 +1,142 @@ +#!/bin/bash +# LinuxGSM command_debug.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Runs the server without tmux and directly from the terminal. + +commandname="DEBUG" +commandaction="Debuging" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +# Trap to remove lockfile on quit. +fn_lockfile_trap() { + # Remove lockfile. + rm -f "${lockdir:?}/${selfname}-started.lock" + # resets terminal. Servers can sometimes mess up the terminal on exit. + reset + fn_print_dots "Stopping debug" + fn_print_ok_nl "Stopping debug" + fn_script_log_pass "Stopping debug" + # remove trap. + trap - INT + core_exit.sh +} + +check.sh +fix.sh +info_distro.sh +info_game.sh +fn_print_header +{ + echo -e "${lightblue}Distro:\t\t${default}${distroname}" + echo -e "${lightblue}Architecture:\t\t${default}${arch}" + echo -e "${lightblue}Kernel:\t\t${default}${kernel}" + echo -e "${lightblue}Hostname:\t\t${default}${HOSTNAME}" + echo -e "${lightblue}tmux:\t\t${default}${tmuxv}" + echo -e "${lightblue}Avg Load:\t\t${default}${load}" + echo -e "${lightblue}Free Memory:\t\t${default}${physmemfree}" + echo -e "${lightblue}Free Disk:\t\t${default}${availspace}" +} | column -s $'\t' -t + +# glibc required. +if [ -n "${glibc}" ]; then + if [ "${glibc}" == "null" ]; then + # Glibc is not required. + : + elif [ -z "${glibc}" ]; then + echo -e "${lightblue}glibc required:\t${red}UNKNOWN${default}" + elif [ "$(printf '%s\n'${glibc}'\n' ${glibcversion} | sort -V | head -n 1)" != "${glibc}" ]; then + echo -e "${lightblue}glibc required:\t${red}${glibc} ${default}(${red}distro glibc ${glibcversion} too old${default})" + else + echo -e "${lightblue}glibc required:\t${green}${glibc}${default}" + fi +fi + +# Server IP. +echo -e "${lightblue}Game Server IP:\t${default}${ip}:${port}" + +# External server IP. +if [ "${publicip}" ]; then + if [ "${ip}" != "${publicip}" ]; then + echo -e "${lightblue}Internet IP:\t${default}${publicip}:${port}" + fi +fi + +# Server password. +if [ "${serverpassword}" ]; then + echo -e "${lightblue}Server password:\t${default}${serverpassword}" +fi + +fn_reload_startparameters +echo -e "${lightblue}Start parameters:${default}" +if [ "${engine}" == "source" ] || [ "${engine}" == "goldsrc" ]; then + echo -e "${executable} ${startparameters} -debug" +elif [ "${engine}" == "quake" ]; then + echo -e "${executable} ${startparameters} -condebug" +else + echo -e "${preexecutable} ${executable} ${startparameters}" +fi +echo -e "" +echo -e "Use debug for identifying server issues only!" +echo -e "Press CTRL+c to drop out of debug mode." +fn_print_warning_nl "If ${selfname} is already running it will be stopped." + +if ! fn_prompt_yn "Continue?" Y; then + exitcode=0 + core_exit.sh +fi + +fn_print_info_nl "Stopping any running servers" +fn_script_log_info "Stopping any running servers" +exitbypass=1 +command_stop.sh +fn_firstcommand_reset +unset exitbypass +fn_print_dots "Starting debug" +fn_script_log_info "Starting debug" +fn_print_ok_nl "Starting debug" + +# Create started lockfile. +date '+%s' > "${lockdir:?}/${selfname}-started.lock" +echo "${version}" >> "${lockdir}/${selfname}-started.lock" +echo "${port}" >> "${lockdir}/${selfname}-started.lock" +fn_script_log_info "Lockfile generated" +fn_script_log_info "${lockdir}/${selfname}-started.lock" + +if [ "${shortname}" == "av" ]; then + cd "${systemdir}" || exit +else + cd "${executabledir}" || exit +fi + +# Note: do not add double quotes to ${executable} ${startparameters}. +if [ "${engine}" == "source" ] || [ "${engine}" == "goldsrc" ]; then + eval "${executable} ${startparameters} -debug" +elif [ "${engine}" == "quake" ]; then + eval "${executable} ${startparameters} -condebug" +else + # shellcheck disable=SC2086 + eval "${preexecutable} ${executable} ${startparameters}" +fi + +if [ $? -ne 0 ]; then + fn_print_error_nl "Server has stopped: exit code: $?" + fn_script_log_error "Server has stopped: exit code: $?" + fn_print_error_nl "Press ENTER to exit debug mode" + read -r +else + fn_print_ok_nl "Server has stopped" + fn_script_log_pass "Server has stopped" + fn_print_ok_nl "Press ENTER to exit debug mode" + read -r +fi + +fn_lockfile_trap + +fn_print_dots "Stopping debug" +fn_print_ok_nl "Stopping debug" +fn_script_log_info "Stopping debug" + +core_exit.sh diff --git a/lgsm/modules/command_details.sh b/lgsm/modules/command_details.sh new file mode 100644 index 0000000..ad55b12 --- /dev/null +++ b/lgsm/modules/command_details.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# LinuxGSM command_details.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Displays server information. + +commandname="DETAILS" +commandaction="Viewing details" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +# Run checks and gathers details to display. +check.sh +info_distro.sh +info_game.sh +info_messages.sh +if [ "${querymode}" == "2" ] || [ "${querymode}" == "3" ]; then + for queryip in "${queryips[@]}"; do + query_gamedig.sh + if [ "${querystatus}" == "0" ]; then + break + fi + done +fi +fn_info_messages_distro +fn_info_messages_server_resource +fn_info_messages_gameserver_resource +fn_info_messages_gameserver +fn_info_messages_script +fn_info_messages_backup +# Some game servers do not have parms. +if [ "${shortname}" != "jc2" ] && [ "${shortname}" != "dst" ] && [ "${shortname}" != "pz" ] && [ "${engine}" != "renderware" ]; then + fn_info_messages_commandlineparms +fi +fn_info_messages_ports_edit +fn_info_messages_ports +fn_info_messages_select_engine +fn_info_messages_statusbottom + +exitcode=0 +core_exit.sh diff --git a/lgsm/modules/command_dev_clear_modules.sh b/lgsm/modules/command_dev_clear_modules.sh new file mode 100644 index 0000000..bf19b25 --- /dev/null +++ b/lgsm/modules/command_dev_clear_modules.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# LinuxGSM command_dev_clear_modules.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Deletes the contents of the modules dir. + +commandname="DEV-CLEAR-MODULES" +commandaction="Clearing modules" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +echo -e "" +echo -e "${bold}${lightyellow}Clear Modules${default}" +fn_messages_separator +echo -e "" +if fn_prompt_yn "Do you want to delete all modules?" Y; then + rm -rfv "${modulesdir:?}/"* + rm -rfv "${configdirdefault:?}/"* + fn_script_log_info "Cleared modules directory" + fn_script_log_info "Cleared default config directory" +fi + +core_exit.sh diff --git a/lgsm/modules/command_dev_debug.sh b/lgsm/modules/command_dev_debug.sh new file mode 100644 index 0000000..eb03569 --- /dev/null +++ b/lgsm/modules/command_dev_debug.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# LinuxGSM command_dev_debug.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Dev only: Enables debugging log to be saved to dev-debug.log. + +commandname="DEV-DEBUG" +commandaction="Developer debug" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_reset + +fn_print_dots "" +check.sh +core_logs.sh + +if [ -f "${rootdir}/.dev-debug" ]; then + rm -f "${rootdir:?}/.dev-debug" + fn_print_ok_nl "Disabled dev-debug" + fn_script_log_info "Disabled dev-debug" +else + date '+%s' > "${rootdir}/.dev-debug" + fn_print_ok_nl "Enabled dev-debug" + fn_script_log_info "Enabled dev-debug" +fi + +core_exit.sh diff --git a/lgsm/modules/command_dev_details.sh b/lgsm/modules/command_dev_details.sh new file mode 100644 index 0000000..93dae77 --- /dev/null +++ b/lgsm/modules/command_dev_details.sh @@ -0,0 +1,98 @@ +#!/bin/bash +# LinuxGSM command_dev_debug.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Dev only: Enables debugging log to be saved to dev-debug.log. + +if [ -f "config" ]; then + servercfgfullpath="config" +fi +if [ -f "clusterconfig" ]; then + clustercfgfullpath="clusterconfig" +fi + +info_game.sh + +carriagereturn=$(file -b "${servercfgfullpath}" | grep -q CRLF && echo "${red}CRLF${default}" || echo "${lightgreen}LF${default}") + +echo -e "" +echo -e "${bold}${lightgreen}Server Details${default}" +fn_messages_separator + +echo -e "" +echo -e "Game: ${gamename}" +echo -e "Config type: ${configtype}" +echo -e "Config file: ${servercfgfullpath}" +if [ -f "${clustercfgfullpath}" ]; then + echo -e "Cluster config file: ${clustercfgfullpath}" +fi +echo -e "Carriage Return: ${carriagereturn}" + +# Create an associative array of the server details. +declare -A server_details=( + ['Admin Password']="${adminpassword}" + ['API Port']="${apiport}" + ['Cave']="${cave}" + ['Cluster']="${cluster}" + ['Config IP']="${configip}" + ['Default Map']="${defaultmap}" + ['Game Mode']="${gamemode}" + ['Game Type']="${gametype}" + ['HTTP Enabled']="${httpenabled}" + ['HTTP IP']="${httpip}" + ['HTTP Password']="${httppassword}" + ['HTTP Port']="${httpport}" + ['HTTP User']="${httpuser}" + ['Internet IP']="${publicip}" + ['LAN Port']="${lanport}" + ['Master Port']="${masterport}" + ['Master']="${master}" + ['Maxplayers']="${maxplayers}" + ['OldQueryPortNumber']="${oldqueryportnumber}" + ['Port']="${port}" + ['Query Port']="${queryport}" + ['RCON Enabled']="${rconenabled}" + ['RCON Password']="${rconpassword}" + ['RCON Port']="${rconport}" + ['Reserved Slots']="${reservedslots}" + ['Server IP']="${ip}" + ['Server Password']="${serverpassword}" + ['Servername']="${servername}" + ['Shard']="${shard}" + ['Sharding']="${sharding}" + ['Steam Auth Port']="${steamauthport}" + ['Telnet Enabled']="${telnetenabled}" + ['Telnet IP']="${telnetip}" + ['Telnet Password']="${telnetpassword}" + ['Telnet Port']="${telnetport}" + ['Tickrate']="${tickrate}" + ['World Name']="${worldname}" + ['World Type']="${worldtype}" +) + +# Initialize a variable to keep track of missing server details. +missing_details="" + +# Loop through the server details and output them. +echo -e "" +echo -e "${bold}${lightgreen}Available Server Details${default}" +fn_messages_separator +for key in "${!server_details[@]}"; do + value=${server_details[$key]} + if [ -z "$value" ]; then + missing_details+="\n${key}" + else + echo -e "$key: $value " + fi +done + +# Output the missing server details if there are any. +if [ -n "$missing_details" ]; then + echo -e "" + echo -e "${lightgreen}Missing Server Details${default}" + fn_messages_separator + echo -e "${missing_details}" +fi + +core_exit.sh diff --git a/lgsm/modules/command_dev_detect_deps.sh b/lgsm/modules/command_dev_detect_deps.sh new file mode 100644 index 0000000..6215fb8 --- /dev/null +++ b/lgsm/modules/command_dev_detect_deps.sh @@ -0,0 +1,231 @@ +#!/bin/bash +# LinuxGSM command_dev_detect_deps.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Detects dependencies the server binary requires. + +commandname="DEV-DETECT-DEPS" +commandaction="Developer detect deps" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +echo -e "" +echo -e "${bold}Dependencies Checker${default}" +fn_messages_separator +echo -e "Checking directory: " +echo -e "${serverfiles}" +if [ "$(command -v eu-readelf 2> /dev/null)" ]; then + readelf=eu-readelf +elif [ "$(command -v readelf 2> /dev/null)" ]; then + readelf=readelf +else + echo -e "readelf/eu-readelf not installed" +fi +files=$(find "${serverfiles}" | wc -l) +find "${serverfiles}" -type f -print0 \ + | while IFS= read -r -d $'\0' line; do + if [ "${readelf}" == "eu-readelf" ]; then + ${readelf} -d "${line}" 2> /dev/null | grep NEEDED | awk '{ print $4 }' | sed 's/\[//g;s/\]//g' >> "${tmpdir}/.depdetect_readelf" + else + ${readelf} -d "${line}" 2> /dev/null | grep NEEDED | awk '{ print $5 }' | sed 's/\[//g;s/\]//g' >> "${tmpdir}/.depdetect_readelf" + fi + echo -n "${i} / ${files}" $'\r' + ((i++)) + done + +sort "${tmpdir}/.depdetect_readelf" | uniq > "${tmpdir}/.depdetect_readelf_uniq" + +touch "${tmpdir}/.depdetect_centos_list" +touch "${tmpdir}/.depdetect_ubuntu_list" +touch "${tmpdir}/.depdetect_debian_list" + +while read -r lib; do + echo -e "${lib}" + libs_array=(libm.so.6 libc.so.6 libtcmalloc_minimal.so.4 libpthread.so.0 libdl.so.2 libnsl.so.1 libgcc_s.so.1 librt.so.1 ld-linux.so.2 libdbus-glib-1.so.2 libgio-2.0.so.0 libglib-2.0.so.0 libGL.so.1 libgobject-2.0.so.0 libnm-glib.so.4 libnm-util.so.2) + for lib_file in "${libs_array[@]}"; do + if [ "${lib}" == "${lib_file}" ]; then + echo -e "glibc.i686" >> "${tmpdir}/.depdetect_centos_list" + echo -e "lib32gcc1" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "lib32gcc1" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + fi + done + + libs_array=(libawt.so libjava.so libjli.so libjvm.so libnet.so libnio.so libverify.so) + for lib_file in "${libs_array[@]}"; do + if [ "${lib}" == "${lib_file}" ]; then + echo -e "java-1.8.0-openjdk" >> "${tmpdir}/.depdetect_centos_list" + echo -e "default-jre" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "default-jre" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + fi + done + + libs_array=(libtier0.so libtier0_srv.so libvstdlib_srv.so Core.so libvstdlib.so libtier0_s.so Editor.so Engine.so liblua.so libsteam_api.so ld-linux-x86-64.so.2 libPhysX3_x86.so libPhysX3Common_x86.so libPhysX3Cooking_x86.so) + for lib_file in "${libs_array[@]}"; do + # Known shared libs what dont requires dependencies. + if [ "${lib}" == "${lib_file}" ]; then + libdetected=1 + fi + done + + if [ "${lib}" == "libstdc++.so.6" ]; then + echo -e "libstdc++.i686" >> "${tmpdir}/.depdetect_centos_list" + echo -e "libstdc++6:i386" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "libstdc++6:i386" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + elif [ "${lib}" == "libstdc++.so.5" ]; then + echo -e "compat-libstdc++-33.i686" >> "${tmpdir}/.depdetect_centos_list" + echo -e "libstdc++5:i386" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "libstdc++5:i386" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + elif [ "${lib}" == "libcurl-gnutls.so.4" ]; then + echo -e "libcurl.i686" >> "${tmpdir}/.depdetect_centos_list" + echo -e "libcurl4-gnutls-dev:i386" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "libcurl4-gnutls-dev:i386" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + elif [ "${lib}" == "libspeex.so.1" ] || [ "${lib}" == "libspeexdsp.so.1" ]; then + echo -e "speex.i686" >> "${tmpdir}/.depdetect_centos_list" + echo -e "speex:i386" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "speex:i386" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + elif [ "${lib}" == "./libSDL-1.2.so.0" ] || [ "${lib}" == "libSDL-1.2.so.0" ]; then + echo -e "SDL.i686" >> "${tmpdir}/.depdetect_centos_list" + echo -e "libsdl1.2debian" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "libsdl1.2debian" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + elif [ "${lib}" == "libtbb.so.2" ]; then + echo -e "tbb.i686" >> "${tmpdir}/.depdetect_centos_list" + echo -e "libtbb2" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "libtbb2" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + + elif [ "${lib}" == "libXrandr.so.2" ]; then + echo -e "libXrandr" >> "${tmpdir}/.depdetect_centos_list" + echo -e "libxrandr2" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "libxrandr2" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + elif [ "${lib}" == "libXext.so.6" ]; then + echo -e "libXext" >> "${tmpdir}/.depdetect_centos_list" + echo -e "libxext6" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "libxext6" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + elif [ "${lib}" == "libXtst.so.6" ]; then + echo -e "libXtst" >> "${tmpdir}/.depdetect_centos_list" + echo -e "libxtst6" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "libxtst6" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + elif [ "${lib}" == "libpulse.so.0" ]; then + echo -e "pulseaudio-libs" >> "${tmpdir}/.depdetect_centos_list" + echo -e "libpulse0" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "libpulse0" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + elif [ "${lib}" == "libopenal.so.1" ]; then + echo -e "" >> "${tmpdir}/.depdetect_centos_list" + echo -e "libopenal1" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "libopenal1" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + elif [ "${lib}" == "libgconf-2.so.4" ]; then + echo -e "GConf2" >> "${tmpdir}/.depdetect_centos_list" + echo -e "libgconf2-4" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "libgconf2-4" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + elif [ "${lib}" == "libz.so.1" ]; then + echo -e "zlib" >> "${tmpdir}/.depdetect_centos_list" + echo -e "zlib1g" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "zlib1g" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + elif [ "${lib}" == "libatk-1.0.so.0" ]; then + echo -e "atk" >> "${tmpdir}/.depdetect_centos_list" + echo -e "libatk1.0-0" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "libatk1.0-0" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + elif [ "${lib}" == "libcairo.so.2" ]; then + echo -e "cairo" >> "${tmpdir}/.depdetect_centos_list" + echo -e "libcairo2" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "libcairo2" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + elif [ "${lib}" == "libfontconfig.so.1" ]; then + echo -e "fontconfig" >> "${tmpdir}/.depdetect_centos_list" + echo -e "libfontconfig1" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "libfontconfig1" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + elif [ "${lib}" == "libfreetype.so.6" ]; then + echo -e "freetype" >> "${tmpdir}/.depdetect_centos_list" + echo -e "libfreetype6" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "libfreetype6" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + elif [ "${lib}" == "libc++.so.1" ]; then + echo -e "libcxx" >> "${tmpdir}/.depdetect_centos_list" + echo -e "libc++1" >> "${tmpdir}/.depdetect_ubuntu_list" + echo -e "libc++1" >> "${tmpdir}/.depdetect_debian_list" + libdetected=1 + fi + + if [ "${libdetected}" != "1" ]; then + unknownlib=1 + echo -e "${lib}" >> "${tmpdir}/.depdetect_unknown" + fi + unset libdetected +done < "${tmpdir}/.depdetect_readelf_uniq" + +sort "${tmpdir}/.depdetect_centos_list" | uniq >> "${tmpdir}/.depdetect_centos_list_uniq" +sort "${tmpdir}/.depdetect_ubuntu_list" | uniq >> "${tmpdir}/.depdetect_ubuntu_list_uniq" +sort "${tmpdir}/.depdetect_debian_list" | uniq >> "${tmpdir}/.depdetect_debian_list_uniq" +if [ "${unknownlib}" == "1" ]; then + sort "${tmpdir}/.depdetect_unknown" | uniq >> "${tmpdir}/.depdetect_unknown_uniq" +fi + +awk -vORS='' '{ print $1,$2 }' "${tmpdir}/.depdetect_centos_list_uniq" > "${tmpdir}/.depdetect_centos_line" +awk -vORS='' '{ print $1,$2 }' "${tmpdir}/.depdetect_ubuntu_list_uniq" > "${tmpdir}/.depdetect_ubuntu_line" +awk -vORS='' '{ print $1,$2 }' "${tmpdir}/.depdetect_debian_list_uniq" > "${tmpdir}/.depdetect_debian_line" +echo -e "" +echo -e "" +echo -e "${bold}Required Dependencies${default}" +fn_messages_separator +echo -e "${executable}" +echo -e "" +echo -e "CentOS" +fn_messages_separator +cat "${tmpdir}/.depdetect_centos_line" +echo -e "" +echo -e "" +echo -e "Ubuntu" +fn_messages_separator +cat "${tmpdir}/.depdetect_ubuntu_line" +echo -e "" +echo -e "" +echo -e "Debian" +fn_messages_separator +cat "${tmpdir}/.depdetect_debian_line" +echo -e "" +if [ "${unknownlib}" == "1" ]; then + echo -e "" + echo -e "Unknown shared Library" + fn_messages_separator + cat "${tmpdir}/.depdetect_unknown" +fi +echo -e "" +echo -e "Required Librarys" +fn_messages_separator +sort "${tmpdir}/.depdetect_readelf" | uniq +echo -en "\n" +rm -f "${tmpdir:?}/.depdetect_centos_line" +rm -f "${tmpdir:?}/.depdetect_centos_list" +rm -f "${tmpdir:?}/.depdetect_centos_list_uniq" + +rm -f "${tmpdir:?}/.depdetect_debian_line" +rm -f "${tmpdir:?}/.depdetect_debian_list" +rm -f "${tmpdir:?}/.depdetect_debian_list_uniq" + +rm -f "${tmpdir:?}/.depdetect_ubuntu_line" +rm -f "${tmpdir:?}/.depdetect_ubuntu_list" +rm -f "${tmpdir:?}/.depdetect_ubuntu_list_uniq" + +rm -f "${tmpdir:?}/.depdetect_readelf" +rm -f "${tmpdir:?}/.depdetect_readelf_uniq" +rm -f "${tmpdir:?}/.depdetect_unknown" +rm -f "${tmpdir:?}/.depdetect_unknown_uniq" + +core_exit.sh diff --git a/lgsm/modules/command_dev_detect_glibc.sh b/lgsm/modules/command_dev_detect_glibc.sh new file mode 100644 index 0000000..214adc8 --- /dev/null +++ b/lgsm/modules/command_dev_detect_glibc.sh @@ -0,0 +1,92 @@ +#!/bin/bash +# LinuxGSM command_dev_detect_glibc.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Automatically detects the version of GLIBC that is required. +# Can check a file or directory recursively. + +commandname="DEV-DETECT-GLIBC" +commandaction="Developer detect glibc" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +fn_messages_separator +echo -e "glibc Requirements Checker" +fn_messages_separator + +if [ ! "$(command -v objdump 2> /dev/null)" ]; then + fn_print_failure_nl "objdump is missing" + fn_script_log_fail "objdump is missing" + core_exit.sh +fi + +if [ -z "${serverfiles}" ]; then + dir=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")") +fi + +if [ -d "${serverfiles}" ]; then + echo -e "Checking directory: " + echo -e "${serverfiles}" +elif [ -f "${serverfiles}" ]; then + echo -e "Checking file: " + echo -e "${serverfiles}" +fi +echo -e "" + +glibc_check_dir_array=(steamcmddir serverfiles) +for glibc_check_var in "${glibc_check_dir_array[@]}"; do + if [ "${glibc_check_var}" == "serverfiles" ]; then + glibc_check_dir="${serverfiles}" + glibc_check_name="${gamename}" + elif [ "${glibc_check_var}" == "steamcmddir" ]; then + glibc_check_dir="${steamcmddir}" + glibc_check_name="SteamCMD" + fi + + if [ -d "${glibc_check_dir}" ]; then + glibc_check_files=$(find "${glibc_check_dir}" | wc -l) + find "${glibc_check_dir}" -type f -print0 \ + | while IFS= read -r -d $'\0' line; do + glibcversion=$(objdump -T "${line}" 2> /dev/null | grep -oP "GLIBC[^ ]+" | grep -v GLIBCXX | sort | uniq | sort -r --version-sort | head -n 1) + if [ "${glibcversion}" ]; then + echo -e "${glibcversion}: ${line}" >> "${tmpdir}/detect_glibc_files_${glibc_check_var}.tmp" + fi + objdump -T "${line}" 2> /dev/null | grep -oP "GLIBC[^ ]+" >> "${tmpdir}/detect_glibc_${glibc_check_var}.tmp" + echo -n "${i} / ${glibc_check_files}" $'\r' + ((i++)) + done + echo -e "" + echo -e "" + echo -e "${glibc_check_name} glibc Requirements" + fn_messages_separator + if [ -f "${tmpdir}/detect_glibc_files_${glibc_check_var}.tmp" ]; then + echo -e "Required glibc" + cat "${tmpdir}/detect_glibc_${glibc_check_var}.tmp" | sort | uniq | sort -r --version-sort | head -1 | tee -a "${tmpdir}/detect_glibc_highest.tmp" + echo -e "" + echo -e "Files requiring GLIBC" + echo -e "Highest verion required: filename" + cat "${tmpdir}/detect_glibc_files_${glibc_check_var}.tmp" + echo -e "" + echo -e "All required GLIBC versions" + cat "${tmpdir}/detect_glibc_${glibc_check_var}.tmp" | sort | uniq | sort -r --version-sort + rm -f "${tmpdir:?}/detect_glibc_${glibc_check_var}.tmp" + rm -f "${tmpdir:?}/detect_glibc_files_${glibc_check_var}.tmp" + else + fn_print_information_nl "glibc is not required" + fi + else + fn_print_information_nl "${glibc_check_name} is not installed" + fi +done +echo -e "" +echo -e "Final glibc Requirement" +fn_messages_separator +if [ -f "${tmpdir}/detect_glibc_highest.tmp" ]; then + cat "${tmpdir}/detect_glibc_highest.tmp" | sort | uniq | sort -r --version-sort | head -1 + rm -f "${tmpdir:?}/detect_glibc_highest.tmp" +else + fn_print_information_nl "glibc is not required" +fi + +core_exit.sh diff --git a/lgsm/modules/command_dev_detect_ldd.sh b/lgsm/modules/command_dev_detect_ldd.sh new file mode 100644 index 0000000..af41bb5 --- /dev/null +++ b/lgsm/modules/command_dev_detect_ldd.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# LinuxGSM command_dev_detect_ldd.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Automatically detects required deps using ldd. +# Can check a file or directory recursively. + +commandname="DEV-DETECT-LDD" +commandaction="Developer detect ldd" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +fn_messages_separator +echo -e "Shared Object dependencies Checker" +fn_messages_separator + +if [ -z "${serverfiles}" ]; then + dir=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")") +fi + +if [ -d "${serverfiles}" ]; then + echo -e "Checking directory: " + echo -e "${serverfiles}" +elif [ -f "${serverfiles}" ]; then + echo -e "Checking file: " + echo -e "${serverfiles}" +fi +echo -e "" +touch "${tmpdir}/detect_ldd.tmp" +touch "${tmpdir}/detect_ldd_not_found.tmp" + +files=$(find "${serverfiles}" | wc -l) +find "${serverfiles}" -type f -print0 \ + | while IFS= read -r -d $'\0' line; do + if ldd "${line}" 2> /dev/null | grep -v "not a dynamic executable"; then + echo -e "${line}" >> "${tmpdir}/detect_ldd.tmp" + ldd "${line}" 2> /dev/null | grep -v "not a dynamic executable" >> "${tmpdir}/detect_ldd.tmp" + if ldd "${line}" 2> /dev/null | grep -v "not a dynamic executable" | grep "not found"; then + echo -e "${line}" >> "${tmpdir}/detect_ldd_not_found.tmp" + ldd "${line}" 2> /dev/null | grep -v "not a dynamic executable" | grep "not found" >> "${tmpdir}/detect_ldd_not_found.tmp" + fi + fi + echo -n "$i / $files" $'\r' + ((i++)) + done +echo -e "" +echo -e "" +echo -e "All" +fn_messages_separator +cat "${tmpdir}/detect_ldd.tmp" + +echo -e "" +echo -e "Not Found" +fn_messages_separator +cat "${tmpdir}/detect_ldd_not_found.tmp" + +rm -f "${tmpdir:?}/detect_ldd.tmp" +rm -f "${tmpdir:?}/detect_ldd_not_found.tmp" + +core_exit.sh diff --git a/lgsm/modules/command_dev_query_raw.sh b/lgsm/modules/command_dev_query_raw.sh new file mode 100644 index 0000000..2314d75 --- /dev/null +++ b/lgsm/modules/command_dev_query_raw.sh @@ -0,0 +1,279 @@ +#!/bin/bash +# LinuxGSM command_dev_query_raw.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Raw gamedig output of the server. + +commandname="DEV-QUERY-RAW" +commandaction="Developer query raw" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +check.sh +info_game.sh +info_distro.sh +info_messages.sh + +echo -e "" +echo -e "${lightgreen}IP Addresses Variables${default}" +fn_messages_separator +echo -e "" +echo -e "IP: ${ip}" +echo -e "HTTP IP: ${httpip}" +echo -e "Public IP: ${publicip}" +echo -e "Telnet IP: ${telnetip}" +echo -e "Display IP: ${displayip}" + +echo -e "" +echo -e "${lightgreen}Query IP Addresses${default}" +fn_messages_separator +echo -e "" +for queryip in "${queryips[@]}"; do + echo -e "${queryip}" +done +echo -e "" +echo -e "${lightgreen}Game Server Ports${default}" +fn_messages_separator +{ + echo -e "${lightblue}Port Name \tPort Number \tStatus \tTCP \tUDP${default}" + if [ -v port ]; then + echo -e "Game: \t${port} \t$(ss -tupl | grep -c "${port}") \t$(ss -tupl | grep "${port}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${port}" | grep udp | awk '{ print $2 }')" + else + echo -e "Game:" + fi + if [ "${shortname}" == "pvr" ]; then + if [ -v port401 ]; then + echo -e "Game+400: \t${port401} \t$(ss -tupl | grep -c "${port401}") \t$(ss -tupl | grep "${port401}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${port401}" | grep udp | awk '{ print $2 }')" + else + echo -e "Game+400:" + fi + fi + + if [ "${shortname}" == "mcb" ]; then + if [ -v portipv6 ]; then + echo -e "Game ipv6: \t${portipv6} \t$(ss -tupl | grep -c "${portipv6}") \t$(ss -tupl | grep "${portipv6}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${portipv6}" | grep udp | awk '{ print $2 }')" + else + echo -e "Game ipv6:" + fi + fi + + if [ -v queryport ]; then + echo -e "Query: \t${queryport} \t$(ss -tupl | grep -c "${queryport}") \t$(ss -tupl | grep "${queryport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${queryport}" | grep udp | awk '{ print $2 }')" + else + echo -e "Query:" + fi + + if [ -v apiport ]; then + echo -e "Game: \t${apiport} \t$(ss -tupl | grep -c "${apiport}") \t$(ss -tupl | grep "${apiport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${apiport}" | grep udp | awk '{ print $2 }')" + else + echo -e "API:" + fi + + if [ -v appport ]; then + echo -e "App: \t${appport} \t$(ss -tupl | grep -c "${appport}") \t$(ss -tupl | grep "${appport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${appport}" | grep udp | awk '{ print $2 }')" + else + echo -e "App:" + fi + + if [ -v battleeyeport ]; then + echo -e "BattleEye: \t${battleeyeport} \t$(ss -tupl | grep -c "${battleeyeport}") \t$(ss -tupl | grep "${battleeyeport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${battleeyeport}" | grep udp | awk '{ print $2 }')" + else + echo -e "BattleEye:" + fi + + if [ -v beaconport ]; then + echo -e "Beacon: \t${beaconport} \t$(ss -tupl | grep -c "${beaconport}") \t$(ss -tupl | grep "${beaconport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${beaconport}" | grep udp | awk '{ print $2 }')" + else + echo -e "Beacon:" + fi + + if [ -v clientport ]; then + echo -e "Client: \t${clientport} \t$(ss -tupl | grep -c "${clientport}") \t$(ss -tupl | grep "${clientport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${clientport}" | grep udp | awk '{ print $2 }')" + else + echo -e "Client:" + fi + + if [ -v fileport ]; then + echo -e "File: \t${fileport} \t$(ss -tupl | grep -c "${fileport}") \t$(ss -tupl | grep "${fileport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${fileport}" | grep udp | awk '{ print $2 }')" + else + echo -e "File:" + fi + + if [ -v httpport ]; then + echo -e "HTTP: \t${httpport} \t$(ss -tupl | grep -c "${httpport}") \t$(ss -tupl | grep "${httpport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${httpport}" | grep udp | awk '{ print $2 }')" + else + echo -e "HTTP:" + fi + + if [ -v httpqueryport ]; then + echo -e "HTTP Query: \t${httpqueryport} \t$(ss -tupl | grep -c "${httpqueryport}") \t$(ss -tupl | grep" ${httpqueryport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${httpqueryport}" | grep udp | awk '{ print $2 }')" + else + echo -e "HTTP Query:" + fi + + if [ -v httpport ]; then + echo -e "Web Interface: \t${httpport} \t$(ss -tupl | grep -c "${httpport}") \t$(ss -tupl | grep "${httpport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${httpport}" | grep udp | awk '{ print $2 }')" + else + echo -e "Web Interface:" + fi + + if [ -v masterport ]; then + echo -e "Game: Master: \t${masterport} \t$(ss -tupl | grep -c "${masterport}") \t$(ss -tupl | grep "${masterport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${masterport}" | grep udp | awk '{ print $2 }')" + else + echo -e "Game: Master:" + fi + + if [ -v rawport ]; then + echo -e "RAW UDP Socket: \t${rawport} \t$(ss -tupl | grep -c "${rawport}") \t$(ss -tupl | grep "${rawport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${rawport}" | grep udp | awk '{ print $2 }')" + else + echo -e "RAW UDP Socket:" + fi + + if [ -v rconport ]; then + echo -e "RCON: \t${rconport} \t$(ss -tupl | grep -c "${rconport}") \t$(ss -tupl | grep "${rconport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${rconport}" | grep udp | awk '{ print $2 }')" + else + echo -e "RCON:" + fi + + if [ -v steamport ]; then + echo -e "Steam: \t${steamport} \t$(ss -tupl | grep -c "${steamport}") \t$(ss -tupl | grep "${steamport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${steamport}" | grep udp | awk '{ print $2 }')" + else + echo -e "Steam:" + fi + + if [ -v steamworksport ]; then + echo -e "Steamworks P2P: \t${steamworksport} \t$(ss -tupl | grep -c "${steamworksport}") \t$(ss -tupl | grep "${steamworksport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${steamworksport}" | grep udp | awk '{ print $2 }')" + else + echo -e "Steamworks P2P:" + fi + + if [ -v steamauthport ]; then + echo -e "Steam: Auth: \t${steamauthport} \t$(ss -tupl | grep -c "${steamauthport}") \t$(ss -tupl | grep "${steamauthport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${steamauthport}" | grep udp | awk '{ print $2 }')" + else + echo -e "Steam: Auth:" + fi + + if [ -v telnetport ]; then + echo -e "Telnet: \t${telnetport} \t$(ss -tupl | grep -c "${telnetport}") \t$(ss -tupl | grep "${telnetport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${telnetport}" | grep udp | awk '{ print $2 }')" + else + echo -e "Telnet:" + fi + + if [ -v statsport ]; then + echo -e "Stats: \t${battleeyeport} \t$(ss -tupl | grep -c "${statsport}") \t$(ss -tupl | grep "${statsport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${statsport}" | grep udp | awk '{ print $2 }')" + else + echo -e "Stats:" + fi + + if [ -v sourcetvport ]; then + echo -e "SourceTV: \t${sourcetvport} \t$(ss -tupl | grep -c "${sourcetvport}") \t$(ss -tupl | grep "${sourcetvport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${sourcetvport}" | grep udp | awk '{ print $2 }')" + else + echo -e "SourceTV:" + fi + + if [ -v udplinkport ]; then + echo -e "UDP Link: \t${udplinkport} \t$(ss -tupl | grep -c "${udplinkport}") \t$(ss -tupl | grep "${udplinkport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${udplinkport}" | grep udp | awk '{ print $2 }')" + else + echo -e "UDP Link:" + fi + + if [ -v voiceport ]; then + echo -e "Voice: \t${voiceport} \t$(ss -tupl | grep -c "${voiceport}") \t$(ss -tupl | grep "${voiceport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${voiceport}" | grep udp | awk '{ print $2 }')" + else + echo -e "Voice:" + fi + + if [ -v voiceunusedport ]; then + echo -e "Voice (Unused): \t${voiceunusedport} \t$(ss -tupl | grep -c "${voiceunusedport}") \t$(ss -tupl | grep "${voiceunusedport}" | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep "${voiceunusedport}" | grep udp | awk '{ print $2 }')" + else + echo -e "Voice (Unused):" + fi + +} \ + | column -s $'\t' -t +echo -e "" +echo -e "${lightgreen}SS Output${default}" +fn_messages_separator +fn_info_messages_ports +eval "${portcommand}" +echo -e "" +echo -e "${lightgreen}Query Port - Raw Output${default}" +fn_messages_separator +echo -e "" +echo -e "PORT: ${port}" +echo -e "QUERY PORT: ${queryport}" +echo -e "" +echo -e "${lightgreen}Gamedig Raw Output${default}" +fn_messages_separator +echo -e "" +if [ ! "$(command -v gamedig 2> /dev/null)" ]; then + fn_print_failure_nl "gamedig not installed" +fi +if [ ! "$(command -v jq 2> /dev/null)" ]; then + fn_print_failure_nl "jq not installed" +fi +for queryip in "${queryips[@]}"; do + query_gamedig.sh + echo -e "${gamedigcmd}" + echo"" + echo "${gamedigraw}" | jq +done +echo -e "" +echo -e "${lightgreen}gsquery Raw Output${default}" +fn_messages_separator +echo -e "" +for queryip in "${queryips[@]}"; do + echo -e "./query_gsquery.py -a \"${queryip}\" -p \"${queryport}\" -e \"${querytype}\"" + echo -e "" + if [ ! -f "${modulesdir}/query_gsquery.py" ]; then + fn_fetch_file_github "lgsm/modules" "query_gsquery.py" "${modulesdir}" "chmodx" "norun" "noforce" "nohash" + fi + "${modulesdir}"/query_gsquery.py -a "${queryip}" -p "${queryport}" -e "${querytype}" +done +echo -e "" +echo -e "${lightgreen}TCP Raw Output${default}" +fn_messages_separator +echo -e "" +for queryip in "${queryips[@]}"; do + echo -e "bash -c 'exec 3<> /dev/tcp/'${queryip}'/'${queryport}''" + echo -e "" + timeout 3 bash -c 'exec 3<> /dev/tcp/'${queryip}'/'${queryport}'' + querystatus="$?" + echo -e "" + if [ "${querystatus}" == "0" ]; then + echo -e "TCP query PASS" + else + echo -e "TCP query FAIL" + fi +done +echo -e "" +echo -e "${lightgreen}Game Port - Raw Output${default}" +fn_messages_separator +echo -e "" +echo -e "${lightgreen}TCP Raw Output${default}" +fn_messages_separator +echo -e "" +for queryip in "${queryips[@]}"; do + echo -e "bash -c 'exec 3<> /dev/tcp/'${queryip}'/'${port}''" + echo -e "" + timeout 3 bash -c 'exec 3<> /dev/tcp/'${queryip}'/'${port}'' + querystatus="$?" + echo -e "" + if [ "${querystatus}" == "0" ]; then + echo -e "TCP query PASS" + else + echo -e "TCP query FAIL" + fi +done +echo -e "" +echo -e "${lightgreen}Steam Master Server Response${default}" +fn_messages_separator +echo -e "" +echo -e "curl -m 3 -s https://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=${publicip}" +echo -e "" +echo -e "Response: ${displaymasterserver}" +echo -e "" + +exitcode=0 +core_exit.sh diff --git a/lgsm/modules/command_fastdl.sh b/lgsm/modules/command_fastdl.sh new file mode 100644 index 0000000..c1c6677 --- /dev/null +++ b/lgsm/modules/command_fastdl.sh @@ -0,0 +1,441 @@ +#!/bin/bash +# LinuxGSM command_fastdl.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Creates a FastDL directory. + +commandname="FASTDL" +commandaction="Fastdl" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +# Directories. +if [ -z "${webdir}" ]; then + webdir="${rootdir}/public_html" +fi +fastdldir="${webdir}/fastdl" +addonsdir="${systemdir}/addons" +# Server lua autorun dir, used to autorun lua on client connect to the server. +luasvautorundir="${systemdir}/lua/autorun/server" +luafastdlfile="lgsm_cl_force_fastdl.lua" +luafastdlfullpath="${luasvautorundir}/${luafastdlfile}" + +# Check if bzip2 is installed. +if [ ! "$(command -v bzip2 2> /dev/null)" ]; then + fn_print_fail "bzip2 is not installed" + fn_script_log_fail "bzip2 is not installed" + core_exit.sh +fi + +# Header +fn_print_header +echo -e "More info: https://docs.linuxgsm.com/commands/fastdl" +echo -e "" + +# Prompts user for FastDL creation settings. +echo -e "${commandaction} setup" +fn_messages_separator + +# Prompt for clearing old files if directory was already here. +if [ -d "${fastdldir}" ]; then + fn_print_warning_nl "FastDL directory already exists." + echo -e "${fastdldir}" + echo -e "" + if fn_prompt_yn "Overwrite existing directory?" Y; then + fn_script_log_info "Overwrite existing directory: YES" + else + core_exit.sh + fi +fi + +# Garry's Mod Specific. +if [ "${shortname}" == "gmod" ]; then + # Prompt for download enforcer, which is using a .lua addfile resource generator. + if fn_prompt_yn "Force clients to download files?" Y; then + luaresource="on" + fn_script_log_info "Force clients to download files: YES" + else + luaresource="off" + fn_script_log_info "Force clients to download filesr: NO" + fi +fi + +# Clears any fastdl directory content. +fn_clear_old_fastdl() { + # Clearing old FastDL. + if [ -d "${fastdldir}" ]; then + echo -en "clearing existing FastDL directory ${fastdldir}..." + rm -rf "${fastdldir:?}" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Clearing existing FastDL directory ${fastdldir}" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Clearing existing FastDL directory ${fastdldir}" + fi + fi +} + +fn_fastdl_dirs() { + # Check and create directories. + if [ ! -d "${webdir}" ]; then + echo -en "creating web directory ${webdir}..." + mkdir -p "${webdir}" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Creating web directory ${webdir}" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Creating web directory ${webdir}" + fi + fi + if [ ! -d "${fastdldir}" ]; then + echo -en "creating fastdl directory ${fastdldir}..." + mkdir -p "${fastdldir}" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Creating fastdl directory ${fastdldir}" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Creating fastdl directory ${fastdldir}" + fi + fi +} + +# Using this gist https://gist.github.com/agunnerson-ibm/efca449565a3e7356906 +fn_human_readable_file_size() { + local abbrevs=( + $((1 << 60)):ZB + $((1 << 50)):EB + $((1 << 40)):TB + $((1 << 30)):GB + $((1 << 20)):MB + $((1 << 10)):KB + $((1)):bytes + ) + + local bytes="${1}" + local precision="${2}" + + if [[ "${bytes}" == "1" ]]; then + echo -e "1 byte" + else + for item in "${abbrevs[@]}"; do + local factor="${item%:*}" + local abbrev="${item#*:}" + if [[ "${bytes}" -ge "${factor}" ]]; then + size=$(bc -l <<< "${bytes} / ${factor}") + printf "%.*f %s\n" "${precision}" "${size}" "${abbrev}" + break + fi + done + fi +} + +# Provides info about the fastdl directory content and prompts for confirmation. +fn_fastdl_preview() { + # Remove any file list. + if [ -f "${tmpdir}/fastdl_files_to_compress.txt" ]; then + rm -f "${tmpdir:?}/fastdl_files_to_compress.txt" + fi + echo -e "analysing required files" + fn_script_log_info "Analysing required files" + # Garry's Mod + if [ "${shortname}" == "gmod" ]; then + cd "${systemdir}" || exit + allowed_extentions_array=("*.ain" "*.bsp" "*.mdl" "*.mp3" "*.ogg" "*.otf" "*.pcf" "*.phy" "*.png" "*.svg" "*.vtf" "*.vmt" "*.vtx" "*.vvd" "*.ttf" "*.wav") + for allowed_extention in "${allowed_extentions_array[@]}"; do + fileswc=0 + tput sc + while read -r ext; do + ((fileswc++)) + tput rc + tput el + echo -e "gathering ${allowed_extention} : ${fileswc}..." + echo -e "${ext}" >> "${tmpdir}/fastdl_files_to_compress.txt" + done < <(find . -type f -iname "${allowed_extention}") + if [ ${fileswc} != 0 ]; then + fn_print_ok_eol_nl + else + fn_print_info_eol_nl + fi + done + # Source engine + else + fastdl_directories_array=("maps" "materials" "models" "particles" "sound" "resources") + for directory in "${fastdl_directories_array[@]}"; do + if [ -d "${systemdir}/${directory}" ]; then + if [ "${directory}" == "maps" ]; then + local allowed_extentions_array=("*.bsp" "*.ain" "*.nav" "*.jpg" "*.txt") + elif [ "${directory}" == "materials" ]; then + local allowed_extentions_array=("*.vtf" "*.vmt" "*.vbf" "*.png" "*.svg") + elif [ "${directory}" == "models" ]; then + local allowed_extentions_array=("*.vtx" "*.vvd" "*.mdl" "*.phy" "*.jpg" "*.png" "*.vmt" "*.vtf") + elif [ "${directory}" == "particles" ]; then + local allowed_extentions_array=("*.pcf") + elif [ "${directory}" == "sound" ]; then + local allowed_extentions_array=("*.wav" "*.mp3" "*.ogg") + fi + for allowed_extention in "${allowed_extentions_array[@]}"; do + fileswc=0 + tput sc + while read -r ext; do + ((fileswc++)) + tput rc + tput el + echo -e "gathering ${directory} ${allowed_extention} : ${fileswc}..." + echo -e "${ext}" >> "${tmpdir}/fastdl_files_to_compress.txt" + done < <(find "${systemdir}/${directory}" -type f -iname "${allowed_extention}") + tput rc + tput el + echo -e "gathering ${directory} ${allowed_extention} : ${fileswc}..." + if [ ${fileswc} != 0 ]; then + fn_print_ok_eol_nl + else + fn_print_info_eol_nl + fi + done + fi + done + fi + if [ -f "${tmpdir}/fastdl_files_to_compress.txt" ]; then + echo -e "calculating total file size..." + fn_sleep_time_1 + totalfiles=$(wc -l < "${tmpdir}/fastdl_files_to_compress.txt") + # Calculates total file size. + while read -r dufile; do + filesize=$(stat -c %s "${dufile}") + filesizetotal=$((filesizetotal + filesize)) + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Calculating total file size." + core_exit.sh + fi + done < "${tmpdir}/fastdl_files_to_compress.txt" + else + fn_print_fail_eol_nl "generating file list" + fn_script_log_fail "Generating file list." + core_exit.sh + fi + echo -e "about to compress ${totalfiles} files, total size $(fn_human_readable_file_size ${filesizetotal} 0)" + fn_script_log_info "${totalfiles} files, total size $(fn_human_readable_file_size ${filesizetotal} 0)" + rm -f "${tmpdir:?}/fastdl_files_to_compress.txt" + if ! fn_prompt_yn "Continue?" Y; then + fn_script_log "User exited" + core_exit.sh + fi +} + +# Builds Garry's Mod fastdl directory content. +fn_fastdl_gmod() { + cd "${systemdir}" || exit + for allowed_extention in "${allowed_extentions_array[@]}"; do + fileswc=0 + tput sc + while read -r fastdlfile; do + ((fileswc++)) + tput rc + tput el + echo -e "copying ${allowed_extention} : ${fileswc}..." + cp --parents "${fastdlfile}" "${fastdldir}" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Copying ${fastdlfile} > ${fastdldir}" + core_exit.sh + else + fn_script_log_pass "Copying ${fastdlfile} > ${fastdldir}" + fi + done < <(find . -type f -iname "${allowed_extention}") + if [ ${fileswc} != 0 ]; then + fn_print_ok_eol_nl + fi + done + # Correct addons directory structure for FastDL. + if [ -d "${fastdldir}/addons" ]; then + echo -en "updating addons file structure..." + cp -Rf "${fastdldir}"/addons/*/* "${fastdldir}" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Updating addons file structure" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Updating addons file structure" + fi + # Clear addons directory in fastdl. + echo -en "clearing addons dir from fastdl dir..." + fn_sleep_time_1 + rm -rf "${fastdldir:?}/addons" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Clearing addons dir from fastdl dir" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Clearing addons dir from fastdl dir" + fi + fi + # Correct content that may be into a lua directory by mistake like some darkrpmodification addons. + if [ -d "${fastdldir}/lua" ]; then + echo -en "correcting DarkRP files..." + fn_sleep_time_1 + cp -Rf "${fastdldir}/lua/"* "${fastdldir}" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Correcting DarkRP files" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Correcting DarkRP files" + fi + fi + if [ -f "${tmpdir}/fastdl_files_to_compress.txt" ]; then + totalfiles=$(wc -l < "${tmpdir}/fastdl_files_to_compress.txt") + # Calculates total file size. + while read -r dufile; do + filesize=$(du -b "${dufile}" | awk '{ print $1 }') + filesizetotal=$((filesizetotal + filesize)) + done < "${tmpdir}/fastdl_files_to_compress.txt" + fi +} + +fn_fastdl_source() { + for directory in "${fastdl_directories_array[@]}"; do + if [ -d "${systemdir}/${directory}" ]; then + if [ "${directory}" == "maps" ]; then + local allowed_extentions_array=("*.bsp" "*.ain" "*.nav" "*.jpg" "*.txt") + elif [ "${directory}" == "materials" ]; then + local allowed_extentions_array=("*.vtf" "*.vmt" "*.vbf" "*.png" "*.svg") + elif [ "${directory}" == "models" ]; then + local allowed_extentions_array=("*.vtx" "*.vvd" "*.mdl" "*.phy" "*.jpg" "*.png") + elif [ "${directory}" == "particles" ]; then + local allowed_extentions_array=("*.pcf") + elif [ "${directory}" == "sound" ]; then + local allowed_extentions_array=("*.wav" "*.mp3" "*.ogg") + fi + for allowed_extention in "${allowed_extentions_array[@]}"; do + fileswc=0 + tput sc + while read -r fastdlfile; do + ((fileswc++)) + tput rc + tput el + echo -e "copying ${directory} ${allowed_extention} : ${fileswc}..." + fn_sleep_time_1 + # get relative path of file in the dir + tmprelfilepath="${fastdlfile#"${systemdir}/"}" + copytodir="${tmprelfilepath%/*}" + # create relative path for fastdl + if [ ! -d "${fastdldir}/${copytodir}" ]; then + mkdir -p "${fastdldir}/${copytodir}" + fi + cp "${fastdlfile}" "${fastdldir}/${copytodir}" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Copying ${fastdlfile} > ${fastdldir}/${copytodir}" + core_exit.sh + else + fn_script_log_pass "Copying ${fastdlfile} > ${fastdldir}/${copytodir}" + fi + done < <(find "${systemdir}/${directory}" -type f -iname "${allowed_extention}") + if [ ${fileswc} != 0 ]; then + fn_print_ok_eol_nl + fi + done + fi + done +} + +# Builds the fastdl directory content. +fn_fastdl_build() { + # Copy all needed files for FastDL. + echo -e "copying files to ${fastdldir}" + fn_script_log_info "Copying files to ${fastdldir}" + if [ "${shortname}" == "gmod" ]; then + fn_fastdl_gmod + fn_fastdl_gmod_dl_enforcer + else + fn_fastdl_source + fi +} + +# Generate lua file that will force download any file into the FastDL directory. +fn_fastdl_gmod_dl_enforcer() { + # Clear old lua file. + if [ -f "${luafastdlfullpath}" ]; then + echo -en "removing existing download enforcer: ${luafastdlfile}..." + rm -f "${luafastdlfullpath:?}" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Removing existing download enforcer ${luafastdlfullpath}" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Removing existing download enforcer ${luafastdlfullpath}" + fi + fi + # Generate new one if user said yes. + if [ "${luaresource}" == "on" ]; then + echo -en "creating new download enforcer: ${luafastdlfile}..." + touch "${luafastdlfullpath}" + # Read all filenames and put them into a lua file at the right path. + while read -r line; do + echo -e "resource.AddFile( \"${line}\" )" >> "${luafastdlfullpath}" + done < <(find "${fastdldir:?}" \( -type f ! -name "*.bz2" \) -printf '%P\n') + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Creating new download enforcer ${luafastdlfullpath}" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Creating new download enforcer ${luafastdlfullpath}" + fi + fi +} + +# Compresses FastDL files using bzip2. +fn_fastdl_bzip2() { + while read -r filetocompress; do + echo -en "\r\033[Kcompressing ${filetocompress}..." + bzip2 -f "${filetocompress}" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Compressing ${filetocompress}" + core_exit.sh + else + fn_script_log_pass "Compressing ${filetocompress}" + fi + done < <(find "${fastdldir:?}" \( -type f ! -name "*.bz2" \)) + fn_print_ok_eol_nl +} + +check.sh +# Run functions. +fn_fastdl_preview +fn_clear_old_fastdl +fn_fastdl_dirs +fn_fastdl_build +fn_fastdl_bzip2 +# Finished message. +echo -e "FastDL files are located in:" +echo -e "${fastdldir}" +echo -e "FastDL completed" +fn_script_log_info "FastDL completed" + +core_exit.sh diff --git a/lgsm/modules/command_install.sh b/lgsm/modules/command_install.sh new file mode 100644 index 0000000..e8cba75 --- /dev/null +++ b/lgsm/modules/command_install.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# LinuxGSM command_install.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Overall module for the installer. + +commandname="INSTALL" +commandaction="Installing" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +check.sh +if [ "$(whoami)" == "root" ]; then + check_deps.sh +else + install_header.sh + install_server_dir.sh + install_logs.sh + check_deps.sh + installflag=1 + # Download and install. + if [ "${shortname}" == "ut2k4" ]; then + install_server_files.sh + install_ut2k4_key.sh + elif [ -z "${appid}" ]; then + install_server_files.sh + elif [ "${appid}" ]; then + install_steamcmd.sh + install_server_files.sh + fi + + # Configuration. + install_config.sh + if [ -v gslt ]; then + install_gslt.sh + elif [ "${shortname}" == "dst" ]; then + install_dst_token.sh + elif [ "${shortname}" == "squad" ]; then + install_squad_license.sh + elif [ "${shortname}" == "ts3" ]; then + install_ts3db.sh + elif [ "${shortname}" == "mta" ]; then + command_install_resources_mta.sh + fn_firstcommand_reset + fi + + fix.sh + install_stats.sh + install_complete.sh +fi +core_exit.sh diff --git a/lgsm/modules/command_install_resources_mta.sh b/lgsm/modules/command_install_resources_mta.sh new file mode 100644 index 0000000..31a9165 --- /dev/null +++ b/lgsm/modules/command_install_resources_mta.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# LinuxGSM command_install_resources_mta.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Installs the default resources for Multi Theft Auto. + +commandname="DEFAULT-RESOURCES" +commandaction="Default Resources" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +fn_install_resources() { + echo -e "" + echo -e "${lightyellow}Installing Default Resources${default}" + fn_messages_separator + fn_fetch_file "http://mirror.mtasa.com/mtasa/resources/mtasa-resources-latest.zip" "" "" "" "${tmpdir}" "mtasa-resources-latest.zip" "nochmodx" "norun" "noforce" "nohash" + fn_dl_extract "${tmpdir}" "mtasa-resources-latest.zip" "${resourcesdir}" + echo -e "Default Resources Installed." +} + +fn_print_header + +if [ -z "${autoinstall}" ]; then + fn_print_warning_nl "Installing the default resources with existing resources may cause issues." + if fn_prompt_yn "Do you want to install MTA default resources?" Y; then + fn_install_resources + fi +else + fn_print_warning_nl "Default resources are not installed when using ./${selfname} auto-install." + fn_print_information_nl "To install default resources use ./${selfname} install" +fi diff --git a/lgsm/modules/command_mods_install.sh b/lgsm/modules/command_mods_install.sh new file mode 100644 index 0000000..19de72a --- /dev/null +++ b/lgsm/modules/command_mods_install.sh @@ -0,0 +1,135 @@ +#!/bin/bash +# LinuxGSM command_mods_install.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: List and installs available mods along with mods_list.sh and mods_core.sh. + +commandname="MODS-INSTALL" +commandaction="Installing mods" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +check.sh +mods_core.sh + +fn_print_header + +# Displays a list of installed mods. +fn_mods_installed_list +if [ "${installedmodscount}" -gt "0" ]; then + echo -e "Installed addons/mods" + fn_messages_separator + # Go through all available commands, get details and display them to the user. + for ((llindex = 0; llindex < ${#installedmodslist[@]}; llindex++)); do + # Current mod is the "llindex" value of the array we're going through. + currentmod="${installedmodslist[llindex]}" + fn_mod_get_info + # Display mod info to the user. + echo -e " * ${green}${modcommand}${default}${default}" + done + echo -e "" +fi + +echo -e "Available addons/mods" +fn_messages_separator +# Display available mods from mods_list.sh. +# Set and reset vars +compatiblemodslistindex=0 +# As long as we're within index values. +while [ "${compatiblemodslistindex}" -lt "${#compatiblemodslist[@]}" ]; do + # Set values for convenience. + displayedmodname="${compatiblemodslist[compatiblemodslistindex]}" + displayedmodcommand="${compatiblemodslist[compatiblemodslistindex + 1]}" + displayedmodsite="${compatiblemodslist[compatiblemodslistindex + 2]}" + displayedmoddescription="${compatiblemodslist[compatiblemodslistindex + 3]}" + # Output mods to the user. + echo -e "${displayedmodname} - ${displayedmoddescription} - ${displayedmodsite}" + echo -e " * ${cyan}${displayedmodcommand}${default}" + # Increment index from the amount of values we just displayed. + let "compatiblemodslistindex+=4" + ((totalmodsavailable++)) +done + +# If no mods are available for a specific game. +if [ -z "${compatiblemodslist}" ]; then + fn_print_fail_nl "No mods are currently available for ${gamename}." + fn_script_log_info "No mods are currently available for ${gamename}." + core_exit.sh +fi +fn_script_log_info "${totalmodsavailable} addons/mods are available for install" + +## User selects a mod. +echo -e "" +while [[ ! " ${availablemodscommands[@]} " =~ " ${usermodselect} " ]]; do + echo -en "Enter an ${cyan}addon/mod${default} to ${green}install${default} (or exit to abort): " + read -r usermodselect + # Exit if user says exit or abort. + if [ "${usermodselect}" == "exit" ] || [ "${usermodselect}" == "abort" ]; then + core_exit.sh + # Supplementary output upon invalid user input. + elif [[ ! " ${availablemodscommands[@]} " =~ " ${usermodselect} " ]]; then + fn_print_error2_nl "${usermodselect} is not a valid addon/mod." + fi +done +# Get mod info. +currentmod="${usermodselect}" +fn_mod_get_info + +echo -e "" +echo -e "Installing ${modprettyname}" +fn_messages_separator +fn_script_log_info "${modprettyname} selected for install" + +# Check if the mod is already installed and warn the user. +if [ -f "${modsinstalledlistfullpath}" ]; then + if [ "$(sed -n "/^${modcommand}$/p" "${modsinstalledlistfullpath}")" ]; then + fn_print_warning_nl "${modprettyname} is already installed" + fn_script_log_warn "${modprettyname} is already installed" + echo -e " * Any configs may be overwritten." + if ! fn_prompt_yn "Continue?" Y; then + core_exit.sh + fi + fn_script_log_info "User selected to continue" + fi +fi + +## Installation. +# If amxmodx check if metamod exists first +if [ "${modcommand}" == "amxmodx" ]; then + fn_mod_exist "metamod" +fi + +if [ "${modcommand}" == "amxmodxcs" ] \ + || [ "${modcommand}" == "amxmodxdod" ] \ + || [ "${modcommand}" == "amxmodxtfc" ] \ + || [ "${modcommand}" == "amxmodxns" ] \ + || [ "${modcommand}" == "amxmodxts" ]; then + fn_mod_exist "amxmodx" +fi + +fn_create_mods_dir +fn_mods_clear_tmp_dir +fn_mods_create_tmp_dir +fn_mod_install_files +fn_mod_lowercase +fn_mod_create_filelist +fn_mod_copy_destination +fn_mod_add_list +fn_mod_tidy_files_list +fn_mods_clear_tmp_dir + +# Create/modify existing liblist.gam file for Metamod +if [ "${modcommand}" == "metamod" ]; then + fn_mod_install_liblist_gam_file +fi + +# Create/modify plugins.ini file for Metamod +if [ "${modcommand}" == "amxmodx" ]; then + fn_mod_install_amxmodx_file +fi + +echo -e "${modprettyname} installed" +fn_script_log_pass "${modprettyname} installed." + +core_exit.sh diff --git a/lgsm/modules/command_mods_remove.sh b/lgsm/modules/command_mods_remove.sh new file mode 100644 index 0000000..5f70ac3 --- /dev/null +++ b/lgsm/modules/command_mods_remove.sh @@ -0,0 +1,153 @@ +#!/bin/bash +# LinuxGSM command_mods_uninstall.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Uninstall mods along with mods_list.sh and mods_core.sh. + +commandname="MODS-REMOVE" +commandaction="Removing mods" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +check.sh +mods_core.sh +fn_mods_check_installed + +fn_print_header +echo -e "Remove addons/mods" +fn_messages_separator + +# Displays list of installed mods. +# Generates list to display to user. +fn_mods_installed_list +for ((mlindex = 0; mlindex < ${#installedmodslist[@]}; mlindex++)); do + # Current mod is the "mlindex" value of the array we are going through. + currentmod="${installedmodslist[mlindex]}" + # Get mod info. + fn_mod_get_info + # Display mod info to the user. + echo -e "${red}${modcommand}${default} - ${modprettyname} - ${moddescription}" +done + +echo -e "" +# Keep prompting as long as the user input doesn't correspond to an available mod. +while [[ ! " ${installedmodslist[@]} " =~ " ${usermodselect} " ]]; do + echo -en "Enter an ${cyan}addon/mod${default} to ${red}remove${default} (or exit to abort): " + read -r usermodselect + # Exit if user says exit or abort. + if [ "${usermodselect}" == "exit" ] || [ "${usermodselect}" == "abort" ]; then + core_exit.sh + # Supplementary output upon invalid user input. + elif [[ ! " ${availablemodscommands[@]} " =~ " ${usermodselect} " ]]; then + fn_print_error2_nl "${usermodselect} is not a valid addon/mod." + fi +done + +fn_print_warning_nl "You are about to remove ${cyan}${usermodselect}${default}." +echo -e " * Any custom files/configuration will be removed." +if ! fn_prompt_yn "Continue?" Y; then + core_exit.sh +fi + +currentmod="${usermodselect}" +fn_mod_get_info +fn_check_mod_files_list + +# Uninstall the mod. +fn_script_log_info "Removing ${modsfilelistsize} files from ${modprettyname}" +echo -e "removing ${modprettyname}" +echo -e "* ${modsfilelistsize} files to be removed" +echo -e "* location: ${modinstalldir}" +fn_sleep_time_1 +# Go through every file and remove it. +modfileline="1" +tput sc +while [ "${modfileline}" -le "${modsfilelistsize}" ]; do + # Current line defines current file to remove. + currentfileremove=$(sed "${modfileline}q;d" "${modsdir}/${modcommand}-files.txt") + # If file or directory exists, then remove it. + + if [ -f "${modinstalldir}/${currentfileremove}" ] || [ -d "${modinstalldir}/${currentfileremove}" ]; then + rm -rf "${modinstalldir:?}/${currentfileremove:?}" + ((exitcode = $?)) + if [ "${exitcode}" != 0 ]; then + fn_script_log_fail "Removing ${modinstalldir}/${currentfileremove}" + break + else + fn_script_log_pass "Removing ${modinstalldir}/${currentfileremove}" + fi + fi + tput rc + tput el + echo -e "removing ${modprettyname} ${modfileline} / ${modsfilelistsize} : ${currentfileremove}..." + ((modfileline++)) +done + +# Added logic not to fail since removing game specific mods (amxmodxcs) removes files that will +# not be found when removing the base (amxmodx) mod +if [ "${modcommand}" != "amxmodx" ]; then + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + core_exit.sh + else + fn_print_ok_eol_nl + fi +else + fn_print_ok_eol_nl +fi + +# Remove file list. +echo -en "removing ${modcommand}-files.txt..." +fn_sleep_time_1 +rm -rf "${modsdir:?}/${modcommand}-files.txt" +exitcode=$? +if [ "${exitcode}" != 0 ]; then + fn_script_log_fail "Removing ${modsdir}/${modcommand}-files.txt" + fn_print_fail_eol_nl + core_exit.sh +else + fn_script_log_pass "Removing ${modsdir}/${modcommand}-files.txt" + fn_print_ok_eol_nl +fi + +# Remove mods from installed mods list. +echo -en "removing ${modcommand} from ${modsinstalledlist}..." +fn_sleep_time_1 + +sed -i "/^${modcommand}$/d" "${modsinstalledlistfullpath}" +exitcode=$? +if [ "${exitcode}" != 0 ]; then + fn_script_log_fail "Removing ${modcommand} from ${modsinstalledlist}" + fn_print_fail_eol_nl + core_exit.sh +else + fn_script_log_pass "Removing ${modcommand} from ${modsinstalledlist}" + fn_print_ok_eol_nl +fi + +# Oxide fix +# Oxide replaces server files, so a validate is required after uninstall. +if [ "${engine}" == "unity3d" ] && [[ "${modprettyname}" == *"Oxide"* ]]; then + fn_print_information_nl "Validating to restore original ${gamename} files replaced by Oxide" + fn_script_log "Validating to restore original ${gamename} files replaced by Oxide" + exitbypass=1 + command_validate.sh + fn_firstcommand_reset + unset exitbypass +fi + +# Remove/modify existing liblist.gam file for Metamod +if [ "${modcommand}" == "metamod" ]; then + fn_mod_remove_liblist_gam_file +fi + +# Remove/modify plugins.ini file for AMX Mod X +if [ "${modcommand}" == "amxmodx" ]; then + fn_mod_remove_amxmodx_file +fi + +echo -e "${modprettyname} removed" +fn_script_log "${modprettyname} removed" + +core_exit.sh diff --git a/lgsm/modules/command_mods_update.sh b/lgsm/modules/command_mods_update.sh new file mode 100644 index 0000000..cd5c3b0 --- /dev/null +++ b/lgsm/modules/command_mods_update.sh @@ -0,0 +1,109 @@ +#!/bin/bash +# LinuxGSM command_mods_update.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Updates installed mods along with mods_list.sh and mods_core.sh. + +commandname="MODS-UPDATE" +commandaction="Updating mods" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +check.sh +mods_core.sh + +# Prevents specific files being overwritten upon update (set by ${modkeepfiles}). +# For that matter, remove cfg files after extraction before copying them to destination. +fn_remove_cfg_files() { + if [ "${modkeepfiles}" != "OVERWRITE" ] && [ "${modkeepfiles}" != "NOUPDATE" ]; then + echo -e "the following files/directories will be preserved:" + fn_sleep_time_1 + # Count how many files there are to remove. + filestopreserve=$(echo -e "${modkeepfiles}" | awk -F ';' '{ print NF }') + # Test all subvalues of "modkeepfiles" using the ";" separator. + for ((preservefilesindex = 1; preservefilesindex < filestopreserve; preservefilesindex++)); do + # Put the current file we are looking for into a variable. + filetopreserve=$(echo -e "${modkeepfiles}" | awk -F ';' -v x=${preservefilesindex} '{ print $x }') + echo -e " * serverfiles/${filetopreserve}" + # If it matches an existing file that have been extracted delete the file. + if [ -f "${extractdest}/${filetopreserve}" ] || [ -d "${extractdest}/${filetopreserve}" ]; then + rm -r "${extractdest:?}/${filetopreserve}" + # Write the file path in a tmp file, to rebuild a full file list as it is rebuilt upon update. + if [ ! -f "${modsdir}/.removedfiles.tmp" ]; then + touch "${modsdir}/.removedfiles.tmp" + fi + echo -e "${filetopreserve}" >> "${modsdir}/.removedfiles.tmp" + fi + done + fi +} + +fn_print_dots "Update addons/mods" +fn_mods_check_installed +fn_print_info_nl "Update addons/mods: ${installedmodscount} addons/mods will be updated" +fn_script_log_info "${installedmodscount} mods or addons will be updated" +fn_mods_installed_list +# Go through all available commands, get details and display them to the user. +for ((ulindex = 0; ulindex < ${#installedmodslist[@]}; ulindex++)); do + # Current mod is the "ulindex" value of the array we're going through. + currentmod="${installedmodslist[ulindex]}" + fn_mod_get_info + # Display installed mods and the update policy. + if [ -z "${modkeepfiles}" ]; then + # If modkeepfiles is not set for some reason, that's a problem. + fn_script_log_error "Could not find update policy for ${modprettyname}" + fn_print_error_nl "Could not find update policy for ${modprettyname}" + exitcode="1" + core_exit.sh + # If the mod won't get updated. + elif [ "${modkeepfiles}" == "NOUPDATE" ]; then + echo -e " * ${red}{modprettyname}${default} (won't be updated)" + # If the mode is just overwritten. + elif [ "${modkeepfiles}" == "OVERWRITE" ]; then + echo -e " * ${modprettyname} (overwrite)" + else + echo -e " * ${yellow}${modprettyname}${default} (retain common custom files)" + fi +done + +## Update +# List all installed mods and apply update. +# Reset line value. +installedmodsline="1" +while [ "${installedmodsline}" -le "${installedmodscount}" ]; do + currentmod=$(sed "${installedmodsline}q;d" "${modsinstalledlistfullpath}") + if [ "${currentmod}" ]; then + fn_mod_get_info + # Don not update mod if the policy is set to "NOUPDATE". + if [ "${modkeepfiles}" == "NOUPDATE" ]; then + fn_print_info "${modprettyname} will not be updated to preserve custom files" + fn_script_log_info "${modprettyname} will not be updated to preserve custom files" + else + echo -e "" + echo -e "==> Updating ${modprettyname}" + fn_create_mods_dir + fn_mods_clear_tmp_dir + fn_mods_create_tmp_dir + fn_mod_install_files + fn_mod_lowercase + fn_remove_cfg_files + fn_mod_create_filelist + fn_mod_copy_destination + fn_mod_add_list + fn_mod_tidy_files_list + fn_mods_clear_tmp_dir + fi + ((installedmodsline++)) + else + fn_print_fail "No mod was selected" + fn_script_log_fail "No mod was selected" + exitcode="1" + core_exit.sh + fi +done +echo -e "" +fn_print_ok_nl "Mods update complete" +fn_script_log_info "Mods update complete" + +core_exit.sh diff --git a/lgsm/modules/command_monitor.sh b/lgsm/modules/command_monitor.sh new file mode 100644 index 0000000..5f1ff77 --- /dev/null +++ b/lgsm/modules/command_monitor.sh @@ -0,0 +1,415 @@ +#!/bin/bash +# LinuxGSM command_monitor.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Monitors server by checking for running processes +# then passes to gamedig and gsquery. + +commandname="MONITOR" +commandaction="Monitoring" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +fn_monitor_check_monitoring() { + if [ -f "${lockdir}/${selfname}.lock" ]; then + # Part of migration to v23.5.0. #4296 + rm -f "${lockdir:?}/${selfname}.lock" + date '+%s' > "${lockdir:?}/${selfname}-monitoring.lock" + elif [ ! -f "${lockdir}/${selfname}-monitoring.lock" ]; then + # Monitor does not run if lockfile is not found. + fn_print_dots "Checking lockfile: " + fn_print_checking_eol + fn_script_log_info "Checking lockfile: CHECKING" + fn_print_error "Checking lockfile: No lockfile found: " + fn_print_error_eol_nl + fn_script_log_error "Checking lockfile: No lockfile found: ERROR" + echo -e "* Start ${selfname} to run monitor." + core_exit.sh + fi +} + +fn_monitor_check_install() { + if [ "$(pgrep -fc -u "${USER}" "/bin/bash ./${selfname} install")" != "0" ] || [ "$(pgrep -fcx -u "${USER}" "/bin/bash ./${selfname} i")" != "0" ] || [ "$(pgrep -fcx -u "${USER}" "/bin/bash ./${selfname} auto-install")" != "0" ] || [ "$(pgrep -fcx -u "${USER}" "/bin/bash ./${selfname} ai")" != "0" ]; then + fn_print_dots "Checking installer: " + fn_print_checking_eol + fn_script_log_info "Checking installer: CHECKING" + fn_print_info "Checking installer: LinuxGSM is installing: " + fn_print_info_eol_nl + fn_script_log_pass "Checking installer: LinuxGSM is installing" + core_exit.sh + fi +} + +fn_monitor_check_debug() { + if [ "$(pgrep -fcx -u "${USER}" "/bin/bash ./${selfname} debug")" != "0" ] || [ "$(pgrep -fcx -u "${USER}" "/bin/bash ./${selfname} d")" != "0" ]; then + fn_print_dots "Checking debug: " + fn_print_checking_eol + fn_print_info "Checking debug: Debug is running: " + fn_print_info_eol_nl + fn_script_log_pass "Checking debug: Debug is running" + core_exit.sh + fi +} + +fn_monitor_check_details() { + if [ "$(pgrep -fcx -u "${USER}" "/bin/bash ./${selfname} details")" != "0" ] || [ "$(pgrep -fcx -u "${USER}" "/bin/bash ./${selfname} dt")" != "0" ]; then + fn_print_dots "Checking details: " + fn_print_checking_eol + fn_print_info "Checking details: Details is running: " + fn_print_info_eol_nl + fn_script_log_pass "Checking details: Details is running" + core_exit.sh + fi +} + +fn_monitor_check_starting() { + # Remove stale lockfile. + if [ -f "${lockdir}/${selfname}-starting.lock" ]; then + if [ "$(find "${lockdir}/${selfname}-starting.lock" -mmin +5)" ]; then + fn_print_dots "Checking start: " + fn_print_checking_eol + fn_print_warn "Checking start: Removing stale lockfile: " + fn_print_warn_eol_nl + fn_script_log_warn "Checking start: Removing stale lockfile" + rm -f "${lockdir:?}/${selfname}-starting.lock" + fi + fi + + if [ -f "${lockdir}/${selfname}-starting.lock" ] && [[ "$(pgrep -fcx -u "${USER}" "/bin/bash ./${selfname} start")" != "0" || "$(pgrep -fcx -u "${USER}" "/bin/bash ./${selfname} s")" != "0" ]]; then + fn_print_dots "Checking start: " + fn_print_checking_eol + fn_print_info "Checking start: LinuxGSM is starting: " + fn_print_info_eol_nl + fn_script_log_info "Checking backup: LinuxGSM is starting" + core_exit.sh + fi +} + +fn_monitor_check_stopping() { + # Remove stale lockfile. + if [ -f "${lockdir}/${selfname}-stopping.lock" ]; then + if [ "$(find "${lockdir}/${selfname}-stopping.lock" -mmin +5)" ]; then + fn_print_dots "Checking stop: " + fn_print_checking_eol + fn_print_warn "Checking stop: Removing stale lockfile: " + fn_print_warn_eol_nl + fn_script_log_warn "Checking stop: Removing stale lockfile" + rm -f "${lockdir:?}/${selfname}-stopping.lock" + fi + fi + + if [ -f "${lockdir}/${selfname}-stopping.lock" ] && [[ "$(pgrep -fcx -u "${USER}" "/bin/bash ./${selfname} stop")" != "0" || "$(pgrep -fcx -u "${USER}" "/bin/bash ./${selfname} s")" != "0" ]]; then + fn_print_dots "Checking stop: " + fn_print_checking_eol + fn_print_info "Checking stop: LinuxGSM is stopping: " + fn_print_info_eol_nl + fn_script_log_info "Checking backup: LinuxGSM is stopping" + core_exit.sh + fi +} + +fn_monitor_check_backup() { + # Remove stale lockfile. + if [ -f "${lockdir}/backup.lock" ]; then + if [ "$(find "${lockdir}/backup.lock" -mmin +60)" ]; then + fn_print_dots "Checking backup: " + fn_print_checking_eol + fn_print_warn "Checking backup: Removing stale lockfile: " + fn_print_warn_eol + fn_script_log_warn "Checking backup: Removing stale lockfile" + rm -f "${lockdir:?}/backup.lock" + fi + fi + + if [ -f "${lockdir}/backup.lock" ] && [[ "$(pgrep -fcx -u "${USER}" "/bin/bash ./${selfname} backup")" != "0" || "$(pgrep -fcx -u "${USER}" "/bin/bash ./${selfname} b")" != "0" ]]; then + fn_print_dots "Checking backup: " + fn_print_checking_eol + fn_print_info "Checking backup: Backup is running: " + fn_print_info_eol_nl + fn_script_log_info "Checking backup: Backup is running" + core_exit.sh + fi +} + +fn_monitor_check_update() { + # Remove stale lockfile. + if [ -f "${lockdir}/update.lock" ]; then + if [ "$(find "${lockdir}/update.lock" -mmin +15)" ]; then + fn_print_dots "Checking update: " + fn_print_checking_eol + fn_print_warn "Checking update: Removing stale lockfile: " + fn_print_warn_eol_nl + fn_script_log_warn "Checking update: Removing stale lockfile" + rm -f "${lockdir:?}/update.lock" + fi + fi + + if [ -f "${lockdir}/update.lock" ] && [[ "$(pgrep -fcx -u "${USER}" "/bin/bash ./${selfname} update")" != "0" || "$(pgrep -fcx -u "${USER}" "/bin/bash ./${selfname} validate")" != "0" || "$(pgrep -fcx -u "${USER}" "/bin/bash ./${selfname} v")" != "0" || "$(pgrep -fc force-update "${USER}" "/bin/bash ./${selfname} fu")" != "0" ]]; then + fn_print_dots "Checking update: " + fn_print_checking_eol + fn_print_info "Checking update: LinuxGSM is updating the game server: " + fn_print_info_eol_nl + fn_script_log_pass "Checking update: LinuxGSM is updating the game server" + core_exit.sh + fi +} + +# Source engine games may display a messages to indicate the server needs restarting. +fn_monitor_check_update_source() { + if [ -f "${consolelogdir}/${selfname}-console.log" ] && [ "${engine}" == "source" ]; then + if grep -q "Your server needs to be restarted in order to receive the latest update." "${consolelogdir}/${selfname}-console.log"; then + fn_print_dots "Checking update: " + fn_print_checking_eol + fn_script_log_info "Checking update: CHECKING" + fn_print_ok "Checking update: " + fn_print_ok_eol_nl + fn_script_log_info "Checking update: ${selfname} has requested an update and needs to be restarted" + alert="update-request" + alert.sh + command_update.sh + core_exit.sh + fi + fi +} + +fn_monitor_check_session() { + fn_print_dots "Checking session: " + fn_print_checking_eol + fn_script_log_info "Checking session: CHECKING" + # Tmux session width and height needs to be reviewed as may no longer be required. + sessionwidth="80" + sessionheight="23" + # Check for PIDS with identical tmux sessions running. + if [ "$(pgrep -fcx "tmux -L ${socketname} new-session -d -x ${sessionwidth} -y ${sessionheight} -s ${sessionname}")" -ge "2" ]; then + fn_print_error "Checking session: There are PIDS with identical tmux sessions running: " + fn_print_error_eol_nl + fn_script_log_error "Checking session: ERROR" + fn_script_log_error "Checking session: There are PIDS with identical tmux sessions running" + fn_script_log_error "Checking session: Killing all tmux sessions with the socketname name ${socketname} and session name ${sessionname}" + pkill -f "tmux -L ${socketname} new-session -d -x ${sessionwidth} -y ${sessionheight} -s ${sessionname}" + command_restart.sh + core_exit.sh + # Check for tmux pids with the same tmux session and socket names. This will reduce issues with migration to release v23.5.0. #4296 + elif [ "$(pgrep -fc -u "${USER}" "tmux -L ${sessionname} new-session -d -x ${sessionwidth} -y ${sessionheight} -s ${sessionname}")" != "0" ]; then + fn_print_error "Checking session: PIDS with the same tmux session and socket names are running: " + fn_print_error_eol_nl + fn_script_log_error "Checking session: ERROR" + fn_script_log_error "Checking session: PIDS with the same tmux session and socket names are running" + fn_script_log_error "Checking session: Killing session with the socketname name ${sessionname} and session name ${sessionname}" + pkill -f "tmux -L ${sessionname} new-session -d -x ${sessionwidth} -y ${sessionheight} -s ${sessionname}" + command_restart.sh + core_exit.sh + # Check for tmux pids that are using the old type of tmux session. This will reduce issues with migration to release v23.5.0. #4296 + elif [ "$(pgrep -fc -u "${USER}" "tmux new-session -d -x ${sessionwidth} -y ${sessionheight} -s ${sessionname}")" != "0" ]; then + fn_print_error "Checking session: PIDS with old type tmux session are running: " + fn_print_error_eol_nl + fn_script_log_error "Checking session: ERROR" + fn_script_log_error "Checking session: PIDS with old type tmux session are running" + fn_script_log_error "Checking session: Killing session with the session name ${sessionname}" + pkill -f "tmux new-session -d -x ${sessionwidth} -y ${sessionheight} -s ${sessionname}" + command_restart.sh + core_exit.sh + elif [ "${status}" != "0" ]; then + fn_print_ok "Checking session: " + fn_print_ok_eol_nl + fn_script_log_pass "Checking session: OK" + else + fn_print_error "Checking session: " + fn_print_fail_eol_nl + fn_script_log_fail "Checking session: FAIL" + alert="monitor-session" + alert.sh + fn_script_log_info "Checking session: Monitor is restarting ${selfname}" + command_restart.sh + core_exit.sh + fi +} + +# Monitor will check queryport is set before continuing. +fn_monitor_check_queryport() { + if [ -z "${queryport}" ] || [ "${queryport}" == "0" ]; then + fn_print_dots "Checking port: " + fn_print_checking_eol + fn_script_log_info "Checking port: CHECKING" + if [ -n "${rconenabled}" ] && [ "${rconenabled}" != "true" ] && [ "${shortname}" == "av" ]; then + fn_print_warn "Checking port: Unable to query, rcon is not enabled" + fn_script_log_warn "Checking port: Unable to query, rcon is not enabled" + else + fn_print_error "Checking port: Unable to query, queryport is not set" + fn_script_log_error "Checking port: Unable to query, queryport is not set" + fi + core_exit.sh + fi +} + +fn_query_gsquery() { + if [ ! -f "${modulesdir}/query_gsquery.py" ]; then + fn_fetch_file_github "lgsm/modules" "query_gsquery.py" "${modulesdir}" "chmodx" "norun" "noforce" "nohash" + fi + "${modulesdir}"/query_gsquery.py -a "${queryip}" -p "${queryport}" -e "${querytype}" > /dev/null 2>&1 + querystatus="$?" +} + +fn_query_tcp() { + bash -c "exec 3<> /dev/tcp/'${queryip}'/'${queryport}'" > /dev/null 2>&1 + querystatus="$?" +} + +fn_monitor_query() { + # Will loop and query up to 5 times every 15 seconds. + # Query will wait up to 60 seconds to confirm server is down as server can become non-responsive during map changes. + totalseconds=0 + for queryattempt in {1..5}; do + for queryip in "${queryips[@]}"; do + fn_print_dots "Querying port: ${querymethod}: ${queryip}:${queryport} : ${totalseconds}/${queryattempt}: " + fn_print_querying_eol + fn_script_log_info "Querying port: ${querymethod}: ${queryip}:${queryport} : ${queryattempt} : QUERYING" + # querydelay + if [ "$(head -n 1 "${lockdir}/${selfname}-started.lock")" -gt "$(date "+%s" -d "${querydelay} mins ago")" ]; then + fn_print_ok "Querying port: ${querymethod}: ${ip}:${queryport} : ${totalseconds}/${queryattempt}: " + fn_print_delay_eol_nl + fn_script_log_info "Querying port: ${querymethod}: ${ip}:${queryport} : ${queryattempt} : DELAY" + fn_script_log_info "Query bypassed: ${gameservername} started less than ${querydelay} minutes ago" + fn_script_log_info "Server started: $(date -d "@$(head -n 1 "${lockdir}/${selfname}-started.lock")")" + fn_script_log_info "Current time: $(date)" + monitorpass=1 + core_exit.sh + # will use query method selected in fn_monitor_loop + # gamedig + elif [ "${querymethod}" == "gamedig" ]; then + query_gamedig.sh + # gsquery + elif [ "${querymethod}" == "gsquery" ]; then + fn_query_gsquery + #tcp query + elif [ "${querymethod}" == "tcp" ]; then + fn_query_tcp + fi + + if [ "${querystatus}" == "0" ]; then + # Server query OK. + fn_print_ok "Querying port: ${querymethod}: ${queryip}:${queryport} : ${totalseconds}/${queryattempt}: " + fn_print_ok_eol_nl + fn_script_log_pass "Querying port: ${querymethod}: ${queryip}:${queryport} : ${queryattempt} : OK" + monitorpass=1 + if [ "${querystatus}" == "0" ]; then + # Add query data to log. + if [ "${gdname}" ]; then + fn_script_log_info "Server name: ${gdname}" + fi + if [ "${gdplayers}" ]; then + fn_script_log_info "Players: ${gdplayers}/${gdmaxplayers}" + fi + if [ "${gdbots}" ]; then + fn_script_log_info "Bots: ${gdbots}" + fi + if [ "${gdmap}" ]; then + fn_script_log_info "Map: ${gdmap}" + fi + if [ "${gdgamemode}" ]; then + fn_script_log_info "Game Mode: ${gdgamemode}" + fi + + # send LinuxGSM stats if monitor is OK. + if [ "${stats}" == "on" ] || [ "${stats}" == "y" ]; then + info_stats.sh + fi + fi + core_exit.sh + else + # Server query FAIL. + fn_print_fail "Querying port: ${querymethod}: ${queryip}:${queryport} : ${totalseconds}/${queryattempt}: " + fn_print_fail_eol + fn_script_log_warn "Querying port: ${querymethod}: ${queryip}:${queryport} : ${queryattempt} : FAIL" + # Monitor will try gamedig (if supported) for first 30s then gsquery before restarting. + # gsquery will fail if longer than 60s + if [ "${totalseconds}" -ge "59" ]; then + # Monitor will FAIL if over 60s and trigger gane server reboot. + fn_print_fail "Querying port: ${querymethod}: ${queryip}:${queryport} : ${totalseconds}/${queryattempt}: " + fn_print_fail_eol_nl + fn_script_log_warn "Querying port: ${querymethod}: ${queryip}:${queryport} : ${queryattempt} : FAIL" + # Send alert if enabled. + alert="monitor-query" + alert.sh + command_restart.sh + fn_firstcommand_reset + core_exit.sh + fi + fi + done + # Second counter will wait for 15s before breaking loop. + for seconds in {1..15}; do + fn_print_fail "Querying port: ${querymethod}: ${ip}:${queryport} : ${totalseconds}/${queryattempt} : ${cyan}WAIT${default}" + fn_sleep_time_1 + totalseconds=$((totalseconds + 1)) + if [ "${seconds}" == "15" ]; then + break + fi + done + done +} + +fn_monitor_loop() { + # loop though query methods selected by querymode. + totalseconds=0 + if [ "${querymode}" == "2" ]; then + local query_methods_array=(gamedig gsquery) + elif [ "${querymode}" == "3" ]; then + local query_methods_array=(gamedig) + elif [ "${querymode}" == "4" ]; then + local query_methods_array=(gsquery) + elif [ "${querymode}" == "5" ]; then + local query_methods_array=(tcp) + fi + for querymethod in "${query_methods_array[@]}"; do + # Will check if gamedig is installed and bypass if not. + if [ "${querymethod}" == "gamedig" ]; then + if [ "$(command -v gamedig 2> /dev/null)" ] && [ "$(command -v jq 2> /dev/null)" ]; then + if [ -z "${monitorpass}" ]; then + fn_monitor_query + fi + else + fn_script_log_info "gamedig is not installed" + fn_script_log_info "https://docs.linuxgsm.com/requirements/gamedig" + fi + else + # will not query if query already passed. + if [ -z "${monitorpass}" ]; then + fn_monitor_query + fi + fi + done +} + +fn_print_dots "" +monitorflag=1 +# Dont do any monitoring or checks if installer is running. +fn_monitor_check_install +check.sh +core_logs.sh +info_game.sh + +# query pre-checks +fn_monitor_check_details +fn_monitor_check_backup +fn_monitor_check_debug +fn_monitor_check_update_source +fn_monitor_check_update +fn_monitor_check_monitoring +fn_monitor_check_starting +fn_monitor_check_stopping +fn_monitor_check_session + +# Monitor will not continue if session only check. +if [ "${querymode}" != "1" ]; then + fn_monitor_check_queryport + + # Add a querydelay of 1 min if var missing. + if [ -z "${querydelay}" ]; then + querydelay="1" + fi + + fn_monitor_loop +fi +core_exit.sh diff --git a/lgsm/modules/command_postdetails.sh b/lgsm/modules/command_postdetails.sh new file mode 100644 index 0000000..3bfed78 --- /dev/null +++ b/lgsm/modules/command_postdetails.sh @@ -0,0 +1,78 @@ +#!/bin/bash +# LinuxGSM command_postdetails.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Strips sensitive information out of Details output. + +commandname="POST-DETAILS" +commandaction="Posting details" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +posttarget="https://termbin.com" + +# source all of the modules defined in the details command. +info_messages.sh + +fn_bad_postdetailslog() { + fn_print_fail_nl "Unable to create temporary file ${postdetailslog}." + core_exit.sh +} + +# Remove any existing postdetails.log file. +if [ -f "${postdetailslog}" ]; then + rm -f "${postdetailslog:?}" +fi + +# Rather than a one-pass sed parser, default to using a temporary directory. +if [ "${exitbypass}" ]; then + postdetailslog="${alertlog}" +else + # Run checks and gathers details to display. + check.sh + info_game.sh + info_distro.sh + info_messages.sh + for queryip in "${queryips[@]}"; do + query_gamedig.sh + if [ "${querystatus}" == "0" ]; then + break + fi + done + touch "${postdetailslog}" || fn_bad_postdetailslog + { + fn_info_messages_distro + fn_info_messages_server_resource + fn_info_messages_gameserver_resource + fn_info_messages_gameserver + fn_info_messages_script + fn_info_messages_backup + # Some game servers do not have parms. + if [ "${shortname}" != "jc2" ] && [ "${shortname}" != "jc3" ] && [ "${shortname}" != "dst" ] && [ "${shortname}" != "pz" ] && [ "${engine}" != "renderware" ]; then + fn_info_messages_commandlineparms + fi + fn_info_messages_ports_edit + fn_info_messages_ports + fn_info_messages_select_engine + fn_info_messages_statusbottom + } | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" | tee -a "${postdetailslog}" > /dev/null 2>&1 +fi + +fn_print_dots "termbin.com" +link=$(cat "${postdetailslog}" | nc termbin.com 9999 | tr -d '\n\0') +fn_print_ok_nl "termbin.com for 30D" +fn_script_log_pass "termbin.com for 30D" +pdurl="${link}" + +if [ "${firstcommandname}" == "POST-DETAILS" ]; then + echo -e "" + echo -e "Please share the following url for support: " + echo -e "${pdurl}" +fi +fn_script_log_info "${pdurl}" +alerturl="${pdurl}" + +if [ -z "${exitbypass}" ]; then + core_exit.sh +fi diff --git a/lgsm/modules/command_restart.sh b/lgsm/modules/command_restart.sh new file mode 100644 index 0000000..ed60a55 --- /dev/null +++ b/lgsm/modules/command_restart.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# LinuxGSM command_restart.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Restarts the server. + +commandname="RESTART" +commandaction="Restarting" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +info_game.sh +exitbypass=1 +command_stop.sh +command_start.sh +fn_firstcommand_reset +core_exit.sh diff --git a/lgsm/modules/command_send.sh b/lgsm/modules/command_send.sh new file mode 100644 index 0000000..cf6a9f0 --- /dev/null +++ b/lgsm/modules/command_send.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# LinuxGSM command_send.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Send command to the server tmux console. + +commandname="SEND" +commandaction="Send" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +check.sh +if [ -z "${userinput2}" ]; then + fn_print_header + fn_print_information_nl "Send a command to the console." +fi + +check_status.sh +if [ "${status}" != "0" ]; then + if [ -n "${userinput2}" ]; then + commandtosend="${userinput2}" + else + echo "" + commandtosend=$(fn_prompt_message "send: ") + fi + echo "" + fn_print_dots "Sending command to console: \"${commandtosend}\"" + tmux -L "${socketname}" send-keys -t "${sessionname}" "${commandtosend}" ENTER + fn_print_ok_nl "Sending command to console: \"${commandtosend}\"" + fn_script_log_pass "Command \"${commandtosend}\" sent to console" +else + fn_print_error_nl "Server not running" + fn_script_log_error "Failed to access: Server not running" + if fn_prompt_yn "Do you want to start the server?" Y; then + exitbypass=1 + command_start.sh + fi +fi + +core_exit.sh diff --git a/lgsm/modules/command_skeleton.sh b/lgsm/modules/command_skeleton.sh new file mode 100644 index 0000000..48a6bd1 --- /dev/null +++ b/lgsm/modules/command_skeleton.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# LinuxGSM command_skeleton.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Creates an copy of a game servers directorys. + +commandname="SKELETON" +commandaction="Skeleton" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +fn_print_dots "Creating skeleton directory" +check.sh + +# Find all directorys and create them in the skel directory +find "${rootdir}" -type d -not \( -path ./skel -prune \) | cpio -pdvm skel 2> /dev/null +exitcode=$? +if [ "${exitcode}" != 0 ]; then + fn_print_fail_nl "Creating skeleton directory" + fn_script_log_fail "Creating skeleton directory" +else + fn_print_ok_nl "Creating skeleton directory: ./skel" + fn_script_log_pass "Creating skeleton directory: ./skel" +fi +core_exit.sh diff --git a/lgsm/modules/command_sponsor.sh b/lgsm/modules/command_sponsor.sh new file mode 100755 index 0000000..ea49a30 --- /dev/null +++ b/lgsm/modules/command_sponsor.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# LinuxGSM command_sponsor.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Shows ways to sponsor. + +commandname="SPONSOR" +commandaction="Sponsor" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +fn_print_ascii_logo +echo -e "${lightyellow}Support LinuxGSM${default}" +fn_messages_separator +echo -e "" +echo -e "Been using LinuxGSM?" +echo -e "Consider sponsoring to support development." +echo -e "" +echo -e "* ${lightblue}GitHub:${default} https://github.com/sponsors/dgibbs64" +echo -e "* ${lightblue}Patreon:${default} https://linuxgsm.com/patreon" +echo -e "* ${lightblue}PayPal:${default} https://linuxgsm.com/paypal" +echo -e "" +echo -e "LinuxGSM est. 2012" + +core_exit.sh diff --git a/lgsm/modules/command_start.sh b/lgsm/modules/command_start.sh new file mode 100644 index 0000000..345ede7 --- /dev/null +++ b/lgsm/modules/command_start.sh @@ -0,0 +1,232 @@ +#!/bin/bash +# LinuxGSM command_start.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Starts the server. + +commandname="START" +commandaction="Starting" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +addtimestamp="gawk '{ print strftime(\\\"[$logtimestampformat]\\\"), \\\$0 }'" +fn_firstcommand_set + +# This will allow the Jedi Knight 2 version to be printed in console on start. +# Used to allow update to detect JK2MV server version. +fn_start_jk2() { + fn_start_tmux + tmux -L "${socketname}" end -t "${sessionname}" version ENTER > /dev/null 2>&1 +} + +fn_start_tmux() { + # check for tmux size variables. + if [[ "${servercfgtmuxwidth}" =~ ^[0-9]+$ ]]; then + sessionwidth="${servercfgtmuxwidth}" + else + sessionwidth="80" + fi + if [[ "${servercfgtmuxheight}" =~ ^[0-9]+$ ]]; then + sessionheight="${servercfgtmuxheight}" + else + sessionheight="23" + fi + + # Log rotation. + fn_script_log_info "Rotating log files" + if [ "${engine}" == "unreal2" ] && [ -f "${gamelog}" ]; then + mv "${gamelog}" "${gamelogdate}" + fi + if [ -f "${lgsmlog}" ]; then + mv "${lgsmlog}" "${lgsmlogdate}" + fi + if [ -f "${consolelog}" ]; then + mv "${consolelog}" "${consolelogdate}" + fi + + # Create a starting lockfile that only exists while the start command is running. + date '+%s' > "${lockdir:?}/${selfname}-starting.lock" + + fn_reload_startparameters + + # Create uid to ensure unique tmux socket name. + if [ ! -f "${datadir}/${selfname}.uid" ]; then + check_status.sh + if [ "${status}" != "0" ]; then + # stop running server (if running) to prevent lingering tmux sessions. + exitbypass=1 + command_stop.sh + fi + uid=$(date '+%s' | sha1sum | head -c 8) + echo "${uid}" > "${datadir}/${selfname}.uid" + socketname="${sessionname}-$(cat "${datadir}/${selfname}.uid")" + fi + + if [ "${shortname}" == "av" ]; then + cd "${systemdir}" || exit + else + cd "${executabledir}" || exit + fi + + tmux -L "${socketname}" new-session -d -x "${sessionwidth}" -y "${sessionheight}" -s "${sessionname}" "${preexecutable} ${executable} ${startparameters}" 2> "${lgsmlogdir}/.${selfname}-tmux-error.tmp" + + # Create logfile. + touch "${consolelog}" + + # tmux compiled from source will return "master", therefore ignore it. + if [ "${tmuxv}" == "master" ]; then + fn_script_log "tmux version: master (user compiled)" + echo -e "tmux version: master (user compiled)" >> "${consolelog}" + if [ "${consolelogging}" == "on" ] || [ -z "${consolelogging}" ]; then + if [ "${logtimestamp}" == "on" ]; then + tmux -L "${socketname}" pipe-pane -o -t "${sessionname}" "exec bash -c \"cat | $addtimestamp\" >> '${consolelog}'" + else + tmux -L "${socketname}" pipe-pane -o -t "${sessionname}" "exec cat >> '${consolelog}'" + fi + fi + + elif [ -n "${tmuxv}" ]; then + # tmux pipe-pane not supported in tmux versions < 1.6. + if [ "${tmuxvdigit}" -lt "16" ]; then + echo -e "Console logging disabled: tmux => 1.6 required + https://linuxgsm.com/tmux-upgrade + Currently installed: $(tmux -V)" > "${consolelog}" + + # Console logging disabled: Bug in tmux 1.8 breaks logging. + elif [ "${tmuxvdigit}" -eq "18" ]; then + echo -e "Console logging disabled: Bug in tmux 1.8 breaks logging + https://linuxgsm.com/tmux-upgrade + Currently installed: $(tmux -V)" > "${consolelog}" + # Console logging enable or not set. + elif [ "${consolelogging}" == "on" ] || [ -z "${consolelogging}" ]; then + if [ "${logtimestamp}" == "on" ]; then + tmux -L "${socketname}" pipe-pane -o -t "${sessionname}" "exec bash -c \"cat | $addtimestamp\" >> '${consolelog}'" + else + tmux -L "${socketname}" pipe-pane -o -t "${sessionname}" "exec cat >> '${consolelog}'" + fi + fi + else + echo -e "Unable to detect tmux version" >> "${consolelog}" + fn_script_log_warn "Unable to detect tmux version" + fi + + # Console logging disabled. + if [ "${consolelogging}" == "off" ]; then + echo -e "Console logging disabled in settings" >> "${consolelog}" + fn_script_log_info "Console logging disabled by user" + fi + fn_sleep_time_1 + + # If the server fails to start. + check_status.sh + if [ "${status}" == "0" ]; then + fn_print_fail_nl "Unable to start ${servername}" + fn_script_log_fail "Unable to start ${servername}" + if [ -s "${lgsmlogdir}/.${selfname}-tmux-error.tmp" ]; then + fn_print_fail_nl "Unable to start ${servername}: tmux error:" + fn_script_log_fail "Unable to start ${servername}: tmux error:" + echo -e "" + echo -e "Command" + fn_messages_separator + echo -e "tmux -L \"${sessionname}\" new-session -d -s \"${sessionname}\" \"${preexecutable} ${executable} ${startparameters}\"" | tee -a "${lgsmlog}" + echo -e "" + echo -e "Error" + fn_messages_separator + tee -a "${lgsmlog}" < "${lgsmlogdir}/.${selfname}-tmux-error.tmp" + + # Detected error https://linuxgsm.com/support + if grep -c "Operation not permitted" "${lgsmlogdir}/.${selfname}-tmux-error.tmp"; then + echo -e "" + echo -e "Fix" + fn_messages_separator + if ! grep "tty:" /etc/group | grep "$(whoami)"; then + echo -e "$(whoami) is not part of the tty group." + fn_script_log_info "$(whoami) is not part of the tty group." + group=$(grep tty /etc/group) + echo -e "" + echo -e " ${group}" + fn_script_log_info "${group}" + echo -e "" + echo -e "Run the following command with root privileges." + echo -e "" + echo -e " usermod -G tty $(whoami)" + echo -e "" + echo -e "https://linuxgsm.com/tmux-op-perm" + fn_script_log_info "https://linuxgsm.com/tmux-op-perm" + else + echo -e "No known fix currently. Please log an issue." + fn_script_log_info "No known fix currently. Please log an issue." + echo -e "https://linuxgsm.com/support" + fn_script_log_info "https://linuxgsm.com/support" + fi + fi + fi + # Remove starting lockfile when command ends. + rm -f "${lockdir:?}/${selfname}-starting.lock" + core_exit.sh + else + # Create start lockfile that exists only when the server is running. + date '+%s' > "${lockdir:?}/${selfname}-started.lock" + echo "${version}" >> "${lockdir}/${selfname}-started.lock" + echo "${port}" >> "${lockdir}/${selfname}-started.lock" + fn_print_ok "${servername}" + fn_script_log_pass "Started ${servername}" + + # Create last started Lockfile. + date +%s > "${lockdir}/${selfname}-last-started.lock" + + fn_print_ok "${servername}" + fn_script_log_pass "Started ${servername}" + if [ "${statusalert}" == "on" ] && [ "${firstcommandname}" == "START" ]; then + alert="started" + alert.sh + elif [ "${statusalert}" == "on" ] && [ "${firstcommandname}" == "RESTART" ]; then + alert="restarted" + alert.sh + fi + fi + rm -f "${lgsmlogdir:?}/.${selfname}-tmux-error.tmp" 2> /dev/null + echo -en "\n" +} + +# If user ran the start command monitor will become enabled. +if [ "${firstcommandname}" == "START" ] || [ "${firstcommandname}" == "RESTART" ]; then + date '+%s' > "${lockdir:?}/${selfname}-monitoring.lock" +fi + +fn_print_dots "" +check.sh + +# If the server already started dont start again. +if [ "${status}" != "0" ]; then + fn_print_dots "${servername}" + fn_print_info_nl "${servername} is already running" + fn_script_log_error "${servername} is already running" + if [ -z "${exitbypass}" ]; then + # Remove starting lockfile when command ends. + rm -f "${lockdir:?}/${selfname}-starting.lock" + core_exit.sh + fi +fi + +fix.sh +info_game.sh +core_logs.sh + +# Will check for updates if updateonstart is yes. +if [ "${updateonstart}" == "yes" ] || [ "${updateonstart}" == "1" ] || [ "${updateonstart}" == "on" ]; then + exitbypass=1 + unset updateonstart + command_update.sh + fn_firstcommand_reset +fi + +fn_print_dots "${servername}" +if [ "${shortname}" == "jk2" ]; then + fn_start_jk2 +else + fn_start_tmux +fi + +# Remove starting lockfile when command ends. +rm -f "${lockdir:?}/${selfname}-starting.lock" +core_exit.sh diff --git a/lgsm/modules/command_stop.sh b/lgsm/modules/command_stop.sh new file mode 100644 index 0000000..3d53431 --- /dev/null +++ b/lgsm/modules/command_stop.sh @@ -0,0 +1,319 @@ +#!/bin/bash +# LinuxGSM command_stop.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Stops the server. + +commandname="STOP" +commandaction="Stopping" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +# Attempts graceful shutdown by sending 'CTRL+c'. +fn_stop_graceful_ctrlc() { + fn_print_dots "Graceful: CTRL+c" + fn_script_log_info "Graceful: CTRL+c" + # Sends CTRL+c. + tmux -L "${socketname}" send-keys -t "${sessionname}" C-c > /dev/null 2>&1 + # Waits up to 30 seconds giving the server time to shutdown gracefuly. + for seconds in {1..30}; do + check_status.sh + if [ "${status}" == "0" ]; then + fn_print_ok "Graceful: CTRL+c: ${seconds}: " + fn_print_ok_eol_nl + fn_script_log_pass "Graceful: CTRL+c: OK: ${seconds} seconds" + if [ "${statusalert}" == "on" ] && [ "${firstcommandname}" == "STOP" ]; then + alert="stopped" + alert.sh + fi + break + fi + fn_sleep_time_1 + fn_print_dots "Graceful: CTRL+c: ${seconds}" + done + check_status.sh + if [ "${status}" != "0" ]; then + fn_print_error "Graceful: CTRL+c: " + fn_print_fail_eol_nl + fn_script_log_error "Graceful: CTRL+c: FAIL" + fi +} + +# Attempts graceful shutdown by sending a specified command. +# Usage: fn_stop_graceful_cmd "console_command" "timeout_in_seconds" +# e.g.: fn_stop_graceful_cmd "quit" "30" +fn_stop_graceful_cmd() { + fn_print_dots "Graceful: sending \"${1}\"" + fn_script_log_info "Graceful: sending \"${1}\"" + # Sends specific stop command. + tmux -L "${socketname}" send -t "${sessionname}" ENTER "${1}" ENTER > /dev/null 2>&1 + # Waits up to ${seconds} seconds giving the server time to shutdown gracefully. + for ((seconds = 1; seconds <= ${2}; seconds++)); do + check_status.sh + if [ "${status}" == "0" ]; then + fn_print_ok "Graceful: sending \"${1}\": ${seconds}: " + fn_print_ok_eol_nl + fn_script_log_pass "Graceful: sending \"${1}\": OK: ${seconds} seconds" + if [ "${statusalert}" == "on" ] && [ "${firstcommandname}" == "STOP" ]; then + alert="stopped" + alert.sh + fi + break + fi + fn_sleep_time_1 + fn_print_dots "Graceful: sending \"${1}\": ${seconds}" + done + check_status.sh + if [ "${status}" != "0" ]; then + fn_print_error "Graceful: sending \"${1}\": " + fn_print_fail_eol_nl + fn_script_log_error "Graceful: sending \"${1}\": FAIL" + fi +} + +# Attempts graceful shutdown of goldsrc using rcon 'quit' command. +# There is only a 3 second delay before a forced a tmux shutdown +# as GoldSrc servers 'quit' command does a restart rather than shutdown. +fn_stop_graceful_goldsrc() { + fn_print_dots "Graceful: sending \"quit\"" + fn_script_log_info "Graceful: sending \"quit\"" + # sends quit + tmux -L "${socketname}" send -t "${sessionname}" quit ENTER > /dev/null 2>&1 + # Waits 3 seconds as goldsrc servers restart with the quit command. + for seconds in {1..3}; do + fn_sleep_time_1 + fn_print_dots "Graceful: sending \"quit\": ${seconds}" + done + fn_print_ok "Graceful: sending \"quit\": ${seconds}: " + fn_print_ok_eol_nl + fn_script_log_pass "Graceful: sending \"quit\": OK: ${seconds} seconds" + if [ "${statusalert}" == "on" ] && [ "${firstcommandname}" == "STOP" ]; then + alert="stopped" + alert.sh + fi +} + +# telnet command for sdtd graceful shutdown. +fn_stop_graceful_sdtd_telnet() { + if [ -z "${telnetpass}" ] || [ "${telnetpass}" == "NOT SET" ]; then + sdtd_telnet_shutdown=$(expect -c ' + proc abort {} { + puts "Timeout or EOF\n" + exit 1 + } + spawn telnet '"${telnetip}"' '"${telnetport}"' + expect { + "session." { send "shutdown\r" } + default abort + } + expect { eof } + puts "Completed.\n" + ') + else + sdtd_telnet_shutdown=$(expect -c ' + proc abort {} { + puts "Timeout or EOF\n" + exit 1 + } + spawn telnet '"${telnetip}"' '"${telnetport}"' + expect { + "password:" { send "'"${telnetpass}"'\r" } + default abort + } + expect { + "session." { send "shutdown\r" } + default abort + } + expect { eof } + puts "Completed.\n" + ') + fi +} + +# Attempts graceful shutdown of 7 Days To Die using telnet. +fn_stop_graceful_sdtd() { + fn_print_dots "Graceful: telnet" + fn_script_log_info "Graceful: telnet" + if [ "${telnetenabled}" == "false" ]; then + fn_print_info_nl "Graceful: telnet: DISABLED: Enable in ${servercfg}" + elif [ "$(command -v expect 2> /dev/null)" ]; then + # Tries to shutdown with both localhost and server IP. + for telnetip in 127.0.0.1 ${ip}; do + fn_print_dots "Graceful: telnet: ${telnetip}:${telnetport}" + fn_script_log_info "Graceful: telnet: ${telnetip}:${telnetport}" + fn_stop_graceful_sdtd_telnet + completed=$(echo -en "\n ${sdtd_telnet_shutdown}" | grep "Completed.") + refused=$(echo -en "\n ${sdtd_telnet_shutdown}" | grep "Timeout or EOF") + if [ "${refused}" ]; then + fn_print_error "Graceful: telnet: ${telnetip}:${telnetport} : " + fn_print_fail_eol_nl + fn_script_log_error "Graceful: telnet: ${telnetip}:${telnetport} : FAIL" + elif [ "${completed}" ]; then + break + fi + done + + # If telnet shutdown was successful will use telnet again to check + # the connection has closed, confirming that the tmux session can now be killed. + if [ "${completed}" ]; then + for seconds in {1..30}; do + fn_stop_graceful_sdtd_telnet + refused=$(echo -en "\n ${sdtd_telnet_shutdown}" | grep "Timeout or EOF") + if [ "${refused}" ]; then + fn_print_ok "Graceful: telnet: ${telnetip}:${telnetport} : " + fn_print_ok_eol_nl + fn_script_log_pass "Graceful: telnet: ${telnetip}:${telnetport} : ${seconds} seconds" + if [ "${statusalert}" == "on" ] && [ "${firstcommandname}" == "STOP" ]; then + alert="stopped" + alert.sh + fi + break + fi + fn_sleep_time_1 + fn_print_dots "Graceful: telnet: ${seconds}" + done + # If telnet shutdown fails tmux shutdown will be used, this risks loss of world save. + else + if [ "${refused}" ]; then + fn_print_error "Graceful: telnet: " + fn_print_fail_eol_nl + fn_script_log_error "Graceful: telnet: ${telnetip}:${telnetport} : FAIL" + else + fn_print_error_nl "Graceful: telnet: Unknown error" + fn_script_log_error "Graceful: telnet: Unknown error" + fi + echo -en "\n" | tee -a "${lgsmlog}" + echo -en "Telnet output:" | tee -a "${lgsmlog}" + echo -en "\n ${sdtd_telnet_shutdown}" | tee -a "${lgsmlog}" + echo -en "\n\n" | tee -a "${lgsmlog}" + fi + else + fn_print_warn "Graceful: telnet: expect not installed: " + fn_print_fail_eol_nl + fn_script_log_warn "Graceful: telnet: expect not installed: FAIL" + fi +} + +# Attempts graceful shutdown by sending /save /stop. +fn_stop_graceful_avorion() { + fn_print_dots "Graceful: /save /stop" + fn_script_log_info "Graceful: /save /stop" + # Sends /save. + tmux -L "${socketname}" send-keys -t "${sessionname}" /save ENTER > /dev/null 2>&1 + fn_sleep_time_5 + # Sends /quit. + tmux -L "${socketname}" send-keys -t "${sessionname}" /stop ENTER > /dev/null 2>&1 + # Waits up to 30 seconds giving the server time to shutdown gracefuly. + for seconds in {1..30}; do + check_status.sh + if [ "${status}" == "0" ]; then + fn_print_ok "Graceful: /save /stop: ${seconds}: " + fn_print_ok_eol_nl + fn_script_log_pass "Graceful: /save /stop: OK: ${seconds} seconds" + if [ "${statusalert}" == "on" ] && [ "${firstcommandname}" == "STOP" ]; then + alert="stopped" + alert.sh + fi + break + fi + fn_sleep_time_1 + fn_print_dots "Graceful: /save /stop: ${seconds}" + done + check_status.sh + if [ "${status}" != "0" ]; then + fn_print_error "Graceful: /save /stop: " + fn_print_fail_eol_nl + fn_script_log_error "Graceful: /save /stop: FAIL" + fi +} + +fn_stop_graceful_select() { + if [ "${stopmode}" == "1" ]; then + fn_stop_tmux + elif [ "${stopmode}" == "2" ]; then + fn_stop_graceful_ctrlc + elif [ "${stopmode}" == "3" ]; then + fn_stop_graceful_cmd "quit" 30 + elif [ "${stopmode}" == "4" ]; then + fn_stop_graceful_cmd "quit" 120 + elif [ "${stopmode}" == "5" ]; then + fn_stop_graceful_cmd "stop" 30 + elif [ "${stopmode}" == "6" ]; then + fn_stop_graceful_cmd "q" 30 + elif [ "${stopmode}" == "7" ]; then + fn_stop_graceful_cmd "exit" 30 + elif [ "${stopmode}" == "8" ]; then + fn_stop_graceful_sdtd + elif [ "${stopmode}" == "9" ]; then + fn_stop_graceful_goldsrc + elif [ "${stopmode}" == "10" ]; then + fn_stop_graceful_avorion + elif [ "${stopmode}" == "11" ]; then + fn_stop_graceful_cmd "end" 30 + elif [ "${stopmode}" == "12" ]; then + fn_stop_graceful_cmd "shutdown" 30 + fi +} + +fn_stop_tmux() { + fn_print_dots "${servername}" + fn_script_log_info "tmux kill-session: ${sessionname}: ${servername}" + # Kill tmux session. + tmux -L "${socketname}" kill-session -t "${sessionname}" > /dev/null 2>&1 + fn_sleep_time_1 + check_status.sh + if [ "${status}" == "0" ]; then + fn_print_ok_nl "${servername}" + fn_script_log_pass "Stopped ${servername}" + if [ "${statusalert}" == "on" ] && [ "${firstcommandname}" == "STOP" ]; then + alert="stopped" + alert.sh + fi + else + fn_print_fail_nl "Unable to stop ${servername}" + fn_script_log_fail "Unable to stop ${servername}" + fi +} + +# Checks if the server is already stopped. +fn_stop_pre_check() { + if [ "${status}" == "0" ]; then + fn_print_info_nl "${servername} is already stopped" + fn_script_log_info "${servername} is already stopped" + else + # Select graceful shutdown. + fn_stop_graceful_select + # Check status again, a kill tmux session if graceful shutdown failed. + check_status.sh + if [ "${status}" != "0" ]; then + fn_stop_tmux + fi + fi +} + +fn_print_dots "" +check.sh + +# Create a stopping lockfile that only exists while the stop command is running. +date '+%s' > "${lockdir:?}/${selfname}-stopping.lock" + +fn_print_dots "${servername}" + +info_game.sh +fn_stop_pre_check + +# Remove started lockfile. +rm -f "${lockdir:?}/${selfname}-started.lock" + +# If user ran the stop command monitor will become disabled. +if [ "${firstcommandname}" == "STOP" ]; then + rm -f "${lockdir:?}/${selfname}-monitoring.lock" +fi + +# Remove stopping lockfile. +rm -f "${lockdir:?}/${selfname}-stopping.lock" + +if [ -z "${exitbypass}" ]; then + core_exit.sh +fi diff --git a/lgsm/modules/command_test_alert.sh b/lgsm/modules/command_test_alert.sh new file mode 100644 index 0000000..15f4813 --- /dev/null +++ b/lgsm/modules/command_test_alert.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# LinuxGSM command_test_alert.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Sends a test alert. + +commandname="TEST-ALERT" +commandaction="Sending Alert" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +fn_print_dots "${servername}" +check.sh +info_game.sh +alert="test" +alert.sh + +core_exit.sh diff --git a/lgsm/modules/command_ts3_server_pass.sh b/lgsm/modules/command_ts3_server_pass.sh new file mode 100644 index 0000000..0223a87 --- /dev/null +++ b/lgsm/modules/command_ts3_server_pass.sh @@ -0,0 +1,57 @@ +#!/bin/bash +# LinuxGSM command_ts3_server_pass.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Changes TS3 serveradmin password. + +commandname="CHANGE-PASSWORD" +commandaction="Changing password" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +fn_serveradmin_password_prompt() { + fn_print_header + fn_print_information_nl "You are about to change the ${gamename} ServerAdmin password." + fn_print_warning_nl "${gamename} will restart during this process." + echo -e "" + if ! fn_prompt_yn "Continue?" Y; then + exitcode=0 + core_exit.sh + fi + fn_script_log_info "Initiating ${gamename} ServerAdmin password change" + read -rp "Enter new password: " newpassword + fn_print_info_nl "Changing password" + fn_script_log_info "Changing password" +} + +fn_serveradmin_password_set() { + # Start server in "new password mode". + ts3serverpass="1" + exitbypass=1 + command_start.sh + fn_firstcommand_reset + fn_print_ok_nl "New password applied" + fn_script_log_pass "New ServerAdmin password applied" +} + +# Running functions. +check.sh +fn_serveradmin_password_prompt +if [ "${status}" != "0" ]; then + # Stop any running server. + exitbypass=1 + command_stop.sh + fn_firstcommand_reset + fn_serveradmin_password_set + parms="serveradmin_password=\"${newpassword}\" inifile=\"${servercfgfullpath}\" > /dev/null 2>&1" + ts3serverpass="0" + command_restart.sh + fn_firstcommand_reset +else + fn_serveradmin_password_set + command_stop.sh + fn_firstcommand_reset +fi + +core_exit.sh diff --git a/lgsm/modules/command_update.sh b/lgsm/modules/command_update.sh new file mode 100644 index 0000000..e1fcec9 --- /dev/null +++ b/lgsm/modules/command_update.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# LinuxGSM command_update.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Handles updating of servers. + +commandname="UPDATE" +commandaction="Updating" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +fn_print_dots "" +check.sh +core_logs.sh +check_last_update.sh + +if [ "${shortname}" == "ts3" ]; then + update_ts3.sh +elif [ "${shortname}" == "mc" ]; then + update_mc.sh +elif [ "${shortname}" == "mcb" ]; then + update_mcb.sh +elif [ "${shortname}" == "pmc" ] || [ "${shortname}" == "vpmc" ] || [ "${shortname}" == "wmc" ]; then + update_pmc.sh +elif [ "${shortname}" == "fctr" ]; then + update_fctr.sh +elif [ "${shortname}" == "mta" ]; then + update_mta.sh +elif [ "${shortname}" == "jk2" ]; then + update_jk2.sh +elif [ "${shortname}" == "vints" ]; then + update_vints.sh +elif [ "${shortname}" == "ut99" ]; then + update_ut99.sh +else + update_steamcmd.sh +fi + +# remove update lockfile. +rm -f "${lockdir:?}/update.lock" + +core_exit.sh diff --git a/lgsm/modules/command_update_linuxgsm.sh b/lgsm/modules/command_update_linuxgsm.sh new file mode 100644 index 0000000..f6c1623 --- /dev/null +++ b/lgsm/modules/command_update_linuxgsm.sh @@ -0,0 +1,236 @@ +#!/bin/bash +# LinuxGSM command_update_linuxgsm.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Deletes the modules dir to allow re-downloading of modules from GitHub. + +commandname="UPDATE-LGSM" +commandaction="Updating LinuxGSM" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +fn_print_dots "" +check.sh +info_distro.sh + +fn_script_log_info "Updating LinuxGSM" + +fn_print_dots "Selecting repo" +fn_script_log_info "Selecting repo" +# Select remotereponame +curl --connect-timeout 10 -IsfL "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/linuxgsm.sh" 1> /dev/null +if [ $? != "0" ]; then + curl --connect-timeout 10 -IsfL "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/linuxgsm.sh" 1> /dev/null + if [ $? != "0" ]; then + fn_print_fail_nl "Selecting repo: Unable to to access GitHub or Bitbucket repositories" + fn_script_log_fail "Selecting repo: Unable to to access GitHub or Bitbucket repositories" + core_exit.sh + else + remotereponame="Bitbucket" + fn_print_ok_nl "Selecting repo: ${remotereponame}" + fi +else + remotereponame="GitHub" + fn_print_ok_nl "Selecting repo: ${remotereponame}" +fi + +# Check linuxsm.sh +echo -en "checking ${remotereponame} linuxgsm.sh...\c" +if [ "${remotereponame}" == "GitHub" ]; then + curl --connect-timeout 10 -IsfL "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/linuxgsm.sh" 1> /dev/null +else + curl --connect-timeout 10 -IsfL "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/linuxgsm.sh" 1> /dev/null +fi +if [ $? != "0" ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Checking ${remotereponame} linuxgsm.sh" + fn_script_log_fail "Curl returned error: $?" + core_exit.sh +fi + +if [ "${remotereponame}" == "GitHub" ]; then + tmp_script_diff=$(diff "${tmpdir}/linuxgsm.sh" <(curl --connect-timeout 10 -s "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/linuxgsm.sh")) +else + tmp_script_diff=$(diff "${tmpdir}/linuxgsm.sh" <(curl --connect-timeout 10 -s "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/linuxgsm.sh")) +fi + +if [ "${tmp_script_diff}" != "" ]; then + fn_print_update_eol_nl + fn_script_log_update "Checking ${remotereponame} linuxgsm.sh" + rm -f "${tmpdir:?}/linuxgsm.sh" + fn_fetch_file_github "" "linuxgsm.sh" "${tmpdir}" "nochmodx" "norun" "noforcedl" "nohash" +else + fn_print_ok_eol_nl + fn_script_log_pass "Checking ${remotereponame} linuxgsm.sh" +fi + +# Check gameserver.sh +# Compare gameserver.sh against linuxgsm.sh in the tmp dir. +# Ignoring server specific vars. +echo -en "checking ${selfname}...\c" +fn_script_log_info "Checking ${selfname}" +script_diff=$(diff <(sed '\/shortname/d;\/gameservername/d;\/gamename/d;\/githubuser/d;\/githubrepo/d;\/githubbranch/d' "${tmpdir}/linuxgsm.sh") <(sed '\/shortname/d;\/gameservername/d;\/gamename/d;\/githubuser/d;\/githubrepo/d;\/githubbranch/d' "${rootdir}/${selfname}")) +if [ "${script_diff}" != "" ]; then + fn_print_update_eol_nl + fn_script_log_update "Checking ${selfname}" + echo -en "backup ${selfname}...\c" + fn_script_log_info "Backup ${selfname}" + if [ ! -d "${backupdir}/script" ]; then + mkdir -p "${backupdir}/script" + fi + cp "${rootdir}/${selfname}" "${backupdir}/script/${selfname}-$(date +"%m_%d_%Y_%M").bak" + if [ $? != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Backup ${selfname}" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Backup ${selfname}" + echo -e "backup location ${backupdir}/script/${selfname}-$(date +"%m_%d_%Y_%M").bak" + fn_script_log_pass "Backup location ${backupdir}/script/${selfname}-$(date +"%m_%d_%Y_%M").bak" + fi + + echo -en "copying ${selfname}...\c" + fn_script_log_info "Copying ${selfname}" + cp "${tmpdir}/linuxgsm.sh" "${rootdir}/${selfname}" + sed -i "s+shortname=\"core\"+shortname=\"${shortname}\"+g" "${rootdir}/${selfname}" + sed -i "s+gameservername=\"core\"+gameservername=\"${gameservername}\"+g" "${rootdir}/${selfname}" + sed -i "s+gamename=\"core\"+gamename=\"${gamename}\"+g" "${rootdir}/${selfname}" + sed -i "s+githubuser=\"GameServerManagers\"+githubuser=\"${githubuser}\"+g" "${rootdir}/${selfname}" + sed -i "s+githubrepo=\"LinuxGSM\"+githubrepo=\"${githubrepo}\"+g" "${rootdir}/${selfname}" + sed -i "s+githubbranch=\"master\"+githubbranch=\"${githubbranch}\"+g" "${rootdir}/${selfname}" + + if [ $? != "0" ]; then + fn_print_fail_eol_nl + fn_script_log_fail "copying ${selfname}" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "copying ${selfname}" + fi +else + fn_print_ok_eol_nl + fn_script_log_info "Checking ${selfname}" +fi + +# Check _default.cfg. +echo -en "checking ${remotereponame} config _default.cfg...\c" +fn_script_log_info "Checking ${remotereponame} config _default.cfg" +if [ "${remotereponame}" == "GitHub" ]; then + curl --connect-timeout 10 -IsfL "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/config-default/config-lgsm/${gameservername}/_default.cfg" 1> /dev/null +else + curl --connect-timeout 10 -IsfL "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/config-default/config-lgsm/${gameservername}/_default.cfg" 1> /dev/null +fi +if [ $? != "0" ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Checking ${remotereponame} config _default.cfg" + fn_script_log_fail "Curl returned error: $?" + core_exit.sh +fi + +if [ "${remotereponame}" == "GitHub" ]; then + config_file_diff=$(diff "${configdirdefault}/config-lgsm/${gameservername}/_default.cfg" <(curl --connect-timeout 10 -s "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/config-default/config-lgsm/${gameservername}/_default.cfg")) +else + config_file_diff=$(diff "${configdirdefault}/config-lgsm/${gameservername}/_default.cfg" <(curl --connect-timeout 10 -s "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/config-default/config-lgsm/${gameservername}/_default.cfg")) +fi + +if [ "${config_file_diff}" != "" ]; then + fn_print_update_eol_nl + fn_script_log_update "Checking ${remotereponame} config _default.cfg" + rm -f "${configdirdefault:?}/config-lgsm/${gameservername:?}/_default.cfg" + fn_fetch_file_github "lgsm/config-default/config-lgsm/${gameservername}" "_default.cfg" "${configdirdefault}/config-lgsm/${gameservername}" "nochmodx" "norun" "noforce" "nohash" + alert="config" + alert.sh +else + fn_print_ok_eol_nl + fn_script_log_pass "Checking ${remotereponame} config _default.cfg" +fi + +# Check distro csv. ${datadir}/${distroid}-${distroversioncsv}.csv +if [ -f "${datadir}/${distroid}-${distroversioncsv}.csv" ]; then + echo -en "checking ${remotereponame} config ${distroid}-${distroversioncsv}.csv...\c" + fn_script_log_info "Checking ${remotereponame} ${distroid}-${distroversioncsv}.csv" + if [ "${remotereponame}" == "GitHub" ]; then + curl --connect-timeout 10 -IsfL "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/data/${distroid}-${distroversioncsv}.csv" 1> /dev/null + else + curl --connect-timeout 10 -IsfL "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/data/${distroid}-${distroversioncsv}.csv" 1> /dev/null + fi + if [ $? != "0" ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Checking ${remotereponame} ${distroid}-${distroversioncsv}.csv" + fn_script_log_fail "Curl returned error: $?" + core_exit.sh + fi + + if [ "${remotereponame}" == "GitHub" ]; then + config_file_diff=$(diff "${datadir}/${distroid}-${distroversioncsv}.csv" <(curl --connect-timeout 10 -s "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/data/${distroid}-${distroversioncsv}.csv")) + else + config_file_diff=$(diff "${datadir}/${distroid}-${distroversioncsv}.csv" <(curl --connect-timeout 10 -s "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/lgsm/data/${distroid}-${distroversioncsv}.csv")) + fi + + if [ "${config_file_diff}" != "" ]; then + fn_print_update_eol_nl + fn_script_log_update "Checking ${remotereponame} ${distroid}-${distroversioncsv}.csv" + rm -f "${datadir:?}/${distroid}-${distroversioncsv}.csv" + fn_fetch_file_github "lgsm/data" "${distroid}-${distroversioncsv}.csv" "${datadir}" "nochmodx" "norun" "noforce" "nohash" + else + fn_print_ok_eol_nl + fn_script_log_pass "Checking ${remotereponame} ${distroid}-${distroversioncsv}.csv" + fi +fi +# Check and update modules. +if [ -n "${modulesdir}" ]; then + if [ -d "${modulesdir}" ]; then + ( + cd "${modulesdir}" || exit + for modulefile in *; do + # check if module exists in the repo and remove if missing. + # commonly used if module names change. + echo -en "checking ${remotereponame} module ${modulefile}...\c" + github_file_url_dir="lgsm/modules" + if [ "${remotereponame}" == "GitHub" ]; then + curl --connect-timeout 10 -IsfL "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/${github_file_url_dir}/${modulefile}" 1> /dev/null + else + curl --connect-timeout 10 -IsfL "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/${github_file_url_dir}/${modulefile}" 1> /dev/null + fi + if [ $? != 0 ]; then + fn_print_error_eol_nl + fn_script_log_error "Checking ${remotereponame} module ${modulefile}" + echo -en "removing module ${modulefile}...\c" + if ! rm -f "${modulefile:?}"; then + fn_print_fail_eol_nl + fn_script_log_fail "Removing module ${modulefile}" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Removing module ${modulefile}" + fi + else + # compare file + if [ "${remotereponame}" == "GitHub" ]; then + module_file_diff=$(diff "${modulesdir}/${modulefile}" <(curl --connect-timeout 10 -s "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/${github_file_url_dir}/${modulefile}")) + else + module_file_diff=$(diff "${modulesdir}/${modulefile}" <(curl --connect-timeout 10 -s "https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/${github_file_url_dir}/${modulefile}")) + fi + + # results + if [ "${module_file_diff}" != "" ]; then + fn_print_update_eol_nl + fn_script_log_update "Checking ${remotereponame} module ${modulefile}" + rm -rf "${modulesdir:?}/${modulefile}" + fn_update_module + else + fn_print_ok_eol_nl + fn_script_log_pass "Checking ${remotereponame} module ${modulefile}" + fi + fi + done + ) + fi +fi + +fn_print_ok_nl "Updating modules" +fn_script_log_pass "Updating modules" + +core_exit.sh diff --git a/lgsm/modules/command_validate.sh b/lgsm/modules/command_validate.sh new file mode 100644 index 0000000..d3511d7 --- /dev/null +++ b/lgsm/modules/command_validate.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# LinuxGSM command_validate.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Runs a server validation. + +commandname="VALIDATE" +commandaction="Validating" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +fn_validate() { + fn_print_warn "Validate might overwrite some customised files" + fn_script_log_warn "${commandaction} server: Validate might overwrite some customised files" + totalseconds=3 + for seconds in {3..1}; do + fn_print_warn "Validate might overwrite some customised files: ${totalseconds}" + totalseconds=$((totalseconds - 1)) + fn_sleep_time_1 + if [ "${seconds}" == "0" ]; then + break + fi + done + fn_print_warn_nl "Validate might overwrite some customised files" + date '+%s' > "${lockdir:?}/update.lock" + fn_dl_steamcmd +} + +fn_print_dots "" +check.sh +core_logs.sh + +fn_print_dots "SteamCMD" + +if [ "${status}" != "0" ]; then + fn_print_restart_warning + exitbypass=1 + command_stop.sh + fn_firstcommand_reset + fn_validate + exitbypass=1 + command_start.sh + fn_firstcommand_reset +else + fn_validate +fi + +# remove update lockfile +rm -f "${lockdir:?}/update.lock" + +core_exit.sh diff --git a/lgsm/modules/command_wipe.sh b/lgsm/modules/command_wipe.sh new file mode 100644 index 0000000..378dae0 --- /dev/null +++ b/lgsm/modules/command_wipe.sh @@ -0,0 +1,187 @@ +#!/bin/bash +# LinuxGSM command_backup.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Wipes server data, useful after updates for some games like Rust. + +commandname="WIPE" +commandaction="Wiping" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +# Provides an exit code upon error. +fn_wipe_exit_code() { + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + core_exit.sh + else + fn_print_ok_eol_nl + fi +} + +# Removes files to wipe server. +fn_wipe_files() { + fn_print_start_nl "${wipetype}" + fn_script_log_info "${wipetype}" + + # Remove Map files + if [ -n "${serverwipe}" ] || [ -n "${mapwipe}" ]; then + if [ -n "$(find "${serveridentitydir}" -type f -name "*.map")" ]; then + echo -en "removing .map file(s)..." + fn_script_log_info "Removing *.map file(s)" + fn_sleep_time + find "${serveridentitydir:?}" -type f -name "*.map" -printf "%f\n" >> "${lgsmlog}" + find "${serveridentitydir:?}" -type f -name "*.map" -delete | tee -a "${lgsmlog}" + fn_wipe_exit_code + else + echo -e "no .map file(s) to remove" + fn_sleep_time + fn_script_log_pass "no .map file(s) to remove" + fi + fi + # Remove Save files. + if [ -n "${serverwipe}" ] || [ -n "${mapwipe}" ]; then + if [ -n "$(find "${serveridentitydir}" -type f -name "*.sav*")" ]; then + echo -en "removing .sav file(s)..." + fn_script_log_info "Removing .sav file(s)" + fn_sleep_time + find "${serveridentitydir:?}" -type f -name "*.sav*" -printf "%f\n" >> "${lgsmlog}" + find "${serveridentitydir:?}" -type f -name "*.sav*" -delete + fn_wipe_exit_code + else + echo -e "no .sav file(s) to remove" + fn_script_log_pass "no .sav file(s) to remove" + fn_sleep_time + fi + fi + # Remove db files for full wipe. + # Excluding player.tokens.db for Rust+. + if [ -n "${serverwipe}" ]; then + if [ -n "$(find "${serveridentitydir}" -type f ! -name 'player.tokens.db' -name "*.db")" ]; then + echo -en "removing .db file(s)..." + fn_script_log_info "Removing .db file(s)" + fn_sleep_time + find "${serveridentitydir:?}" -type f ! -name 'player.tokens.db' -name "*.db" -printf "%f\n" >> "${lgsmlog}" + find "${serveridentitydir:?}" -type f ! -name 'player.tokens.db' -name "*.db" -delete + fn_wipe_exit_code + else + echo -e "no .db file(s) to remove" + fn_sleep_time + fn_script_log_pass "no .db file(s) to remove" + fi + fi +} + +fn_map_wipe_warning() { + fn_print_warn "Map wipe will reset the map data and keep blueprint data" + fn_script_log_warn "Map wipe will reset the map data and keep blueprint data" + totalseconds=3 + for seconds in {3..1}; do + fn_print_warn "map wipe will reset the map data and keep blueprint data: ${totalseconds}" + totalseconds=$((totalseconds - 1)) + fn_sleep_time_1 + if [ "${seconds}" == "0" ]; then + break + fi + done + fn_print_warn_nl "Map wipe will reset the map data and keep blueprint data" +} + +fn_full_wipe_warning() { + fn_print_warn "Server wipe will reset the map data and remove blueprint data" + fn_script_log_warn "Server wipe will reset the map data and remove blueprint data" + totalseconds=3 + for seconds in {3..1}; do + fn_print_warn "server wipe will reset the map data and remove blueprint data: ${totalseconds}" + totalseconds=$((totalseconds - 1)) + fn_sleep_time_1 + if [ "${seconds}" == "0" ]; then + break + fi + done + fn_print_warn_nl "Server wipe will reset the map data and remove blueprint data" +} + +# Will change the seed if the seed is not defined by the user. +fn_wipe_random_seed() { + if [ -f "${datadir}/${selfname}-seed.txt" ] && [ -n "${randomseed}" ]; then + shuf -i 1-2147483647 -n 1 > "${datadir}/${selfname}-seed.txt" + seed=$(cat "${datadir}/${selfname}-seed.txt") + randomseed=1 + echo -en "generating new random seed (${cyan}${seed}${default})..." + fn_script_log_pass "Generating new random seed (${cyan}${seed}${default})" + fn_sleep_time + fn_print_ok_eol_nl + fi +} + +# A summary of what wipe is going to do. +fn_wipe_details() { + fn_print_information_nl "Wipe does not remove Rust+ data." + echo -en "* Wipe map data: " + if [ -n "${serverwipe}" ] || [ -n "${mapwipe}" ]; then + fn_print_yes_eol_nl + else + fn_print_no_eol_nl + fi + + echo -en "* Wipe blueprint data: " + if [ -n "${serverwipe}" ]; then + fn_print_yes_eol_nl + else + fn_print_no_eol_nl + fi + + echo -en "* Change Procedural Map seed: " + if [ -n "${randomseed}" ]; then + fn_print_yes_eol_nl + else + fn_print_no_eol_nl + fi +} + +fn_print_dots "" +check.sh +fix_rust.sh + +# Check if there is something to wipe. +if [ -n "$(find "${serveridentitydir}" -type f -name "*.map")" ] || [ -n "$(find "${serveridentitydir}" -type f -name "*.sav*")" ] && [ -n "$(find "${serveridentitydir}" -type f ! -name 'player.tokens.db' -name "*.db")" ]; then + if [ -n "${serverwipe}" ]; then + wipetype="Full wipe" + fn_full_wipe_warning + fn_wipe_details + elif [ -n "${mapwipe}" ]; then + wipetype="Map wipe" + fn_map_wipe_warning + fn_wipe_details + fi + check_status.sh + if [ "${status}" != "0" ]; then + fn_print_restart_warning + exitbypass=1 + command_stop.sh + fn_firstcommand_reset + fn_wipe_files + fn_wipe_random_seed + fn_print_complete_nl "${wipetype}" + fn_script_log_pass "${wipetype}" + alert="wipe" + alert.sh + exitbypass=1 + command_start.sh + fn_firstcommand_reset + else + fn_wipe_files + fn_wipe_random_seed + fn_print_complete_nl "${wipetype}" + fn_script_log_pass "${wipetype}" + alert="wipe" + alert.sh + fi +else + fn_print_ok_nl "Wipe not required" + fn_script_log_pass "Wipe not required" +fi +core_exit.sh diff --git a/lgsm/modules/compress_unreal2_maps.sh b/lgsm/modules/compress_unreal2_maps.sh new file mode 100644 index 0000000..f67ac70 --- /dev/null +++ b/lgsm/modules/compress_unreal2_maps.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# LinuxGSM compress_unreal2_maps.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Compresses unreal maps. + +commandname="MAP-COMPRESSOR" +commandaction="Compressing maps" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +check.sh +fn_print_header +echo -e "Will compress all maps in:" +echo -e "" +pwd +echo -e "" +echo -e "Compressed maps saved to:" +echo -e "" +echo -e "${compressedmapsdir}" +echo -e "" +if ! fn_prompt_yn "Start compression?" Y; then + exitcode=0 + core_exit.sh +fi +mkdir -pv "${compressedmapsdir}" > /dev/null 2>&1 +rm -rfv "${serverfiles:?}/Maps/"*.ut2.uz2 +cd "${systemdir}" || exit +for map in "${serverfiles}/Maps/"*; do + ./ucc-bin compress "${map}" --nohomedir +done +mv -fv "${serverfiles}/Maps/"*.ut2.uz2 "${compressedmapsdir}" + +core_exit.sh diff --git a/lgsm/modules/compress_ut99_maps.sh b/lgsm/modules/compress_ut99_maps.sh new file mode 100644 index 0000000..51bbd38 --- /dev/null +++ b/lgsm/modules/compress_ut99_maps.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# LinuxGSM compress_ut99_maps.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Compresses unreal maps. + +commandname="MAP-COMPRESSOR" +commandaction="Compressing maps" +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +fn_firstcommand_set + +check.sh +fn_print_header +echo -e "Will compress all maps in:" +echo -e "" +pwd +echo -e "" +echo -e "Compressed maps saved to:" +echo -e "" +echo -e "${compressedmapsdir}" +echo -e "" +if ! fn_prompt_yn "Start compression?" Y; then + exitcode=0 + core_exit.sh +fi +mkdir -pv "${compressedmapsdir}" > /dev/null 2>&1 +rm -rfv "${serverfiles:?}/Maps/"*.unr.uz +cd "${systemdir}" || exit +for map in "${serverfiles}/Maps/"*; do + ./ucc-bin compress "${map}" --nohomedir +done +mv -fv "${serverfiles}/Maps/"*.unr.uz "${compressedmapsdir}" + +core_exit.sh diff --git a/lgsm/modules/core_dl.sh b/lgsm/modules/core_dl.sh new file mode 100644 index 0000000..b2846af --- /dev/null +++ b/lgsm/modules/core_dl.sh @@ -0,0 +1,630 @@ +#!/bin/bash +# LinuxGSM core_dl.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Deals with all downloads for LinuxGSM. + +# remote_fileurl: The URL of the file: http://example.com/dl/File.tar.bz2 +# local_filedir: location the file is to be saved: /home/server/lgsm/tmp +# local_filename: name of file (this can be different from the url name): file.tar.bz2 +# chmodx: Optional, set to "chmodx" to make file executable using chmod +x +# run: Optional, set run to execute the file after download +# forcedl: Optional, force re-download of file even if exists +# hash: Optional, set an hash sum and will compare it against the file. +# +# Downloads can be defined in code like so: +# fn_fetch_file "${remote_fileurl}" "${remote_fileurl_backup}" "${remote_fileurl_name}" "${remote_fileurl_backup_name}" "${local_filedir}" "${local_filename}" "${chmodx}" "${run}" "${forcedl}" "${hash}" +# fn_fetch_file "http://example.com/file.tar.bz2" "http://example.com/file2.tar.bz2" "file.tar.bz2" "file2.tar.bz2" "/some/dir" "file.tar.bz2" "chmodx" "run" "forcedl" "10cd7353aa9d758a075c600a6dd193fd" + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_dl_steamcmd() { + fn_print_start_nl "${remotelocation}" + fn_script_log_info "${commandaction} ${selfname}: ${remotelocation}" + if [ -n "${branch}" ]; then + echo -e "Branch: ${branch}" + fn_script_log_info "Branch: ${branch}" + fi + if [ -n "${betapassword}" ]; then + echo -e "Branch password: ${betapassword}" + fn_script_log_info "Branch password: ${betapassword}" + fi + if [ -d "${steamcmddir}" ]; then + cd "${steamcmddir}" || exit + fi + + # Unbuffer will allow the output of steamcmd not buffer allowing a smooth output. + # unbuffer us part of the expect package. + if [ "$(command -v unbuffer 2> /dev/null)" ]; then + unbuffer="unbuffer" + fi + + # Validate will be added as a parameter if required. + if [ "${commandname}" == "VALIDATE" ] || [ "${commandname}" == "INSTALL" ]; then + validate="validate" + fi + + # To do error checking for SteamCMD the output of steamcmd will be saved to a log. + steamcmdlog="${lgsmlogdir}/${selfname}-steamcmd.log" + + # clear previous steamcmd log + if [ -f "${steamcmdlog}" ]; then + rm -f "${steamcmdlog:?}" + fi + counter=0 + while [ "${counter}" == "0" ] || [ "${exitcode}" != "0" ]; do + counter=$((counter + 1)) + # Select SteamCMD parameters + # If GoldSrc (appid 90) servers. GoldSrc (appid 90) require extra commands. + if [ "${appid}" == "90" ]; then + # If using a specific branch. + if [ -n "${branch}" ] && [ -n "${betapassword}" ]; then + ${unbuffer} ${steamcmdcommand} +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_set_config 90 mod "${appidmod}" +app_update "${appid}" -beta "${branch}" -betapassword "${betapassword}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + elif [ -n "${branch}" ]; then + ${unbuffer} ${steamcmdcommand} +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_set_config 90 mod "${appidmod}" +app_update "${appid}" -beta "${branch}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + else + ${unbuffer} ${steamcmdcommand} +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_set_config 90 mod "${appidmod}" +app_update "${appid}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + fi + # Force Windows Platform type. + elif [ "${steamcmdforcewindows}" == "yes" ]; then + if [ -n "${branch}" ] && [ -n "${betapassword}" ]; then + ${unbuffer} ${steamcmdcommand} +@sSteamCmdForcePlatformType windows +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_update "${appid}" -beta "${branch}" -betapassword "${betapassword}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + elif [ -n "${branch}" ]; then + ${unbuffer} ${steamcmdcommand} +@sSteamCmdForcePlatformType windows +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_update "${appid}" -beta "${branch}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + else + ${unbuffer} ${steamcmdcommand} +@sSteamCmdForcePlatformType windows +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_update "${appid}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + fi + # All other servers. + else + if [ -n "${branch}" ] && [ -n "${betapassword}" ]; then + ${unbuffer} ${steamcmdcommand} +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_update "${appid}" -beta "${branch}" -betapassword "${betapassword}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + elif [ -n "${branch}" ]; then + ${unbuffer} ${steamcmdcommand} +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_update "${appid}" -beta "${branch}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + else + ${unbuffer} ${steamcmdcommand} +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_update "${appid}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + fi + fi + + # Error checking for SteamCMD. Some errors will loop to try again and some will just exit. + # Check also if we have more errors than retries to be sure that we do not loop to many times and error out. + exitcode=$? + if [ -n "$(grep -i "Error!" "${steamcmdlog}" | tail -1)" ] && [ "$(grep -ic "Error!" "${steamcmdlog}")" -ge "${counter}" ]; then + # Not enough space. + if [ -n "$(grep "0x202" "${steamcmdlog}" | tail -1)" ]; then + fn_print_failure_nl "${commandaction} ${selfname}: ${remotelocation}: Not enough disk space to download server files" + fn_script_log_fail "${commandaction} ${selfname}: ${remotelocation}: Not enough disk space to download server files" + core_exit.sh + # Not enough space. + elif [ -n "$(grep "0x212" "${steamcmdlog}" | tail -1)" ]; then + fn_print_failure_nl "${commandaction} ${selfname}: ${remotelocation}: Not enough disk space to download server files" + fn_script_log_fail "${commandaction} ${selfname}: ${remotelocation}: Not enough disk space to download server files" + core_exit.sh + # Need tp purchase game. + elif [ -n "$(grep "No subscription" "${steamcmdlog}" | tail -1)" ]; then + fn_print_failure_nl "${commandaction} ${selfname}: ${remotelocation}: Steam account does not have a license for the required game" + fn_script_log_fail "${commandaction} ${selfname}: ${remotelocation}: Steam account does not have a license for the required game" + core_exit.sh + # Two-factor authentication failure + elif [ -n "$(grep "Two-factor code mismatch" "${steamcmdlog}" | tail -1)" ]; then + fn_print_failure_nl "${commandaction} ${selfname}: ${remotelocation}: Two-factor authentication failure" + fn_script_log_fail "${commandaction} ${selfname}: ${remotelocation}: Two-factor authentication failure" + core_exit.sh + # Incorrect Branch password + elif [ -n "$(grep "Password check for AppId" "${steamcmdlog}" | tail -1)" ]; then + fn_print_failure_nl "${commandaction} ${selfname}: ${remotelocation}: betapassword is incorrect" + fn_script_log_fail "${commandaction} ${selfname}: ${remotelocation}: betapassword is incorrect" + core_exit.sh + # Update did not finish. + elif [ -n "$(grep "0x402" "${steamcmdlog}" | tail -1)" ] || [ -n "$(grep "0x602" "${steamcmdlog}" | tail -1)" ]; then + fn_print_error2_nl "${commandaction} ${selfname}: ${remotelocation}: Update required but not completed - check network" + fn_script_log_error "${commandaction} ${selfname}: ${remotelocation}: Update required but not completed - check network" + # Disk write failure. + elif [ -n "$(grep "0x606" "${steamcmdlog}" | tail -1)" ] || [ -n "$(grep "0x602" "${steamcmdlog}" | tail -1)" ]; then + fn_print_error2_nl "${commandaction} ${selfname}: ${remotelocation}: Disk write failure" + fn_script_log_error "${commandaction} ${selfname}: ${remotelocation}: Disk write failure" + # Missing update files. + elif [ -n "$(grep "0x626" "${steamcmdlog}" | tail -1)" ] || [ -n "$(grep "0x626" "${steamcmdlog}" | tail -1)" ]; then + fn_print_error2_nl "${commandaction} ${selfname}: ${remotelocation}: Missing update files" + fn_script_log_error "${commandaction} ${selfname}: ${remotelocation}: Missing update files" + else + fn_print_error2_nl "${commandaction} ${selfname}: ${remotelocation}: Unknown error occured" + echo -en "Please provide content log to LinuxGSM developers https://linuxgsm.com/steamcmd-error" + fn_script_log_error "${commandaction} ${selfname}: ${remotelocation}: Unknown error occured" + fi + elif [ "${exitcode}" != 0 ]; then + fn_print_error2_nl "${commandaction} ${selfname}: ${remotelocation}: Exit code: ${exitcode}" + fn_script_log_error "${commandaction} ${selfname}: ${remotelocation}: Exit code: ${exitcode}" + else + fn_print_complete_nl "${commandaction} ${selfname}: ${remotelocation}" + fn_script_log_pass "${commandaction} ${selfname}: ${remotelocation}" + fi + + if [ "${counter}" -gt "10" ]; then + fn_print_failure_nl "${commandaction} ${selfname}: ${remotelocation}: Did not complete the download, too many retrys" + fn_script_log_fail "${commandaction} ${selfname}: ${remotelocation}: Did not complete the download, too many retrys" + core_exit.sh + fi + done +} + +# Emptys contents of the LinuxGSM tmpdir. +fn_clear_tmp() { + echo -en "clearing LinuxGSM tmp directory..." + if [ -d "${tmpdir}" ]; then + rm -rf "${tmpdir:?}/"* + local exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_error_eol_nl + fn_script_log_error "clearing LinuxGSM tmp directory" + else + fn_print_ok_eol_nl + fn_script_log_pass "clearing LinuxGSM tmp directory" + fi + fi +} + +fn_dl_hash() { + # Runs Hash Check if available. + if [ "${hash}" != "0" ] && [ "${hash}" != "nohash" ] && [ "${hash}" != "nomd5" ]; then + # MD5 + if [ "${#hash}" == "32" ]; then + hashbin="md5sum" + hashtype="MD5" + # SHA1 + elif [ "${#hash}" == "40" ]; then + hashbin="sha1sum" + hashtype="SHA1" + # SHA256 + elif [ "${#hash}" == "64" ]; then + hashbin="sha256sum" + hashtype="SHA256" + # SHA512 + elif [ "${#hash}" == "128" ]; then + hashbin="sha512sum" + hashtype="SHA512" + else + fn_script_log_error "hash lengh not known for hash type" + fn_print_error_nl "hash lengh not known for hash type" + core_exit.sh + fi + echo -en "verifying ${local_filename} with ${hashtype}..." + fn_sleep_time + hashsumcmd=$(${hashbin} "${local_filedir}/${local_filename}" | awk '{print $1}') + if [ "${hashsumcmd}" != "${hash}" ]; then + fn_print_fail_eol_nl + echo -e "${local_filename} returned ${hashtype} checksum: ${hashsumcmd}" + echo -e "expected ${hashtype} checksum: ${hash}" + fn_script_log_fail "Verifying ${local_filename} with ${hashtype}" + fn_script_log_info "${local_filename} returned ${hashtype} checksum: ${hashsumcmd}" + fn_script_log_info "Expected ${hashtype} checksum: ${hash}" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Verifying ${local_filename} with ${hashtype}" + fn_script_log_info "${local_filename} returned ${hashtype} checksum: ${hashsumcmd}" + fn_script_log_info "Expected ${hashtype} checksum: ${hash}" + fi + fi +} + +# Extracts bzip2, gzip or zip files. +# Extracts can be defined in code like so: +# fn_dl_extract "${local_filedir}" "${local_filename}" "${extractdest}" "${extractsrc}" +# fn_dl_extract "/home/gameserver/lgsm/tmp" "file.tar.bz2" "/home/gamserver/serverfiles" +fn_dl_extract() { + local_filedir="${1}" + local_filename="${2}" + extractdest="${3}" + extractsrc="${4}" + # Extracts archives. + echo -en "extracting ${local_filename}..." + + if [ ! -d "${extractdest}" ]; then + mkdir "${extractdest}" + fi + if [ ! -f "${local_filedir}/${local_filename}" ]; then + fn_print_fail_eol_nl + echo -en "file ${local_filedir}/${local_filename} not found" + fn_script_log_fail "Extracting ${local_filename}" + fn_script_log_fail "File ${local_filedir}/${local_filename} not found" + core_exit.sh + fi + mime=$(file -b --mime-type "${local_filedir}/${local_filename}") + if [ "${mime}" == "application/gzip" ] || [ "${mime}" == "application/x-gzip" ]; then + if [ -n "${extractsrc}" ]; then + extractcmd=$(tar -zxf "${local_filedir}/${local_filename}" -C "${extractdest}" --strip-components=1 "${extractsrc}") + else + extractcmd=$(tar -zxf "${local_filedir}/${local_filename}" -C "${extractdest}") + fi + elif [ "${mime}" == "application/x-bzip2" ]; then + if [ -n "${extractsrc}" ]; then + extractcmd=$(tar -jxf "${local_filedir}/${local_filename}" -C "${extractdest}" --strip-components=1 "${extractsrc}") + else + extractcmd=$(tar -jxf "${local_filedir}/${local_filename}" -C "${extractdest}") + fi + elif [ "${mime}" == "application/x-xz" ]; then + if [ -n "${extractsrc}" ]; then + extractcmd=$(tar -Jxf "${local_filedir}/${local_filename}" -C "${extractdest}" --strip-components=1 "${extractsrc}") + else + extractcmd=$(tar -Jxf "${local_filedir}/${local_filename}" -C "${extractdest}") + fi + elif [ "${mime}" == "application/zip" ]; then + if [ -n "${extractsrc}" ]; then + extractcmd=$(unzip -qoj -d "${extractdest}" "${local_filedir}/${local_filename}" "${extractsrc}"/*) + else + extractcmd=$(unzip -qo -d "${extractdest}" "${local_filedir}/${local_filename}") + fi + fi + local exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Extracting ${local_filename}" + if [ -f "${lgsmlog}" ]; then + echo -e "${extractcmd}" >> "${lgsmlog}" + fi + echo -e "${extractcmd}" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Extracting ${local_filename}" + fi +} + +# Trap to remove file download if canceled before completed. +fn_fetch_trap() { + echo -e "" + echo -en "downloading ${local_filename}..." + fn_print_canceled_eol_nl + fn_script_log_info "Downloading ${local_filename}...CANCELED" + rm -f "${local_filedir:?}/${local_filename}" + echo -en "downloading ${local_filename}..." + fn_print_removed_eol_nl + fn_script_log_info "Downloading ${local_filename}...REMOVED" + core_exit.sh +} + +# Will check a file exists and download it. Will not exit if fails to download. +fn_check_file() { + remote_fileurl="${1}" + remote_fileurl_backup="${2}" + remote_fileurl_name="${3}" + remote_fileurl_backup_name="${4}" + remote_filename="${5}" + # If backup fileurl exists include it. + if [ -n "${remote_fileurl_backup}" ]; then + # counter set to 0 to allow second try + counter=0 + remote_fileurls_array=(remote_fileurl remote_fileurl_backup) + else + # counter set to 1 to not allow second try + counter=1 + remote_fileurls_array=(remote_fileurl) + fi + for remote_fileurl_array in "${remote_fileurls_array[@]}"; do + if [ "${remote_fileurl_array}" == "remote_fileurl" ]; then + fileurl="${remote_fileurl}" + fileurl_name="${remote_fileurl_name}" + elif [ "${remote_fileurl_array}" == "remote_fileurl_backup" ]; then + fileurl="${remote_fileurl_backup}" + fileurl_name="${remote_fileurl_backup_name}" + fi + counter=$((counter + 1)) + echo -en "checking ${fileurl_name} ${remote_filename}...\c" + curlcmd=$(curl --output /dev/null --silent --head --fail "${fileurl}" 2>&1) + local exitcode=$? + + # On first try will error. On second try will fail. + if [ "${exitcode}" != 0 ]; then + if [ ${counter} -ge 2 ]; then + fn_print_fail_eol_nl + if [ -f "${lgsmlog}" ]; then + fn_script_log_fail "Checking ${remote_filename}" + fn_script_log_fail "${fileurl}" + checkflag=1 + fi + else + fn_print_error_eol_nl + if [ -f "${lgsmlog}" ]; then + fn_script_log_error "Checking ${remote_filename}" + fn_script_log_error "${fileurl}" + checkflag=2 + fi + fi + else + fn_print_ok_eol + echo -en "\033[2K\\r" + if [ -f "${lgsmlog}" ]; then + fn_script_log_pass "Checking ${remote_filename}" + checkflag=0 + fi + break + fi + done + + if [ -f "${local_filedir}/${local_filename}" ]; then + fn_dl_hash + # Execute file if run is set. + if [ "${run}" == "run" ]; then + # shellcheck source=/dev/null + source "${local_filedir}/${local_filename}" + fi + fi +} + +fn_fetch_file() { + remote_fileurl="${1}" + remote_fileurl_backup="${2}" + remote_fileurl_name="${3}" + remote_fileurl_backup_name="${4}" + local_filedir="${5}" + local_filename="${6}" + chmodx="${7:-0}" + run="${8:-0}" + forcedl="${9:-0}" + hash="${10:-0}" + + # Download file if missing or download forced. + if [ ! -f "${local_filedir}/${local_filename}" ] || [ "${forcedl}" == "forcedl" ]; then + # If backup fileurl exists include it. + if [ -n "${remote_fileurl_backup}" ]; then + # counter set to 0 to allow second try + counter=0 + remote_fileurls_array=(remote_fileurl remote_fileurl_backup) + else + # counter set to 1 to not allow second try + counter=1 + remote_fileurls_array=(remote_fileurl) + fi + for remote_fileurl_array in "${remote_fileurls_array[@]}"; do + if [ "${remote_fileurl_array}" == "remote_fileurl" ]; then + fileurl="${remote_fileurl}" + fileurl_name="${remote_fileurl_name}" + elif [ "${remote_fileurl_array}" == "remote_fileurl_backup" ]; then + fileurl="${remote_fileurl_backup}" + fileurl_name="${remote_fileurl_backup_name}" + fi + counter=$((counter + 1)) + if [ ! -d "${local_filedir}" ]; then + mkdir -p "${local_filedir}" + fi + # Trap will remove part downloaded files if canceled. + trap fn_fetch_trap INT + curlcmd=(curl --connect-timeout 10 --fail -L -o "${local_filedir}/${local_filename}" --retry 2) + + # if is large file show progress, else be silent + local exitcode="" + large_files=("bz2" "gz" "zip" "jar" "xz") + if grep -qE "(^|\s)${local_filename##*.}(\s|$)" <<< "${large_files[@]}"; then + echo -en "downloading ${local_filename}..." + fn_sleep_time + echo -en "\033[1K" + "${curlcmd[@]}" --progress-bar "${fileurl}" 2>&1 + exitcode="$?" + else + echo -en "fetching ${fileurl_name} ${local_filename}...\c" + "${curlcmd[@]}" --silent --show-error "${fileurl}" 2>&1 + exitcode="$?" + fi + + # Download will fail if downloads a html file. + if [ -f "${local_filedir}/${local_filename}" ]; then + if head -n 1 "${local_filedir}/${local_filename}" | grep -q "DOCTYPE"; then + rm "${local_filedir:?}/${local_filename:?}" + local exitcode=2 + fi + fi + + # On first try will error. On second try will fail. + if [ "${exitcode}" != 0 ]; then + if [ ${counter} -ge 2 ]; then + fn_print_fail_eol_nl + if [ -f "${lgsmlog}" ]; then + fn_script_log_fail "Downloading ${local_filename}..." + fn_script_log_fail "${fileurl}" + fi + core_exit.sh + else + fn_print_error_eol_nl + if [ -f "${lgsmlog}" ]; then + fn_script_log_error "Downloading ${local_filename}..." + fn_script_log_error "${fileurl}" + fi + fi + else + fn_print_ok_eol_nl + if [ -f "${lgsmlog}" ]; then + fn_script_log_pass "Downloading ${local_filename}..." + fi + + # Make file executable if chmodx is set. + if [ "${chmodx}" == "chmodx" ]; then + chmod +x "${local_filedir}/${local_filename}" + fi + + # Remove trap. + trap - INT + + break + fi + done + fi + + if [ -f "${local_filedir}/${local_filename}" ]; then + fn_dl_hash + # Execute file if run is set. + if [ "${run}" == "run" ]; then + # shellcheck source=/dev/null + source "${local_filedir}/${local_filename}" + fi + fi +} + +# GitHub file download modules. +# Used to simplify downloading specific files from GitHub. + +# github_file_url_dir: the directory of the file in the GitHub: lgsm/modules +# github_file_url_name: the filename of the file to download from GitHub: core_messages.sh +# github_file_url_dir: the directory of the file in the GitHub: lgsm/modules +# github_file_url_name: the filename of the file to download from GitHub: core_messages.sh +# githuburl: the full GitHub url + +# remote_fileurl: The URL of the file: http://example.com/dl/File.tar.bz2 +# local_filedir: location the file is to be saved: /home/server/lgsm/tmp +# local_filename: name of file (this can be different from the url name): file.tar.bz2 +# chmodx: Optional, set to "chmodx" to make file executable using chmod +x +# run: Optional, set run to execute the file after download +# forcedl: Optional, force re-download of file even if exists +# hash: Optional, set an hash sum and will compare it against the file. + +# Fetches files from the Git repo. +fn_fetch_file_github() { + github_file_url_dir="${1}" + github_file_url_name="${2}" + # If master branch will currently running LinuxGSM version to prevent "version mixing". This is ignored if a fork. + if [ "${githubbranch}" == "master" ] && [ "${githubuser}" == "GameServerManagers" ] && [ "${commandname}" != "UPDATE-LGSM" ]; then + remote_fileurl="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/tag/${version}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/tag/${version}/${github_file_url_dir}/${github_file_url_name}" + else + remote_fileurl="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + fi + remote_fileurl_name="GitHub" + remote_fileurl_backup_name="Bitbucket" + local_filedir="${3}" + local_filename="${github_file_url_name}" + chmodx="${4:-0}" + run="${5:-0}" + forcedl="${6:-0}" + hash="${7:-0}" + # Passes vars to the file download module. + fn_fetch_file "${remote_fileurl}" "${remote_fileurl_backup}" "${remote_fileurl_name}" "${remote_fileurl_backup_name}" "${local_filedir}" "${local_filename}" "${chmodx}" "${run}" "${forcedl}" "${hash}" +} + +fn_check_file_github() { + github_file_url_dir="${1}" + github_file_url_name="${2}" + if [ "${githubbranch}" == "master" ] && [ "${githubuser}" == "GameServerManagers" ] && [ "${commandname}" != "UPDATE-LGSM" ]; then + remote_fileurl="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/tag/${version}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/tag/${version}/${github_file_url_dir}/${github_file_url_name}" + else + remote_fileurl="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + fi + remote_fileurl_name="GitHub" + remote_fileurl_backup_name="Bitbucket" + fn_check_file "${remote_fileurl}" "${remote_fileurl_backup}" "${remote_fileurl_name}" "${remote_fileurl_backup_name}" "${github_file_url_name}" +} + +# Fetches config files from the Git repo. +fn_fetch_config() { + github_file_url_dir="${1}" + github_file_url_name="${2}" + # If master branch will currently running LinuxGSM version to prevent "version mixing". This is ignored if a fork. + if [ "${githubbranch}" == "master" ] && [ "${githubuser}" == "GameServerManagers" ] && [ "${commandname}" != "UPDATE-LGSM" ]; then + remote_fileurl="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/tag/${version}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/tag/${version}/${github_file_url_dir}/${github_file_url_name}" + else + remote_fileurl="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + fi + remote_fileurl_name="GitHub" + remote_fileurl_backup_name="Bitbucket" + local_filedir="${3}" + local_filename="${4}" + chmodx="nochmodx" + run="norun" + forcedl="noforce" + hash="nohash" + # Passes vars to the file download module. + fn_fetch_file "${remote_fileurl}" "${remote_fileurl_backup}" "${remote_fileurl_name}" "${remote_fileurl_backup_name}" "${local_filedir}" "${local_filename}" "${chmodx}" "${run}" "${forcedl}" "${hash}" +} + +# Fetches modules from the Git repo during first download. +fn_fetch_module() { + github_file_url_dir="lgsm/modules" + github_file_url_name="${modulefile}" + # If master branch will currently running LinuxGSM version to prevent "version mixing". This is ignored if a fork. + if [ "${githubbranch}" == "master" ] && [ "${githubuser}" == "GameServerManagers" ] && [ "${commandname}" != "UPDATE-LGSM" ]; then + remote_fileurl="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/tag/${version}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/tag/${version}/${github_file_url_dir}/${github_file_url_name}" + else + remote_fileurl="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + fi + remote_fileurl_name="GitHub" + remote_fileurl_backup_name="Bitbucket" + local_filedir="${modulesdir}" + local_filename="${github_file_url_name}" + chmodx="chmodx" + run="run" + forcedl="noforce" + hash="nohash" + # Passes vars to the file download module. + fn_fetch_file "${remote_fileurl}" "${remote_fileurl_backup}" "${remote_fileurl_name}" "${remote_fileurl_backup_name}" "${local_filedir}" "${local_filename}" "${chmodx}" "${run}" "${forcedl}" "${hash}" +} + +# Fetches modules from the Git repo during update-lgsm. +fn_update_module() { + github_file_url_dir="lgsm/modules" + github_file_url_name="${modulefile}" + # If master branch will currently running LinuxGSM version to prevent "version mixing". This is ignored if a fork. + if [ "${githubbranch}" == "master" ] && [ "${githubuser}" == "GameServerManagers" ] && [ "${commandname}" != "UPDATE-LGSM" ]; then + remote_fileurl="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/tag/${version}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/tag/${version}/${github_file_url_dir}/${github_file_url_name}" + else + remote_fileurl="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + fi + remote_fileurl_name="GitHub" + remote_fileurl_backup_name="Bitbucket" + local_filedir="${modulesdir}" + local_filename="${github_file_url_name}" + chmodx="chmodx" + run="norun" + forcedl="noforce" + hash="nohash" + # Passes vars to the file download module. + fn_fetch_file "${remote_fileurl}" "${remote_fileurl_backup}" "${remote_fileurl_name}" "${remote_fileurl_backup_name}" "${local_filedir}" "${local_filename}" "${chmodx}" "${run}" "${forcedl}" "${hash}" + +} + +# Function to download latest github release. +# $1 GitHub user / organisation. +# $2 Repo name. +# $3 Destination for download. +# $4 Search string in releases (needed if there are more files that can be downloaded from the release pages). +fn_dl_latest_release_github() { + local githubreleaseuser="${1}" + local githubreleaserepo="${2}" + local githubreleasedownloadpath="${3}" + local githubreleasesearch="${4}" + local githublatestreleaseurl="https://api.github.com/repos/${githubreleaseuser}/${githubreleaserepo}/releases/latest" + + # Get last github release. + # If no search for the release filename is set, just get the first file from the latest release. + if [ -z "${githubreleasesearch}" ]; then + githubreleaseassets=$(curl -s "${githublatestreleaseurl}" | jq '[ .assets[] ]') + else + githubreleaseassets=$(curl -s "${githublatestreleaseurl}" | jq "[ .assets[]|select(.browser_download_url | contains(\"${githubreleasesearch}\")) ]") + fi + + # Check how many releases we got from the api and exit if we have more then one. + if [ "$(echo -e "${githubreleaseassets}" | jq '. | length')" -gt 1 ]; then + fn_print_fatal_nl "Found more than one release to download - Please report this to the LinuxGSM issue tracker" + fn_script_log_fail "Found more than one release to download - Please report this to the LinuxGSM issue tracker" + else + # Set variables for download via fn_fetch_file. + githubreleasefilename=$(echo -e "${githubreleaseassets}" | jq -r '.[]name') + githubreleasedownloadlink=$(echo -e "${githubreleaseassets}" | jq -r '.[]browser_download_url') + + # Error if no version is there. + if [ -z "${githubreleasefilename}" ]; then + fn_print_fail_nl "Cannot get version from GitHub API for ${githubreleaseuser}/${githubreleaserepo}" + fn_script_log_fail "Cannot get version from GitHub API for ${githubreleaseuser}/${githubreleaserepo}" + else + # Fetch file from the remote location from the existing module to the ${tmpdir} for now. + fn_fetch_file "${githubreleasedownloadlink}" "" "${githubreleasefilename}" "" "${githubreleasedownloadpath}" "${githubreleasefilename}" + fi + fi +} diff --git a/lgsm/modules/core_exit.sh b/lgsm/modules/core_exit.sh new file mode 100644 index 0000000..989a4c5 --- /dev/null +++ b/lgsm/modules/core_exit.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# LinuxGSM core_exit.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Handles exiting of LinuxGSM by running and reporting an exit code. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_exit_dev_debug() { + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "" + echo -e "${moduleselfname} exiting with code: ${exitcode}" + if [ -f "${rootdir}/dev-debug.log" ]; then + grep -a "modulefile=" "${rootdir}/dev-debug.log" | sed 's/modulefile=//g' > "${rootdir}/dev-debug-module-order.log" + elif [ -f "${lgsmlogdir}/dev-debug.log" ]; then + grep -a "modulefile=" "${lgsmlogdir}/dev-debug.log" | sed 's/modulefile=//g' > "${rootdir}/dev-debug-module-order.log" + fi + fi +} + +# If running dependency check as root will remove any files that belong to root user. +if [ "$(whoami)" == "root" ]; then + find "${lgsmdir}"/ -group root -prune -exec rm -rf {} + > /dev/null 2>&1 + find "${logdir}"/ -group root -prune -exec rm -rf {} + > /dev/null 2>&1 +fi + +if [ "${exitbypass}" ]; then + unset exitbypass +elif [ "${exitcode}" != "0" ]; then + # List LinuxGSM version in logs + fn_script_log_info "LinuxGSM version: ${version}" + if [ "${exitcode}" == "1" ]; then + fn_script_log_fail "${moduleselfname} exiting with code: ${exitcode}" + elif [ "${exitcode}" == "2" ]; then + fn_script_log_error "${moduleselfname} exiting with code: ${exitcode}" + elif [ "${exitcode}" == "3" ]; then + fn_script_log_warn "${moduleselfname} exiting with code: ${exitcode}" + else + # if exit code is not set assume error. + fn_script_log_warn "${moduleselfname} exiting with code: ${exitcode}" + exitcode=4 + fi + fn_exit_dev_debug + # remove trap. + trap - INT + exit "${exitcode}" +elif [ "${exitcode}" ] && [ "${exitcode}" == "0" ]; then + # List LinuxGSM version in logs + fn_script_log_info "LinuxGSM version: ${version}" + fn_script_log_pass "${moduleselfname} exiting with code: ${exitcode}" + fn_exit_dev_debug + # remove trap. + trap - INT + exit "${exitcode}" +else + # List LinuxGSM version in logs + fn_script_log_info "LinuxGSM version: ${version}" + fn_print_error "No exit code set" + fn_script_log_pass "${moduleselfname} exiting with code: NOT SET" + fn_exit_dev_debug + # remove trap. + trap - INT + exit "${exitcode}" +fi diff --git a/lgsm/modules/core_getopt.sh b/lgsm/modules/core_getopt.sh new file mode 100644 index 0000000..1003839 --- /dev/null +++ b/lgsm/modules/core_getopt.sh @@ -0,0 +1,216 @@ +#!/bin/bash +# LinuxGSM core_getopt.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: getopt arguments. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +### Define all commands here. +## User commands | Trigger commands | Description +# Standard commands. +cmd_install=("i;install" "command_install.sh" "Install the server.") +cmd_auto_install=("ai;auto-install" "fn_autoinstall" "Install the server without prompts.") +cmd_start=("st;start" "command_start.sh" "Start the server.") +cmd_stop=("sp;stop" "command_stop.sh" "Stop the server.") +cmd_restart=("r;restart" "command_restart.sh" "Restart the server.") +cmd_details=("dt;details" "command_details.sh" "Display server information.") +cmd_postdetails=("pd;postdetails" "command_postdetails.sh" "Post details to termbin.com (removing passwords).") +cmd_backup=("b;backup" "command_backup.sh" "Create backup archives of the server.") +cmd_update_linuxgsm=("ul;update-lgsm;uf;update-modules" "command_update_linuxgsm.sh" "Check and apply any LinuxGSM updates.") +cmd_test_alert=("ta;test-alert" "command_test_alert.sh" "Send a test alert.") +cmd_monitor=("m;monitor" "command_monitor.sh" "Check server status and restart if crashed.") +cmd_skeleton=("sk;skeleton" "command_skeleton.sh" "Create a skeleton directory.") +cmd_sponsor=("s;sponsor" "command_sponsor.sh" "Donation options.") +cmd_send=("sd;send" "command_send.sh" "Send command to game server console.") +# Console servers only. +cmd_console=("c;console" "command_console.sh" "Access server console.") +cmd_debug=("d;debug" "command_debug.sh" "Start server directly in your terminal.") +# Update servers only. +cmd_update=("u;update" "command_update.sh" "Check and apply any server updates.") +cmd_check_update=("cu;check-update" "command_check_update.sh" "Check if a gameserver update is available") +cmd_force_update=("fu;force-update;update-restart;ur" "forceupdate=1; command_update.sh" "Apply server updates bypassing check.") +# SteamCMD servers only. +cmd_validate=("v;validate" "command_validate.sh" "Validate server files with SteamCMD.") +# Server with mods-install. +cmd_mods_install=("mi;mods-install" "command_mods_install.sh" "View and install available mods/addons.") +cmd_mods_remove=("mr;mods-remove" "command_mods_remove.sh" "View and remove an installed mod/addon.") +cmd_mods_update=("mu;mods-update" "command_mods_update.sh" "Update installed mods/addons.") +# Server specific. +cmd_change_password=("pw;change-password" "command_ts3_server_pass.sh" "Change TS3 serveradmin password.") +cmd_install_default_resources=("ir;install-default-resources" "command_install_resources_mta.sh" "Install the MTA default resources.") +cmd_fullwipe=("fw;full-wipe;wa;wipeall" "serverwipe=1; command_wipe.sh" "Reset the map and remove blueprint data.") +cmd_mapwipe=("mw;map-wipe;w;wipe;wi" "mapwipe=1; command_wipe.sh" "Reset the map and keep blueprint data.") +cmd_map_compressor_u99=("mc;map-compressor" "compress_ut99_maps.sh" "Compresses all ${gamename} server maps.") +cmd_map_compressor_u2=("mc;map-compressor" "compress_unreal2_maps.sh" "Compresses all ${gamename} server maps.") +cmd_install_cdkey=("cd;server-cd-key" "install_ut2k4_key.sh" "Add your server cd key.") +cmd_install_dst_token=("ct;cluster-token" "install_dst_token.sh" "Configure cluster token.") +cmd_install_squad_license=("li;license" "install_squad_license.sh" "Add your Squad server license.") +cmd_fastdl=("fd;fastdl" "command_fastdl.sh" "Build a FastDL directory.") +# Dev commands. +cmd_dev_debug=("dev;developer" "command_dev_debug.sh" "Enable developer Mode.") +cmd_dev_details=("ddt;detect-details" "command_dev_details.sh" "Display parsed details.") +cmd_dev_detect_deps=("dd;detect-deps" "command_dev_detect_deps.sh" "Detect required dependencies.") +cmd_dev_detect_glibc=("dg;detect-glibc" "command_dev_detect_glibc.sh" "Detect required glibc.") +cmd_dev_detect_ldd=("dl;detect-ldd" "command_dev_detect_ldd.sh" "Detect required dynamic dependencies.") +cmd_dev_query_raw=("qr;query-raw" "command_dev_query_raw.sh" "The raw output of gamedig and gsquery.") +cmd_dev_clear_modules=("cm;clear-modules" "command_dev_clear_modules.sh" "Delete the contents of the modules dir.") + +### Set specific opt here. + +currentopt=("${cmd_start[@]}" "${cmd_stop[@]}" "${cmd_restart[@]}" "${cmd_monitor[@]}" "${cmd_test_alert[@]}" "${cmd_details[@]}" "${cmd_postdetails[@]}" "${cmd_skeleton[@]}") + +# Update LinuxGSM. +currentopt+=("${cmd_update_linuxgsm[@]}") + +# Exclude noupdate games here. +if [ "${shortname}" == "jk2" ] || [ "${engine}" != "idtech3" ]; then + if [ "${shortname}" != "bf1942" ] && [ "${shortname}" != "bfv" ] && [ "${engine}" != "idtech2" ] && [ "${engine}" != "iw2.0" ] && [ "${engine}" != "iw3.0" ] && [ "${engine}" != "quake" ] && [ "${shortname}" != "samp" ] && [ "${shortname}" != "ut2k4" ]; then + currentopt+=("${cmd_update[@]}" "${cmd_check_update[@]}") + # force update for SteamCMD or Multi Theft Auto only. + if [ "${appid}" ] || [ "${shortname}" == "mta" ]; then + currentopt+=("${cmd_force_update[@]}") + fi + fi +fi + +# Validate and check-update command. +if [ "${appid}" ]; then + currentopt+=("${cmd_validate[@]}") +fi + +# Backup. +currentopt+=("${cmd_backup[@]}") + +# Console & Debug. +currentopt+=("${cmd_console[@]}" "${cmd_debug[@]}") + +# Console send. +if [ "${consoleinteract}" == "yes" ]; then + currentopt+=("${cmd_send[@]}") +fi + +## Game server exclusive commands. + +# FastDL command. +if [ "${engine}" == "source" ]; then + currentopt+=("${cmd_fastdl[@]}") +fi + +# TeamSpeak exclusive. +if [ "${shortname}" == "ts3" ]; then + currentopt+=("${cmd_change_password[@]}") +fi + +# Rust exclusive. +if [ "${shortname}" == "rust" ]; then + currentopt+=("${cmd_fullwipe[@]}" "${cmd_mapwipe[@]}") +fi + +# Unreal exclusive. +if [ "${engine}" == "unreal2" ]; then + if [ "${shortname}" == "ut2k4" ]; then + currentopt+=("${cmd_install_cdkey[@]}" "${cmd_map_compressor_u2[@]}") + else + currentopt+=("${cmd_map_compressor_u2[@]}") + fi +fi +if [ "${engine}" == "unreal" ]; then + currentopt+=("${cmd_map_compressor_u99[@]}") +fi + +# DST exclusive. +if [ "${shortname}" == "dst" ]; then + currentopt+=("${cmd_install_dst_token[@]}") +fi + +# MTA exclusive. +if [ "${shortname}" == "mta" ]; then + currentopt+=("${cmd_install_default_resources[@]}") +fi + +# Squad license exclusive. +if [ "${shortname}" == "squad" ]; then + currentopt+=("${cmd_install_squad_license[@]}") +fi + +## Mods commands. +if [ "${engine}" == "source" ] || [ "${shortname}" == "rust" ] || [ "${shortname}" == "hq" ] || [ "${shortname}" == "sdtd" ] || [ "${shortname}" == "cs" ] || [ "${shortname}" == "dod" ] || [ "${shortname}" == "tfc" ] || [ "${shortname}" == "ns" ] || [ "${shortname}" == "ts" ] || [ "${shortname}" == "hldm" ] || [ "${shortname}" == "vh" ]; then + currentopt+=("${cmd_mods_install[@]}" "${cmd_mods_remove[@]}" "${cmd_mods_update[@]}") +fi + +## Installer. +currentopt+=("${cmd_install[@]}" "${cmd_auto_install[@]}") + +## Developer commands. +currentopt+=("${cmd_dev_debug[@]}") +if [ -f ".dev-debug" ]; then + currentopt+=("${cmd_dev_details[@]}" "${cmd_dev_detect_deps[@]}" "${cmd_dev_detect_glibc[@]}" "${cmd_dev_detect_ldd[@]}" "${cmd_dev_query_raw[@]}" "${cmd_dev_clear_modules[@]}") +fi + +## Sponsor. +currentopt+=("${cmd_sponsor[@]}") + +### Build list of available commands. +optcommands=() +index="0" +for ((index = "0"; index < ${#currentopt[@]}; index += 3)); do + cmdamount=$(echo -e "${currentopt[index]}" | awk -F ';' '{ print NF }') + for ((cmdindex = 1; cmdindex <= cmdamount; cmdindex++)); do + optcommands+=("$(echo -e "${currentopt[index]}" | awk -F ';' -v x=${cmdindex} '{ print $x }')") + done +done + +# Shows LinuxGSM usage. +fn_opt_usage() { + echo -e "Usage: $0 [option]" + echo -e "" + echo -e "LinuxGSM - ${gamename} - Version ${version}" + echo -e "https://linuxgsm.com/${gameservername}" + echo -e "" + echo -e "${lightyellow}Commands${default}" + # Display available commands. + index="0" + { + for ((index = "0"; index < ${#currentopt[@]}; index += 3)); do + # Hide developer commands. + if [ "${currentopt[index + 2]}" != "DEVCOMMAND" ]; then + echo -e "${cyan}$(echo -e "${currentopt[index]}" | awk -F ';' '{ print $2 }')\t${default}$(echo -e "${currentopt[index]}" | awk -F ';' '{ print $1 }')\t| ${currentopt[index + 2]}" + fi + done + } | column -s $'\t' -t + fn_script_log_pass "Display commands" + core_exit.sh +} + +# Check if command exists and run corresponding scripts, or display script usage. +if [ -z "${getopt}" ]; then + fn_opt_usage +fi +# If command exists. +for i in "${optcommands[@]}"; do + if [ "${i}" == "${getopt}" ]; then + # Seek and run command. + index="0" + for ((index = "0"; index < ${#currentopt[@]}; index += 3)); do + currcmdamount=$(echo -e "${currentopt[index]}" | awk -F ';' '{ print NF }') + for ((currcmdindex = 1; currcmdindex <= currcmdamount; currcmdindex++)); do + if [ "$(echo -e "${currentopt[index]}" | awk -F ';' -v x=${currcmdindex} '{ print $x }')" == "${getopt}" ]; then + # Run command. + eval "${currentopt[index + 1]}" + # Exit should occur in modules. Should this not happen print an error + fn_print_error2_nl "Command did not exit correctly: ${getopt}" + fn_script_log_error "Command did not exit correctly: ${getopt}" + core_exit.sh + fi + done + done + fi +done + +# If we're executing this, it means command was not found. +fn_print_error2_nl "Unknown command: $0 ${getopt}" +fn_script_log_error "Unknown command: $0 ${getopt}" +fn_opt_usage +core_exit.sh diff --git a/lgsm/modules/core_github.sh b/lgsm/modules/core_github.sh new file mode 100644 index 0000000..7290f9b --- /dev/null +++ b/lgsm/modules/core_github.sh @@ -0,0 +1,114 @@ +#!/bin/bash +# LinuxGSM core_github.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: core module file for updates via github + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +github_api="https://api.github.com" + +fn_githublocalversionfile() { + local githubreleaseuser="${1}" + local githubreleaserepo="${2}" + + githublocalversionfile="${datadir}/github-${githubreleaseuser}-${githubreleaserepo}-version" +} + +# $1 githubuser/group +# $2 github repo name +fn_github_get_latest_release_version() { + local githubreleaseuser="${1}" + local githubreleaserepo="${2}" + local githublatestreleaseurl="${github_api}/repos/${githubreleaseuser}/${githubreleaserepo}/releases/latest" + + githubreleaseversion=$(curl -s --connect-timeout 10 "${githublatestreleaseurl}" | jq '.tag_name') + + # error if no version is there + if [ -z "${githubreleaseversion}" ]; then + fn_print_fail_nl "Cannot get version from GitHub API for ${githubreleaseuser}/${githubreleaserepo}" + fn_script_log_fail "Cannot get version from GitHub API for ${githubreleaseuser}/${githubreleaserepo}" + fi +} + +# $1 githubuser/group +# $2 github repo name +fn_github_set_latest_release_version() { + local githubreleaseuser="${1}" + local githubreleaserepo="${2}" + + fn_githublocalversionfile "${githubreleaseuser}" "${githubreleaserepo}" + + local githublatestreleaseurl="${github_api}/repos/${githubreleaseuser}/${githubreleaserepo}/releases/latest" + githubreleaseversion=$(curl -s "${githublatestreleaseurl}" | jq -r '.tag_name') + + # error if no version is there + if [ -z "${githubreleaseversion}" ]; then + fn_print_fail_nl "Cannot get version from GitHub API for ${githubreleaseuser}/${githubreleaserepo}" + fn_script_log_fail "Cannot get version from GitHub API for ${githubreleaseuser}/${githubreleaserepo}" + else + echo "${githubreleaseversion}" > "${githublocalversionfile}" + fi +} + +# $1 githubuser/group +# $2 github repo name +fn_github_get_installed_version() { + local githubreleaseuser="${1}" + local githubreleaserepo="${2}" + + fn_githublocalversionfile "${githubreleaseuser}" "${githubreleaserepo}" + + githublocalversion=$(cat "${githublocalversionfile}") +} + +# $1 githubuser/group +# $2 github repo name +# if a update needs to be downloaded - updateneeded is set to 1 +fn_github_compare_version() { + local githubreleaseuser="${1}" + local githubreleaserepo="${2}" + exitcode=0 + updateneeded=0 + + fn_githublocalversionfile "${githubreleaseuser}" "${githubreleaserepo}" + local githublatestreleaseurl="${github_api}/repos/${githubreleaseuser}/${githubreleaserepo}/releases/latest" + + githublocalversion=$(cat "${githublocalversionfile}") + githubreleaseversion=$(curl -s "${githublatestreleaseurl}" | jq '.tag_name') + + # error if no version is there + if [ -z "${githubreleaseversion}" ]; then + fn_print_fail_nl "Can not get version from Github Api for ${githubreleaseuser}/${githubreleaserepo}" + fn_script_log_fail "Can not get version from Github Api for ${githubreleaseuser}/${githubreleaserepo}" + else + if [ "${githublocalversion}" == "${githubreleaseversion}" ]; then + echo -en "\n" + echo -e "No update from github.com/${githubreleaseuser}/${githubreleaserepo}/ available:" + echo -e "* Local build: ${red}${githublocalversion}${default}" + echo -e "* Remote build: ${green}${githubreleaseversion}${default}" + echo -en "\n" + else + # check if version that is installed is higher than the remote version to not override it + last_version=$(echo -e "${githublocalversion}\n${githubreleaseversion}" | sort -V | head -n1) + if [ "${githubreleaseversion}" == "${last_version}" ]; then + echo -en "\n" + echo -e "Update from github.com/${githubreleaseuser}/${githubreleaserepo}/ available:" + echo -e "* Local build: ${red}${githublocalversion}${default}" + echo -e "* Remote build: ${green}${githubreleaseversion}${default}" + echo -en "\n" + updateneeded=1 + else + # local version is higher than the remote version output this to the user + # strange case but could be possible, as a release could be removed from github + echo -en "\n" + echo -e "Local version is newer than the remote version" + echo -e "* Local version: ${green}${githublocalversion}${default}" + echo -e "* Remote version: ${green}${githubreleaseversion}${default}" + echo -en "\n" + exitcode=1 + fi + fi + fi +} diff --git a/lgsm/modules/core_legacy.sh b/lgsm/modules/core_legacy.sh new file mode 100644 index 0000000..cf11e3a --- /dev/null +++ b/lgsm/modules/core_legacy.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# LinuxGSM core_legacy.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Code for backwards compatability with older versions of LinuxGSM. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +if [ -z "${socketname}" ]; then + socketname="${sessionname}" +fi + +if [ -n "${webadminuser}" ]; then + httpuser="${webadminuser}" +fi + +if [ -n "${webadminpass}" ]; then + httppassword="${webadminpass}" +fi + +if [ -n "${webadminport}" ]; then + httpport="${webadminport}" +fi + +if [ -n "${webadminip}" ]; then + httpip="${webadminip}" +fi + +if [ -n "${gameworld}" ]; then + worldname="${gameworld}" +fi + +if [ -n "${autosaveinterval}" ]; then + saveinterval="${autosaveinterval}" +fi + +# Added as part of migrating functions dir to modules dir. +# Will remove functions dir if files in modules dir older than 14 days +functionsdir="${lgsmdir}/modules" +if [ -d "${lgsmdir}/functions" ]; then + if [ "$(find "${lgsmdir}/modules"/ -type f -mtime +"14" | wc -l)" -ne "0" ]; then + rm -rf "${lgsmdir:?}/functions" + fi +fi + +fn_parms() { + fn_reload_startparameters + parms="${startparameters}" +} diff --git a/lgsm/modules/core_logs.sh b/lgsm/modules/core_logs.sh new file mode 100644 index 0000000..3166041 --- /dev/null +++ b/lgsm/modules/core_logs.sh @@ -0,0 +1,109 @@ +#!/bin/bash +# LinuxGSM core_logs.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Acts as a log rotator, removing old logs. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Check if logfile variable and file exist, create logfile if it doesn't exist. +if [ "${consolelog}" ]; then + if [ ! -f "${consolelog}" ]; then + touch "${consolelog}" + fi +fi + +# For games not displaying a console, and having logs into their game directory. +check_status.sh +if [ "${status}" != "0" ] && [ "${commandname}" == "START" ] && [ -n "${gamelogfile}" ]; then + if [ "$(find "${systemdir}" -name "gamelog*.log")" ]; then + fn_print_info "Moving game logs to ${gamelogdir}" + fn_script_log_info "Moving game logs to ${gamelogdir}" + echo -en "\n" + fn_sleep_time + mv "${systemdir}"/gamelog*.log "${gamelogdir}" + fi +fi + +# Log manager will start the cleanup if it finds logs older than "${logdays}". +if [ "$(find "${lgsmlogdir}"/ -type f -mtime +"${logdays}" | wc -l)" -ne "0" ]; then + fn_print_dots "Starting" + # Set common logs directories + commonlogs="${systemdir}/logs" + commonsourcelogs="${systemdir}/*/logs" + # Set addon logs directories + sourcemodlogdir="${systemdir}/addons/sourcemod/logs" + ulxlogdir="${systemdir}/data/ulx_logs" + darkrplogdir="${systemdir}/data/darkrp_logs" + legacyserverlogdir="${logdir}/server" + # Setting up counting variables + scriptcount="0" + consolecount="0" + gamecount="0" + srcdscount="0" + smcount="0" + ulxcount="0" + darkrpcount="0" + legacycount="0" + fn_print_info "Removing logs older than ${logdays} days" + fn_script_log_info "Removing logs older than ${logdays} days" + # Logging logfiles to be removed according to "${logdays}", counting and removing them. + # Script logfiles. + find "${lgsmlogdir}"/ -type f -mtime +"${logdays}" | tee >> "${lgsmlog}" + scriptcount=$(find "${lgsmlogdir}"/ -type f -mtime +"${logdays}" | wc -l) + find "${lgsmlogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \; + # SRCDS and unreal logfiles. + if [ "${engine}" == "unreal2" ] || [ "${engine}" == "source" ]; then + find "${gamelogdir}"/ -type f -mtime +"${logdays}" | tee >> "${lgsmlog}" + gamecount=$(find "${gamelogdir}"/ -type f -mtime +"${logdays}" | wc -l) + find "${gamelogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \; + fi + # Console logfiles. + if [ "${consolelog}" ]; then + find "${consolelogdir}"/ -type f -mtime +"${logdays}" | tee >> "${lgsmlog}" + consolecount=$(find "${consolelogdir}"/ -type f -mtime +"${logdays}" | wc -l) + find "${consolelogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \; + fi + # Common logfiles. + if [ -d "${commonlogs}" ]; then + find "${commonlogs}"/ -type f -mtime +"${logdays}" | tee >> "${lgsmlog}" + smcount=$(find "${commonlogs}"/ -type f -mtime +"${logdays}" | wc -l) + find "${commonlogs}"/ -mtime +"${logdays}" -type f -exec rm -f {} \; + fi + if [ -d "${commonsourcelogs}" ]; then + find "${commonsourcelogs}"/* -type f -mtime +"${logdays}" | tee >> "${lgsmlog}" + smcount=$(find "${commonsourcelogs}"/* -type f -mtime +"${logdays}" | wc -l) + find "${commonsourcelogs}"/* -mtime +"${logdays}" -type f -exec rm -f {} \; + fi + # Source addons logfiles. + if [ "${engine}" == "source" ]; then + # SourceMod logfiles. + if [ -d "${sourcemodlogdir}" ]; then + find "${sourcemodlogdir}"/ -type f -mtime +"${logdays}" | tee >> "${lgsmlog}" + smcount=$(find "${sourcemodlogdir}"/ -type f -mtime +"${logdays}" | wc -l) + find "${sourcemodlogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \; + fi + # Garry's Mod logfiles. + if [ "${shortname}" == "gmod" ]; then + # ULX logfiles. + if [ -d "${ulxlogdir}" ]; then + find "${ulxlogdir}"/ -type f -mtime +"${logdays}" | tee >> "${lgsmlog}" + ulxcount=$(find "${ulxlogdir}"/ -type f -mtime +"${logdays}" | wc -l) + find "${ulxlogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \; + fi + # DarkRP logfiles. + if [ -d "${darkrplogdir}" ]; then + find "${darkrplogdir}"/ -type f -mtime +"${logdays}" | tee >> "${lgsmlog}" + darkrpcount=$(find "${darkrplogdir}"/ -type f -mtime +"${logdays}" | wc -l) + find "${darkrplogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \; + fi + fi + fi + + # Count total amount of files removed. + countlogs=$((scriptcount + consolecount + gamecount + srcdscount + smcount + ulxcount + darkrpcount)) + # Job done. + fn_print_ok "Removed ${countlogs} log files" + fn_script_log "Removed ${countlogs} log files" +fi diff --git a/lgsm/modules/core_messages.sh b/lgsm/modules/core_messages.sh new file mode 100644 index 0000000..6488c02 --- /dev/null +++ b/lgsm/modules/core_messages.sh @@ -0,0 +1,621 @@ +#!/bin/bash +# LinuxGSM core_messages.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Defines on-screen messages such as [ OK ] and how script logs look. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# nl: new line: message is following by a new line. +# eol: end of line: message is placed at the end of the current line. +fn_ansi_loader() { + # carriage return. + creeol="\r" + if [ "${ansi}" != "off" ]; then + # echo colors + default="\e[0m" + black="\e[30m" + red="\e[31m" + lightred="\e[91m" + green="\e[32m" + lightgreen="\e[92m" + yellow="\e[33m" + lightyellow="\e[93m" + blue="\e[34m" + lightblue="\e[94m" + magenta="\e[35m" + lightmagenta="\e[95m" + cyan="\e[36m" + lightcyan="\e[96m" + darkgrey="\e[90m" + lightgrey="\e[37m" + white="\e[97m" + # erase to end of line. + creeol+="\033[K" + fi +} + +fn_sleep_time() { + sleep "0.1" +} + +fn_sleep_time_05() { + sleep "0.5" +} + +fn_sleep_time_1() { + sleep "1" +} + +fn_sleep_time_5() { + sleep "5" +} + +fn_sleep_time_10() { + sleep "10" +} + +# Log display +######################## +## Feb 28 14:56:58 ut99-server: Monitor: +fn_script_log() { + if [ -d "${lgsmlogdir}" ]; then + if [ -n "${commandname}" ]; then + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ${commandname}: ${1}" >> "${lgsmlog}" + else + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ${1}" >> "${lgsmlog}" + fi + fi +} + +## Feb 28 14:56:58 ut99-server: Monitor: PASS: +fn_script_log_pass() { + if [ -d "${lgsmlogdir}" ]; then + + if [ -n "${commandname}" ]; then + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ${commandname}: PASS: ${1}" >> "${lgsmlog}" + else + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: PASS: ${1}" >> "${lgsmlog}" + fi + fi + exitcode=0 +} + +## Feb 28 14:56:58 ut99-server: Monitor: FATAL: +fn_script_log_fail() { + if [ -d "${lgsmlogdir}" ]; then + if [ -n "${commandname}" ]; then + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ${commandname}: FATAL: ${1}" >> "${lgsmlog}" + else + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: FATAL: ${1}" >> "${lgsmlog}" + fi + fi + exitcode=1 +} + +## Feb 28 14:56:58 ut99-server: Monitor: ERROR: +fn_script_log_error() { + if [ -d "${lgsmlogdir}" ]; then + if [ -n "${commandname}" ]; then + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ${commandname}: ERROR: ${1}" >> "${lgsmlog}" + else + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ERROR: ${1}" >> "${lgsmlog}" + fi + fi + exitcode=2 +} + +## Feb 28 14:56:58 ut99-server: Monitor: WARN: +fn_script_log_warn() { + if [ -d "${lgsmlogdir}" ]; then + if [ -n "${commandname}" ]; then + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ${commandname}: WARN: ${1}" >> "${lgsmlog}" + else + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: WARN: ${1}" >> "${lgsmlog}" + fi + fi + exitcode=3 +} + +## Feb 28 14:56:58 ut99-server: Monitor: INFO: +fn_script_log_info() { + if [ -d "${lgsmlogdir}" ]; then + if [ -n "${commandname}" ]; then + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ${commandname}: INFO: ${1}" >> "${lgsmlog}" + else + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: INFO: ${1}" >> "${lgsmlog}" + fi + fi +} + +## Feb 28 14:56:58 ut99-server: Monitor: UPDATE: +fn_script_log_update() { + if [ -d "${lgsmlogdir}" ]; then + if [ -n "${commandname}" ]; then + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ${commandname}: UPDATE: ${1}" >> "${lgsmlog}" + else + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: UPDATE: ${1}" >> "${lgsmlog}" + fi + fi +} + +# On-Screen - Automated functions +################################## + +# [ .... ] +fn_print_dots() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[ .... ] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[ .... ] $*" + fi + fn_sleep_time_05 +} + +fn_print_dots_nl() { + if [ "${commandaction}" ]; then + echo -e "${creeol}[ .... ] ${commandaction} ${selfname}: $*" + else + echo -e "${creeol}[ .... ] $*" + fi + fn_sleep_time_05 + echo -en "\n" +} + +# [ OK ] +fn_print_ok() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${green} OK ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${green} OK ${default}] $*" + fi + fn_sleep_time +} + +fn_print_ok_nl() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${green} OK ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${green} OK ${default}] $*" + fi + fn_sleep_time + echo -en "\n" +} + +# [ FAIL ] +fn_print_fail() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${red} FAIL ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${red} FAIL ${default}] $*" + fi + fn_sleep_time +} + +fn_print_fail_nl() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${red} FAIL ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${red} FAIL ${default}] $*" + fi + fn_sleep_time + echo -en "\n" +} + +# [ ERROR ] +fn_print_error() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${red} ERROR ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${red} ERROR ${default}] $*" + fi + fn_sleep_time +} + +fn_print_error_nl() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${red} ERROR ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${red} ERROR ${default}] $*" + fi + fn_sleep_time + echo -en "\n" +} + +# [ WARN ] +fn_print_warn() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${lightyellow} WARN ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${lightyellow} WARN ${default}] $*" + fi + fn_sleep_time +} + +fn_print_warn_nl() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${lightyellow} WARN ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${lightyellow} WARN ${default}] $*" + fi + fn_sleep_time + echo -en "\n" +} + +# [ INFO ] +fn_print_info() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${cyan} INFO ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${cyan} INFO ${default}] $*" + fi + fn_sleep_time +} + +fn_print_info_nl() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${cyan} INFO ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${cyan} INFO ${default}] $*" + fi + fn_sleep_time + echo -en "\n" +} + +# [ START ] +fn_print_start() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${lightgreen} START ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${lightgreen} START ${default}] $*" + fi + fn_sleep_time +} + +fn_print_start_nl() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${lightgreen} START ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${lightgreen} START ${default}] $*" + fi + fn_sleep_time + echo -en "\n" +} + +# On-Screen - Interactive messages +################################## + +# Separator is different for details. +fn_messages_separator() { + if [ "${commandname}" == "DETAILS" ]; then + printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' = + else + echo -e "${bold}=================================${default}" + fn_sleep_time + fi +} + +# No More Room in Hell Debug +# ================================= +fn_print_header() { + echo -e "" + echo -e "${bold}${lightyellow}${gamename} ${commandaction}${default}" + fn_messages_separator +} + +# Complete! +fn_print_complete() { + echo -en "${green}Complete!${default} $*" + fn_sleep_time +} + +fn_print_complete_nl() { + echo -e "${green}Complete!${default} $*" + fn_sleep_time +} + +# Failure! +fn_print_failure() { + echo -en "${red}Failure!${default} $*" + fn_sleep_time +} + +fn_print_failure_nl() { + echo -e "${red}Failure!${default} $*" + fn_sleep_time +} + +# Error! +fn_print_error2() { + echo -en "${red}Error!${default} $*" + fn_sleep_time +} + +fn_print_error2_nl() { + echo -e "${red}Error!${default} $*" + fn_sleep_time +} + +# Warning! +fn_print_warning() { + echo -en "${lightyellow}Warning!${default} $*" + fn_sleep_time +} + +fn_print_warning_nl() { + echo -e "${lightyellow}Warning!${default} $*" + fn_sleep_time +} + +# Information! +fn_print_information() { + echo -en "${cyan}Information!${default} $*" + fn_sleep_time +} + +fn_print_information_nl() { + echo -e "${cyan}Information!${default} $*" + fn_sleep_time +} + +# Y/N Prompt +fn_prompt_yn() { + local prompt="$1" + local initial="$2" + + if [ "${initial}" == "Y" ]; then + prompt+=" [Y/n] " + elif [ "${initial}" == "N" ]; then + prompt+=" [y/N] " + else + prompt+=" [y/n] " + fi + + while true; do + read -e -i "${initial}" -p "${prompt}" -r yn + case "${yn}" in + [Yy] | [Yy][Ee][Ss]) return 0 ;; + [Nn] | [Nn][Oo]) return 1 ;; + *) echo -e "Please answer yes or no." ;; + esac + done +} + +# Prompt for message +fn_prompt_message() { + while true; do + unset prompt + local prompt="$1" + read -e -p "${prompt}" -r answer + if fn_prompt_yn "Continue" Y; then + break + fi + done + echo "${answer}" +} + +# On-Screen End of Line +################################## + +# YES +fn_print_yes_eol() { + echo -en "${cyan}YES${default}" + fn_sleep_time +} + +fn_print_yes_eol_nl() { + echo -e "${cyan}YES${default}" + fn_sleep_time +} + +# NO +fn_print_no_eol() { + echo -en "${red}NO${default}" + fn_sleep_time +} + +fn_print_no_eol_nl() { + echo -e "${red}NO${default}" + fn_sleep_time +} + +# OK +fn_print_ok_eol() { + echo -en "${green}OK${default}" + fn_sleep_time +} + +fn_print_ok_eol_nl() { + echo -e "${green}OK${default}" + fn_sleep_time +} + +# FAIL +fn_print_fail_eol() { + echo -en "${red}FAIL${default}" + fn_sleep_time +} + +fn_print_fail_eol_nl() { + echo -e "${red}FAIL${default}" + fn_sleep_time +} + +# ERROR +fn_print_error_eol() { + echo -en "${red}ERROR${default}" + fn_sleep_time +} + +fn_print_error_eol_nl() { + echo -e "${red}ERROR${default}" + fn_sleep_time +} + +# WAIT +fn_print_wait_eol() { + echo -en "${cyan}WAIT${default}" + fn_sleep_time +} + +fn_print_wait_eol_nl() { + echo -e "${cyan}WAIT${default}" + fn_sleep_time +} + +# WARN +fn_print_warn_eol() { + echo -en "${lightyellow}WARN${default}" + fn_sleep_time +} + +fn_print_warn_eol_nl() { + echo -e "${lightyellow}WARN${default}" + fn_sleep_time +} + +# INFO +fn_print_info_eol() { + echo -en "${cyan}INFO${default}" + fn_sleep_time +} + +fn_print_info_eol_nl() { + echo -e "${cyan}INFO${default}" + fn_sleep_time +} + +# QUERYING +fn_print_querying_eol() { + echo -en "${cyan}QUERYING${default}" + fn_sleep_time_1 +} + +fn_print_querying_eol_nl() { + echo -e "${cyan}QUERYING${default}" + fn_sleep_time_1 +} + +# CHECKING +fn_print_checking_eol() { + echo -en "${cyan}CHECKING${default}" + fn_sleep_time_1 +} + +fn_print_checking_eol_nl() { + echo -e "${cyan}CHECKING${default}" + fn_sleep_time_1 +} + +# DELAY +fn_print_delay_eol() { + echo -en "${green}DELAY${default}" + fn_sleep_time_1 +} + +fn_print_delay_eol_nl() { + echo -e "${green}DELAY${default}" + fn_sleep_time_1 +} + +# CANCELED +fn_print_canceled_eol() { + echo -en "${lightyellow}CANCELED${default}" + fn_sleep_time_1 +} + +fn_print_canceled_eol_nl() { + echo -e "${lightyellow}CANCELED${default}" + fn_sleep_time_1 +} + +# REMOVED +fn_print_removed_eol() { + echo -en "${red}REMOVED${default}" + fn_sleep_time_1 +} + +fn_print_removed_eol_nl() { + echo -e "${red}REMOVED${default}" + fn_sleep_time_1 +} + +# UPDATE +fn_print_update_eol() { + echo -en "${cyan}UPDATE${default}" + fn_sleep_time +} + +fn_print_update_eol_nl() { + echo -e "${cyan}UPDATE${default}" + fn_sleep_time +} + +fn_print_ascii_logo() { + echo -e "" + echo -e " mdMMMMbm" + echo -e " mMMMMMMMMMMm" + echo -e " mMMMMMMMMMMMMm" + echo -e " mMMMMMMMMMMMMMMm" + echo -e " hMMMV^VMMV^VMMMh" + echo -e " MMMMM MM MMMMM" + echo -e " hMMs vv sMMh" + echo -e " hMMM: :MMMh" + echo -e " .hMMMh hMMMh." + echo -e " -dMMMh ${lightgrey}__${default} hMMMd-" + echo -e " :mMMMs ${lightgrey}||${default} sMMMm:" + echo -e " :MMMM+ ${lightgrey}||${default} ${red}_${default} +NMMN:" + echo -e " .mMMM+ ${lightgrey}========${default} +MMMm." + echo -e " yMMMy ${darkgrey}##############${default} yMMMy" + echo -e " mMMM: ${darkgrey}##############${default} :MMMm" + echo -e " mMM ${lightyellow}nn${default} ${lightyellow}nn${default} ${lightyellow}nn${default} ${lightyellow}nn${default} MMm" + echo -e " o ${lightyellow}nNNNNNNNn${default} ${lightyellow}nNNNNNNNn${default} o" + echo -e " ${lightyellow}nNNNNNNNNNn${default} ${lightyellow}nNNNNNNNNNn${default}" + echo -e " ${lightyellow}nNNNNNNNNNNN${default} ${lightyellow}NNNNNNNNNNNn${default}" + echo -e " ${lightyellow}+NNNNNNNNN:${default} ${lightyellow}:NNNNNNNNN+${default}" + echo -e " ${lightyellow}nNNNNNNN${default} /\ ${lightyellow}NNNNNNNn${default}" + echo -e " ${lightyellow}nnnnn${default} db ${lightyellow}nnnnn${default}" + echo -e "" + echo -e "${lightyellow}888${default} ${lightyellow}d8b${default} ${default}.d8888b. .d8888b. 888b d888" + echo -e "${lightyellow}888 Y8P ${default}d88P Y88b d88P Y88b 8888b d8888" + echo -e "${lightyellow}888${default} ${default}888${default} 888 Y88b. 88888b.d88888" + echo -e "${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}88888b.${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} 888 Y888b. 888Y88888P888" + echo -e "${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}88b${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}Y8bd8P${default} 888 88888 Y88b. 888 Y888P 888" + echo -e "${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}X88K${default} 888 888 888 888 Y8P 888" + echo -e "${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}Y88b${default} ${lightyellow}88Y${default} ${lightyellow}.d8pq8b.${default} Y88b d88P Y88b d88P 888 * 888" + echo -e "${lightyellow}LinuxGSM${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}Y8888Y${default} ${lightyellow}888${default} ${lightyellow}888${default} Y2012P88 Y8888P 888 888" + echo -e "" +} + +fn_print_restart_warning() { + fn_print_warn "${selfname} will be restarted" + fn_script_log_warn "${selfname} will be restarted" + totalseconds=3 + for seconds in {3..1}; do + fn_print_warn "${selfname} will be restarted: ${totalseconds}" + totalseconds=$((totalseconds - 1)) + fn_sleep_time_1 + if [ "${seconds}" == "0" ]; then + break + fi + done + fn_print_warn_nl "${selfname} will be restarted" +} + +# Functions below are used to ensure that logs and UI correctly reflect the command it is actually running. +# Useful when a command has to call upon another command causing the other command to overrite commandname variables + +# Used to remember the command that ran first. +fn_firstcommand_set() { + if [ -z "${firstcommandname}" ]; then + firstcommandname="${commandname}" + firstcommandaction="${commandaction}" + fi +} + +# Used to reset commandname variables to the command the script ran first. +fn_firstcommand_reset() { + commandname="${firstcommandname}" + commandaction="${firstcommandaction}" +} diff --git a/lgsm/modules/core_modules.sh b/lgsm/modules/core_modules.sh new file mode 100644 index 0000000..29249fb --- /dev/null +++ b/lgsm/modules/core_modules.sh @@ -0,0 +1,821 @@ +#!/bin/bash +# LinuxGSM core_modules.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Defines all modules to allow download and execution of modules using fn_fetch_module. +# This module is called first before any other module. Without this file other modules will not load. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +modulesversion="v23.6.2" + +# Core + +core_dl.sh() { + modulefile="${FUNCNAME[0]}" + if [ "$(type fn_fetch_core_dl 2> /dev/null)" ]; then + fn_fetch_core_dl "lgsm/modules" "core_dl.sh" "${modulesdir}" "chmodx" "run" "noforcedl" "nohash" + else + fn_bootstrap_fetch_file_github "lgsm/modules" "core_dl.sh" "${modulesdir}" "chmodx" "run" "noforcedl" "nohash" + fi +} + +core_messages.sh() { + modulefile="${FUNCNAME[0]}" + if [ "$(type fn_fetch_core_dl 2> /dev/null)" ]; then + fn_fetch_core_dl "lgsm/modules" "core_messages.sh" "${modulesdir}" "chmodx" "run" "noforcedl" "nohash" + else + fn_bootstrap_fetch_file_github "lgsm/modules" "core_messages.sh" "${modulesdir}" "chmodx" "run" "noforcedl" "nohash" + fi +} + +core_legacy.sh() { + modulefile="${FUNCNAME[0]}" + if [ "$(type fn_fetch_core_dl 2> /dev/null)" ]; then + fn_fetch_core_dl "lgsm/modules" "core_legacy.sh" "${modulesdir}" "chmodx" "run" "noforcedl" "nohash" + else + fn_bootstrap_fetch_file_github "lgsm/modules" "core_legacy.sh" "${modulesdir}" "chmodx" "run" "noforcedl" "nohash" + fi +} + +core_exit.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +core_getopt.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +core_trap.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +core_steamcmd.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +core_github.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Commands + +command_backup.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_console.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_debug.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_details.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_sponsor.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_postdetails.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_test_alert.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_monitor.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_start.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_stop.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_validate.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_install.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_install_resources_mta.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_squad_license.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_mods_install.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_mods_update.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_mods_remove.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_fastdl.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_ts3_server_pass.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_restart.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_skeleton.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_wipe.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_send.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Checks + +check.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_config.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_deps.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_executable.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_glibc.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_ip.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_last_update.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_logs.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_permissions.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_root.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_status.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_steamcmd.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_system_dir.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_system_requirements.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_tmuxception.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_version.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Compress + +compress_unreal2_maps.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +compress_ut99_maps.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Mods + +mods_list.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +mods_core.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Dev + +command_dev_clear_modules.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_dev_debug.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_dev_details.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_dev_detect_deps.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_dev_detect_glibc.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_dev_detect_ldd.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_dev_query_raw.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Fix + +fix.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_ark.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_av.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_arma3.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_armar.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_bt.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_bo.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_cmw.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_csgo.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_dst.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_hw.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_ins.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_kf.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_kf2.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_mcb.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_mta.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_nmrih.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_onset.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_pvr.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_ro.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_rust.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_rw.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_sfc.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_st.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_steamcmd.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_terraria.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_tf2.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_ut3.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_rust.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_samp.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_sdtd.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_sof2.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_squad.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_ts3.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_ut2k4.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_ut.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_unt.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_vh.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_wurm.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_zmr.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Info + +info_distro.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +info_game.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +info_messages.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +info_stats.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Alert + +alert.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_discord.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_email.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_ifttt.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_pushbullet.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_pushover.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_gotify.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_telegram.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_rocketchat.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_slack.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} +# Logs + +core_logs.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Query + +query_gamedig.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Update + +command_update_modules.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_update_linuxgsm.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_update.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_check_update.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_ts3.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_mc.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_mcb.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_pmc.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_mta.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_fctr.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_jk2.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_steamcmd.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_vints.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_ut99.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fn_update_modules.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# +## Installer modules +# + +fn_autoinstall() { + autoinstall=1 + command_install.sh +} + +install_complete.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_config.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_factorio_save.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_dst_token.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_eula.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_gsquery.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_gslt.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_header.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_logs.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_retry.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_server_dir.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} +install_server_files.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_stats.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_steamcmd.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_ts3.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_ts3db.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_ut2k4.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_dl_ut2k4.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_ut2k4_key.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Calls code required for legacy servers +core_legacy.sh + +# Creates tmp dir if missing +if [ ! -d "${tmpdir}" ]; then + mkdir -p "${tmpdir}" +fi + +# Creates lock dir if missing +if [ ! -d "${lockdir}" ]; then + mkdir -p "${lockdir}" +fi + +# if $USER id missing set to whoami +if [ -z "${USER}" ]; then + USER="$(whoami)" +fi + +# Calls on-screen messages (bootstrap) +core_messages.sh + +#Calls file downloader (bootstrap) +core_dl.sh + +# Calls the global Ctrl-C trap +core_trap.sh diff --git a/lgsm/modules/core_steamcmd.sh b/lgsm/modules/core_steamcmd.sh new file mode 100644 index 0000000..e628e44 --- /dev/null +++ b/lgsm/modules/core_steamcmd.sh @@ -0,0 +1,426 @@ +#!/bin/bash +# LinuxGSM core_steamcmd.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Core modules for SteamCMD + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_install_steamcmd() { + if [ "${shortname}" == "ark" ] && [ "${installsteamcmd}" == "1" ]; then + steamcmddir="${serverfiles}/Engine/Binaries/ThirdParty/SteamCMD/Linux" + fi + if [ ! -d "${steamcmddir}" ]; then + mkdir -p "${steamcmddir}" + fi + fn_fetch_file "http://media.steampowered.com/client/steamcmd_linux.tar.gz" "" "" "" "${tmpdir}" "steamcmd_linux.tar.gz" "nochmodx" "norun" "noforce" "nohash" + fn_dl_extract "${tmpdir}" "steamcmd_linux.tar.gz" "${steamcmddir}" + chmod +x "${steamcmddir}/steamcmd.sh" +} + +fn_check_steamcmd_user() { + # Checks if steamuser is setup. + if [ "${steamuser}" == "username" ]; then + fn_print_fail_nl "Steam login not set. Update steamuser in ${configdirserver}" + echo -e " * Change steamuser=\"username\" to a valid steam login." + if [ -d "${lgsmlogdir}" ]; then + fn_script_log_fail "Steam login not set. Update steamuser in ${configdirserver}" + fi + core_exit.sh + fi + # Anonymous user is set if steamuser is missing. + if [ -z "${steamuser}" ]; then + if [ -d "${lgsmlogdir}" ]; then + fn_script_log_info "Using anonymous Steam login" + fi + steamuser="anonymous" + steampass='' + fi +} + +fn_check_steamcmd() { + # Checks if SteamCMD exists when starting or updating a server. + # Only install if steamcmd package is missing or steamcmd dir is missing. + if [ ! -f "${steamcmddir}/steamcmd.sh" ] && [ -z "$(command -v steamcmd 2> /dev/null)" ]; then + if [ "${commandname}" == "INSTALL" ]; then + fn_install_steamcmd + else + fn_print_warn_nl "SteamCMD is missing" + fn_script_log_warn "SteamCMD is missing" + fn_install_steamcmd + fi + elif [ "${commandname}" == "INSTALL" ]; then + fn_print_information "SteamCMD is already installed..." + fn_print_ok_eol_nl + fi +} + +fn_check_steamcmd_dir() { + # Worksround that pre-installs the correct steam directories to ensure all packages use the correct Standard. + # https://github.com/ValveSoftware/steam-for-linux/issues/6976#issuecomment-610446347 + + # Create Steam installation directory. + if [ ! -d "${XDG_DATA_HOME:="${HOME}/.local/share"}/Steam" ]; then + mkdir -p "${XDG_DATA_HOME:="${HOME}/.local/share"}/Steam" + fi + + # Create common Steam directory. + if [ ! -d "${HOME}/.steam" ]; then + mkdir -p "${HOME}/.steam" + fi + + # Symbolic links to Steam installation directory. + if [ ! -L "${HOME}/.steam/root" ]; then + if [ -d "${HOME}/.steam/root" ]; then + rm -f "${HOME:?}/.steam/root" + fi + ln -s "${XDG_DATA_HOME:="${HOME}/.local/share"}/Steam" "${HOME}/.steam/root" + fi + + if [ ! -L "${HOME}/.steam/steam" ]; then + if [ -d "${HOME}/.steam/steam" ]; then + rm -rf "${HOME}/.steam/steam" + fi + ln -s "${XDG_DATA_HOME:="${HOME}/.local/share"}/Steam" "${HOME}/.steam/steam" + fi +} + +fn_check_steamcmd_dir_legacy() { + # Remove old Steam installation directories ~/Steam and ${rootdir}/steamcmd + if [ -d "${rootdir}/steamcmd" ] && [ "${steamcmddir}" == "${XDG_DATA_HOME:="${HOME}/.local/share"}/Steam" ]; then + rm -rf "${rootdir:?}/steamcmd" + fi + + if [ -d "${HOME}/Steam" ] && [ "${steamcmddir}" == "${XDG_DATA_HOME:="${HOME}/.local/share"}/Steam" ]; then + rm -rf "${HOME}/Steam" + fi +} + +fn_check_steamcmd_steamapp() { + # Check that steamapp directory fixes issue #3481 + if [ ! -d "${serverfiles}/steamapps" ]; then + mkdir -p "${serverfiles}/steamapps" + fi +} + +fn_check_steamcmd_ark() { + # Checks if SteamCMD exists in + # Engine/Binaries/ThirdParty/SteamCMD/Linux + # to allow ark mods to work + if [ ! -f "${serverfiles}/Engine/Binaries/ThirdParty/SteamCMD/Linux/steamcmd.sh" ]; then + installsteamcmd=1 + if [ "${commandname}" == "INSTALL" ]; then + fn_install_steamcmd + else + fn_print_warn_nl "ARK mods SteamCMD is missing" + fn_script_log_warn "ARK mods SteamCMD is missing" + fn_install_steamcmd + fi + elif [ "${commandname}" == "INSTALL" ]; then + fn_print_information "ARK mods SteamCMD is already installed..." + fn_print_ok_eol_nl + fi +} + +fn_check_steamcmd_clear() { + # Will remove steamcmd dir if steamcmd package is installed. + if [ "$(command -v steamcmd 2> /dev/null)" ] && [ -d "${rootdir}/steamcmd" ]; then + rm -rf "${steamcmddir:?}" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_script_log_fail "Removing ${rootdir}/steamcmd" + else + fn_script_log_pass "Removing ${rootdir}/steamcmd" + fi + fi +} + +fn_check_steamcmd_exec() { + if [ "$(command -v steamcmd 2> /dev/null)" ]; then + steamcmdcommand="steamcmd" + else + steamcmdcommand="./steamcmd.sh" + fi +} + +fn_update_steamcmd_localbuild() { + # Gets local build info. + fn_print_dots "Checking local build: ${remotelocation}" + fn_check_steamcmd_appmanifest + # Uses appmanifest to find local build. + localbuild=$(grep buildid "${appmanifestfile}" | tr '[:blank:]"' ' ' | tr -s ' ' | cut -d\ -f3) + + # Checks if localbuild variable has been set. + if [ -z "${localbuild}" ]; then + fn_print_fail "Checking local build: ${remotelocation}: missing local build info" + fn_script_log_fail "Missing local build info" + core_exit.sh + else + fn_print_ok "Checking local build: ${remotelocation}" + fn_script_log_pass "Checking local build" + fi +} + +fn_update_steamcmd_remotebuild() { + # Get remote build info. + if [ -d "${steamcmddir}" ]; then + cd "${steamcmddir}" || exit + fi + + # Removes appinfo.vdf as a fix for not always getting up to date version info from SteamCMD. + if [ "$(find "${HOME}" -type f -name "appinfo.vdf" 2> /dev/null | wc -l)" -ne "0" ]; then + find "${HOME}" -type f -name "appinfo.vdf" -exec rm -f {} \; 2> /dev/null + fi + + # Set branch to public if no custom branch. + if [ -z "${branch}" ]; then + branch="public" + fi + + # added as was failing GitHub Actions test. Running SteamCMD twice seems to fix it. + ${steamcmdcommand} +login "${steamuser}" "${steampass}" +app_info_update 1 +quit > /dev/null 2>&1 + # password for branch not needed to check the buildid + remotebuildversion=$(${steamcmdcommand} +login "${steamuser}" "${steampass}" +app_info_update 1 +app_info_print "${appid}" +quit | sed -e '/"branches"/,/^}/!d' | sed -n "/\"${branch}\"/,/}/p" | grep -m 1 buildid | tr -cd '[:digit:]') + + if [ "${firstcommandname}" != "INSTALL" ]; then + fn_print_dots "Checking remote build: ${remotelocation}" + # Checks if remotebuildversion variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_fail "Checking remote build: ${remotelocation}" + fn_script_log_fail "Checking remote build" + core_exit.sh + else + fn_print_ok "Checking remote build: ${remotelocation}" + fn_script_log_pass "Checking remote build" + fi + else + # Checks if remotebuild variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_failure "Unable to get remote build" + fn_script_log_fail "Unable to get remote build" + core_exit.sh + fi + fi +} + +fn_update_steamcmd_compare() { + fn_print_dots "Checking for update: ${remotelocation}" + # Update has been found or force update. + if [ "${localbuild}" != "${remotebuildversion}" ] || [ "${forceupdate}" == "1" ]; then + # Create update lockfile. + date '+%s' > "${lockdir:?}/update.lock" + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "Update available" + echo -e "* Local build: ${red}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + if [ -n "${betapassword}" ]; then + echo -e "* Branch password: ${betapassword}" + fi + echo -e "https://steamdb.info/app/${appid}/" + echo -en "\n" + fn_script_log_info "Update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + if [ -n "${betapassword}" ]; then + fn_script_log_info "Branch password: ${betapassword}" + fi + fn_script_log_info "${localbuild} > ${remotebuildversion}" + + if [ "${commandname}" == "UPDATE" ]; then + unset updateonstart + check_status.sh + # If server stopped. + if [ "${status}" == "0" ]; then + fn_dl_steamcmd + # If server started. + else + fn_print_restart_warning + exitbypass=1 + command_stop.sh + fn_firstcommand_reset + exitbypass=1 + fn_dl_steamcmd + exitbypass=1 + command_start.sh + fn_firstcommand_reset + fi + unset exitbypass + date +%s > "${lockdir:?}/last-updated.lock" + alert="update" + elif [ "${commandname}" == "CHECK-UPDATE" ]; then + alert="check-update" + fi + alert.sh + else + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "No update available" + echo -e "* Local build: ${green}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + if [ -n "${betapassword}" ]; then + echo -e "* Branch password: ${betapassword}" + fi + echo -e "https://steamdb.info/app/${appid}/" + echo -en "\n" + fn_script_log_info "No update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + if [ -n "${betapassword}" ]; then + fn_script_log_info "Branch password: ${betapassword}" + fi + fi +} + +fn_appmanifest_info() { + appmanifestfile=$(find -L "${serverfiles}/steamapps" -type f -name "appmanifest_${appid}.acf") + appmanifestfilewc=$(find -L "${serverfiles}/steamapps" -type f -name "appmanifest_${appid}.acf" | wc -l) +} + +fn_check_steamcmd_appmanifest() { + fn_appmanifest_info + # Multiple or no matching appmanifest files may sometimes be present. + if [ "${appmanifestfilewc}" -ge "2" ]; then + fn_print_error "Multiple appmanifest_${appid}.acf files found" + fn_script_log_error "Multiple appmanifest_${appid}.acf files found" + fn_print_dots "Removing x${appmanifestfilewc} appmanifest_${appid}.acf files" + for appfile in ${appmanifestfile}; do + rm -f "${appfile:?}" + done + appmanifestfilewc1="${appmanifestfilewc}" + fn_appmanifest_info + # if error can not be resolved. + if [ "${appmanifestfilewc}" -ge "2" ]; then + fn_print_fail "Unable to remove x${appmanifestfilewc} appmanifest_${appid}.acf files" + fn_script_log_fail "Unable to remove x${appmanifestfilewc} appmanifest_${appid}.acf files" + echo -e "* Check user permissions" + for appfile in ${appmanifestfile}; do + echo -e " ${appfile}" + done + core_exit.sh + else + fn_print_ok "Removed x${appmanifestfilewc1} appmanifest_${appid}.acf files" + fn_script_log_pass "Removed x${appmanifestfilewc1} appmanifest_${appid}.acf files" + fn_print_info_nl "Forcing update to correct issue" + fn_script_log_info "Forcing update to correct issue" + fn_dl_steamcmd + fi + elif [ "${appmanifestfilewc}" -eq "0" ]; then + fn_print_error_nl "No appmanifest_${appid}.acf found" + fn_script_log_error "No appmanifest_${appid}.acf found" + fn_print_info_nl "Forcing update to correct issue" + fn_script_log_info "Forcing update to correct issue" + fn_dl_steamcmd + fn_appmanifest_info + if [ "${appmanifestfilewc}" -eq "0" ]; then + fn_print_fail_nl "Still no appmanifest_${appid}.acf found" + fn_script_log_fail "Still no appmanifest_${appid}.acf found" + core_exit.sh + fi + fi + + # Checking for half completed updates. + bytesdownloaded=$(grep BytesDownloaded "${appmanifestfile}" | tr -cd '[:digit:]') + bytestodownload=$(grep BytesToDownload "${appmanifestfile}" | tr -cd '[:digit:]') + if [ "${bytesdownloaded}" != "${bytestodownload}" ]; then + fn_print_error_nl "BytesDownloaded and BytesToDownload do not match" + fn_script_log_error "BytesDownloaded and BytesToDownload do not match" + fn_print_info_nl "Forcing update to correct issue" + fn_script_log_info "Forcing update to correct issue" + fn_dl_steamcmd + fi + + bytesstaged=$(grep BytesStaged "${appmanifestfile}" | tr -cd '[:digit:]') + bytestostage=$(grep BytesToStage "${appmanifestfile}" | tr -cd '[:digit:]') + if [ "${bytesstaged}" != "${bytestostage}" ]; then + fn_print_error_nl "BytesStaged and BytesToStage do not match" + fn_script_log_error "BytesStaged and BytesToStage do not match" + fn_print_info_nl "Forcing update to correct issue" + fn_script_log_info "Forcing update to correct issue" + fn_dl_steamcmd + fi + + # if engine is GoldSrc check SharedDepots exists in appmanifest_90.acf + if [ "${engine}" == "goldsrc" ]; then + shareddepotsexists=$(grep -c SharedDepots "${serverfiles}/steamapps/appmanifest_90.acf") + if [ ! -f "${serverfiles}/steamapps/appmanifest_90.acf" ] || [ "${shareddepotsexists}" == "0" ]; then + fn_print_error_nl "SharedDepots missing from appmanifest_90.acf" + fn_script_log_error "SharedDepots missing from appmanifest_90.acf" + fn_print_info_nl "Forcing update to correct issue" + fn_script_log_info "Forcing update to correct issue" + if [ "${shortname}" == "ahl" ]; then + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_90.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_10.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_70.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + elif [ "${shortname}" == "bb" ]; then + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_90.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_10.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_70.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + elif [ "${shortname}" == "cscz" ]; then + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_90.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_10.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_70.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_80.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + elif [ "${shortname}" == "css" ]; then + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_90.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_10.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_70.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + elif [ "${shortname}" == "dmc" ]; then + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_90.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_10.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_40.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_70.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + elif [ "${shortname}" == "dod" ]; then + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_90.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_10.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_30.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_70.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + elif [ "${shortname}" == "hldm" ]; then + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_90.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_10.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_70.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + elif [ "${shortname}" == "ns" ]; then + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_90.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_10.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_70.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + elif [ "${shortname}" == "opfor" ]; then + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_90.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_10.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_50.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_70.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + elif [ "${shortname}" == "ricochet" ]; then + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_90.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_10.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_60.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_70.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + elif [ "${shortname}" == "tfc" ]; then + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_90.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_10.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_20.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_70.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + elif [ "${shortname}" == "ts" ]; then + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_90.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_10.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_70.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + elif [ "${shortname}" == "vs" ]; then + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_90.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_10.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fn_fetch_file_github "lgsm/data/appmanifest/${shortname}" "appmanifest_70.acf" "${serverfiles}/steamapps" "nochmodx" "norun" "noforce" "nohash" + fi + fn_dl_steamcmd + fi + fi +} diff --git a/lgsm/modules/core_trap.sh b/lgsm/modules/core_trap.sh new file mode 100644 index 0000000..ea6fce8 --- /dev/null +++ b/lgsm/modules/core_trap.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# LinuxGSM core_trap.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Handles CTRL-C trap to give an exit code. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_exit_trap() { + if [ -z "${exitcode}" ]; then + exitcode=$? + fi + echo -e "" + if [ -z "${exitcode}" ]; then + exitcode=0 + fi + core_exit.sh +} + +# trap to give an exit code. +trap fn_exit_trap INT diff --git a/lgsm/modules/fix.sh b/lgsm/modules/fix.sh new file mode 100644 index 0000000..2f8b544 --- /dev/null +++ b/lgsm/modules/fix.sh @@ -0,0 +1,87 @@ +#!/bin/bash +# LinuxGSM fix.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Overall module for managing fixes. +# Runs modules that will fix an issue. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Messages that are displayed for some fixes. +fn_fix_msg_start() { + fn_print_dots "Applying ${fixname} fix: ${gamename}" + fn_print_info "Applying ${fixname} fix: ${gamename}" + fn_script_log_info "Applying ${fixname} fix: ${gamename}" +} + +fn_fix_msg_start_nl() { + fn_print_dots "Applying ${fixname} fix: ${gamename}" + fn_print_info_nl "Applying ${fixname} fix: ${gamename}" + fn_script_log_info "Applying ${fixname} fix: ${gamename}" +} + +fn_fix_msg_end() { + if [ $? != 0 ]; then + fn_print_error_nl "Applying ${fixname} fix: ${gamename}" + fn_script_log_error "Applying ${fixname} fix: ${gamename}" + else + fn_print_ok_nl "Applying ${fixname} fix: ${gamename}" + fn_script_log_pass "Applying ${fixname} fix: ${gamename}" + fi +} + +fn_exists_fix() { + local short="${1:?}" + + if [ "$(type -t "fix_${short}.sh")" == 'function' ]; then + return 0 + else + return 1 + fi +} + +fn_apply_fix() { + local phase_message="${1:?}" + local short="${2:?}" + + if fn_exists_fix "${short}"; then + "fix_${short}.sh" + else + fn_print_error_nl "${shortname} is marked to apply pre start fix but there is no fix registered" + fi +} + +apply_pre_start_fix=(arma3 armar ark av bt bo csgo cmw dst hw ins nmrih onset pvr rust rw sdtd sfc sof2 squad st tf2 terraria ts3 mcb mta unt vh wurm zmr) +apply_post_install_fix=(av kf kf2 ro samp ut2k4 ut ut3) + +# validate registered fixes for safe development +for fix in "${apply_pre_start_fix[@]}" "${apply_post_install_fix[@]}"; do + if ! fn_exists_fix "${fix}"; then + fn_print_fail_nl "fix_${fix}.sh is registered but doesn't exist. Typo or did you miss to modify core_modules.sh?" + exitcode=1 + core_exit.sh + fi +done + +# Fixes that are run on start. +if [ "${commandname}" != "INSTALL" ] && [ -z "${fixbypass}" ]; then + if [ "${appid}" ]; then + fix_steamcmd.sh + fi + + if grep -qEe "(^|\s)${shortname}(\s|$)" <<< "${apply_pre_start_fix[@]}"; then + fn_apply_fix "pre start" "${shortname}" + fi +fi + +# Fixes that are run on install only. +if [ "${commandname}" == "INSTALL" ]; then + if grep -qEe "(^|\s)${shortname}(\s|$)" <<< "${apply_post_install_fix[@]}"; then + echo -e "" + echo -e "${lightyellow}Applying Post-Install Fixes${default}" + fn_messages_separator + postinstall=1 + fn_apply_fix "post install" "${shortname}" + fi +fi diff --git a/lgsm/modules/fix_ark.sh b/lgsm/modules/fix_ark.sh new file mode 100644 index 0000000..03e5338 --- /dev/null +++ b/lgsm/modules/fix_ark.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# LinuxGSM fix_ark.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with ARK: Survival Evolved. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# removes mulitple appworkshop_346110.acf if found. +steamappsfilewc="$(find "${HOME}" -name appworkshop_346110.acf | wc -l)" +if [ "${steamappsfilewc}" -gt "1" ]; then + fixname="multiple appworkshop acf files" + fn_fix_msg_start + find "${HOME}" -name appworkshop_346110.acf -exec rm -f {} \; + fn_fix_msg_end +elif [ "${steamappsfilewc}" -eq "1" ]; then + # Steam mods directory selecter + # This allows LinxuGSM to select either ~/.steam or ~/Steam. depending on what is being used + steamappsfile=$(find "${HOME}" -name appworkshop_346110.acf) + steamappsdir=$(dirname "${steamappsfile}") + steamappspath=$( + cd "${steamappsdir}" || return + cd ../ + pwd + ) + + # removes the symlink if exists. + # fixes issue with older versions of LinuxGSM linking to /home/arkserver/steamcmd + if [ -L "${serverfiles}/Engine/Binaries/ThirdParty/SteamCMD/Linux" ]; then + fixname="broken SteamCMD symlink" + fn_fix_msg_start + unlink "${serverfiles:?}/Engine/Binaries/ThirdParty/SteamCMD/Linux" + fn_fix_msg_end + check_steamcmd.sh + fi + + # removed ARK steamcmd directory if steamcmd is missing. + if [ ! -f "${serverfiles}/Engine/Binaries/ThirdParty/SteamCMD/Linux/steamcmd.sh" ]; then + fixname="remove invalid ARK SteamCMD directory" + fn_fix_msg_start + rm -rf "${serverfiles:?}/Engine/Binaries/ThirdParty/SteamCMD/Linux" + fn_fix_msg_end + check_steamcmd.sh + fi + + # if the steamapps symlink is incorrect unlink it. + if [ -d "${serverfiles}/Engine/Binaries/ThirdParty/SteamCMD/Linux" ] && [ -L "${serverfiles}/Engine/Binaries/ThirdParty/SteamCMD/Linux/steamapps" ] && [ "$(readlink "${serverfiles}/Engine/Binaries/ThirdParty/SteamCMD/Linux/steamapps")" != "${steamappspath}" ]; then + fixname="incorrect steamapps symlink" + fn_fix_msg_start + unlink "${serverfiles:?}/Engine/Binaries/ThirdParty/SteamCMD/Linux/steamapps" + fn_fix_msg_end + fi + + # Put symlink to steamapps directory into the ARK SteamCMD directory to link the downloaded mods to the correct location. + if [ ! -L "${serverfiles}/Engine/Binaries/ThirdParty/SteamCMD/Linux/steamapps" ]; then + fixname="steamapps symlink" + fn_fix_msg_start + ln -s "${steamappspath}" "${serverfiles}/Engine/Binaries/ThirdParty/SteamCMD/Linux/steamapps" + fn_fix_msg_end + fi +fi diff --git a/lgsm/modules/fix_arma3.sh b/lgsm/modules/fix_arma3.sh new file mode 100644 index 0000000..b415b81 --- /dev/null +++ b/lgsm/modules/fix_arma3.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# LinuxGSM fix_arma3.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with ARMA3. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Fixes: 20150 Segmentation fault (core dumped) error. +if [ ! -d "${XDG_DATA_HOME:="${HOME}/.local/share"}/Arma 3" ] || [ ! -d "${XDG_DATA_HOME:="${HOME}/.local/share"}/Arma 3 - Other Profiles" ]; then + fixname="20150 Segmentation fault (core dumped)" + fn_fix_msg_start + mkdir -p "${XDG_DATA_HOME:="${HOME}/.local/share"}/Arma 3 - Other Profiles" + fn_fix_msg_end +fi diff --git a/lgsm/modules/fix_armar.sh b/lgsm/modules/fix_armar.sh new file mode 100755 index 0000000..6b68c2a --- /dev/null +++ b/lgsm/modules/fix_armar.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# LinuxGSM fix_armar.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Arma Reforger. + +module_selfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Fixes: Profile directory doesn't exist. +# Issue Link: https://feedback.bistudio.com/T164845 +if [ ! -d "${serverprofilefullpath}" ]; then + fixname="Profile directory doesn't exist" + fn_fix_msg_start + mkdir -p "${serverprofilefullpath}" + fn_fix_msg_end +fi diff --git a/lgsm/modules/fix_av.sh b/lgsm/modules/fix_av.sh new file mode 100644 index 0000000..bfff59a --- /dev/null +++ b/lgsm/modules/fix_av.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# LinuxGSM fix_av.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Avorion. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}:${serverfiles}/linux64" + +# Generates the server config if it doesn't exist. +if [ ! -f "${servercfgfullpath}" ]; then + startparameters="--datapath ${avdatapath} --galaxy-name ${selfname} --init-folders-only" + fn_print_information "starting ${gamename} server to generate configs." + cd "${systemdir}" || exit + eval "${executable} ${startparameters}" +fi diff --git a/lgsm/modules/fix_bo.sh b/lgsm/modules/fix_bo.sh new file mode 100644 index 0000000..24e7687 --- /dev/null +++ b/lgsm/modules/fix_bo.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# LinuxGSM fix_hw.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Ballistic Overkill. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}:${serverfiles}/BODS_Data/Plugins/x86_64" diff --git a/lgsm/modules/fix_bt.sh b/lgsm/modules/fix_bt.sh new file mode 100755 index 0000000..4d837a1 --- /dev/null +++ b/lgsm/modules/fix_bt.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# LinuxGSM fix_bt.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Barotrauma. + +module_selfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Fixes: Missing user data directory error. +if [ ! -d "${XDG_DATA_HOME:="${HOME}/.local/share"}/Daedalic Entertainment GmbH/Barotrauma" ]; then + fixname="Missing user data directory error." + fn_fix_msg_start + mkdir -p "${XDG_DATA_HOME:="${HOME}/.local/share"}/Daedalic Entertainment GmbH/Barotrauma" + fn_fix_msg_end +fi + +# check if startscript is with windows line endings and reformat it +if file -b "${serverfiles}${executable:1}" | grep -q CRLF; then + fixname="Convert ${executable:2} to unix file format" + fn_fix_msg_start + dos2unix -q "${serverfiles}${executable:1}" + fn_fix_msg_end +fi diff --git a/lgsm/modules/fix_cmw.sh b/lgsm/modules/fix_cmw.sh new file mode 100644 index 0000000..a57c6c8 --- /dev/null +++ b/lgsm/modules/fix_cmw.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# LinuxGSM fix_cmw.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Chivalry: Medieval Warfare. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +if [ ! -f "${executabledir}/steam_appid.txt" ]; then + fixname="steam_appid.txt" + fn_fix_msg_start + echo 219640 > "${executabledir}/steam_appid.txt" + fn_fix_msg_end +fi + +if [ ! -f "${servercfgfullpath}" ]; then + fn_fix_msg_start + fixname="copy config" + if [ ! -d "${servercfgdir}" ]; then + mkdir -p "${servercfgdir}" + fi + cp "${systemdir}/UDKGame/Config/"*.ini "${servercfgdir}" + fn_fix_msg_end +fi diff --git a/lgsm/modules/fix_csgo.sh b/lgsm/modules/fix_csgo.sh new file mode 100644 index 0000000..ea858ee --- /dev/null +++ b/lgsm/modules/fix_csgo.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# LinuxGSM fix_csgo.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Counter-Strike: Global Offensive. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Fixes: server not always creating steam_appid.txt file. +if [ ! -f "${serverfiles}/steam_appid.txt" ]; then + fixname="730 steam_appid.txt" + fn_fix_msg_start + echo -n "730" >> "${serverfiles}/steam_appid.txt" + fn_fix_msg_end +fi + +# Fixes: Error parsing BotProfile.db - unknown attribute 'Rank'". +if [ -f "${systemdir}/botprofile.db" ] && grep "^\s*Rank" "${systemdir}/botprofile.db" > /dev/null 2>&1; then + fixname="botprofile.db" + fn_fix_msg_start + sed -i 's/^\s*Rank/\t\/\/Rank/g' "${systemdir}/botprofile.db" > /dev/null 2>&1 + fn_fix_msg_end +fi + +# Fixes: Unknown command "cl_bobamt_vert" and exec: couldn't exec joystick.cfg. +if [ -f "${servercfgdir}/valve.rc" ] && grep -E '^\s*exec\s*(default|joystick)\.cfg' "${servercfgdir}/valve.rc" > /dev/null 2>&1; then + fixname="valve.rc" + fn_fix_msg_start + sed -i 's/^\s*exec\s*default.cfg/\/\/exec default.cfg/g' "${servercfgdir}/valve.rc" > /dev/null 2>&1 + sed -i 's/^\s*exec\s*joystick.cfg/\/\/exec joystick.cfg/g' "${servercfgdir}/valve.rc" > /dev/null 2>&1 + fn_fix_msg_end +fi + +# Fixes: Detected engine 11 but could not load: /home/csgo/serverfiles/bin/libgcc_s.so.1: version `GCC_7.0.0' not found (required by /lib/i386-linux-gnu/libstdc++.so.6) +libgccc_so="${serverfiles}/bin/libgcc_s.so.1" +if [ -f "${libgccc_so}" ]; then + fixname="libgcc_s.so.1 move away" + fn_fix_msg_start + mv "${libgccc_so}" "${libgccc_so}.bak" + fn_fix_msg_end +fi diff --git a/lgsm/modules/fix_dst.sh b/lgsm/modules/fix_dst.sh new file mode 100644 index 0000000..ff963d3 --- /dev/null +++ b/lgsm/modules/fix_dst.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# LinuxGSM fix_dst.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Don't Starve Together. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Fixes: ./dontstarve_dedicated_server_nullrenderer: ./lib32/libcurl-gnutls.so.4: no version information available (required by ./dontstarve_dedicated_server_nullrenderer). +# Issue only occures on CentOS as libcurl-gnutls.so.4 is called libcurl.so.4 on CentOS. +if [ -f "/etc/redhat-release" ] && [ ! -f "${serverfiles}/bin/lib32/libcurl-gnutls.so.4" ]; then + fixname="libcurl-gnutls.so.4" + fn_fix_msg_start + ln -s "/usr/lib/libcurl.so.4" "${serverfiles}/bin/lib32/libcurl-gnutls.so.4" + fn_fix_msg_end +fi diff --git a/lgsm/modules/fix_hw.sh b/lgsm/modules/fix_hw.sh new file mode 100644 index 0000000..0e70b71 --- /dev/null +++ b/lgsm/modules/fix_hw.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# LinuxGSM fix_hw.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Hurtworld. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}:${serverfiles}/Hurtworld_Data/Plugins/x86_64" diff --git a/lgsm/modules/fix_ins.sh b/lgsm/modules/fix_ins.sh new file mode 100644 index 0000000..cc79e36 --- /dev/null +++ b/lgsm/modules/fix_ins.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# LinuxGSM fix_ins.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Insurgency. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Fixes: ./srcds_linux: error while loading shared libraries: libtier0.so: cannot open shared object file: No such file or directory. + +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}:${serverfiles}/bin" + +# Fixes: issue #529 - gamemode not passed to debug or start. + +if [ "${commandname}" == "DEBUG" ]; then + defaultmap="\"${defaultmap}\"" +else + defaultmap="\\\"${defaultmap}\\\"" +fi diff --git a/lgsm/modules/fix_kf.sh b/lgsm/modules/fix_kf.sh new file mode 100644 index 0000000..1bec47a --- /dev/null +++ b/lgsm/modules/fix_kf.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# LinuxGSM fix_kf.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Killing Floor. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +echo -e "applying WebAdmin ROOst.css fix." +echo -e "http://forums.tripwireinteractive.com/showpost.php?p=585435&postcount=13" +sed -i 's/none}/none;/g' "${serverfiles}/Web/ServerAdmin/ROOst.css" +sed -i 's/underline}/underline;/g' "${serverfiles}/Web/ServerAdmin/ROOst.css" +fn_sleep_time +echo -e "applying WebAdmin CharSet fix." +echo -e "http://forums.tripwireinteractive.com/showpost.php?p=442340&postcount=1" +sed -i 's/CharSet="iso-8859-1"/CharSet="utf-8"/g' "${systemdir}/UWeb.int" +fn_sleep_time +echo -e "applying server name fix." +fn_sleep_time +echo -e "forcing server restart..." +fn_sleep_time +exitbypass=1 +command_start.sh +fn_firstcommand_reset +fn_sleep_time_5 +exitbypass=1 +command_stop.sh +fn_firstcommand_reset +exitbypass=1 +command_start.sh +fn_firstcommand_reset +fn_sleep_time_5 +exitbypass=1 +command_stop.sh +fn_firstcommand_reset diff --git a/lgsm/modules/fix_kf2.sh b/lgsm/modules/fix_kf2.sh new file mode 100644 index 0000000..cb47074 --- /dev/null +++ b/lgsm/modules/fix_kf2.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# LinuxGSM fix_kf2.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Killing Floor 2. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +startparameters="\"${defaultmap}?Game=KFGameContent.KFGameInfo_VersusSurvival\"" + +fn_print_information "starting ${gamename} server to generate configs." +exitbypass=1 +command_start.sh +fn_firstcommand_reset +fn_sleep_time_10 +exitbypass=1 +command_stop.sh +fn_firstcommand_reset diff --git a/lgsm/modules/fix_mcb.sh b/lgsm/modules/fix_mcb.sh new file mode 100644 index 0000000..1e95bb4 --- /dev/null +++ b/lgsm/modules/fix_mcb.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# LinuxGSM fix_mcb.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves various issues with Minecraft Bedrock. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# official docs state that the server should be started with: LD_LIBRARY_PATH=. ./bedrock_server +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}" diff --git a/lgsm/modules/fix_mta.sh b/lgsm/modules/fix_mta.sh new file mode 100644 index 0000000..4e533eb --- /dev/null +++ b/lgsm/modules/fix_mta.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# LinuxGSM fix_mta.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves various issues with Multi Theft Auto. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +if [ ! -f "${lgsmdir}/lib/libmysqlclient.so.16" ]; then + fixname="libmysqlclient16" + fn_fix_msg_start_nl + fn_fetch_file "https://nightly.mtasa.com/files/modules/64/libmysqlclient.so.16" "" "" "" "${lgsmdir}/lib" "libmysqlclient.so.16" "chmodx" "norun" "noforce" "6c188e0f8fb5d7a29f4bc413b9fed6c2" + fn_fix_msg_end +fi diff --git a/lgsm/modules/fix_nmrih.sh b/lgsm/modules/fix_nmrih.sh new file mode 100644 index 0000000..83a5ad4 --- /dev/null +++ b/lgsm/modules/fix_nmrih.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# LinuxGSM fix_nmrih.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Create symlinks for renamed No More Room In Hell serverfiles. +# Solution from Steam Community post: https://steamcommunity.com/app/224260/discussions/2/1732089092441769414/ + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +ln -s "${serverfiles}/bin/vphysics_srv.so" "${serverfiles}/bin/vphysics.so" +ln -s "${serverfiles}/bin/studiorender_srv.so" "${serverfiles}/bin/studiorender.so" +ln -s "${serverfiles}/bin/soundemittersystem_srv.so" "${serverfiles}/bin/soundemittersystem.so" +ln -s "${serverfiles}/bin/shaderapiempty_srv.so" "${serverfiles}/bin/shaderapiempty.so" +ln -s "${serverfiles}/bin/scenefilecache_srv.so" "${serverfiles}/bin/scenefilecache.so" +ln -s "${serverfiles}/bin/replay_srv.so" "${serverfiles}/bin/replay.so" +ln -s "${serverfiles}/bin/materialsystem_srv.so" "${serverfiles}/bin/materialsystem.so" diff --git a/lgsm/modules/fix_onset.sh b/lgsm/modules/fix_onset.sh new file mode 100644 index 0000000..7d644ef --- /dev/null +++ b/lgsm/modules/fix_onset.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# LinuxGSM fix_onset.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves various issues with Onset. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}" + +# Fixes: Failed loading "mariadb": libmariadbclient.so.18: cannot open shared object file: No such file or directory +# Issue only occures on CentOS as libmariadbclient.so.18 is called libmariadb.so.3 on CentOS. +if [ -f "/etc/redhat-release" ] && [ ! -f "${serverfiles}/libmariadbclient.so.18" ] && [ -f "/usr/lib64/libmariadb.so.3" ]; then + fixname="libmariadbclient.so.18" + fn_fix_msg_start + ln -s "/usr/lib64/libmariadb.so.3" "${serverfiles}/libmariadbclient.so.18" + fn_fix_msg_end +fi diff --git a/lgsm/modules/fix_pvr.sh b/lgsm/modules/fix_pvr.sh new file mode 100644 index 0000000..6d8727e --- /dev/null +++ b/lgsm/modules/fix_pvr.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# LinuxGSM fix_pvr.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves various issues with Pavlov VR. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +if [ ! -f "${serverfiles}/linux64/libc++.so" ] && [ -f "/usr/lib/x86_64-linux-gnu/libc++.so.1" ]; then + cp "/usr/lib/x86_64-linux-gnu/libc++.so.1" "${serverfiles}/linux64/libc++.so" +fi + +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}:${serverfiles}/linux64" diff --git a/lgsm/modules/fix_ro.sh b/lgsm/modules/fix_ro.sh new file mode 100644 index 0000000..72864d6 --- /dev/null +++ b/lgsm/modules/fix_ro.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# LinuxGSM fix_ro.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Red Orchestra. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +echo -e "applying webinterface ROOst.css fix." +echo -e "http://forums.tripwireinteractive.com/showpost.php?p=585435&postcount=13" +sed -i 's/none}/none;/g' "${serverfiles}/Web/ServerAdmin/ROOst.css" +sed -i 's/underline}/underline;/g' "${serverfiles}/Web/ServerAdmin/ROOst.css" +fn_sleep_time +echo -e "applying webinterface CharSet fix." +echo -e "http://forums.tripwireinteractive.com/showpost.php?p=442340&postcount=1" +sed -i 's/CharSet="iso-8859-1"/CharSet="utf-8"/g' "${systemdir}/uweb.int" +fn_sleep_time +echo -e "applying Steam AppID fix." +sed -i 's/1210/1200/g' "${systemdir}/steam_appid.txt" +fn_sleep_time +echo -e "applying server name fix." +fn_sleep_time +echo -e "forcing server restart..." +fn_sleep_time +exitbypass=1 +command_start.sh +fn_firstcommand_reset +fn_sleep_time_5 +exitbypass=1 +command_stop.sh +fn_firstcommand_reset +exitbypass=1 +command_start.sh +fn_firstcommand_reset +fn_sleep_time_5 +exitbypass=1 +command_stop.sh +fn_firstcommand_reset diff --git a/lgsm/modules/fix_rust.sh b/lgsm/modules/fix_rust.sh new file mode 100644 index 0000000..6d4cebc --- /dev/null +++ b/lgsm/modules/fix_rust.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# LinuxGSM fix_rust.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Rust. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Fixes: [Raknet] Server Shutting Down (Shutting Down). +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}:${serverfiles}/RustDedicated_Data/Plugins/x86_64" + +# Part of random seed feature. +# If seed is not defined by user generate a seed file. +if [ -z "${seed}" ] || [ "${seed}" == "0" ]; then + if [ ! -f "${datadir}/${selfname}-seed.txt" ]; then + shuf -i 1-2147483647 -n 1 > "${datadir}/${selfname}-seed.txt" + seed="$(cat "${datadir}/${selfname}-seed.txt")" + fn_print_info_nl "Generating new random seed (${cyan}${seed}${default})" + fn_script_log_pass "Generating new random seed (${cyan}${seed}${default})" + fi + seed="$(cat "${datadir}/${selfname}-seed.txt")" + randomseed=1 +fi + +# If Carbon mod is installed, run enviroment.sh +if [ -f "${serverfiles}/carbon/tools/environment.sh" ]; then + fn_print_info_nl "Running Carbon environment.sh" + fn_script_log_info "Running Carbon environment.sh" + # shellcheck source=/dev/null + source "${serverfiles}/carbon/tools/environment.sh" +fi diff --git a/lgsm/modules/fix_rw.sh b/lgsm/modules/fix_rw.sh new file mode 100644 index 0000000..17acf4d --- /dev/null +++ b/lgsm/modules/fix_rw.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# LinuxGSM fix_rw.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Rising World. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}:${serverfiles}/linux64" diff --git a/lgsm/modules/fix_samp.sh b/lgsm/modules/fix_samp.sh new file mode 100644 index 0000000..0b5d0ab --- /dev/null +++ b/lgsm/modules/fix_samp.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# LinuxGSM fix_sfc.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issue that the default rcon password is not changed. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +if [ -f "${servercfgfullpath}" ]; then + # check if default password is set "changeme" + currentpass=$(grep -E "^rcon_password" "${servercfgfullpath}" | sed 's/^rcon_password //') + defaultpass="changeme" + # check if default password is set + if [ "${currentpass}" == "${defaultpass}" ]; then + fixname="change default rcon password" + fn_fix_msg_start + fn_script_log_info "Changing rcon/admin password." + randomstring=$(tr -dc 'A-Za-z0-9_' < /dev/urandom 2> /dev/null | head -c 8 | xargs) + rconpass="admin${randomstring}" + sed -i "s/rcon_password changeme/rcon_password ${rconpass}/g" "${servercfgfullpath}" + fn_fix_msg_end + fi + # check if the hostname is the default name + currenthostname=$(grep -E "^hostname" "${servercfgfullpath}" | sed 's/^hostname //') + defaulthostname="SA-MP 0.3 Server" + if [ "${currenthostname}" == "${defaulthostname}" ]; then + fixname="change default hostname" + fn_fix_msg_start + fn_script_log_info "Changing default hostname to LinuxGSM" + sed -i "s/hostname ${defaulthostname}/hostname LinuxGSM/g" "${servercfgfullpath}" + fn_fix_msg_end + fi +fi diff --git a/lgsm/modules/fix_sdtd.sh b/lgsm/modules/fix_sdtd.sh new file mode 100644 index 0000000..7988b0d --- /dev/null +++ b/lgsm/modules/fix_sdtd.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# LinuxGSM fix_sdtd.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with 7 Days to Die. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}/7DaysToDieServer_Data/Plugins/x86_64" diff --git a/lgsm/modules/fix_sfc.sh b/lgsm/modules/fix_sfc.sh new file mode 100644 index 0000000..308f74b --- /dev/null +++ b/lgsm/modules/fix_sfc.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# LinuxGSM fix_sfc.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Source Forts Classic. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +if [ ! -f "${serverfiles}/bin/datacache.so" ]; then + ln -s "${serverfiles}/bin/datacache_srv.so" "${serverfiles}/bin/datacache.so" +fi + +if [ ! -f "${serverfiles}/bin/dedicated.so" ]; then + ln -s "${serverfiles}/bin/dedicated_srv.so" "${serverfiles}/bin/dedicated.so" +fi + +if [ ! -f "${serverfiles}/bin/engine.so" ]; then + ln -s "${serverfiles}/bin/engine_srv.so" "${serverfiles}/bin/engine.so" +fi + +if [ ! -f "${serverfiles}/bin/materialsystem.so" ]; then + ln -s "${serverfiles}/bin/materialsystem_srv.so" "${serverfiles}/bin/materialsystem.so" +fi + +if [ ! -f "${serverfiles}/bin/replay.so" ]; then + ln -s "${serverfiles}/bin/replay_srv.so" "${serverfiles}/bin/replay.so" +fi + +if [ ! -f "${serverfiles}/bin/shaderapiempty.so" ]; then + ln -s "${serverfiles}/bin/shaderapiempty_srv.so" "${serverfiles}/bin/shaderapiempty.so" +fi + +if [ ! -f "${serverfiles}/bin/soundemittersystem.so" ]; then + ln -s "${serverfiles}/bin/soundemittersystem_srv.so" "${serverfiles}/bin/soundemittersystem.so" +fi + +if [ ! -f "${serverfiles}/bin/studiorender.so" ]; then + ln -s "${serverfiles}/bin/studiorender_srv.so" "${serverfiles}/bin/studiorender.so" +fi + +if [ ! -f "${serverfiles}/bin/vphysics.so" ]; then + ln -s "${serverfiles}/bin/vphysics_srv.so" "${serverfiles}/bin/vphysics.so" +fi + +if [ ! -f "${serverfiles}/bin/scenefilecache.so" ]; then + ln -s "${serverfiles}/bin/scenefilecache_srv.so" "${serverfiles}/bin/scenefilecache.so" +fi diff --git a/lgsm/modules/fix_sof2.sh b/lgsm/modules/fix_sof2.sh new file mode 100644 index 0000000..4e5b136 --- /dev/null +++ b/lgsm/modules/fix_sof2.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# LinuxGSM fix_rust.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Soldier of Fortune 2. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Fixes: error while loading shared libraries: libcxa.so.1 +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}" diff --git a/lgsm/modules/fix_squad.sh b/lgsm/modules/fix_squad.sh new file mode 100644 index 0000000..2fec57f --- /dev/null +++ b/lgsm/modules/fix_squad.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# LinuxGSM fix_squad.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Squad. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# As the server base dir changed for the game, we need to migrate the default config from the old to the new location +oldservercfg="${serverfiles}/Squad/ServerConfig/${servercfg}" +if [ -f "${oldservercfg}" ] && [ -f "${servercfgfullpath}" ]; then + # diff old and new config - if it is different move the old config over the new one + if [ "$(diff -c "${oldservercfg}" "${servercfgfullpath}" | wc -l)" -gt 0 ]; then + fixname="Migrate server config to new Game folder" + fn_fix_msg_start + mv -v "${oldservercfg}" "${servercfgfullpath}" + fn_fix_msg_end + else + fixname="remove the same config from old configdir" + fn_fix_msg_start + rm -f "${oldservercfg}" + fn_fix_msg_end + + fi +fi diff --git a/lgsm/modules/fix_st.sh b/lgsm/modules/fix_st.sh new file mode 100644 index 0000000..4d100c6 --- /dev/null +++ b/lgsm/modules/fix_st.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# LinuxGSM fix_rust.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Stationeers. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Fixes: [Raknet] Server Shutting Down (Shutting Down). +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}:${serverfiles}/rocketstation_DedicatedServer_Data/Plugins/x86_64" diff --git a/lgsm/modules/fix_steamcmd.sh b/lgsm/modules/fix_steamcmd.sh new file mode 100644 index 0000000..2a20760 --- /dev/null +++ b/lgsm/modules/fix_steamcmd.sh @@ -0,0 +1,141 @@ +#!/bin/bash +# LinuxGSM fix_steamcmd.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with SteamCMD. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# function to simplify the steamclient.so fix +# example +# fn_fix_steamclient_so 32|64 (bit) "${serverfiles}/linux32/" +fn_fix_steamclient_so() { + # $1 type of fix 32 or 64 as possible values + # $2 as destination where the lib will be copied to + if [ "$1" == "32" ]; then + # steamclient.so x86 fix. + if [ ! -f "${2}/steamclient.so" ]; then + fixname="steamclient.so x86" + fn_fix_msg_start + if [ ! -d "${2}" ]; then + mkdir -p "${2}" + fi + if [ -f "${HOME}/.steam/steamcmd/linux32/steamclient.so" ]; then + cp "${HOME}/.steam/steamcmd/linux32/steamclient.so" "${2}/steamclient.so" + elif [ -f "${steamcmddir}/linux32/steamclient.so" ]; then + cp "${steamcmddir}/linux32/steamclient.so" "${2}/steamclient.so" + elif [ -f "${HOME}/.local/share/Steam/steamcmd/linux32/steamclient.so" ]; then + cp "${HOME}/.local/share/Steam/steamcmd/linux32/steamclient.so" "${2}/steamclient.so" + fi + fn_fix_msg_end + fi + elif [ "$1" == "64" ]; then + # steamclient.so x86_64 fix. + if [ ! -f "${2}/steamclient.so" ]; then + fixname="steamclient.so x86_64" + fn_fix_msg_start + if [ ! -d "${2}" ]; then + mkdir -p "${2}" + fi + if [ -f "${HOME}/.steam/steamcmd/linux64/steamclient.so" ]; then + cp "${HOME}/.steam/steamcmd/linux64/steamclient.so" "${2}/steamclient.so" + elif [ -f "${steamcmddir}/linux64/steamclient.so" ]; then + cp "${steamcmddir}/linux64/steamclient.so" "${2}/steamclient.so" + elif [ -f "${HOME}/.local/share/Steam/steamcmd/linux64/steamclient.so" ]; then + cp "${HOME}/.local/share/Steam/steamcmd/linux64/steamclient.so" "${2}/steamclient.so" + fi + fn_fix_msg_end + fi + fi +} + +# Helps fix: [S_API FAIL] SteamAPI_Init() failed; unable to locate a running instance of Steam,or a local steamclient.so. +steamsdk64="${HOME}/.steam/sdk64" +steamclientsdk64="${steamsdk64}/steamclient.so" +# remove any old unlinked versions of steamclient.so +if [ -f "${steamclientsdk64}" ]; then + if [ "$(stat -c '%h' "${steamclientsdk64}")" -eq 1 ]; then + fixname="steamclient.so sdk64 - remove old file" + fn_fix_msg_start + rm -f "${steamclientsdk64}" + fn_fix_msg_end + fi +fi + +# place new hardlink for the file to the disk +if [ ! -f "${steamclientsdk64}" ]; then + fixname="steamclient.so sdk64 hardlink" + fn_fix_msg_start + if [ ! -d "${steamsdk64}" ]; then + mkdir -p "${steamsdk64}" + fi + if [ -f "${HOME}/.steam/steamcmd/linux64/steamclient.so" ]; then + ln "${HOME}/.steam/steamcmd/linux64/steamclient.so" "${steamclientsdk64}" + elif [ -f "${steamcmddir}/linux64/steamclient.so" ]; then + ln "${steamcmddir}/linux64/steamclient.so" "${steamclientsdk64}" + elif [ -f "${HOME}/.local/share/Steam/steamcmd/linux64/steamclient.so" ]; then + ln "${HOME}/.local/share/Steam/steamcmd/linux64/steamclient.so" "${steamclientsdk64}" + else + fn_print_fail_nl "Could not copy any steamclient.so 64bit for the gameserver" + fi + fn_fix_msg_end +fi + +# Helps fix: [S_API FAIL] SteamAPI_Init() failed; unable to locate a running instance of Steam,or a local steamclient.so. +steamsdk32="${HOME}/.steam/sdk32" +steamclientsdk32="${HOME}/.steam/sdk32/steamclient.so" +if [ -f "${steamclientsdk32}" ]; then + if [ " $(stat -c '%h' "${steamclientsdk32}")" -eq 1 ]; then + fixname="steamclient.so sdk32 - remove old file" + fn_fix_msg_start + rm -f "${steamclientsdk32}" + fn_fix_msg_end + fi +fi + +# place new hardlink for the file to the disk +if [ ! -f "${steamclientsdk32}" ]; then + fixname="steamclient.so sdk32 link" + fn_fix_msg_start + if [ ! -d "${steamsdk32}" ]; then + mkdir -p "${steamsdk32}" + fi + if [ -f "${HOME}/.steam/steamcmd/linux32/steamclient.so" ]; then + ln "${HOME}/.steam/steamcmd/linux32/steamclient.so" "${steamclientsdk32}" + elif [ -f "${steamcmddir}/linux32/steamclient.so" ]; then + ln "${steamcmddir}/linux32/steamclient.so" "${steamclientsdk32}" + elif [ -f "${HOME}/.local/share/Steam/steamcmd/linux32/steamclient.so" ]; then + ln "${HOME}/.local/share/Steam/steamcmd/linux32/steamclient.so" "${steamclientsdk32}" + else + fn_print_fail_nl "Could not copy any steamclient.so 32bit for the gameserver" + fi + fn_fix_msg_end +fi + +# steamclient.so fixes +if [ "${shortname}" == "bo" ]; then + fn_fix_steamclient_so "32" "${serverfiles}/BODS_Data/Plugins/x86" + fn_fix_steamclient_so "64" "${serverfiles}/BODS_Data/Plugins/x86_64" +elif [ "${shortname}" == "cmw" ]; then + fn_fix_steamclient_so "32" "${executabledir}/lib" +elif [ "${shortname}" == "cs" ]; then + fn_fix_steamclient_so "32" "${serverfiles}" +elif [ "${shortname}" == "col" ]; then + fn_fix_steamclient_so "64" "${serverfiles}" +elif [ "${shortname}" == "ins" ]; then + fn_fix_steamclient_so "32" "${serverfiles}/bin" +elif [ "${shortname}" == "pz" ]; then + fn_fix_steamclient_so "32" "${serverfiles}/linux32" + fn_fix_steamclient_so "64" "${serverfiles}/linux64" +elif [ "${shortname}" == "pvr" ]; then + fn_fix_steamclient_so "64" "${executabledir}" +elif [ "${shortname}" == "ss3" ]; then + fn_fix_steamclient_so "32" "${serverfiles}/Bin" +elif [ "${shortname}" == "tu" ]; then + fn_fix_steamclient_so "64" "${executabledir}" +elif [ "${shortname}" == "unt" ]; then + fn_fix_steamclient_so "64" "${serverfiles}" +elif [ "${shortname}" == "wurm" ]; then + fn_fix_steamclient_so "64" "${serverfiles}/nativelibs" +fi diff --git a/lgsm/modules/fix_terraria.sh b/lgsm/modules/fix_terraria.sh new file mode 100644 index 0000000..dc734b6 --- /dev/null +++ b/lgsm/modules/fix_terraria.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# LinuxGSM fix_terraria.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Terraria. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +export TERM=xterm diff --git a/lgsm/modules/fix_tf2.sh b/lgsm/modules/fix_tf2.sh new file mode 100644 index 0000000..fe7de82 --- /dev/null +++ b/lgsm/modules/fix_tf2.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# LinuxGSM fix_tf2.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Team Fortress 2. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Fixes: Team Fortress 2 Segmentation fault for Red-Hat Distros #2062. +if [ -f "/etc/redhat-release" ] && [ ! -f "${serverfiles}/bin/libcurl-gnutls.so.4" ]; then + fixname="libcurl-gnutls.so.4" + fn_fix_msg_start + ln -s "/usr/lib/libcurl.so.4" "${serverfiles}/bin/libcurl-gnutls.so.4" + fn_fix_msg_end +fi diff --git a/lgsm/modules/fix_ts3.sh b/lgsm/modules/fix_ts3.sh new file mode 100644 index 0000000..5c80aa1 --- /dev/null +++ b/lgsm/modules/fix_ts3.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# LinuxGSM fix_ts3.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Teamspeak 3. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Creates a blank ts3server.ini if it does not exist. +if [ ! -f "${servercfgfullpath}" ]; then + fixname="create blank ${servercfg}" + fn_fix_msg_start + touch "${servercfgfullpath}" + fn_fix_msg_end +fi + +# Accept license. +if [ ! -f "${executabledir}/.ts3server_license_accepted" ]; then + install_eula.sh +fi + +# Fixes: makes libmariadb2 available #1924. +if [ ! -f "${serverfiles}/libmariadb.so.2" ]; then + fixname="libmariadb.so.2" + fn_fix_msg_start + cp "${serverfiles}/redist/libmariadb.so.2" "${serverfiles}/libmariadb.so.2" + fn_fix_msg_end +fi + +# Fixes: failed to register local accounting service: No such file or directory. +accountingfile="/dev/shm/7gbhujb54g8z9hu43jre8" +if [ -f "${accountingfile}" ] && [ "${status}" == "0" ]; then + # Check permissions for the file if the current user owns it, if not exit. + if [ "$(stat -c %U ${accountingfile})" == "$(whoami)" ]; then + fixname="Delete file ${accountingfile}" + fn_fix_msg_start + rm -f "${accountingfile}" + fn_fix_msg_end + # file is not owned by the current user and needs to be deleted manually. + else + fn_print_error_nl "File ${accountingfile} is not owned by $(whoami) and needs to be deleted manually" + fn_script_log_fail "File ${accountingfile} is not owned by $(whoami) and needs to be deleted manually" + core_exit.sh + fi +fi diff --git a/lgsm/modules/fix_unt.sh b/lgsm/modules/fix_unt.sh new file mode 100644 index 0000000..9afdce3 --- /dev/null +++ b/lgsm/modules/fix_unt.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# LinuxGSM fix_rust.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Unturned. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}:${serverfiles}/Unturned_Headless_Data/Plugins/x86_64" diff --git a/lgsm/modules/fix_ut.sh b/lgsm/modules/fix_ut.sh new file mode 100644 index 0000000..ded65dd --- /dev/null +++ b/lgsm/modules/fix_ut.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# LinuxGSM fix_ut.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Unreal Tournament. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +#Set Binary Executable +echo -e "chmod +x ${executabledir}/${executable}" +chmod +x "${executabledir}/${executable}" +fn_sleep_time diff --git a/lgsm/modules/fix_ut2k4.sh b/lgsm/modules/fix_ut2k4.sh new file mode 100644 index 0000000..5da1eee --- /dev/null +++ b/lgsm/modules/fix_ut2k4.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# LinuxGSM fix_ut2k4.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Unreal Tournament 2004. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +echo -e "applying WebAdmin ut2003.css fix." +echo -e "http://forums.tripwireinteractive.com/showpost.php?p=585435&postcount=13" +sed -i 's/none}/none;/g' "${serverfiles}/Web/ServerAdmin/ut2003.css" +sed -i 's/underline}/underline;/g' "${serverfiles}/Web/ServerAdmin/ut2003.css" +fn_sleep_time +echo -e "applying WebAdmin CharSet fix." +echo -e "http://forums.tripwireinteractive.com/showpost.php?p=442340&postcount=1" +sed -i 's/CharSet="iso-8859-1"/CharSet="utf-8"/g' "${systemdir}/UWeb.int" +fn_sleep_time +echo -e "applying server name fix." +fn_sleep_time +echo -e "forcing server restart." +fn_sleep_time +exitbypass=1 +command_start.sh +fn_firstcommand_reset +fn_sleep_time_5 +exitbypass=1 +command_stop.sh +fn_firstcommand_reset +exitbypass=1 +command_start.sh +fn_firstcommand_reset +fn_sleep_time_5 +exitbypass=1 +command_stop.sh +fn_firstcommand_reset diff --git a/lgsm/modules/fix_ut3.sh b/lgsm/modules/fix_ut3.sh new file mode 100644 index 0000000..386833e --- /dev/null +++ b/lgsm/modules/fix_ut3.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# LinuxGSM fix_ut2.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Unreal Tournament 3. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +startparameters="server VCTF-Suspense?Game=UTGameContent.UTVehicleCTFGame_Content?bIsDedicated=true?bIsLanMatch=false?bUsesStats=false?bShouldAdvertise=false?PureServer=1?bAllowJoinInProgress=true?ConfigSubDir=${selfname} -port=${port} -queryport=${queryport} -multihome=${ip} -nohomedir -unattended -log=${gamelog}" + +fn_print_information "starting ${gamename} server to generate configs." +exitbypass=1 +command_start.sh +fn_firstcommand_reset +fn_sleep_time_10 +exitbypass=1 +command_stop.sh +fn_firstcommand_reset diff --git a/lgsm/modules/fix_vh.sh b/lgsm/modules/fix_vh.sh new file mode 100644 index 0000000..c642a1a --- /dev/null +++ b/lgsm/modules/fix_vh.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# LinuxGSM fix_rust.sh module +# Author: Alasdair Haig +# Website: https://linuxgsm.com +# Description: Resolves issues with Valheim. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +export LD_LIBRARY_PATH=./linux64:$LD_LIBRARY_PATH + +modsdir="${lgsmdir}/mods" +modsinstalledlistfullpath="${modsdir}/installed-mods.txt" +if [ -f "${modsinstalledlistfullpath}" ]; then + # special check if Valheim Plus is installed + if grep -qE "^valheimplus" "${modsinstalledlistfullpath}"; then + if ! grep -qE "^executable=\"./start_server_bepinex.sh\"" "${configdirserver}/${selfname}.cfg"; then + echo 'executable="./start_server_bepinex.sh"' >> "${configdirserver}/${selfname}.cfg" + executable="./start_server_bepinex.sh" + fi + fi + # special exports for BepInEx if installed + if grep -qE "^bepinexvh" "${modsinstalledlistfullpath}"; then + fn_print_info_nl "BepInEx install detected, applying start exports" + fn_script_log_info "BepInEx install detected, applying start exports" + # exports for BepInEx framework from script start_server_bepinex.sh + export DOORSTOP_ENABLE=TRUE + export DOORSTOP_INVOKE_DLL_PATH=./BepInEx/core/BepInEx.Preloader.dll + export DOORSTOP_CORLIB_OVERRIDE_PATH=./unstripped_corlib + + export LD_LIBRARY_PATH="./doorstop_libs:${LD_LIBRARY_PATH}" + export LD_PRELOAD="libdoorstop_x64.so:${LD_PRELOAD}" + + export SteamAppId=892970 + fi +fi diff --git a/lgsm/modules/fix_wurm.sh b/lgsm/modules/fix_wurm.sh new file mode 100644 index 0000000..b6f5762 --- /dev/null +++ b/lgsm/modules/fix_wurm.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# LinuxGSM fix_wurm.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Wurm Unlimited. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# First run requires start with no parms. +# After first run new dirs are created. +if [ ! -d "${serverfiles}/Creative" ]; then + fixname="Copy Creative directory" + fn_fix_msg_start + cp -R "${serverfiles}/dist/Creative" "${serverfiles}/Creative" + fn_fix_msg_end +fi + +if [ ! -d "${serverfiles}/Adventure" ]; then + fixname="Copy Adventure directory" + fn_fix_msg_start + cp -R "${serverfiles}/dist/Adventure" "${serverfiles}/Adventure" + fn_fix_msg_end +fi diff --git a/lgsm/modules/fix_zmr.sh b/lgsm/modules/fix_zmr.sh new file mode 100644 index 0000000..a88d82f --- /dev/null +++ b/lgsm/modules/fix_zmr.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# LinuxGSM fix_sfc.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Resolves issues with Zombie Master: Reborn. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +if [ ! -f "${serverfiles}/bin/datacache.so" ]; then + ln -s "${serverfiles}/bin/datacache_srv.so" "${serverfiles}/bin/datacache.so" +fi + +if [ ! -f "${serverfiles}/bin/dedicated.so" ]; then + ln -s "${serverfiles}/bin/dedicated_srv.so" "${serverfiles}/bin/dedicated.so" +fi + +if [ ! -f "${serverfiles}/bin/engine.so" ]; then + ln -s "${serverfiles}/bin/engine_srv.so" "${serverfiles}/bin/engine.so" +fi + +if [ ! -f "${serverfiles}/bin/materialsystem.so" ]; then + ln -s "${serverfiles}/bin/materialsystem_srv.so" "${serverfiles}/bin/materialsystem.so" +fi + +if [ ! -f "${serverfiles}/bin/replay.so" ]; then + ln -s "${serverfiles}/bin/replay_srv.so" "${serverfiles}/bin/replay.so" +fi + +if [ ! -f "${serverfiles}/bin/shaderapiempty.so" ]; then + ln -s "${serverfiles}/bin/shaderapiempty_srv.so" "${serverfiles}/bin/shaderapiempty.so" +fi + +if [ ! -f "${serverfiles}/bin/soundemittersystem.so" ]; then + ln -s "${serverfiles}/bin/soundemittersystem_srv.so" "${serverfiles}/bin/soundemittersystem.so" +fi + +if [ ! -f "${serverfiles}/bin/studiorender.so" ]; then + ln -s "${serverfiles}/bin/studiorender_srv.so" "${serverfiles}/bin/studiorender.so" +fi + +if [ ! -f "${serverfiles}/bin/vphysics.so" ]; then + ln -s "${serverfiles}/bin/vphysics_srv.so" "${serverfiles}/bin/vphysics.so" +fi + +if [ ! -f "${serverfiles}/bin/scenefilecache.so" ]; then + ln -s "${serverfiles}/bin/scenefilecache_srv.so" "${serverfiles}/bin/scenefilecache.so" +fi diff --git a/lgsm/modules/info_distro.sh b/lgsm/modules/info_distro.sh new file mode 100644 index 0000000..a5607ef --- /dev/null +++ b/lgsm/modules/info_distro.sh @@ -0,0 +1,290 @@ +#!/bin/bash +# LinuxGSM info_distro.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Variables providing useful info on the Operating System such as disk and performace info. +# Used for command_details.sh, command_debug.sh and alert.sh. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +### Game Server pid +if [ "${status}" == "1" ]; then + gameserverpid="$(tmux -L "${socketname}" list-sessions -F "#{session_name} #{pane_pid}" | grep "^${sessionname} " | awk '{print $NF}')" + if [ "${engine}" == "source" ]; then + srcdslinuxpid="$(ps -ef | grep -v grep | grep "${gameserverpid}" | grep srcds_linux | awk '{print $2}')" + elif [ "${engine}" == "goldsrc" ]; then + hldslinuxpid="$(ps -ef | grep -v grep | grep "${gameserverpid}" | grep hlds_linux | awk '{print $2}')" + fi +fi +### Distro information + +## Distro +# Returns architecture, kernel and distro/os. +arch="$(uname -m)" +kernel="$(uname -r)" + +# Distro Name - Ubuntu 16.04 LTS +# Distro Version - 16.04 +# Distro ID - ubuntu +# Distro Codename - xenial + +# Gathers distro info from various sources filling in missing gaps. +distro_info_array=(os-release lsb_release hostnamectl debian_version redhat-release) +for distro_info in "${distro_info_array[@]}"; do + if [ -f "/etc/os-release" ] && [ "${distro_info}" == "os-release" ]; then + distroname="$(grep "PRETTY_NAME" /etc/os-release | awk -F\= '{gsub(/"/,"",$2);print $2}')" + distroversion="$(grep "VERSION_ID" /etc/os-release | awk -F\= '{gsub(/"/,"",$2);print $2}')" + # Special var for rhel like distros to removed point in number e.g 8.4 to just 8. + distroversionrh="$(sed -nr 's/^VERSION_ID="([0-9]*).+?"/\1/p' /etc/os-release)" + distroid="$(grep "ID=" /etc/os-release | grep -v _ID | awk -F\= '{gsub(/"/,"",$2);print $2}')" + distroidlike="$(grep "ID_LIKE=" /etc/os-release | grep -v _ID | awk -F\= '{gsub(/"/,"",$2);print $2}')" + distrocodename="$(grep "VERSION_CODENAME" /etc/os-release | awk -F\= '{gsub(/"/,"",$2);print $2}')" + elif [ "$(command -v lsb_release 2> /dev/null)" ] && [ "${distro_info}" == "lsb_release" ]; then + if [ -z "${distroname}" ]; then + distroname="$(lsb_release -sd)" + elif [ -z "${distroversion}" ]; then + distroversion="$(lsb_release -sr)" + elif [ -z "${distroid}" ]; then + distroid="$(lsb_release -si)" + elif [ -z "${distrocodename}" ]; then + distrocodename="$(lsb_release -sc)" + fi + elif [ "$(command -v hostnamectl 2> /dev/null)" ] && [ "${distro_info}" == "hostnamectl" ]; then + if [ -z "${distroname}" ]; then + distroname="$(hostnamectl | grep "Operating System" | sed 's/Operating System: //g')" + fi + elif [ -f "/etc/debian_version" ] && [ "${distro_info}" == "debian_version" ]; then + if [ -z "${distroname}" ]; then + distroname="Debian $(cat /etc/debian_version)" + elif [ -z "${distroversion}" ]; then + distroversion="$(cat /etc/debian_version)" + elif [ -z "${distroid}" ]; then + distroid="debian" + fi + elif [ -f "/etc/redhat-release" ] && [ "${distro_info}" == "redhat-release" ]; then + if [ -z "${distroname}" ]; then + distroname="$(cat /etc/redhat-release)" + elif [ -z "${distroversion}" ]; then + distroversion="$(rpm -qa \*-release | grep -Ei "oracle|redhat|centos|fedora" | cut -d"-" -f3)" + elif [ -z "${distroid}" ]; then + distroid="$(awk '{print $1}' /etc/redhat-release)" + fi + fi +done + +# Get virtual environment type. +if [ "$(command -v systemd-detect-virt 2> /dev/null)" ]; then + virtualenvironment="$(systemd-detect-virt)" +fi + +# Some RHEL based distros use 8.4 instead of just 8. +if [[ "${distroidlike}" == *"rhel"* ]] || [ "${distroid}" == "rhel" ]; then + distroversioncsv="${distroversionrh}" +else + distroversioncsv="${distroversion}" +fi + +# Check if distro supported by distro vendor. +if [ "$(command -v distro-info 2> /dev/null)" ]; then + distrosunsupported="$(distro-info --unsupported)" + distrosunsupported_array=("${distrosunsupported}") + for distrounsupported in "${distrosunsupported_array[@]}"; do + if [ "${distrounsupported}" == "${distrocodename}" ]; then + distrosupport=unsupported + break + else + distrosupport=supported + fi + done +else + distrosupport=unknown +fi + +## Glibc version +# e.g: 1.17 +glibcversion="$(ldd --version | sed -n '1s/.* //p')" + +## tmux version +# e.g: tmux 1.6 +if [ ! "$(command -V tmux 2> /dev/null)" ]; then + tmuxv="${red}NOT INSTALLED!${default}" + tmuxvdigit="0" +else + tmuxvdigit="$(tmux -V | sed "s/tmux //" | sed -n '1 p' | tr -cd '[:digit:]')" + if [ "${tmuxvdigit}" -lt "16" ]; then + tmuxv="$(tmux -V) (>= 1.6 required for console log)" + else + tmuxv="$(tmux -V)" + fi +fi + +if [ "$(command -V java 2> /dev/null)" ]; then + javaversion="$(java -version 2>&1 | grep "version")" +fi + +if [ "$(command -v mono 2> /dev/null)" ]; then + monoversion="$(mono --version 2>&1 | grep -Po '(?<=version )\d')" +fi + +if [ "$(command -v dotnet 2> /dev/null)" ]; then + dotnetversion="$(dotnet --list-runtimes | grep -E 'Microsoft\.NETCore\.App' | awk '{print $2}')" +fi + +## Uptime +uptime="$(< /proc/uptime)" +uptime=${uptime/[. ]*/} +minutes="$((uptime / 60 % 60))" +hours="$((uptime / 60 / 60 % 24))" +days="$((uptime / 60 / 60 / 24))" + +### Performance information + +## Average server load +load="$(uptime | awk -F 'load average: ' '{ print $2 }')" + +## CPU information +cpumodel="$(awk -F: '/model name/ {name=$2} END {print name}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//')" +cpucores="$(awk -F: '/model name/ {core++} END {print core}' /proc/cpuinfo)" +cpufreqency="$(awk -F: '/cpu MHz/ {freq=$2} END {print freq}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//')" +# CPU usage of the game server pid +if [ -n "${gameserverpid}" ]; then + cpuused="$(ps --forest -o pcpu -g "${gameserverpid}" | awk '{s+=$1} END {print s}')" + cpuusedmhz="$(echo "${cpufreqency} * ${cpuused} / 100" | bc)" +fi + +## Memory information +# Available RAM and swap. + +# Newer distros can use numfmt to give more accurate results. +if [ "$(command -v numfmt 2> /dev/null)" ]; then + # Issue #2005 - Kernel 3.14+ contains MemAvailable which should be used. All others will be calculated. + + # get the raw KB values of these fields. + physmemtotalkb="$(grep MemTotal /proc/meminfo | awk '{print $2}')" + physmemfreekb="$(grep ^MemFree /proc/meminfo | awk '{print $2}')" + physmembufferskb="$(grep ^Buffers /proc/meminfo | awk '{print $2}')" + physmemcachedkb="$(grep ^Cached /proc/meminfo | awk '{print $2}')" + physmemreclaimablekb="$(grep ^SReclaimable /proc/meminfo | awk '{print $2}')" + + # check if MemAvailable Exists. + if grep -q ^MemAvailable /proc/meminfo; then + physmemactualfreekb="$(grep ^MemAvailable /proc/meminfo | awk '{print $2}')" + else + physmemactualfreekb="$((physmemfreekb + physmembufferskb + physmemcachedkb))" + fi + + # Available RAM and swap. + physmemtotalmb="$((physmemtotalkb / 1024))" + physmemtotal="$(numfmt --to=iec --from=iec --suffix=B "${physmemtotalkb}K")" + physmemfree="$(numfmt --to=iec --from=iec --suffix=B "${physmemactualfreekb}K")" + physmemused="$(numfmt --to=iec --from=iec --suffix=B "$((physmemtotalkb - physmemfreekb - physmembufferskb - physmemcachedkb - physmemreclaimablekb))K")" + physmemavailable="$(numfmt --to=iec --from=iec --suffix=B "${physmemactualfreekb}K")" + physmemcached="$(numfmt --to=iec --from=iec --suffix=B "$((physmemcachedkb + physmemreclaimablekb))K")" + + swaptotal="$(numfmt --to=iec --from=iec --suffix=B "$(grep ^SwapTotal /proc/meminfo | awk '{print $2}')K")" + swapfree="$(numfmt --to=iec --from=iec --suffix=B "$(grep ^SwapFree /proc/meminfo | awk '{print $2}')K")" + swapused="$(numfmt --to=iec --from=iec --suffix=B "$(($(grep ^SwapTotal /proc/meminfo | awk '{print $2}') - $(grep ^SwapFree /proc/meminfo | awk '{print $2}')))K")" + # RAM usage of the game server pid + # MB + if [ "${gameserverpid}" ]; then + memused="$(ps --forest -o rss -g "${gameserverpid}" | awk '{s+=$1} END {print s}' | awk '{$1/=1024;printf "%.0f",$1}{print $2}')" + # % + pmemused="$(ps --forest -o %mem -g "${gameserverpid}" | awk '{s+=$1} END {print s}')" + fi +else + # Older distros will need to use free. + # Older versions of free do not support -h option. + if [ "$( + free -h > /dev/null 2>&1 + echo $? + )" -ne "0" ]; then + humanreadable="-m" + else + humanreadable="-h" + fi + physmemtotalmb="$(free -m | awk '/Mem:/ {print $2}')" + physmemtotal="$(free ${humanreadable} | awk '/Mem:/ {print $2}')" + physmemfree="$(free ${humanreadable} | awk '/Mem:/ {print $4}')" + physmemused="$(free ${humanreadable} | awk '/Mem:/ {print $3}')" + + oldfree="$(free ${humanreadable} | awk '/cache:/')" + if [ "${oldfree}" ]; then + physmemavailable="n/a" + physmemcached="n/a" + else + physmemavailable="$(free ${humanreadable} | awk '/Mem:/ {print $7}')" + physmemcached="$(free ${humanreadable} | awk '/Mem:/ {print $6}')" + fi + + swaptotal="$(free ${humanreadable} | awk '/Swap:/ {print $2}')" + swapused="$(free ${humanreadable} | awk '/Swap:/ {print $3}')" + swapfree="$(free ${humanreadable} | awk '/Swap:/ {print $4}')" +fi + +### Disk information + +## Available disk space on the partition. +filesystem="$(LC_ALL=C df -hP "${rootdir}" | tail -n 1 | awk '{print $1}')" +totalspace="$(LC_ALL=C df -hP "${rootdir}" | tail -n 1 | awk '{print $2}')" +usedspace="$(LC_ALL=C df -hP "${rootdir}" | tail -n 1 | awk '{print $3}')" +availspace="$(LC_ALL=C df -hP "${rootdir}" | tail -n 1 | awk '{print $4}')" + +## LinuxGSM used space total. +rootdirdu="$(du -sh "${rootdir}" 2> /dev/null | awk '{print $1}')" +if [ -z "${rootdirdu}" ]; then + rootdirdu="0M" +fi + +## LinuxGSM used space in serverfiles dir. +serverfilesdu="$(du -sh "${serverfiles}" 2> /dev/null | awk '{print $1}')" +if [ -z "${serverfilesdu}" ]; then + serverfilesdu="0M" +fi + +## LinuxGSM used space total minus backup dir. +rootdirduexbackup="$(du -sh --exclude="${backupdir}" "${serverfiles}" 2> /dev/null | awk '{print $1}')" +if [ -z "${rootdirduexbackup}" ]; then + rootdirduexbackup="0M" +fi + +## Backup info +if [ -d "${backupdir}" ]; then + # Used space in backups dir. + backupdirdu="$(du -sh "${backupdir}" | awk '{print $1}')" + # If no backup dir, size is 0M. + if [ -z "${backupdirdu}" ]; then + backupdirdu="0M" + fi + + # number of backups set to 0 by default. + backupcount=0 + + # If there are backups in backup dir. + if [ "$(find "${backupdir}" -name "*.tar.gz" | wc -l)" -ne "0" ]; then + # number of backups. + backupcount="$(find "${backupdir}"/*.tar.gz | wc -l)" + # most recent backup. + lastbackup="$(ls -1t "${backupdir}"/*.tar.gz | head -1)" + # date of most recent backup. + lastbackupdate="$(date -r "${lastbackup}")" + # no of days since last backup. + lastbackupdaysago="$((($(date +'%s') - $(date -r "${lastbackup}" +'%s')) / 60 / 60 / 24))" + # size of most recent backup. + lastbackupsize="$(du -h "${lastbackup}" | awk '{print $1}')" + fi +fi + +# Network Interface name +netint=$(${ipcommand} -o addr | grep "${ip}" | awk '{print $2}') +netlink=$(${ethtoolcommand} "${netint}" 2> /dev/null | grep Speed | awk '{print $2}') + +# Sets the SteamCMD glibc requirement if the game server requirement is less or not required. +if [ "${appid}" ]; then + if [ "${glibc}" = "null" ] || [ -z "${glibc}" ] || [ "$(printf '%s\n'${glibc}'\n' "2.14" | sort -V | head -n 1)" != "2.14" ]; then + glibc="2.14" + fi +fi + +# Gather Port Info using ss +ssinfo="$(ss -tuplwn)" diff --git a/lgsm/modules/info_game.sh b/lgsm/modules/info_game.sh new file mode 100644 index 0000000..c75f1c2 --- /dev/null +++ b/lgsm/modules/info_game.sh @@ -0,0 +1,2506 @@ +#!/bin/bash +# LinuxGSM info_game.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Gathers various game server information. + +# shellcheck disable=SC2317 +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Config Type: ini +# Comment: ; or # +# Note: this ini filter does not filter by section. Can cause issues with some games that have multiple sections with the same variable name. +fn_info_game_ini() { + # sed is used to process the file. + # -n: Suppresses automatic printing of pattern space. + # /^\<'"${2}"'\>/: Matches lines starting with the word provided as the second argument ($2), considering it as a whole word. + # { s/.*= *"\?\([^"]*\)"\?/\1/p;q }: Command block executed for lines that match the pattern. + # - s/.*= *"\?\([^"]*\)"\?/\1/: Matches and captures the value after an equals sign (=), possibly surrounded by optional double quotes. + # - .*: Matches any characters before the equals sign. + # - = *"\?: Matches the equals sign and any optional spaces before an optional double quote. + # - \([^"]*\): Captures any characters that are not double quotes. + # - "\?: Matches an optional double quote. + # - /1: Replaces the entire matched pattern with the captured value. + # - p: Prints the modified line. + # - q: Quits processing after modifying and printing the line. + + if [ -n "${3}" ]; then + servercfgparse="${3}" + else + servercfgparse="${servercfgfullpath}" + fi + eval "${1}=\"$(sed -n '/^\<'"${2}"'\>/ { s/.*= *\"\?\([^"]*\)\"\?/\1/p;q }' "${servercfgparse}" | tr -d '\r')\"" + configtype="ini" +} + +# Config Type: Key Value Pairs (Equals Delimited) +# Comment: ; or # +fn_info_game_keyvalue_pairs_equals() { + # sed is used to process the file. + # -n: Suppresses automatic printing of pattern space. + # /^\<'"${2}"'\>/: Matches lines starting with the word provided as the second argument ($2), considering it as a whole word. + # { s/.*= *"\?\([^"]*\)"\?/\1/p;q }: Command block executed for lines that match the pattern. + # - s/.*= *"\?\([^"]*\)"\?/\1/: Matches and captures the value after an equals sign (=), possibly surrounded by optional double quotes. + # - .*: Matches any characters before the equals sign. + # - = *"\?: Matches the equals sign and any optional spaces before an optional double quote. + # - \([^"]*\): Captures any characters that are not double quotes. + # - "\?: Matches an optional double quote. + # - /1: Replaces the entire matched pattern with the captured value. + # - p: Prints the modified line. + # - q: Quits processing after modifying and printing the line. + + if [ -n "${3}" ]; then + servercfgparse="${3}" + else + servercfgparse="${servercfgfullpath}" + fi + eval "${1}=\"$(sed -n '/^\<'"${2}"'\>/ { s/.*= *\"\?\([^"]*\)\"\?/\1/p;q }' "${servercfgparse}" | tr -d '\r')\"" + configtype="keyvalue_pairs" +} + +# Config Type: Key Value Pairs (Space Delimited) +# Comment: ; or # +fn_info_game_keyvalue_pairs_space() { + # sed is used to process the file. + # -n: Suppresses automatic printing of pattern space. + # /^\<'"${2}"'\>/: Matches lines starting with the word provided as the second argument ($2), considering it as a whole word. + # { s/.* *"\?\([^"]*\)"\?/\1/p;q }: Command block executed for lines that match the pattern. + # - s/.* *"\?\([^"]*\)"\?/\1/: Matches and captures the value after an space ( ), possibly surrounded by optional double quotes. + # - .*: Matches any characters before the space. + # - = *"\?: Matches the space and any optional spaces before an optional double quote. + # - \([^"]*\): Captures any characters that are not double quotes. + # - "\?: Matches an optional double quote. + # - /1: Replaces the entire matched pattern with the captured value. + # - p: Prints the modified line. + # - q: Quits processing after modifying and printing the line. + + if [ -n "${3}" ]; then + servercfgparse="${3}" + else + servercfgparse="${servercfgfullpath}" + fi + eval "${1}=\"$(sed -n '/^\<'"${2}"'\>/ { s/.* *\"\?\([^"]*\)\"\?/\1/p;q }' "${servercfgparse}" | tr -d '\r')\"" + configtype="keyvalue_pairs" +} + +# Config Type: QuakeC +# Comment: // or /* */ +fn_info_game_quakec() { + # -n: Suppresses automatic printing of pattern space. + # /^[[:space:]]*\<'"${2}"'\>/: Matches lines starting with optional leading whitespace and the word provided as the second argument ($2), considering it as a whole word. + # { s/.* *"\?\([^"]*\)"\?/\1/p;q }: Command block executed for lines that match the pattern. + # - s/.* *"\?\([^"]*\)"\?/\1/: Matches and captures the value after any number of spaces, possibly surrounded by optional double quotes. + # - .*: Matches any characters before the spaces. + # - *: Matches any number of spaces. + # - "\?: Matches an optional double quote. + # - \([^"]*\): Captures any characters that are not double quotes. + # - "\?: Matches an optional double quote. + # - /1: Replaces the entire matched pattern with the captured value. + # - p: Prints the modified line. + # - q: Quits processing after modifying and printing the line. + + if [ -n "${3}" ]; then + servercfgparse="${3}" + else + servercfgparse="${servercfgfullpath}" + fi + eval "${1}=\"$(sed -n '/[[:space:]]\<'"${2}"'\>/ { s/.* *\"\?\([^"]*\)\"\?/\1/p;q }' "${servercfgparse}" | tr -d '\r')\"" + configtype="quakec" +} + +# Config Type: json +# Comment: // or /* */ +fn_info_game_json() { + if [ -n "${3}" ]; then + servercfgparse="${3}" + else + servercfgparse="${servercfgfullpath}" + fi + eval "${1}=\"$(jq -r "${2}" "${servercfgparse}")\"" + configtype="json" +} + +# Config Type: SQF +# Comment: // or /* */ +fn_info_game_sqf() { + # sed is the command itself, indicating that we want to use the sed utility. + # -n: Suppresses automatic printing of pattern space. + # /^\<'"${2}"'\>/: Matches lines starting with the word provided as the second argument ($2), considering it as a whole word. + # { s/.*= *"\?\([^"]*\)"\?/\1/;s/;$//p;q }: Command block executed for lines that match the pattern. + # - s/.*= *"\?\([^"]*\)"\?/\1/: Matches and captures the value after an equals sign (=), possibly surrounded by optional double quotes. + # - .*: Matches any characters before the equals sign. + # - = *"\?: Matches the equals sign and any optional spaces before an optional double quote. + # - \([^"]*\): Captures any characters that are not double quotes. + # - "\?: Matches an optional double quote. + # - /1: Replaces the entire matched pattern with the captured value. + # - s/;$//: Removes a semicolon (;) at the end of the line, if present. + # - p: Prints the modified line. + # - q: Quits processing after modifying and printing the line. + + if [ -n "${3}" ]; then + servercfgparse="${3}" + else + servercfgparse="${servercfgfullpath}" + fi + eval "${1}=\"$(sed -n '/^\<'"${2}"'\>/ { s/.*= *"\?\([^"]*\)"\?/\1/;s/;$//p;q }' "${servercfgparse}" | tr -d '\r')\"" + configtype="sqf" +} + +# Config Type: XML +# Comment: +fn_info_game_xml() { + if [ -n "${3}" ]; then + servercfgparse="${3}" + else + servercfgparse="${servercfgfullpath}" + fi + eval "${1}=\"$(xmllint --xpath "string(${2})" "${servercfgparse}")\"" + configtype="xml" +} + +# Config Type: Valve KeyValues +# Comment: // +fn_info_game_valve_keyvalues() { + # sed is used to process the file. + # -n: Suppresses automatic printing of pattern space. + # /^[[:space:]]*\<'"${2}"'\>/: Matches lines starting with optional leading whitespace and the word provided as the second argument ($2), considering it as a whole word. + # { s/.* *"\?\([^"]*\)"\?/\1/p;q }: Command block executed for lines that match the pattern. + # - s/.* *"\?\([^"]*\)"\?/\1/: Matches and captures the value after any number of spaces, possibly surrounded by optional double quotes. + # - .*: Matches any characters before the spaces. + # - *: Matches any number of spaces. + # - "\?: Matches an optional double quote. + # - \([^"]*\): Captures any characters that are not double quotes. + # - "\?: Matches an optional double quote. + # - /1: Replaces the entire matched pattern with the captured value. + # - p: Prints the modified line. + # - q: Quits processing after modifying and printing the line. + + if [ -n "${3}" ]; then + servercfgparse="${3}" + else + servercfgparse="${servercfgfullpath}" + fi + eval "${1}=\"$(sed -n '/^\<'"${2}"'\>/ { s/.* *"\([^"]*\)".*/\1/p;q }' "${servercfgparse}" | tr -d '\r')\"" + configtype="valve_keyvalues" +} + +# Config Type: Java properties +# Comment: # or ! +fn_info_game_java_properties() { + # sed is used to process the file. + # -n: Suppresses automatic printing of pattern space. + # /^\<'"${2}"'\>/: Matches lines starting with the word provided as the second argument ($2), considering it as a whole word. + # { s/.*= *"\?\([^"]*\)"\?/\1/p;q }: Command block executed for lines that match the pattern. + # - s/.*= *"\?\([^"]*\)"\?/\1/: Matches and captures the value after an equals sign (=), possibly surrounded by optional double quotes. + # - .*: Matches any characters before the equals sign. + # - = *"\?: Matches the equals sign and any optional spaces before an optional double quote. + # - \([^"]*\): Captures any characters that are not double quotes. + # - "\?: Matches an optional double quote. + # - /1: Replaces the entire matched pattern with the captured value. + # - p: Prints the modified line. + # - q: Quits processing after modifying and printing the line. + + if [ -n "${3}" ]; then + servercfgparse="${3}" + else + servercfgparse="${servercfgfullpath}" + fi + eval "${1}=\"$(sed -n '/^\<'"${2}"'\>/ { s/.*= *\"\?\([^"]*\)\"\?/\1/p;q }' "${servercfgparse}" | tr -d '\r')\"" + configtype="java" +} + +# Config Type: ini +# Comment: ; or # +# Note: this ini filter does not filter by section. Can cause issues with some games that have multiple sections with the same variable name. +fn_info_game_lua() { + # - The '-n' option suppresses automatic printing of pattern space. + # - The pattern '/^[[:space:]]*\<'"${2}"'\>/' matches lines that begin with optional whitespace characters, + # followed by the exact word specified by the second argument. + # - If the pattern matches, the following actions are performed within the curly braces: + # - 's/.*= *"\?\([^"]*\)"\?/\1/' extracts the value within double quotes after an equal sign (if present), + # removing any leading or trailing spaces. + # - 's#,.*##' removes everything after the first comma encountered. + # - 'p' prints the modified pattern space. + # - 'q' quits processing after printing the modified pattern space. + + if [ -n "${3}" ]; then + servercfgparse="${3}" + else + servercfgparse="${servercfgfullpath}" + fi + eval "${1}=\"$(sed -n '/^[[:space:]]*\<'"${2}"'\>/ { s/.*= *"\?\([^"]*\)"\?/\1/;s#,.*##;p;q }' "${servercfgparse}" | tr -d '\r')\"" + configtype="lua" +} + +# Config Type: custom (Project Cars) +# Comment: // +fn_info_game_pc_config() { + # sed is used to process the file. + # -n: Suppresses automatic printing of pattern space. + # /^\<'"${2}"'\>/: Matches lines starting with the word provided as the second argument ($2), considering it as a whole word. + # { s/.*: *"\?\([^"]*\)"\?/\1/p;q }: Command block executed for lines that match the pattern. + # - s/.*: *"\?\([^"]*\)"\?/\1/: Matches and captures the value after an equals sign (=), possibly surrounded by optional double quotes. + # - .*: Matches any characters before the equals sign. + # - : *"\?: Matches the : sign and any optional spaces before an optional double quote. + # - \([^"]*\): Captures any characters that are not double quotes. + # - "\?: Matches an optional double quote. + # - /1: Replaces the entire matched pattern with the captured value. + # - p: Prints the modified line. + # - q: Quits processing after modifying and printing the line. + + if [ -n "${3}" ]; then + servercfgparse="${3}" + else + servercfgparse="${servercfgfullpath}" + fi + eval "${1}=\"$(sed -n '/^\<'"${2}"'\>/ { s/.*: *\"\?\([^"]*\)\"\?/\1/p;q }' "${servercfgparse}" | tr -d '\r')\"" + configtype="pc_config" +} + +# Config Type: ini +# Parameters: false +# Comment: ; or # +# Example: NAME=SERVERNAME +# Filetype: ini +fn_info_game_ac() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "adminpassword" "ADMIN_PASSWORD" + fn_info_game_ini "httpport" "HTTP_PORT" + fn_info_game_ini "port" "TCP_PORT" + fn_info_game_ini "servername" "NAME" + fn_info_game_ini "serverpassword" "PASSWORD" + fi + adminpassword="${adminpassword:-NOT SET}" + httpport="${httpport:-0}" + port="${port:-0}" + queryport="${httpport:-0}" + servername="${servername:-NOT SET}" + serverpassword="${serverpassword:-NOT SET}" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: SessionName=SERVERNAME +# Filetype: ini +fn_info_game_ark() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "adminpassword" "ServerAdminPassword" + fn_info_game_ini "servername" "SessionName" + fn_info_game_ini "serverpassword" "ServerPassword" + fi + adminpassword="${adminpassword:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + rawport="$((port + 1))" + rconport="${rconport:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" +} + +# Config Type: SQF +# Parameters: true +# Comment: // or /* */ +# Example: serverName = "SERVERNAME"; +# Filetype: cfg +fn_info_game_arma3() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_sqf "adminpassword" "passwordAdmin" + fn_info_game_sqf "maxplayers" "maxPlayers" + fn_info_game_sqf "servername" "hostname" + fn_info_game_sqf "serverpassword" "password" + fi + adminpassword="${adminpassword:-"NOT SET"}" + battleeyeport="$((port + 4))" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="$((port + 1))" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + steamport="$((port + 2))" + voiceport="${port:-"0"}" + voiceunusedport="$((port + 3))" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: serverName=SERVERNAME +# Filetype: ini +fn_info_game_av() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "maxplayers" "maxPlayers" + fn_info_game_ini "port" "port" + fn_info_game_ini "rconport" "rconPort" + fn_info_game_ini "servername" "name" + fn_info_game_ini "serverpassword" "password" + fn_info_game_ini "rconpassword" "rconPassword" + if [ -n "${rconpassword}" ]; then + rconenabled="true" + fi + fi + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + + rconenabled="${rconenabled:-"false"}" + rconpassword="${rconpassword:-"NOT SET"}" + rconport="${rconport:-"0"}" + # queryport doesnt respond to any queries, using session only. + queryport=""$((port + 3))"" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + steamport="$((port + 21))" + steamworksport="$((port + 20))" +} + +# Config Type: ini unknown (Source?) +# Parameters: true +# Comment: # or // +# Example: ServerName=SERVERNAME +# Filetype: txt +fn_info_game_bo() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "maxplayers" "MaxPlayers" + fn_info_game_ini "port" "ServerPort" + fn_info_game_ini "servername" "ServerName" + fn_info_game_ini "serverpassword" "Password" + fi + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="$((port + 1))" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: ServerName=SERVERNAME +# Filetype: ini +fn_info_game_btl() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "adminpassword" "AdminPassword" + fn_info_game_ini "servername" "ServerName" + fi + adminpassword="${adminpassword:-"NOT SET"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + rconport="$((port + 2))" + servername="${servername:-"NOT SET"}" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: ServerName=SERVERNAME +# Filetype: ini +fn_info_game_cmw() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "maxplayers" "MaxPlayers" + fn_info_game_ini "servername" "ServerName" + fn_info_game_ini "serverpassword" "GamePassword" + fn_info_game_ini "rconport" "RConPort" "${servercfgdir}/DefaultGame.ini" + fi + defaultmap="${defaultmap:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + rconport="${rconport:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: iMaxClanMembers=1024 +# Filetype: ini +fn_info_game_dodr() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "maxplayers" "iMaxPlayers" + fi + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + servername="${servername:-"NOT SET"}" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: cluster_name = SERVERNAME +# Filetype: ini +fn_info_game_dst() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "port" "server_port" + fn_info_game_ini "steamauthport" "authentication_port" + fn_info_game_ini "steamport" "master_server_port" + fi + if [ -f "${clustercfgfullpath}" ]; then + fn_info_game_ini "maxplayers" "max_players" "${clustercfgfullpath}" + fn_info_game_ini "servername" "cluster_name" "${clustercfgfullpath}" + fn_info_game_ini "serverpassword" "cluster_password" "${clustercfgfullpath}" + fn_info_game_ini "tickrate" "tick_rate" "${clustercfgfullpath}" + fn_info_game_ini "masterport" "master_port" "${clustercfgfullpath}" + fn_info_game_ini "gamemode" "game_mode" "${clustercfgfullpath}" + fn_info_game_ini "configip" "bind_ip" "${clustercfgfullpath}" + fi + + cave="${cave:-"NOT SET"}" + cluster="${cluster:-"NOT SET"}" + configip="${configip:-"0.0.0.0"}" + gamemode="${gamemode:-"NOT SET"}" + master="${master:-"NOT SET"}" + masterport="${masterport:-"0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + shard="${shard:-"NOT SET"}" + sharding="${sharding:-"NOT SET"}" + steamauthport="${steamauthport:-"0"}" + steamport="${steamport:-"0"}" + tickrate="${tickrate:-"0"}" +} + +# Config Type: parameters +# Parameters: true +# Comment: ; or # +# Example: SessionName=SERVERNAME +# Filetype: ini +fn_info_game_hcu() { + defaultmap="${defaultmap:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + servername="${servername:-"NOT SET"}" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: ServerName=SERVERNAME +# Filetype: ini +fn_info_game_kf() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "adminpassword" "AdminPassword" + fn_info_game_ini "httpenabled" "bEnabled" + fn_info_game_ini "httppassword" "httppasswordword" + fn_info_game_ini "httpport" "ListenPort" + fn_info_game_ini "httpuser" "AdminName" + fn_info_game_ini "lanport" "LANServerPort" + fn_info_game_ini "maxplayers" "MaxPlayers" + fn_info_game_ini "port" "Port" + fn_info_game_ini "queryportgs" "QueryPort" + fn_info_game_ini "servername" "ServerName" + fn_info_game_ini "serverpassword" "GamePassword" + fi + adminpassword="${adminpassword:-"NOT SET"}" + defaultmap="${defaultmap:-"NOT SET"}" + httpenabled="${httpenabled:-"NOT SET"}" + httppassword="${adminpassword}" + httpport="${httpport:-"0"}" + httpuser="${httpuser:-"NOT SET"}" + lanport="${lanport:-"0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="$((port + 1))" + queryportgs="${queryportgs:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + steamport="28852" + steamworksport="20560" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: ServerName=SERVERNAME +# Filetype: ini +fn_info_game_kf2() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "adminpassword" "AdminPassword" + fn_info_game_ini "httpport" "ListenPort" "${servercfgdir}/KFWeb.ini" + fn_info_game_ini "port" "Port" + fn_info_game_ini "servername" "ServerName" + fn_info_game_ini "serverpassword" "GamePassword" + fn_info_game_ini "httpenabled" "bEnabled" + fn_info_game_ini "httppassword" "httppasswordword" + fi + adminpassword="${adminpassword:-"NOT SET"}" + defaultmap="${defaultmap:-"NOT SET"}" + httpport="${httpport:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + httpenabled="${httpenabled:-"NOT SET"}" + httppassword="${httppassword:-"NOT SET"}" + httpuser="Admin" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: ServerName=SERVERNAME +# Filetype: ini +fn_info_game_mh() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "servername" "ServerName" + fn_info_game_ini "serverpassword" "ServerPassword" + fn_info_game_ini "rconpassword" "AdminPassword" + fn_info_game_ini "maxplayers" "MaxSlots" + fi + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + rconpassword="${rconpassword:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + beaconport="${beaconport:-"0"}" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: ServerName="SERVERNAME" +# Filetype: cfg +fn_info_game_ps() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "servername" "ServerName" + fn_info_game_ini "maxplayers" "MaxPlayers" + fn_info_game_ini "reservedslots" "NumReservedSlots" + fn_info_game_ini "serverpassword" "ServerPassword" + fi + if [ -f "${servercfgdir}/Rcon.cfg" ]; then + fn_info_game_ini "rconpassword" "Password" "${servercfgdir}/Rcon.cfg" + fn_info_game_ini "rconport" "Port" "${servercfgdir}/Rcon.cfg" + fi + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + if [ -z "${queryport}" ]; then + queryport="${port:-"0"}" + fi + randommap="${randommap:-"NOT SET"}" + if [ -z "${rconpassword}" ] || [ "${#rconpassword}" == 1 ]; then + rconpassword="NOT SET" + fi + rconport="${rconport:-"0"}" + reservedslots="${reservedslots:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + tickrate="${tickrate:-"0"}" +} + +# Config Type: ini +# Parameters: false +# Comment: ; or # +# Example: ServerName=SERVERNAME +# Filetype: cfg +fn_info_game_pvr() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "servername" "ServerName" + fn_info_game_ini "maxplayers" "MaxPlayers" + fi + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + port401="$((port + 400))" + queryport="${port:-"0"}" + servername="${servername:-"NOT SET"}" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: PublicName=SERVERNAME +# Filetype: ini +fn_info_game_pz() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "maxplayers" "MaxPlayers" + fn_info_game_ini "port" "DefaultPort" + fn_info_game_ini "rconpassword" "RCONPassword" + fn_info_game_ini "servername" "PublicName" + fn_info_game_ini "serverpassword" "Password" + fn_info_game_ini "worldname" "Map" + + fi + adminpassword="${adminpassword:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port:-"0"}" + rconpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + worldname="${worldname:-"NOT SET"}" +} + +# Config Type: xml +# Comment: +# Example: SERVERNAME +# Filetype: xml +fn_info_game_st() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_xml "adminpassword" "/SettingData/AdminPassword" + fn_info_game_xml "maxplayers" "/SettingData/ServerMaxPlayers" + fn_info_game_xml "port" "/SettingData/GamePort" + fn_info_game_xml "queryport" "/SettingData/UpdatePort" + fn_info_game_xml "saveinterval" "/SettingData/SaveInterval" + fn_info_game_xml "servername" "/SettingData/ServerName" + fn_info_game_xml "serverpassword" "/SettingData/ServerPassword" + fi + adminpassword="${adminpassword:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + saveinterval="${saveinterval:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + worldname="${worldname:-"NOT SET"}" + worldtype="${worldtype:-"NOT SET"}" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: ServerName=SERVERNAME +# Filetype: ini +fn_info_game_stn() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "configip" "ServerIP" + fn_info_game_ini "port" "ServerPort" + fn_info_game_ini "servername" "ServerName" + fn_info_game_ini "serverpassword" "ServerPassword" + fi + configip="${configip:-"0.0.0.0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="$((port + 1))" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" +} + +# Config Type: parameters +# Parameters: true +# Comment: +# Example: -ServerName="SERVERNAME" +# Filetype: parameters +fn_info_game_tf() { + beaconport="${beaconport:-"0"}" + gamemode="${gamemode:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + saveinterval="${saveinterval:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + shutdownport="${shutdownport:-"0"}" + +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: ServerName=ServerName +# Filetype: ini +fn_info_game_ti() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "maxplayers" "MaxPlayerCount" + fn_info_game_ini "queueenabled" "bQueueEnabled" + fn_info_game_ini "queueport" "QueuePort" + fn_info_game_ini "rconenabled" "bRconEnabled" + fn_info_game_ini "rconpassword" "RconPassword" + fn_info_game_ini "rconport" "RconPort" + fn_info_game_ini "servername" "ServerName" + fn_info_game_ini "serverpassword" "ServerPassword" + fn_info_game_ini "serverpasswordenabled" "bServerPassword" + fi + maxplayers="${maxplayers:-"0"}" + queueenabled="${queueenabled:-"NOT SET"}" + queueport="${queueport:-"0"}" + rconenabled="${rconenabled:-"NOT SET"}" + rconpassword="${rconpassword:-"NOT SET"}" + rconport="${rconport:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + serverpasswordenabled="${serverpasswordenabled:-"NOT SET"}" +} + +# Config Type: ini +# Parameters: false +# Comment: ; or # +# Example: default_voice_port=9987 +# Filetype: ini +fn_info_game_ts3() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "configip" "voice_ip" + fn_info_game_ini "dbplugin" "dbplugin" + fn_info_game_ini "fileport" "filetransfer_port" + fn_info_game_ini "port" "default_voice_port" + fn_info_game_ini "queryhttpport" "query_http_port" + fn_info_game_ini "queryhttpsport" "query_https_port" + fn_info_game_ini "queryport" "query_port" + fn_info_game_ini "querysshport" "query_ssh_port" + fi + configip="${configip:-"0.0.0.0"}" + dbplugin="${dbplugin:-"NOT SET"}" + fileport="${fileport:-"0"}" + port="${port:-"0"}" + queryhttpport="${queryhttpport:-"0"}" + queryhttpsport="${queryhttpsport:-"0"}" + queryport="${queryport:-"0"}" + querysshport="${querysshport:-"0"}" + telnetport="${queryport}" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: ServerTitle=SERVERNAME +# Filetype: ini +fn_info_game_tu() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "maxplayers" "MaxPlayers" + fn_info_game_ini "servername" "ServerTitle" + fi + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + servername="${servername:-"NOT SET"}" + steamport="$((port + 1))" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: ServerName=SERVERNAME +# Filetype: ini +fn_info_game_ut99() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "adminpassword" "AdminPassword" + fn_info_game_ini "beaconport" "ServerBeaconPort" + fn_info_game_ini "port" "Port" + fn_info_game_ini "queryportgs" "OldQueryPortNumber" + fn_info_game_ini "servername" "ServerName" + fn_info_game_ini "serverpassword" "GamePassword" + fn_info_game_ini "httpenabled" "bEnabled" + fn_info_game_ini "httppassword" "AdminPassword" + fn_info_game_ini "httpport" "ListenPort" + fn_info_game_ini "httpuser" "AdminUserName" + fi + adminpassword="${adminpassword:-"NOT SET"}" + beaconport="${beaconport:-"0"}" + defaultmap="${defaultmap:-"NOT SET"}" + httpport="${httpport:-"0"}" + port="${port:-"0"}" + queryport="$((port + 1))" + queryportgs="${queryportgs:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + httpenabled="${httpenabled:-"0"}" + httppassword="${httppassword:-"NOT SET"}" + httpuser="${httpuser:-"NOT SET"}" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: ServerName=SERVERNAME +# Filetype: ini +fn_info_game_ut3() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "adminpassword" "AdminPassword" + fn_info_game_ini "maxplayers" "MaxPlayers" + fn_info_game_ini "servername" "ServerName" + fn_info_game_ini "serverpassword" "GamePassword" + fn_info_game_ini "httpenabled" "bEnabled" + fn_info_game_ini "httppassword" "AdminPassword" + fn_info_game_ini "httpport" "ListenPort" + fi + adminpassword="${adminpassword:-"NOT SET"}" + defaultmap="${defaultmap:-"NOT SET"}" + httpport="${httpport:-"0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + httpenabled="${httpenabled:-"0"}" + httppassword="${httppassword:-"NOT SET"}" + httpuser="Admin" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: ServerName=SERVERNAME +# Filetype: ini +fn_info_game_unreal2() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "adminpassword" "AdminPassword" + fn_info_game_ini "httpport" "ListenPort" + fn_info_game_ini "port" "Port" + fn_info_game_ini "queryportgs" "OldQueryPortNumber" + fn_info_game_ini "servername" "ServerName" + fn_info_game_ini "serverpassword" "GamePassword" + fn_info_game_ini "httpenabled" "bEnabled" + fn_info_game_ini "httpuser" "AdminName" + fi + adminpassword="${adminpassword:-"NOT SET"}" + defaultmap="${defaultmap:-"NOT SET"}" + httpport="${httpport:-"0"}" + port="${port:-"0"}" + queryport="$((port + 1))" + queryportgs="${queryportgs:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + httpenabled="${httpenabled:-"0"}" + httppassword="${adminpassword:-"NOT SET"}" + httpuser="${httpuser:-"NOT SET"}" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: ServerName="SERVERNAME" +# Filetype: ini +fn_info_game_ut() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "servername" "ServerName" + fi + defaultmap="${defaultmap:-"NOT SET"}" + gametype="${gametype:-"NOT SET"}" + port="${port:-"0"}" + queryport="$((port + 1))" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: ServerName=SERVERNAME +# Filetype: ini +fn_info_game_ut2k4() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "adminpassword" "AdminPassword" + fn_info_game_ini "httpport" "ListenPort" + fn_info_game_ini "lanport" "LANServerPort" + fn_info_game_ini "port" "Port" + fn_info_game_ini "queryportgs" "OldQueryPortNumber" + fn_info_game_ini "servername" "ServerName" + fn_info_game_ini "serverpassword" "GamePassword" + fn_info_game_ini "httpenabled" "bEnabled" + fn_info_game_ini "httpuser" "AdminName" + fi + adminpassword="${adminpassword:-"NOT SET"}" + defaultmap="${defaultmap:-"NOT SET"}" + httpport="${httpport:-"0"}" + lanport="${lanport:-"0"}" + port="${port:-"0"}" + queryport="$((port + 1))" + queryportgs="${queryportgs:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + httpenabled="${httpenabled:-"0"}" + httppassword="${adminpassword}" + httpuser="${httpuser:-"NOT SET"}" +} + +# Config Type: json +# Parameters: true +# Comment: // or /* */ +# Example: "name": "SERVERNAME", +# Filetype: json +fn_info_game_armar() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_json "adminpassword" ".game.passwordAdmin" + fn_info_game_json "configip" ".bindAddress" + fn_info_game_json "maxplayers" ".game.maxPlayers" + fn_info_game_json "port" ".bindPort" + fn_info_game_json "queryport" ".a2s.port" + fn_info_game_json "servername" ".game.name" + fn_info_game_json "serverpassword" ".game.password" + fi + adminpassword="${adminpassword:-"NOT SET"}" + battleeyeport="$((port + 4))" + configip="${configip:-"0.0.0.0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" +} + +# Config Type: con +# Parameters: true +# Comment: # or // +# Example: game.serverName "SERVERNAME" +# Filetype: con +fn_info_game_bf1942() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_keyvalue_pairs_space "configip" "game.serverIP" + fn_info_game_keyvalue_pairs_space "maxplayers" "game.serverMaxPlayers" + fn_info_game_keyvalue_pairs_space "port" "game.serverPort" + fn_info_game_keyvalue_pairs_space "servername" "game.serverName" + fn_info_game_keyvalue_pairs_space "serverpassword" "game.serverPassword" + fi + configip="${configip:-"0.0.0.0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="22000" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" +} + +# Config Type: con +# Parameters: true +# Comment: # or // +# Example: game.serverName "SERVERNAME" +# Filetype: con +fn_info_game_bfv() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_keyvalue_pairs_space "configip" "game.serverIp" + fn_info_game_keyvalue_pairs_space "maxplayers" "game.serverMaxPlayers" + fn_info_game_keyvalue_pairs_space "port" "game.serverPort" + fn_info_game_keyvalue_pairs_space "servername" "game.serverName" + fn_info_game_keyvalue_pairs_space "serverpassword" "game.serverPassword" + fi + configip="${configip:-"0.0.0.0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="22000" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" +} + +# Config Type: XML +# Parameters: false +# Comment: +# Example: +# Filetype: xml +fn_info_game_bt() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_xml "maxplayers" "/serversettings/@MaxPlayers" + fn_info_game_xml "port" "/serversettings/@port" + fn_info_game_xml "queryport" "/serversettings/@queryport" + fn_info_game_xml "servername" "/serversettings/@name" + fn_info_game_xml "serverpassword" "/serversettings/@password" + fn_info_game_xml "tickrate" "/serversettings/@TickRate" + fi + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + tickrate="${tickrate:-"0"}" +} + +# Config Type: json +# Parameters: false +# Comment: // or /* */ +# Example: "game_title":"SERVERNAME" +# Filetype: json +fn_info_game_cd() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_json "maxplayers" ".player_count" + fn_info_game_json "port" ".game_port" + fn_info_game_json "rconenabled" ".rcon" + fn_info_game_json "rconpassword" ".rcon_password" + fn_info_game_json "rconport" ".rcon_port" + fn_info_game_json "servername" ".game_title" + fn_info_game_json "steamport" ".steam_port_messages" + fi + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + rconenabled="${rconenabled:-"NOT SET"}" + rconpassword="${rconpassword:-"NOT SET"}" + rconport="${rconport:-"0"}" + servername="${servername:-"NOT SET"}" + steamport="${steamport:-"0"}" +} + +# Config Type: json +# Parameters: true +# Comment: // or /* */ +# Example: "worldName":"SERVERNAME" +# Filetype: json +fn_info_game_ck() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_json "servername" ".worldName" + fn_info_game_json "maxplayers" ".maxNumberPlayers" + fi + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="$((port + 1))" + servername="${servername:-"NOT SET"}" +} + +# Config Type: QuakeC +# Parameters: true +# Comment: // or /* */ +# Example: set sv_hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_cod() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_quakec "rconpassword" "rconpassword" + fn_info_game_quakec "servername" "sv_hostname" + fi + defaultmap="${defaultmap:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port}" + rconpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" +} + +# Config Type: QuakeC +# Parameters: true +# Comment: // or /* */ +# Example: set sv_hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_coduo() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_quakec "rconpassword" "rconpassword" + fn_info_game_quakec "servername" "sv_hostname" + fi + defaultmap="${defaultmap:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port}" + rconpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" +} + +# Config Type: QuakeC +# Parameters: true +# Comment: // or /* */ +# Example: set sv_hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_cod2() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_quakec "rconpassword" "rconpassword" + fn_info_game_quakec "servername" "sv_hostname" + fi + defaultmap="${defaultmap:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port}" + rconpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" +} + +# Config Type: QuakeC +# Parameters: true +# Comment: // or /* */ +# Example: set sv_hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_cod4() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_quakec "rconpassword" "rcon_password" + fn_info_game_quakec "servername" "sv_hostname" + fi + defaultmap="${defaultmap:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port}" + rconpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" +} + +# Config Type: QuakeC +# Parameters: true +# Comment: // or /* */ +# Example: set sv_hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_codwaw() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_quakec "rconpassword" "rcon_password" + fn_info_game_quakec "servername" "sv_hostname" + fi + defaultmap="${defaultmap:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port}" + rconpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" +} + +# Config Type: json +# Parameters: false +# Comment: // or /* */ +# Example: "ServerName": "SERVERNAME" +# Filetype: json +fn_info_game_col() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_json "configip" ".ServerSettings.ServerIP" + fn_info_game_json "maxplayers" ".ServerSettings.MaxPlayerCount" + fn_info_game_json "port" ".ServerSettings.ServerGamePort" + fn_info_game_json "rconpassword" ".ServerSettings.RCONPassword" + fn_info_game_json "servername" ".ServerSettings.ServerName" + fn_info_game_json "serverpassword" ".ServerSettings.ServerPassword" + fn_info_game_json "steamport" ".ServerSettings.ServerSteamPort" + fi + configip="${configip:-"0.0.0.0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port:-"0"}" + rcpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + steamport="${steamport:-"0"}" +} + +# Config Type: Valve KeyValues +# Comment: // +# Example: hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_cs2() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_valve_keyvalues "servername" "hostname" + fi + # Steamport can be between 26901-26910 and is normally automatically set. + # Some servers might support -steamport parameter to set + if [ "${steamport}" == "0" ] || [ -v "${steamport}" ]; then + steamport="$(echo "${ssinfo}" | grep "${srcdslinuxpid}" | awk '{print $5}' | grep ":269" | cut -d ":" -f2)" + fi + defaultmap="${defaultmap:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port:-"0"}" + servername="${servername:-"NOT SET"}" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: ServerName=SERVERNAME +# Filetype: ini +fn_info_game_ct() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "configip" "bindAddress" + fn_info_game_ini "gamemode" "gameMode" + fn_info_game_ini "maxplayers" "maxPlayerNumber" + fn_info_game_ini "port" "port" + fn_info_game_ini "saveinterval" "autoSaveSec" + fn_info_game_ini "servername" "name" + fn_info_game_ini "serverpassword" "serverPassword" + fn_info_game_ini "serverpasswordenabled" "usePassword" + fi + configip="${configip:-"0.0.0.0"}" + gamemode="${gamemode:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + saveinterval="${saveinterval:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + serverpasswordenabled="${serverpasswordenabled:-"NOT SET"}" +} + +# Config Type: SQF +# Parameters: true +# Comment: // or /* */ +# Example: serverName = "SERVERNAME"; +# Filetype: cfg +fn_info_game_dayz() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_sqf "adminpassword" "passwordAdmin" + fn_info_game_sqf "maxplayers" "maxPlayers" + fn_info_game_sqf "queryport" "steamQueryPort" + fn_info_game_sqf "servername" "hostname" + fn_info_game_sqf "serverpassword" "password" + fi + adminpassword="${adminpassword:-"NOT SET"}" + battleeyeport="$((port + 4))" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + steamport="$((port + 2))" +} + +# Config Type: json +# Parameters: false +# Comment: // or /* */ +# Example: "Description": "SERVERNAME" +# Filetype: json +fn_info_game_eco() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_json "configip" ".IPAddress" + fn_info_game_json "httpport" ".WebServerPort" + fn_info_game_json "maxplayers" ".MaxConnections" + fn_info_game_json "port" ".GameServerPort" + fn_info_game_json "servername" ".Description" + fn_info_game_json "serverpassword" ".Password" + fn_info_game_json "tickrate" ".Rate" + fi + configip="${configip:-"0.0.0.0"}" + httpport="${httpport:-"0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + tickrate="${tickrate:-"0"}" +} + +# Config Type: QuakeC +# Parameters: true +# Comment: // or /* */ +# Example: set sv_hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_etl() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_quakec "configip" "net_ip" + fn_info_game_quakec "maxplayers" "sv_maxclients" + fn_info_game_quakec "port" "net_port" + fn_info_game_quakec "rconpassword" "rconpassword" + fn_info_game_quakec "servername" "sv_hostname" + fn_info_game_quakec "serverpassword" "g_password" + fi + configip="${configip:-"0.0.0.0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port}" + rconpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" +} + +# Config Type: json +# Parameters: true +# Comment: // or /* */ +# Example: "name": "SERVERNAME" +# Filetype: json +fn_info_game_fctr() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_json "authtoken" ".token" + fn_info_game_json "maxplayers" ".max_players" + fn_info_game_json "savegameinterval" ".autosave_interval" + fn_info_game_json "servername" ".name" + fn_info_game_json "serverpassword" ".game_password" + fn_info_game_json "versioncount" ".autosave_slots" + fi + authtoken="${authtoken:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + rconpassword="${rconpassword:-"NOT SET"}" + rconport="${rconport:-"0"}" + savegameinterval="${savegameinterval:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + versioncount="${versioncount:-"0"}" + + # get server version if installed. + local factoriobin="${executabledir}${executable:1}" + if [ -f "${factoriobin}" ]; then + serverversion="$(${factoriobin} --version | grep "Version:" | awk '{print $2}')" + fi +} + +# Config Type: parameters (json possibly supported) +# Parameters: true +# Comment: +# Example: -serverName="SERVERNAME" +# Filetype: parameters +fn_info_game_hw() { + servername="${servername:-"NOT SET"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + maxplayers="${maxplayers:-"0"}" + # #4189 option setting can be blank + # defaultmap="${defaultmap:-"NOT SET"}" + creativemode="${creativemode:-"NOT SET"}" +} + +# Config Type: parameters +# Parameters: true +# Comment: +# Example: -hostname='SERVERNAME' +# Filetype: parameters +fn_info_game_inss() { + port="${port:-"0"}" + queryport="${queryport:-"0"}" + rconport="${rconport:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + defaultmap="${defaultmap:-"NOT SET"}" + defaultscenario="${defaultscenario:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" +} + +# Config Type: lua (Custom) +# Parameters: false +# Comment: -- +# Example: Name = "SERVERNAME", +# Filetype: lua +fn_info_game_jc2() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_lua "configip" "BindIP" + fn_info_game_lua "maxplayers" "MaxPlayers" + fn_info_game_lua "port" "BindPort" + fn_info_game_lua "serverdescription" "Description" + fn_info_game_lua "servername" "Name" + fn_info_game_lua "serverpassword" "Password" + fi + configip="${configip:-"0.0.0.0"}" + maxplayers="${maxplayers:-"0"}" + queryport="${port}" + queryport="${queryport:-"0"}" + serverdescription="${serverdescription:-"NOT SET"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" +} + +# Config Type: json +# Parameters: false +# Comment: // or /* */ +# Example: "name": "SERVERNAME" +# Filetype: json +fn_info_game_jc3() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_json "configip" ".host" + fn_info_game_json "httpport" ".httpPort" + fn_info_game_json "maxplayers" ".maxPlayers" + fn_info_game_json "port" ".port" + fn_info_game_json "queryport" ".queryPort" + fn_info_game_json "serverdescription" ".description" + fn_info_game_json "servername" ".name" + fn_info_game_json "serverpassword" ".password" + fn_info_game_json "steamport" ".steamPort" + fn_info_game_json "tickrate" ".maxTickRate" + fi + configip="${configip:-"0.0.0.0"}" + httpport="${httpport:-"0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + serverdescription="${serverdescription:-"NOT SET"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + steamport="${steamport:-"0"}" + tickrate="${tickrate:-"0"}" +} + +# Config Type: QuakeC +# Parameters: true +# Comment: // or /* */ +# Example: set sv_hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_jk2() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_quakec "maxplayers" "sv_maxclients" + fn_info_game_quakec "rconpassword" "rconpassword" + fn_info_game_quakec "servername" "sv_hostname" + fn_info_game_quakec "serverpassword" "g_password" + fn_info_game_quakec "serverversion" "mv_serverversion" + fi + defaultmap="${defaultmap:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port}" + rconpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + serverversion="${serverversion:-"NOT SET"}" +} + +# Config Type: Java properties +# Comment: # or ! +# Example: motd=SERVERNAME +# Filetype: properties +fn_info_game_mc() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_java_properties "configip" "server-ip" + fn_info_game_java_properties "gamemode" "gamemode" + fn_info_game_java_properties "maxplayers" "max-players" + fn_info_game_java_properties "port" "server-port" + fn_info_game_java_properties "queryenabled" "enable-query" + fn_info_game_java_properties "queryport" "query.port" + fn_info_game_java_properties "rconpassword" "rcon.password" + fn_info_game_java_properties "rconport" "rcon.port" + fn_info_game_java_properties "servername" "motd" + fn_info_game_java_properties "worldname" "level-name" + fi + configip="${configip:-"0.0.0.0"}" + gamemode="${gamemode:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryenabled="${queryenabled:-"NOT SET"}" + if [ -z "${queryport}" ]; then + queryport="${port}" + fi + rconpassword="${rconpassword:-"NOT SET"}" + rconport="${rconport:-"0"}" + servername="${servername:-"NOT SET"}" + worldname="${worldname:-"NOT SET"}" +} + +# Config Type: Java properties +# Comment: # or ! +# Example: server-name=SERVERNAME +# Filetype: properties +fn_info_game_mcb() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_java_properties "gamemode" "gamemode" + fn_info_game_java_properties "maxplayers" "max-players" + fn_info_game_java_properties "port" "server-port" + fn_info_game_java_properties "portv6" "server-portv6" + fn_info_game_java_properties "servername" "server-name" + fn_info_game_java_properties "worldname" "level-name" + fi + gamemode="${gamemode:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + portipv6="${portipv6:-"NOT SET"}" + queryport="${port}" + servername="${servername:-"NOT SET"}" + worldname="${worldname:-"NOT SET"}" +} + +# Config Type: QuakeC +# Comment: // or /* */ +# Example: set sv_hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_mohaa() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_quakec "maxplayers" "sv_maxclients" + fn_info_game_quakec "rconpassword" "rconPassword" + fn_info_game_quakec "servername" "sv_hostname" + fn_info_game_quakec "serverpassword" "g_password" + fi + defaultmap="${defaultmap:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port:-"0"}" + rconpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" +} + +# Config Type: json +# Parameters: true +# Comment: // or /* */ +fn_info_game_mom() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_json "defaultmap" ".MapName" + fn_info_game_json "maxplayers" ".MaxPlayers" + fn_info_game_json "servername" ".ServerName" + fn_info_game_json "serverpassword" ".ServerPassword" + fi + beaconport="${beaconport:-"0"}" + defaultmap="${defaultmap:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" +} + +# Config Type: xml +# Comment: +# Example: Default MTA Server +# Filetype: conf +fn_info_game_mta() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_xml "port" "/config/serverport" + fn_info_game_xml "httpport" "/config/httpport" + fn_info_game_xml "servername" "/config/servername" + fn_info_game_xml "maxplayers" "/config/maxplayers" + fn_info_game_xml "ase" "/config/ase" + fi + if [ "${ase}" == "1" ]; then + ase="Enabled" + else + ase="Disabled" + fi + port="${port:-"0"}" + queryport="$((port + 123))" + httpport="${httpport:-"0"}" + ase="${ase:-"Disabled"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" +} + +# Config Type: custom +# Comment: // +# Example: port = 14159, +# Filetype: cfg +fn_info_game_nec() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_lua "maxplayers" "slots" + fn_info_game_lua "port" "port" + fn_info_game_lua "serverpassword" "password" + fi + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + servername="Necesse Port ${port}" + serverpassword="${serverpassword:-"NOT SET"}" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Example: ServerName=SERVERNAME +# Filetype: ini +fn_info_game_ohd() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini rconenabled "bEnabled" + fn_info_game_ini rconport "ListenPort" + fn_info_game_ini rconpassword "Password" + fi + rconenabled="${rconenabled:-"false"}" + rconport="${rconport:-"0"}" + rconpassword="${rconpassword:-"NOT SET"}" +} + +# Config Type: json +# Parameters: false +# Comment: // or /* */ +fn_info_game_onset() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_json "maxplayers" ".maxplayers" + fn_info_game_json "port" ".port" + fn_info_game_json "servername" ".servername_short" + fn_info_game_json "serverpassword" ".password" + fi + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + httpport="$((port - 2))" + queryport="$((port - 1))" + servername="${servername:-"NOT SET"}" +} + +# Config Type: custom +# Parameters: false +# Comment: // +# Filetype: cfg +fn_info_game_pc() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_pc_config "apiport" "httpApiPort" + fn_info_game_pc_config "httpenabled" "enableHttpApi" + fn_info_game_pc_config "httpport" "httpApiPort" + fn_info_game_pc_config "maxplayers" "maxPlayerCount" + fn_info_game_pc_config "port" "hostPort" + fn_info_game_pc_config "queryport" "queryPort" + fn_info_game_pc_config "servername" "name" + fn_info_game_pc_config "serverpassword" "password" + fn_info_game_pc_config "steamport" "steamPort" + fi + apiport="${apiport:-"0"}" + httpenabled="${httpenabled:-"0"}" + httpport="${httpport:-"0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + steamport="${steamport:-"0"}" +} + +fn_info_game_pc2() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_pc_config "apiport" "httpApiPort" + fn_info_game_pc_config "httpenabled" "enableHttpApi" + fn_info_game_pc_config "httpport" "httpApiPort" + fn_info_game_pc_config "maxplayers" "maxPlayerCount" + fn_info_game_pc_config "port" "hostPort" + fn_info_game_pc_config "queryport" "queryPort" + fn_info_game_pc_config "servername" "name" + fn_info_game_pc_config "serverpassword" "password" + fn_info_game_pc_config "steamport" "steamPort" + fi + apiport="${apiport:-"0"}" + httpenabled="${httpenabled:-"0"}" + httpport="${httpport:-"0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + steamport="${steamport:-"0"}" +} + +# Config Type: SiiNunit +# Comment: // +# Example: lobby_name: "SERVERNAME" +# Filetype: ssi +fn_info_game_prism3d() { + # Config + if [ ! -f "${servercfgfullpath}" ]; then + maxplayers="${unavailable}" + port="${zero}" + queryport="${zero}" + servername="${unavailable}" + serverpassword="${unavailable}" + else + maxplayers=$(sed -nr 's/^\s*max_players\s*:\s*([0-9]+)/\1/p' "${servercfgfullpath}") + port=$(sed -nr 's/^\s*connection_dedicated_port\s*:\s*([0-9]+)/\1/p' "${servercfgfullpath}") + queryport=$(sed -nr 's/^\s*query_dedicated_port\s*:\s*([0-9]+)/\1/p' "${servercfgfullpath}") + servername=$(sed -nr 's/^\s*lobby_name\s*:\s*"?([^"\r\n]+)"?/\1/p' "${servercfgfullpath}") + serverpassword=$(sed -nr 's/^\s*password\s*:\s*"(.*)"/\1/p' "${servercfgfullpath}") + + # Not set + maxplayers="${maxplayers:-"0"}" + port="${port:-"27015"}" + queryport="${queryport:-"27016"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + fi +} + +# Config Type: QuakeC +# Comment: // or /* */ +# Example: set hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_q2() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_quakec "maxplayers" "maxclients" + fn_info_game_quakec "rconpassword" "rcon_password" + fn_info_game_quakec "servername" "hostname" + fi + defaultmap="${defaultmap:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port}" + rconpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" +} + +# Config Type: QuakeC +# Comment: // or /* */ +# Example: set sv_hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_q3() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_quakec "maxplayers" "sv_maxclients" + fn_info_game_quakec "rconpassword" "rconpassword" + fn_info_game_quakec "servername" "sv_hostname" + fi + maxplayers="${maxplayers:-"0"}" + rconpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" + port="${port:-"0"}" + queryport="${port}" + defaultmap="${defaultmap:-"NOT SET"}" +} + +# Config Type: QuakeC +# Comment: // or /* */ +# Example: set sv_hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_ql() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_quakec "configip" "net_ip" + fn_info_game_quakec "maxplayers" "sv_maxClients" + fn_info_game_quakec "port" "net_port" + fn_info_game_quakec "rconpassword" "zmq_rcon_password" + fn_info_game_quakec "rconport" "zmq_rcon_port" + fn_info_game_quakec "servername" "sv_hostname" + fn_info_game_quakec "serverpassword" "g_password" + fn_info_game_quakec "statsport" "zmq_stats_port" + fi + configip="${configip:-"0.0.0.0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port}" + rconpassword="${rconpassword:-"NOT SET"}" + rconport="${rconport:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + statsport="${statsport:-"0"}" +} + +# Config Type: QuakeC +# Comment: // or /* */ +# Example: hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_qw() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_quakec "maxplayers" "maxclients" + fn_info_game_quakec "rconpassword" "rcon_password" + fn_info_game_quakec "servername" "hostname" + fi + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port}" + rconpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" +} + +fn_info_game_ro() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "adminpassword" "AdminPassword" + fn_info_game_ini "httpenabled" "bEnabled" + fn_info_game_ini "httppassword" "httppasswordword" + fn_info_game_ini "httpport" "ListenPort" + fn_info_game_ini "httpuser" "AdminName" + fn_info_game_ini "lanport" "LANServerPort" + fn_info_game_ini "maxplayers" "MaxPlayers" + fn_info_game_ini "port" "Port" + fn_info_game_ini "queryportgs" "QueryPort" + fn_info_game_ini "servername" "ServerName" + fn_info_game_ini "serverpassword" "GamePassword" + fi + adminpassword="${adminpassword:-"NOT SET"}" + defaultmap="${defaultmap:-"NOT SET"}" + httpenabled="${httpenabled:-"NOT SET"}" + httppassword="${adminpassword}" + httpport="${httpport:-"0"}" + httpuser="${httpuser:-"NOT SET"}" + lanport="${lanport:-"0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="$((port + 1))" + queryportgs="${queryportgs:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + steamport="28902" + steamworksport="20610" +} + +# Config Type: QuakeC +# Comment: // or /* */ +# Example: set sv_hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_rtcw() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_quakec "rconpassword" "rconpassword" + fn_info_game_quakec "servername" "sv_hostname" + fn_info_game_quakec "serverpassword" "g_password" + fn_info_game_quakec "maxplayers" "sv_maxclients" + fi + rconpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port:-"0"}" + defaultmap="${defaultmap:-"NOT SET"}" +} + +# Config Type: Parameters (mostly) +fn_info_game_rust() { + # Parameters + servername="${servername:-"NOT SET"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + appport="${appport:-"0"}" + rconport="${rconport:-"0"}" + gamemode="${gamemode:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + rconpassword="${rconpassword:-"NOT SET"}" + rconweb="${rconweb:-"NOT SET"}" + tickrate="${tickrate:-"0"}" + saveinterval="${saveinterval:-"0"}" + serverlevel="${serverlevel:-"NOT SET"}" + customlevelurl="${customlevelurl:-"NOT SET"}" + worldsize="${worldsize:-"0"}" + if [ -n "${seed}" ]; then + seed="${seed:-"0"}" + elif [ -f "${datadir}/${selfname}-seed.txt" ]; then + seed=$(cat "${datadir}/${selfname}-seed.txt") + fi + salt="${salt:-"0"}" +} + +fn_info_game_rw() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_keyvalue_pairs_equals "configip" "Server_IP" + fn_info_game_keyvalue_pairs_equals "gamemode" "World_GameMode" + fn_info_game_keyvalue_pairs_equals "maxplayers" "Server_MaxPlayers" + fn_info_game_keyvalue_pairs_equals "port" "Server_Port" + fn_info_game_keyvalue_pairs_equals "rconport" "RCON_Port" + fn_info_game_keyvalue_pairs_equals "seed" "World_Seed" + fn_info_game_keyvalue_pairs_equals "servername" "Server_Name" + fn_info_game_keyvalue_pairs_equals "worldname" "World_Name" + fi + configip="${configip:-"0.0.0.0"}" + gamemode="${gamemode:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="$((port - 1))" + rconport="${rconport:-"0"}" + seed="${seed:-"0"}" + servername="${servername:-"NOT SET"}" + worldname="${worldname:-"NOT SET"}" + +} + +# Config Type: custom +# Comment: // or /* */ +# example: hostname "SERVERNAME" +# filetypes: cfg +fn_info_game_samp() { + # Config + if [ ! -f "${servercfgfullpath}" ]; then + servername="unnamed server" + rconpassword="${unavailable}" + port="7777" + rconport="${port}" + maxplayers="50" + else + servername=$(grep "hostname" "${servercfgfullpath}" | sed -e 's/^[ \t]*//g' -e '/^\//d' -e 's/hostname//g' | tr -d '=\";,:' | sed -e 's/^[ \t]*//' -e 's/[ \t]*$//') + rconpassword=$(grep "rcon_password" "${servercfgfullpath}" | sed -e 's/^[ \t]*//g' -e '/^#/d' -e 's/^rcon_password//g' | tr -d '=\";,:' | sed -e 's/^[ \t]*//' -e 's/[ \t]*$//') + port=$(grep "port" "${servercfgfullpath}" | grep -v "#" | tr -cd '[:digit:]') + queryport="${port}" + rconport="${port}" + maxplayers=$(grep "maxplayers" "${servercfgfullpath}" | grep -v "#" | tr -cd '[:digit:]') + + # Not set + servername="${servername:-"NOT SET"}" + rconpassword="${rconpassword:-"NOT SET"}" + port="${port:-"7777"}" + queryport="${port:-"7777"}" + rconport="${rconport:-"7777"}" + maxplayers="${maxplayers:-"12"}" + fi +} + +# Config Type: json +# Parameters: false +# Comment: // or /* */ +fn_info_game_sb() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_json "maxplayers" ".maxPlayers" + fn_info_game_json "port" ".gameServerPort" + fn_info_game_json "queryenabled" ".runQueryServer" + fn_info_game_json "queryport" ".queryServerPort" + fn_info_game_json "rconenabled" ".runRconServer" + fn_info_game_json "rconpassword" ".rconServerPassword" + fn_info_game_json "rconport" ".rconServerPort" + fn_info_game_json "servername" ".serverName" + fi + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryenabled="${queryenabled:-"NOT SET"}" + queryport="${queryport:-"0"}" + rconenabled="${rconenabled:-"NOT SET"}" + rconpassword="${rconpassword:-"NOT SET"}" + rconport="${rconport:-"0"}" + servername="${servername:-"NOT SET"}" +} + +# Config Type: Parameters +fn_info_game_sbots() { + port="${port:-"0"}" + queryport="${queryport:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + defaultmap="${defaultmap:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" +} + +# Config Type: custom (possibly YAML) +# Comment: # +# Example: server_name: SERVERNAME +# Filetype: txt +fn_info_game_scpsl() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_pc_config "adminpassword" "administrator_query_password" + fn_info_game_pc_config "configip" "ipv4_bind_ip" + fn_info_game_pc_config "maxplayers" "max_players" + fn_info_game_pc_config "servername" "server_name" + fn_info_game_pc_config "tickrate" "server_tickrate" + fi + adminpassword="${adminpassword:-"NOT SET"}" + configip="${configip:-"0.0.0.0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port}" + servername="${servername:-"NOT SET"}" + tickrate="${tickrate:-"NOT SET"}" +} + +# Config Type: xml +# Comment: +# Example: +# Filetype: xml +fn_info_game_sdtd() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_xml "gamemode" "/ServerSettings/property[@name='GameMode']/@value" + fn_info_game_xml "httpenabled" "/ServerSettings/property[@name='ControlPanelEnabled']/@value" + fn_info_game_xml "httppassword" "/ServerSettings/property[@name='ControlPanelPassword']/@value" + fn_info_game_xml "httpport" "/ServerSettings/property[@name='ControlPanelPort']/@value" + fn_info_game_xml "maxplayers" "/ServerSettings/property[@name='ServerMaxPlayerCount']/@value" + fn_info_game_xml "servername" "/ServerSettings/property[@name='ServerName']/@value" + fn_info_game_xml "serverpassword" "/ServerSettings/property[@name='ServerPassword']/@value" + fn_info_game_xml "port" "/ServerSettings/property[@name='ServerPort']/@value" + fn_info_game_xml "telnetenabled" "/ServerSettings/property[@name='TelnetEnabled']/@value" + fn_info_game_xml "telnetpass" "/ServerSettings/property[@name='TelnetPassword']/@value" + fn_info_game_xml "telnetport" "/ServerSettings/property[@name='TelnetPort']/@value" + fn_info_game_xml "worldname" "/ServerSettings/property[@name='GameWorld']/@value" + fi + gamemode="${gamemode:-"NOT SET"}" + httpenabled="${httpenabled:-"NOT SET"}" + httppassword="${httppassword:-"NOT SET"}" + httpport="${httpport:-"0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + port3="$((port + 2))" + queryport="${port:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + telnetenabled="${telnetenabled:-"NOT SET"}" + # Telnet IP will be localhost if no password is set + # check_ip will set the IP first. This will overwrite it. + if [ -z "${telnetpass}" ]; then + telnetip="127.0.0.1" + fi + telnetpass="${telnetpass:-"NOT SET"}" + telnetport="${telnetport:-"0"}" + worldname="${worldname:-"NOT SET"}" + +} + +# Config Type: Parameters (with an ini) +fn_info_game_sf() { + # Parameters + servername="${selfname:-"NOT SET"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + beaconport="${beaconport:-"0"}" +} + +# Config Type: QuakeC +# Comment: // or /* */ +# Example: set sv_hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_sof2() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_quakec "rconpassword" "rconpassword" + fn_info_game_quakec "servername" "sv_hostname" + fn_info_game_quakec "serverpassword" "g_password" + fn_info_game_quakec "maxplayers" "sv_maxclients" + fi + rconpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port}" + defaultmap="${defaultmap:-"NOT SET"}" +} + +# Config Type: ini +# Parameters: true +# Comment: ; or # +# Server_Name=SERVERNAME +# Filetype: ini +fn_info_game_sol() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_ini "adminpassword" "Admin_Password" + fn_info_game_ini "maxplayers" "Max_Players" + fn_info_game_ini "port" "Port" + fn_info_game_ini "servername" "Server_Name" + fn_info_game_ini "serverpassword" "Game_Password" + fi + adminpassword="${adminpassword:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + filesport="$((port + 10))" + queryport="${filesport}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" +} + +# Config Type: Valve KeyValues +# Comment: // +# Example: hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_source() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_valve_keyvalues "rconpassword" "rcon_password" + fn_info_game_valve_keyvalues "servername" "hostname" + fn_info_game_valve_keyvalues "serverpassword" "sv_password" + fi + # Steamport can be between 26901-26910 and is normally automatically set. + # Some servers might support -steamport parameter to set + if [ "${steamport}" == "0" ] || [ -v "${steamport}" ]; then + steamport="$(echo "${ssinfo}" | grep "${srcdslinuxpid}" | awk '{print $5}' | grep ":269" | cut -d ":" -f2)" + fi + clientport="${clientport:-"0"}" + defaultmap="${defaultmap:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port:-"0"}" + rconpassword="${rconpassword:-"NOT SET"}" + rconport="${port:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + # steamport="${steamport:-"0"}" Steamport is optional so we dont want it to show as not set. +} + +fn_info_game_spark() { + defaultmap="${defaultmap:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="$((port + 1))" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + httpuser="${httpuser:-"NOT SET"}" + httppassword="${httppassword:-"NOT SET"}" + httpport="${httpport:-"0"}" +} + +# Config Type: Custom (key-value pairs) +# Parameters: true +# Comment: # or // +# Example: ServerName="SERVERNAME" +# Filetype: cfg +fn_info_game_squad() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_keyvalue_pairs_equals "servername" "ServerName" + fn_info_game_keyvalue_pairs_equals "maxplayers" "MaxPlayers" + fi + if [ -f "${servercfgdir}/Rcon.cfg" ]; then + fn_info_game_keyvalue_pairs_equals "rconport" "Port" "${servercfgdir}/Rcon.cfg" + fn_info_game_keyvalue_pairs_equals "rconpassword" "Password" "${servercfgdir}/Rcon.cfg" + fi + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + rconport="${rconport:-"0"}" + servername="${servername:-"NOT SET"}" + if [ -z "${rconpassword}" ] || [ ${#rconpassword} == 1 ]; then + rconpassword="NOT SET" + fi +} + +# Config Type: Custom (key-value pairs) +# Comment: # or // +# Example: ServerName="SERVERNAME" +# Filetype: cfg +fn_info_game_terraria() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_keyvalue_pairs_equals "maxplayers" "maxplayers" + fn_info_game_keyvalue_pairs_equals "port" "port" + fn_info_game_keyvalue_pairs_equals "servername" "worldname" + fn_info_game_keyvalue_pairs_equals "worldname" "world" + fi + queryport="${port:-"0"}" + servername="${servername:-"NOT SET"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" + worldname="${worldname:-"NOT SET"}" + maxplayers="${maxplayers:-"0"}" +} + +# Config Type: QuakeC (custom) +# Comment: // or /* */ +# Example: set sv_hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_tw() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_keyvalue_pairs_space "servername" "sv_name" + fn_info_game_keyvalue_pairs_space "serverpassword" "password" + fn_info_game_keyvalue_pairs_space "rconpassword" "sv_rcon_password" + fn_info_game_keyvalue_pairs_space "port" "sv_port" + fn_info_game_keyvalue_pairs_space "maxplayers" "sv_max_clients" + fi + queryport="${port}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + rconpassword="${rconpassword:-"NOT SET"}" + port="${port:-"0"}" + maxplayers="${maxplayers:-"0"}" +} + +# Config Type: Parameters +fn_info_game_unt() { + servername="${selfname:-"NOT SET"}" + port="${port:-"0"}" + queryport="${port}" + steamport="$((port + 1))" +} + +# Config Type: Parameters +fn_info_game_vh() { + port="${port:-"0"}" + # Query port only enabled if public server + if [ "${public}" != "0" ]; then + queryport="$((port + 1))" + else + querymode="1" + fi + worldname="${worldname:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" +} + +# Config Type: json +# Parameters: false +# Comment: // or /* */ +fn_info_game_vints() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_json "configip" "select(.Ip != null) | .Ip" + fn_info_game_json "maxplayers" ".MaxClients" + fn_info_game_json "port" ".Port" + fn_info_game_json "servername" ".ServerName" + fn_info_game_json "serverpassword" "select(.Password != null) | .Password" + fi + configip="${configip:-"0.0.0.0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port:-"0"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" +} + +# Config Type: Java properties +# Comment: # or ! +# Example: motd=SERVERNAME +# Filetype: properties +fn_info_game_vpmc() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_java_properties "servername" "motd" + fn_info_game_java_properties "bindaddress" "bind" + fi + configip="$(echo "${bindaddress}" | cut -d ':' -f 1)" + port="$(echo "${bindaddress}" | cut -d ':' -f 2)" + queryport="${port:-"0"}" + servername="${servername:-"NOT SET"}" +} + +# Config Type: QuakeC +# Comment: // or /* */ +# Example: set sv_hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_wet() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_quakec "configip" "net_ip" + fn_info_game_quakec "maxplayers" "sv_maxclients" + fn_info_game_quakec "port" "net_port" + fn_info_game_quakec "rconpassword" "zmq_rcon_password" + fn_info_game_quakec "servername" "sv_hostname" + fn_info_game_quakec "serverpassword" "g_password" + fi + configip="${configip:-"0.0.0.0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port}" + rconpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" + serverpassword="${serverpassword:-"NOT SET"}" +} + +# Config Type: QuakeC +# Comment: // or /* */ +# Example: set sv_hostname "SERVERNAME" +# Filetype: cfg +fn_info_game_wf() { + if [ -f "${servercfgfullpath}" ]; then + fn_info_game_quakec "maxplayers" "sv_maxclients" + fn_info_game_quakec "rconpassword" "rcon_password" + fn_info_game_quakec "servername" "sv_hostname" + fi + httpport="${httpport:-"0"}" + maxplayers="${maxplayers:-"0"}" + port="${port:-"0"}" + queryport="${port:-"0"}" + rconpassword="${rconpassword:-"NOT SET"}" + servername="${servername:-"NOT SET"}" +} + +fn_info_game_wmc() { + if [ ! -f "${servercfgfullpath}" ]; then + servername="${unavailable}" + maxplayers="${zero}" + port="${zero}" + queryport="${zero}" + queryenabled="${unavailable}" + else + servername=$(sed -e '/^listeners:/,/^[a-z]/!d' "${servercfgfullpath}" | sed -nr 's/^[ ]+motd: (.*)$/\1/p' | tr -d "'" | sed 's/&1//') + queryport=$(sed -nr 's/^[ -]+query_port: ([0-9]+)/\1/p' "${servercfgfullpath}") + queryenabled=$(sed -nr 's/^[ ]+query_enabled: (.*)$/\1/p' "${servercfgfullpath}") + port=$(sed -nr 's/^[ ]+host: [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:([0-9]+)/\1/p' "${servercfgfullpath}") + # the normal max_players does only show in on the client side and has no effect how many players can connect. + maxplayers=$(sed -nr 's/^player_limit: ([-]*[0-9])/\1/p' "${servercfgfullpath}") + configip=$(sed -nr 's/^[ ]+host: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+):[0-9]+/\1/p' "${servercfgfullpath}") + + if [ "${maxplayers}" == "-1" ] || [ "${maxplayers}" == "0" ]; then + maxplayers="UNLIMITED" + fi + + # Not set + servername="${servername:-"NOT SET"}" + queryport="${queryport:-"25577"}" + maxplayers="${maxplayers:-"0"}" + configip="${configip:-"0.0.0.0"}" + fi +} + +# Config Type: parameters +# Parameters: true +# Comment: +# Example: hostname='SERVERNAME' +# Filetype: parameters +fn_info_game_wurm() { + gamemode="${gamemode:-"NOT SET"}" + homekingdom="${homekingdom:-"0"}" + adminpassword="${adminpassword:-"NOT SET"}" + epicsettings="${epicsettings:-"NOT SET"}" + homeserver="${homeserver:-"NOT SET"}" + loginserver="${loginserver:-"NOT SET"}" + rmiport="${rmiport:-"0"}" + rmiregport="${rmiregport:-"0"}" + maxplayers="${maxplayers:-"0"}" + servername="${servername:-"NOT SET"}" + # serverpassword="${serverpassword:-"NOT SET"}" + port="${port:-"0"}" + queryport="${queryport:-"0"}" +} + +unavailable="${red}UNAVAILABLE${default}" +zero="${red}0${default}" + +if [ "${shortname}" == "ac" ]; then + fn_info_game_ac +elif [ "${shortname}" == "ark" ]; then + fn_info_game_ark +elif [ "${shortname}" == "arma3" ]; then + fn_info_game_arma3 +elif [ "${shortname}" == "armar" ]; then + fn_info_game_armar +elif [ "${shortname}" == "av" ]; then + fn_info_game_av +elif [ "${shortname}" == "bf1942" ]; then + fn_info_game_bf1942 +elif [ "${shortname}" == "bfv" ]; then + fn_info_game_bfv +elif [ "${shortname}" == "bo" ]; then + fn_info_game_bo +elif [ "${shortname}" == "bt" ]; then + fn_info_game_bt +elif [ "${shortname}" == "btl" ]; then + fn_info_game_btl +elif [ "${shortname}" == "cd" ]; then + fn_info_game_cd +elif [ "${shortname}" == "ck" ]; then + fn_info_game_ck +elif [ "${shortname}" == "cmw" ]; then + fn_info_game_cmw +elif [ "${shortname}" == "cod" ]; then + fn_info_game_cod +elif [ "${shortname}" == "coduo" ]; then + fn_info_game_cod +elif [ "${shortname}" == "cod2" ]; then + fn_info_game_cod2 +elif [ "${shortname}" == "cod4" ]; then + fn_info_game_cod4 +elif [ "${shortname}" == "codwaw" ]; then + fn_info_game_codwaw +elif [ "${shortname}" == "col" ]; then + fn_info_game_col +elif [ "${shortname}" == "cs2" ]; then + fn_info_game_cs2 +elif [ "${shortname}" == "ct" ]; then + fn_info_game_ct +elif [ "${shortname}" == "dayz" ]; then + fn_info_game_dayz +elif [ "${shortname}" == "dodr" ]; then + fn_info_game_dodr +elif [ "${shortname}" == "dst" ]; then + fn_info_game_dst +elif [ "${shortname}" == "eco" ]; then + fn_info_game_eco +elif [ "${shortname}" == "etl" ]; then + fn_info_game_etl +elif [ "${shortname}" == "fctr" ]; then + fn_info_game_fctr +elif [ "${shortname}" == "hw" ]; then + fn_info_game_hw +elif [ "${shortname}" == "inss" ]; then + fn_info_game_inss +elif [ "${shortname}" == "jc2" ]; then + fn_info_game_jc2 +elif [ "${shortname}" == "jc3" ]; then + fn_info_game_jc3 +elif [ "${shortname}" == "jk2" ]; then + fn_info_game_jk2 +elif [ "${shortname}" == "kf" ]; then + fn_info_game_kf +elif [ "${shortname}" == "kf2" ]; then + fn_info_game_kf2 +elif [ "${shortname}" == "mc" ] || [ "${shortname}" == "pmc" ]; then + fn_info_game_mc +elif [ "${shortname}" == "mcb" ]; then + fn_info_game_mcb +elif [ "${shortname}" == "mh" ]; then + fn_info_game_mh +elif [ "${shortname}" == "mohaa" ]; then + fn_info_game_mohaa +elif [ "${shortname}" == "mom" ]; then + fn_info_game_mom +elif [ "${shortname}" == "mta" ]; then + fn_info_game_mta +elif [ "${shortname}" == "nec" ]; then + fn_info_game_nec +elif [ "${shortname}" == "ohd" ]; then + fn_info_game_ohd +elif [ "${shortname}" == "onset" ]; then + fn_info_game_onset +elif [ "${shortname}" == "pc" ]; then + fn_info_game_pc +elif [ "${shortname}" == "pc2" ]; then + fn_info_game_pc2 +elif [ "${shortname}" == "ps" ]; then + fn_info_game_ps +elif [ "${shortname}" == "pvr" ]; then + fn_info_game_pvr +elif [ "${shortname}" == "pz" ]; then + fn_info_game_pz +elif [ "${shortname}" == "q2" ]; then + fn_info_game_q2 +elif [ "${shortname}" == "q3" ]; then + fn_info_game_q3 +elif [ "${shortname}" == "ql" ]; then + fn_info_game_ql +elif [ "${shortname}" == "qw" ]; then + fn_info_game_qw +elif [ "${shortname}" == "ro" ]; then + fn_info_game_ro +elif [ "${shortname}" == "rtcw" ]; then + fn_info_game_rtcw +elif [ "${shortname}" == "rust" ]; then + fn_info_game_rust +elif [ "${shortname}" == "rw" ]; then + fn_info_game_rw +elif [ "${shortname}" == "samp" ]; then + fn_info_game_samp +elif [ "${shortname}" == "sb" ]; then + fn_info_game_sb +elif [ "${shortname}" == "sbots" ]; then + fn_info_game_sbots +elif [ "${shortname}" == "scpsl" ] || [ "${shortname}" == "scpslsm" ]; then + fn_info_game_scpsl +elif [ "${shortname}" == "sdtd" ]; then + fn_info_game_sdtd +elif [ "${shortname}" == "sf" ]; then + fn_info_game_sf +elif [ "${shortname}" == "sof2" ]; then + fn_info_game_sof2 +elif [ "${shortname}" == "sol" ]; then + fn_info_game_sol +elif [ "${engine}" == "spark" ]; then + fn_info_game_spark +elif [ "${shortname}" == "squad" ]; then + fn_info_game_squad +elif [ "${shortname}" == "st" ]; then + fn_info_game_st +elif [ "${shortname}" == "stn" ]; then + fn_info_game_stn +elif [ "${shortname}" == "terraria" ]; then + fn_info_game_terraria +elif [ "${shortname}" == "tf" ]; then + fn_info_game_tf +elif [ "${shortname}" == "ti" ]; then + fn_info_game_ti +elif [ "${shortname}" == "ts3" ]; then + fn_info_game_ts3 +elif [ "${shortname}" == "tu" ]; then + fn_info_game_tu +elif [ "${shortname}" == "tw" ]; then + fn_info_game_tw +elif [ "${shortname}" == "unt" ]; then + fn_info_game_unt +elif [ "${shortname}" == "ut" ]; then + fn_info_game_ut +elif [ "${shortname}" == "ut2k4" ]; then + fn_info_game_ut2k4 +elif [ "${shortname}" == "ut3" ]; then + fn_info_game_ut3 +elif [ "${shortname}" == "ut99" ]; then + fn_info_game_ut99 +elif [ "${shortname}" == "vh" ]; then + fn_info_game_vh +elif [ "${shortname}" == "vints" ]; then + fn_info_game_vints +elif [ "${shortname}" == "vpmc" ]; then + fn_info_game_vpmc +elif [ "${shortname}" == "wet" ]; then + fn_info_game_wet +elif [ "${shortname}" == "wf" ]; then + fn_info_game_wf +elif [ "${shortname}" == "wmc" ]; then + fn_info_game_wmc +elif [ "${shortname}" == "wurm" ]; then + fn_info_game_wurm +elif [ "${engine}" == "prism3d" ]; then + fn_info_game_prism3d +elif [ "${engine}" == "source" ] || [ "${engine}" == "goldsrc" ]; then + fn_info_game_source +elif [ "${engine}" == "unreal2" ]; then + fn_info_game_unreal2 +fi + +# Public IP address +# Cache public IP address for 24 hours +if [ ! -f "${tmpdir}/publicip.json" ] || [ "$(find "${tmpdir}/publicip.json" -mmin +1440)" ]; then + apiurl="http://ip-api.com/json" + publicipresponse=$(curl -s "${apiurl}") + exitcode=$? + # if curl passes add publicip to publicip.json + if [ "${exitcode}" == "0" ]; then + fn_script_log_pass "Getting public IP address" + echo "${publicipresponse}" > "${tmpdir}/publicip.json" + publicip="$(jq -r '.query' "${tmpdir}/publicip.json")" + country="$(jq -r '.country' "${tmpdir}/publicip.json")" + countrycode="$(jq -r '.countryCode' "${tmpdir}/publicip.json")" + else + fn_script_log_warn "Unable to get public IP address" + publicip="NOT SET" + country="NOT SET" + countrycode="NOT SET" + fi +else + publicip="$(jq -r '.query' "${tmpdir}/publicip.json")" + country="$(jq -r '.country' "${tmpdir}/publicip.json")" + countrycode="$(jq -r '.countryCode' "${tmpdir}/publicip.json")" +fi + +# Alert IP address +if [ "${displayip}" ]; then + alertip="${displayip}" +elif [ "${publicip}" ]; then + alertip="${publicip}" +else + alertip="${ip}" +fi + +# Steam Master Server - checks if detected by master server. +# Checked after config init, as the queryport is needed +if [ -z "${displaymasterserver}" ]; then + # if queryport and port3 are not set then set them to 123456789 + # this is to prevent the query from failing. + if [ -z "${queryport}" ]; then + queryport="123456789" + fi + if [ -z "${port3}" ]; then + port3="123456789" + fi + if [ "$(command -v jq 2> /dev/null)" ]; then + if [ -n "${ip}" ] && [ -n "${port}" ]; then + if [ "${steammaster}" == "true" ] || [ "${commandname}" == "DEV-QUERY-RAW" ]; then + # Query external IP first as most liky to succeed. + masterserver="$(curl --connect-timeout 10 -m 3 -s "https://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=${publicip}&format=json" | jq --arg port "${port}" --arg queryport "${queryport}" --arg port3 "${port3}" 'if .response.servers != null then .response.servers[] | select((.gameport == ($port|tonumber) or .gameport == ($queryport|tonumber) or .gameport == ($port3|tonumber))) | .addr else empty end' | wc -l 2> /dev/null)" + if [ "${masterserver}" == "0" ]; then + # Loop though server IP addresses if external IP fails. + for queryip in "${queryips[@]}"; do + masterserver="$(curl --connect-timeout 10 -m 3 -s "https://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=${queryip}&format=json" | jq --arg port "${port}" --arg queryport "${queryport}" --arg port3 "${port3}" 'if .response.servers != null then .response.servers[] | select((.gameport == ($port|tonumber) or .gameport == ($queryport|tonumber) or .gameport == ($port3|tonumber))) | .addr else empty end' | wc -l 2> /dev/null)" + done + fi + if [ "${masterserver}" == "0" ]; then + displaymasterserver="false" + else + displaymasterserver="true" + fi + fi + fi + fi + # unset the ports if they are set to 123456789 + if [ "${port3}" == "123456789" ]; then + unset port3 + fi + if [ "${queryport}" == "123456789" ]; then + unset queryport + fi +fi diff --git a/lgsm/modules/info_messages.sh b/lgsm/modules/info_messages.sh new file mode 100644 index 0000000..0b928aa --- /dev/null +++ b/lgsm/modules/info_messages.sh @@ -0,0 +1,1873 @@ +#!/bin/bash +# LinuxGSM info_messages.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Defines server info messages for details and alerts. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Removes the passwords form all but details. +fn_info_messages_password_strip() { + if [ "${commandname}" != "DETAILS" ]; then + if [ "${serverpassword}" ]; then + serverpassword="********" + fi + + if [ "${rconpassword}" ]; then + rconpassword="********" + fi + + if [ "${adminpassword}" ]; then + adminpassword="********" + fi + + if [ "${statspassword}" ]; then + statspassword="********" + fi + + if [ "${httppassword}" ]; then + httppassword="********" + fi + + if [ "${telnetpass}" ]; then + telnetpass="********" + fi + + if [ "${wsapikey}" ]; then + wsapikey="********" + fi + + if [ "${gslt}" ]; then + gslt="********" + fi + fi +} + +# Alert Summary +# used with alertlog +fn_info_messages_head() { + echo -e "" + echo -e "LinuxGSM Alert Summary" + fn_messages_separator + echo -e "" + echo -e "Server name" + echo -e "${servername}" + echo -e "" + echo -e "Information" + echo -e "${alertmessage}" + echo -e "" + echo -e "Game" + echo -e "${gamename}" + echo -e "" + echo -e "Server IP" + echo -e "${alertip}:${port}" + echo -e "" + echo -e "Hostname" + echo -e "${HOSTNAME}" + echo -e "" + echo -e "Server Time" + echo -e "$(date)" +} + +fn_info_messages_distro() { + # + # Distro Details + # ================================= + # Date: Sun 21 Feb 2021 09:22:53 AM UTC + # Distro: Ubuntu 20.04.2 LTS + # Arch: x86_64 + # Kernel: 5.4.0-65-generic + # Hostname: server + # Environment: kvm + # Uptime: 16d, 5h, 18m + # tmux: tmux 3.0a + # glibc: 2.31 + + echo -e "" + echo -e "${bold}${lightyellow}Distro Details${default}" + fn_messages_separator + { + echo -e "${lightblue}Date:\t${default}$(date)" + echo -e "${lightblue}Distro:\t${default}${distroname}" + echo -e "${lightblue}Arch:\t${default}${arch}" + echo -e "${lightblue}Kernel:\t${default}${kernel}" + echo -e "${lightblue}Hostname:\t${default}${HOSTNAME}" + echo -e "${lightblue}Environment:\t${default}${virtualenvironment}" + echo -e "${lightblue}Uptime:\t${default}${days}d, ${hours}h, ${minutes}m" + echo -e "${lightblue}tmux:\t${default}${tmuxv}" + echo -e "${lightblue}glibc:\t${default}${glibcversion}" + if [ -n "${javaram}" ]; then + echo -e "${lightblue}Java:\t${default}${javaversion}" + fi + } | column -s $'\t' -t +} + +fn_info_messages_server_resource() { + # + # Server Resource + # ================================= + # CPU + # Model: AMD EPYC 7601 32-Core Processor + # Cores: 2 + # Frequency: 2199.994MHz + # Avg Load: 0.01, 0.05, 0.18 + # + # Memory + # Mem: total used free cached available + # Physical: 3.9GB 350MB 3.3GB 3.2GB 3.3GB + # Swap: 512MB 55MB 458MB + # + # Storage + # Filesystem: /dev/sda + # Total: 79G + # Used: 73G + # Available: 1.4G + # + # Network + # IP: 0.0.0.0 + # Internet IP: 176.58.124.96 + + echo -e "" + echo -e "${bold}${lightyellow}Server Resource${default}" + fn_messages_separator + { + echo -e "${lightyellow}CPU\t${default}" + echo -e "${lightblue}Model:\t${default}${cpumodel}" + echo -e "${lightblue}Cores:\t${default}${cpucores}" + echo -e "${lightblue}Frequency:\t${default}${cpufreqency}MHz" + echo -e "${lightblue}Avg Load:\t${default}${load}" + } | column -s $'\t' -t + echo -e "" + { + echo -e "${lightyellow}Memory\t${default}" + echo -e "${lightblue}Mem:\t${lightblue}total\tused\tfree\tcached\tavailable${default}" + echo -e "${lightblue}Physical:\t${default}${physmemtotal}\t${physmemused}\t${physmemfree}\t${physmemcached}\t${physmemavailable}${default}" + echo -e "${lightblue}Swap:\t${default}${swaptotal}\t${swapused}\t${swapfree}${default}" + } | column -s $'\t' -t + echo -e "" + { + echo -e "${lightyellow}Storage${default}" + echo -e "${lightblue}Filesystem:\t${default}${filesystem}" + echo -e "${lightblue}Total:\t${default}${totalspace}" + echo -e "${lightblue}Used:\t${default}${usedspace}" + echo -e "${lightblue}Available:\t${default}${availspace}" + } | column -s $'\t' -t + echo -e "" + { + echo -e "${lightyellow}Network${default}" + if [ -n "${netint}" ]; then + echo -e "${lightblue}Interface:\t${default}${netint}" + fi + if [ -n "${netlink}" ]; then + echo -e "${lightblue}Link Speed:\t${default}${netlink}" + fi + echo -e "${lightblue}IP:\t${default}${ip}" + if [ "${ip}" != "${publicip}" ]; then + echo -e "${lightblue}Internet IP:\t${default}${publicip}" + fi + } | column -s $'\t' -t +} + +fn_info_messages_gameserver_resource() { + # + # Game Server Resource Usage + # ================================= + # CPU Used: 1.1% + # Mem Used: 4.8% 189MB + # + # Storage + # Total: 241M + # Serverfiles: 240M + # Backups: 24K + + echo -e "" + echo -e "${bold}${lightgreen}${gamename} Resource Usage${default}" + fn_messages_separator + { + if [ "${status}" != "0" ] && [ -v status ]; then + if [ -n "${cpuused}" ]; then + echo -e "${lightblue}CPU Used:\t${default}${cpuused}%${default}" + else + echo -e "${lightblue}CPU Used:\t${red}unknown${default}" + fi + if [ -n "${memused}" ]; then + echo -e "${lightblue}Mem Used:\t${default}${pmemused}%\t${memused}MB${default}" + else + echo -e "${lightblue}Mem Used:\t${default}${pmemused}\t${red}unknown${default}" + fi + else + echo -e "${lightblue}CPU Used:\t${default}0%${default}" + echo -e "${lightblue}Mem Used:\t${default}0%\t0MB${default}" + fi + } | column -s $'\t' -t + echo -e "" + { + echo -e "${lightyellow}Storage${default}" + echo -e "${lightblue}Total:\t${default}${rootdirdu}" + echo -e "${lightblue}Serverfiles:\t${default}${serverfilesdu}" + if [ -d "${backupdir}" ]; then + echo -e "${lightblue}Backups:\t${default}${backupdirdu}" + fi + } | column -s $'\t' -t +} + +fn_info_messages_gameserver() { + # + # Counter-Strike: Global Offensive Server Details + # ================================= + # Server name: LinuxGSM + # Server IP: 0.0.0.0:27015 + # Internet IP: 176.48.124.96:34197 + # Server password: NOT SET + # RCON password: adminF54CC0VR + # Players: 0/16 + # Current map: de_mirage + # Default map: de_mirage + # Game type: 0 + # Game mode: 0 + # Tick rate: 64 + # Master Server: listed + # Status: STARTED + + echo -e "" + echo -e "${bold}${lightgreen}${gamename} Server Details${default}" + fn_info_messages_password_strip + fn_messages_separator + { + # Server name + if [ -n "${gdname}" ]; then + echo -e "${lightblue}Server name:\t${default}${gdname}" + elif [ -n "${servername}" ]; then + echo -e "${lightblue}Server name:\t${default}${servername}" + fi + + # Server description + if [ -n "${serverdescription}" ]; then + echo -e "${lightblue}Server Description:\t${default}${serverdescription}" + fi + + # Appid + if [ -n "${appid}" ]; then + echo -e "${lightblue}App ID:\t${default}${appid}" + fi + + # Branch + if [ -n "${branch}" ]; then + echo -e "${lightblue}Branch:\t${default}${branch}" + fi + + # Beta Password + if [ -n "${betapassword}" ]; then + echo -e "${lightblue}Beta Password:\t${default}${betapassword}" + fi + + # Server Version + if [ -n "${gdversion}" ]; then + echo -e "${lightblue}Server Version:\t${default}${gdversion}" + fi + + # Server ip + echo -e "${lightblue}Server IP:\t${default}${ip}:${port}" + + # Internet ip + if [ -n "${publicip}" ]; then + if [ "${ip}" != "${publicip}" ]; then + echo -e "${lightblue}Internet IP:\t${default}${publicip}:${port}" + fi + fi + + # Display ip + if [ -n "${displayip}" ]; then + echo -e "${lightblue}Display IP:\t${default}${displayip}:${port}" + fi + + # Server password enabled (Craftopia) + if [ -n "${serverpasswordenabled}" ]; then + echo -e "${lightblue}Server password enabled:\t${default}${serverpasswordenabled}" + fi + + # Server password + if [ -n "${serverpassword}" ]; then + echo -e "${lightblue}Server password:\t${default}${serverpassword}" + fi + + # Query enabled (Starbound) + if [ -n "${queryenabled}" ]; then + echo -e "${lightblue}Query enabled:\t${default}${queryenabled}" + fi + + # RCON enabled (Starbound) + if [ -n "${rconenabled}" ]; then + echo -e "${lightblue}RCON enabled:\t${default}${rconenabled}" + fi + + # RCON password + if [ -n "${rconpassword}" ]; then + echo -e "${lightblue}RCON password:\t${default}${rconpassword}" + fi + + # RCON web (Rust) + if [ -n "${rconweb}" ]; then + echo -e "${lightblue}RCON web:\t${default}${rconweb}" + fi + + # Admin password + if [ -n "${adminpassword}" ]; then + echo -e "${lightblue}Admin password:\t${default}${adminpassword}" + fi + + # Stats password (Quake Live) + if [ -n "${statspassword}" ]; then + echo -e "${lightblue}Stats password:\t${default}${statspassword}" + fi + + # Players + if [ "${querystatus}" != "0" ]; then + if [ -n "${maxplayers}" ]; then + echo -e "${lightblue}Maxplayers:\t${default}${maxplayers}" + fi + else + if [ -n "${gdplayers}" ] && [ -n "${gdmaxplayers}" ]; then + echo -e "${lightblue}Players:\t${default}${gdplayers}/${gdmaxplayers}" + elif [ -n "${gdplayers}" ] && [ -n "${maxplayers}" ]; then + echo -e "${lightblue}Players:\t${default}${gdplayers}/${maxplayers}" + elif [ -z "${gdplayers}" ] && [ -n "${gdmaxplayers}" ]; then + echo -e "${lightblue}Players:\t${default}0/${gdmaxplayers}" + elif [ -n "${gdplayers}" ] && [ -z "${gdmaxplayers}" ]; then + echo -e "${lightblue}Players:\t${default}${gdplayers}/∞" + elif [ -z "${gdplayers}" ] && [ -z "${gdmaxplayers}" ] && [ -n "${maxplayers}" ]; then + echo -e "${lightblue}Maxplayers:\t${default}${maxplayers}" + fi + fi + + # Reverved Slots + if [ -n "${statspassword}" ]; then + echo -e "${lightblue}Reserved Slots:\t${default}${reservedslots}" + fi + + # Bots + if [ -n "${gdbots}" ]; then + echo -e "${lightblue}Bots:\t${default}${gdbots}" + fi + + # Current map + if [ -n "${gdmap}" ]; then + echo -e "${lightblue}Current map:\t${default}${gdmap}" + fi + + # Default map + if [ -n "${defaultmap}" ]; then + echo -e "${lightblue}Default map:\t${default}${defaultmap}" + fi + + if [ -n "${defaultscenario}" ]; then + # Current scenario (Insurgency: Sandstorm) + if [ -n "${gdgamemode}" ]; then + echo -e "${lightblue}Current scenario:\t${default}${gdgamemode}" + fi + else + # Current game mode + if [ -n "${gdgamemode}" ]; then + echo -e "${lightblue}Current game mode:\t${default}${gdgamemode}" + fi + fi + + # Default scenario + if [ -n "${defaultscenario}" ]; then + echo -e "${lightblue}Default scenario:\t${default}${defaultscenario}" + fi + + # Game type + if [ -n "${gametype}" ]; then + echo -e "${lightblue}Game type:\t${default}${gametype}" + fi + + # Game mode + if [ -n "${gamemode}" ]; then + echo -e "${lightblue}Game mode:\t${default}${gamemode}" + fi + + # Game world + if [ -n "${gameworld}" ]; then + echo -e "${lightblue}Game world:\t${default}${gameworld}" + fi + + # Tick rate + if [ -n "${tickrate}" ]; then + echo -e "${lightblue}Tick rate:\t${default}${tickrate}" + fi + + # Sharding (Don't Starve Together) + if [ -n "${sharding}" ]; then + echo -e "${lightblue}Sharding:\t${default}${sharding}" + fi + + # Master (Don't Starve Together) + if [ -n "${master}" ]; then + echo -e "${lightblue}Master:\t${default}${master}" + fi + + # Shard (Don't Starve Together) + if [ -n "${shard}" ]; then + echo -e "${lightblue}Shard:\t${default}${shard}" + fi + + # Cluster (Don't Starve Together) + if [ -n "${cluster}" ]; then + echo -e "${lightblue}Cluster:\t${default}${cluster}" + fi + + # Cave (Don't Starve Together) + if [ -n "${cave}" ]; then + echo -e "${lightblue}Cave:\t${default}${cave}" + fi + + # Creativemode (Hurtworld) + if [ -n "${creativemode}" ]; then + echo -e "${lightblue}Creativemode:\t${default}${creativemode}" + fi + + # TeamSpeak dbplugin + if [ -n "${dbplugin}" ]; then + echo -e "${lightblue}dbplugin:\t${default}${dbplugin}" + fi + + # ASE (Multi Theft Auto) + if [ -n "${ase}" ]; then + echo -e "${lightblue}ASE:\t${default}${ase}" + fi + + # Save interval (Rust) + if [ -n "${saveinterval}" ]; then + echo -e "${lightblue}Save interval:\t${default}${saveinterval}s" + fi + + # Seed (Rust) + if [ -n "${seed}" ]; then + echo -e "${lightblue}Seed:\t${default}${seed}" + fi + + # Salt (Rust) + if [ -n "${salt}" ]; then + echo -e "${lightblue}Salt:\t${default}${salt}" + fi + + # World Size (Rust) + if [ -n "${worldsize}" ]; then + echo -e "${lightblue}World size:\t${default}${worldsize}m" + fi + + # Random map rotation mode (Squad and Post Scriptum) + if [ -n "${randommap}" ]; then + echo -e "${lightblue}Map rotation:\t${default}${randommap}" + fi + + # Server Version (Jedi Knight II: Jedi Outcast) + if [ -n "${serverversion}" ]; then + echo -e "${lightblue}Server Version:\t${default}${serverversion}" + fi + + # authentication token (Factorio) + if [ -n "${authtoken}" ]; then + echo -e "${lightblue}Auth Token:\t${default}${authtoken}" + fi + + # savegameinterval (Factorio) + if [ -n "${savegameinterval}" ]; then + echo -e "${lightblue}Savegame Interval:\t${default}${savegameinterval}" + fi + + # versioncount (Factorio) + if [ -n "${versioncount}" ]; then + echo -e "${lightblue}Version Count:\t${default}${versioncount}" + fi + + # Listed on Master server + if [ -n "${displaymasterserver}" ]; then + if [ "${displaymasterserver}" == "true" ]; then + echo -e "${lightblue}Master server:\t${green}listed${default}" + else + echo -e "${lightblue}Master server:\t${red}not listed${default}" + fi + fi + + # Game server status + if [ "${status}" == "0" ]; then + echo -e "${lightblue}Status:\t${red}STOPPED${default}" + else + echo -e "${lightblue}Status:\t${green}STARTED${default}" + fi + } | column -s $'\t' -t + echo -e "" +} + +fn_info_messages_script() { + # csgoserver Script Details + # ================================= + # Script name: csgoserver + # LinuxGSM version: v21.1.3 + # glibc required: 2.18 + # Discord alert: off + # Email alert: off + # Gotify alert: off + # IFTTT alert: off + # Pushbullet alert: off + # Pushover alert: off + # Rocketchat alert: off + # Slack alert: off + # Telegram alert: off + # Update on start: off + # User: lgsm + # Location: /home/lgsm/csgoserver + # Config file: /home/lgsm/csgoserver/serverfiles/csgo/cfg/csgoserver.cfg + + echo -e "${bold}${lightgreen}${selfname} Script Details${default}" + fn_messages_separator + { + # Script name + echo -e "${lightblue}Script name:\t${default}${selfname}" + + # LinuxGSM version + if [ -n "${version}" ]; then + echo -e "${lightblue}LinuxGSM version:\t${default}${version}" + fi + + # glibc required + if [ -n "${glibc}" ]; then + if [ "${glibc}" == "null" ]; then + # Glibc is not required. + : + elif [ -z "${glibc}" ]; then + echo -e "${lightblue}glibc required:\t${red}UNKNOWN${default}" + elif [ "$(printf '%s\n'${glibc}'\n' ${glibcversion} | sort -V | head -n 1)" != "${glibc}" ]; then + echo -e "${lightblue}glibc required:\t${red}${glibc} ${default}(${red}distro glibc ${glibcversion} too old${default})" + else + echo -e "${lightblue}glibc required:\t${green}${glibc}${default}" + fi + fi + + # Discord alert + echo -e "${lightblue}Discord alert:\t${default}${discordalert}" + # Email alert + echo -e "${lightblue}Email alert:\t${default}${emailalert}" + # Gotify alert + echo -e "${lightblue}Gotify alert:\t${default}${gotifyalert}" + # IFTTT alert + echo -e "${lightblue}IFTTT alert:\t${default}${iftttalert}" + # Pushbullet alert + echo -e "${lightblue}Pushbullet alert:\t${default}${pushbulletalert}" + # Pushover alert + echo -e "${lightblue}Pushover alert:\t${default}${pushoveralert}" + # Rocketchat alert + echo -e "${lightblue}Rocketchat alert:\t${default}${rocketchatalert}" + # Slack alert + echo -e "${lightblue}Slack alert:\t${default}${slackalert}" + # Telegram alert + echo -e "${lightblue}Telegram alert:\t${default}${telegramalert}" + + # Update on start + if [ -n "${updateonstart}" ]; then + echo -e "${lightblue}Update on start:\t${default}${updateonstart}" + fi + + # User + echo -e "${lightblue}User:\t${default}$(whoami)" + + # Script location + echo -e "${lightblue}Location:\t${default}${rootdir}" + + # Config file location + if [ -n "${servercfgfullpath}" ]; then + if [ -f "${servercfgfullpath}" ]; then + echo -e "${lightblue}Config file:\t${default}${servercfgfullpath}" + elif [ -d "${servercfgfullpath}" ]; then + echo -e "${lightblue}Config dir:\t${default}${servercfgfullpath}" + else + echo -e "${lightblue}Config file:\t${default}${red}${servercfgfullpath}${default} (${red}FILE MISSING${default})" + fi + fi + + # Network config file location (ARMA 3) + if [ -n "${networkcfgfullpath}" ]; then + echo -e "${lightblue}Network config file:\t${default}${networkcfgfullpath}" + fi + + # Cluster config file location (DST) + if [ -n "${clustercfgfullpath}" ]; then + echo -e "${lightblue}Cluster config file:\t${default}${clustercfgfullpath}" + fi + + } | column -s $'\t' -t +} + +fn_info_messages_backup() { + # + # Backups + # ================================= + # No. of backups: 1 + # Latest backup: + # date: Fri May 6 18:34:19 UTC 2016 + # file: /home/lgsm/qlserver/backups/ql-server-2016-05-06-183239.tar.gz + # size: 945M + + echo -e "" + echo -e "${bold}${lightgreen}Backups${default}" + fn_messages_separator + if [ ! -d "${backupdir}" ] || [ "${backupcount}" == "0" ]; then + echo -e "No Backups created" + else + { + echo -e "${lightblue}No. of backups:\t${default}${backupcount}" + echo -e "${lightblue}Latest backup:${default}" + if [ "${lastbackupdaysago}" == "0" ]; then + echo -e "${lightblue} date:\t${default}${lastbackupdate} (less than 1 day ago)" + elif [ "${lastbackupdaysago}" == "1" ]; then + echo -e "${lightblue} date:\t${default}${lastbackupdate} (1 day ago)" + else + echo -e "${lightblue} date:\t${default}${lastbackupdate} (${lastbackupdaysago} days ago)" + fi + echo -e "${lightblue} file:\t${default}${lastbackup}" + echo -e "${lightblue} size:\t${default}${lastbackupsize}" + } | column -s $'\t' -t + fi +} + +fn_info_messages_commandlineparms() { + # + # Command-line Parameters + # ================================= + # ./run_server_x86.sh +set net_strict 1 + + echo -e "" + echo -e "${bold}${lightgreen}Command-line Parameters${default}" + fn_info_messages_password_strip + fn_messages_separator + if [ "${serverpassword}" == "NOT SET" ]; then + unset serverpassword + fi + fn_reload_startparameters + echo -e "${preexecutable} ${executable} ${startparameters}" +} + +fn_info_messages_ports_edit() { + # + # Ports + # ================================= + # Change ports by editing the parameters in: + # /home/lgsm/qlserver/serverfiles/baseq3/ql-server.cfg + echo -e "" + echo -e "${bold}${lightgreen}Ports${default}" + fn_messages_separator + echo -e "${lightblue}Change ports by editing the parameters in:${default}" + + startparameterslocation="${red}UNKNOWN${default}" + # engines/games that require editing in the config file. + local ports_edit_array=("ac" "arma3" "armar" "bo" "bt" "cd" "ct" "dst" "eco" "idtech2" "idtech3" "idtech3_ql" "jc2" "jc3" "lwjgl2" "mcb" "nec" "pc" "pc2" "prism3d" "pz" "qw" "refractor" "renderware" "rw" "sb" "sdtd" "st" "stn" "ts3" "tw" "terraria" "unreal" "unreal2" "unreal3" "vints" "wurm") + for port_edit in "${ports_edit_array[@]}"; do + if [ "${shortname}" == "ut3" ]; then + startparameterslocation="${servercfgdir}/UTWeb.ini" + elif [ "${shortname}" == "kf2" ]; then + startparameterslocation="${servercfgdir}/LinuxServer-KFEngine.ini\n${servercfgdir}/KFWeb.ini" + elif [ "${engine}" == "${port_edit}" ] || [ "${gamename}" == "${port_edit}" ] || [ "${shortname}" == "${port_edit}" ]; then + startparameterslocation="${servercfgfullpath}" + fi + done + # engines/games that require editing the start parameters. + local ports_edit_array=("av" "ck" "col" "cs2" "fctr" "goldsrc" "hcu" "hw" "iw3.0" "ioquake3" "qfusion" "rust" "scpsl" "scpslsm" "sol" "spark" "source" "unreal4" "arma3" "dayz" "unt" "vh") + for port_edit in "${ports_edit_array[@]}"; do + if [ "${engine}" == "${port_edit}" ] || [ "${gamename}" == "${port_edit}" ] || [ "${shortname}" == "${port_edit}" ]; then + startparameterslocation="${configdirserver}" + fi + done + echo -e "${startparameterslocation}" + echo -e "" +} + +fn_info_messages_ports() { + echo -e "${lightblue}Useful port diagnostic command:${default}" + if [ "${shortname}" == "armar" ]; then + portcommand="ss -tuplwn | grep enfMain" + elif [ "${shortname}" == "av" ]; then + portcommand="ss -tuplwn | grep AvorionServer" + elif [ "${shortname}" == "bf1942" ]; then + portcommand="ss -tuplwn | grep bf1942_lnxded" + elif [ "${shortname}" == "mc" ] || [ "${shortname}" == "nec" ] || [ "${shortname}" == "pmc" ] || [ "${shortname}" == "vpmc" ] || [ "${shortname}" == "wmc" ]; then + portcommand="ss -tuplwn | grep java" + elif [ "${shortname}" == "terraria" ]; then + portcommand="ss -tuplwn | grep Main" + elif [ "${engine}" == "source" ]; then + portcommand="ss -tuplwn | grep srcds_linux" + elif [ "${engine}" == "goldsrc" ]; then + portcommand="ss -tuplwn | grep hlds_linux" + else + executableshort="$(basename "${executable}" | cut -c -15)" + portcommand="ss -tuplwn | grep ${executableshort}" + fi + echo -e "${portcommand}" + echo -e "" +} + +fn_info_messages_statusbottom() { + echo -e "" + if [ "${status}" == "0" ]; then + echo -e "${lightblue}Status:\t${red}STOPPED${default}" + else + echo -e "${lightblue}Status:\t${green}STARTED${default}" + fi + echo -e "" +} + +fn_info_logs() { + echo -e "" + echo -e "${bold}${selfname} Logs" + fn_messages_separator + + if [ -n "${lgsmlog}" ]; then + echo -e "\nScript log\n===================" + if [ ! "$(ls -A "${lgsmlogdir}")" ]; then + echo -e "${lgsmlogdir} (NO LOG FILES)" + elif [ ! -s "${lgsmlog}" ]; then + echo -e "${lgsmlog} (LOG FILE IS EMPTY)" + else + echo -e "${lgsmlog}" + tail -25 "${lgsmlog}" + fi + echo -e "" + fi + + if [ -n "${consolelog}" ]; then + echo -e "\nConsole log\n====================" + if [ ! "$(ls -A "${consolelogdir}")" ]; then + echo -e "${consolelogdir} (NO LOG FILES)" + elif [ ! -s "${consolelog}" ]; then + echo -e "${consolelog} (LOG FILE IS EMPTY)" + else + echo -e "${consolelog}" + tail -25 "${consolelog}" | awk '{ sub("\r$", ""); print }' + fi + echo -e "" + fi + + if [ -n "${gamelogdir}" ]; then + echo -e "\nServer log\n===================" + if [ ! "$(ls -A "${gamelogdir}")" ]; then + echo -e "${gamelogdir} (NO LOG FILES)" + else + echo -e "${gamelogdir}" + # dos2unix sed 's/\r//' + tail "${gamelogdir}"/* 2> /dev/null | grep -av "==>" | sed '/^$/d' | sed 's/\r//' | tail -25 + fi + echo -e "" + fi +} + +# Engine/Game Specific details + +# Function used to generate port info. by passing info to function. (Reduces repeating code) +# example output +# DESCRIPTION PORT PROTOCOL LISTEN +# Game 7777 udp 1 +# RAW UDP Socket 7778 udp 1 +# Query 27015 udp 1 +# RCON 27020 tcp 1 + +fn_port() { + if [ "${1}" == "header" ]; then + echo -e "${lightblue}DESCRIPTION\tPORT\tPROTOCOL\tLISTEN${default}" + else + portname="${1}" + porttype="${2}" + portprotocol="${3}" + echo -e "${portname}\t${!porttype}\t${portprotocol}\t$(echo "${ssinfo}" | grep "${portprotocol}" | grep -c "${!porttype}")" + fi +} + +fn_info_messages_ac() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Game" port tcp + fn_port "Query" queryport udp + fn_port "HTTP" httpport tcp + } | column -s $'\t' -t +} + +fn_info_messages_ark() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "RAW UDP Socket" rawport udp + fn_port "Query" queryport udp + fn_port "RCON" rconport tcp + } | column -s $'\t' -t +} + +fn_info_messages_arma3() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Voice" voiceport udp + fn_port "Query" queryport udp + fn_port "Steam" steamport udp + fn_port "Voice (unused)" voiceunusedport udp + fn_port "BattleEye" battleeyeport udp + } | column -s $'\t' -t +} + +fn_info_messages_armar() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Steam Query" queryport udp + fn_port "BattleEye" battleeyeport tcp + } | column -s $'\t' -t +} + +fn_info_messages_av() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "Steam" steamport udp + fn_port "Steamworks P2P" steamworksport udp + fn_port "RCON" rconport tcp + } | column -s $'\t' -t +} + +fn_info_messages_bf1942() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_bfv() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_bo() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_bt() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_btl() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "RCON" rconport tcp + } | column -s $'\t' -t +} + +fn_info_messages_cd() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Steam" steamport udp + fn_port "RCON" rconport tcp + } | column -s $'\t' -t +} + +fn_info_messages_ck() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_cmw() { + fn_info_messages_password_strip + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "RCON" rconport tcp + } | column -s $'\t' -t +} + +fn_info_messages_cod() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_coduo() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_cod2() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_cod4() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_codwaw() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_col() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport tcp + fn_port "Steam" steamport tcp + } | column -s $'\t' -t +} + +fn_info_messages_cs2() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport tcp + } | column -s $'\t' -t +} + +fn_info_messages_csgo() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport tcp + fn_port "RCON" rconport tcp + fn_port "SourceTV" sourcetvport udp + fn_port "Client" clientport udp + } | column -s $'\t' -t +} + +fn_info_messages_ct() { + fn_info_messages_password_strip + { + fn_port "header" + fn_port "Game" port udp + } | column -s $'\t' -t +} + +fn_info_messages_dayz() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query Steam" queryport udp + fn_port "Steam" steamport udp + fn_port "BattleEye" battleeyeport udp + } | column -s $'\t' -t +} + +fn_info_messages_dodr() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_dst() { + { + fn_port "header" + fn_port "Game: Server" port udp + fn_port "Game: Master" masterport udp + fn_port "Steam" steamport udp + fn_port "Steam: Auth" steamauthport udp + } | column -s $'\t' -t +} + +fn_info_messages_eco() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Web Interface" httpport tcp + } | column -s $'\t' -t +} + +fn_info_messages_etl() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_fctr() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "RCON" rconport tcp + } | column -s $'\t' -t +} + +fn_info_messages_goldsrc() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport tcp + fn_port "Client" clientport udp + } | column -s $'\t' -t +} + +fn_info_messages_hcu() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport tcp + } | column -s $'\t' -t +} + +fn_info_messages_hw() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_ins() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport tcp + fn_port "RCON" rconport tcp + fn_port "SourceTV" sourcetvport udp + fn_port "Client" clientport udp + } | column -s $'\t' -t +} + +fn_info_messages_inss() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "RCON" rconport tcp + } | column -s $'\t' -t +} + +fn_info_messages_jc2() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_jc3() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "Steam" steamport udp + fn_port "HTTP" httpport tcp + } | column -s $'\t' -t +} + +fn_info_messages_jk2() { + { + fn_port "header" + fn_port "Game" port udp + } | column -s $'\t' -t +} + +fn_info_messages_kf() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "Query (GameSpy)" queryportgs udp + fn_port "Web Interface" httpport tcp + fn_port "LAN" lanport udp + fn_port "Steamworks P2P" steamworksport udp + fn_port "Steam" steamport udp + } | column -s $'\t' -t + echo -e "" + echo -e "${bold}${lightgreen}${servername} Web Interface${default}" + fn_messages_separator + { + echo -e "${lightblue}Web Interface enabled:\t${default}${httpenabled}" + echo -e "${lightblue}Web Interface url:\t${default}http://${httpip}:${httpport}" + echo -e "${lightblue}Web Interface username:\t${default}${httpuser}" + echo -e "${lightblue}Web Interface password:\t${default}${httppassword}" + } | column -s $'\t' -t +} + +fn_info_messages_kf2() { + fn_info_messages_password_strip + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "Web Interface" httpport tcp + } | column -s $'\t' -t + echo -e "" + echo -e "${bold}${lightgreen}${servername} Web Interface${default}" + fn_messages_separator + { + echo -e "${lightblue}Web Interface enabled:\t${default}${httpenabled}" + echo -e "${lightblue}Web Interface url:\t${default}http://${httpip}:${httpport}" + echo -e "${lightblue}Web Interface username:\t${default}${httpuser}" + echo -e "${lightblue}Web Interface password:\t${default}${httppassword}" + } | column -s $'\t' -t +} + +fn_info_messages_mc() { + { + fn_port "header" + fn_port "Game" port tcp + fn_port "Query" queryport udp + fn_port "RCON" rconport tcp + } | column -s $'\t' -t +} + +fn_info_messages_mcb() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Game" portipv6 udp6 + } | column -s $'\t' -t +} + +fn_info_messages_mh() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "Beacon" beaconport udp + } | column -s $'\t' -t +} + +fn_info_messages_mohaa() { + { + fn_port "header" + fn_port "Game" port udp + } | column -s $'\t' -t +} + +fn_info_messages_mom() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Beacon" beaconport udp + } | column -s $'\t' -t +} + +fn_info_messages_mta() { + { + fn_port "header" + fn_port "Game" port udp + if [ "${ase}" == "Enabled" ]; then + fn_port "Query" queryport udp + fi + fn_port "HTTP" httpport tcp + } | column -s $'\t' -t +} + +fn_info_messages_nec() { + { + fn_port "header" + fn_port "Game" port udp + } | column -s $'\t' -t +} + +fn_info_messages_ohd() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "RCON" rconport tcp + } | column -s $'\t' -t +} + +fn_info_messages_onset() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "HTTP" httpport tcp + } | column -s $'\t' -t +} + +fn_info_messages_pc() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "Steam" steamport udp + fn_port "HTTP" httpport tcp + fn_port "API" apiport tcp + } | column -s $'\t' -t + echo -e "" + echo -e "${bold}${lightgreen}${gamename} Web Interface${default}" + fn_messages_separator + { + echo -e "${lightblue}Web Interface enabled:\t${default}${httpenabled}" + echo -e "${lightblue}Web Interface url:\t${default}http://${httpip}:${httpport}" + } | column -s $'\t' -t +} + +fn_info_messages_pc2() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "Steam" steamport udp + } | column -s $'\t' -t +} + +fn_info_messages_ps() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "RCON" rconport tcp + } | column -s $'\t' -t +} + +fn_info_messages_pvr() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Game" port tcp + fn_port "Game+400" port401 udp + fn_port "Query" queryport tcp + } | column -s $'\t' -t +} + +fn_info_messages_pz() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_qw() { + { + fn_port "header" + fn_port "Game" port udp + } | column -s $'\t' -t +} + +fn_info_messages_q2() { + { + fn_port "header" + fn_port "Game" port udp + } | column -s $'\t' -t +} + +fn_info_messages_q3() { + { + fn_port "header" + fn_port "Game" port udp + } | column -s $'\t' -t +} + +fn_info_messages_ql() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "RCON" rconport tcp + fn_port "Stats" statsport udp + } | column -s $'\t' -t +} + +fn_info_messages_ro() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "Web Interface" httpport tcp + fn_port "LAN" lanport udp + fn_port "Steamworks P2P" steamworksport udp + fn_port "Steam" steamport udp + } | column -s $'\t' -t + echo -e "" + echo -e "${bold}${lightgreen}${servername} Web Interface${default}" + fn_messages_separator + { + echo -e "${lightblue}Web Interface enabled:\t${default}${httpenabled}" + echo -e "${lightblue}Web Interface url:\t${default}http://${httpip}:${httpport}" + echo -e "${lightblue}Web Interface username:\t${default}${httpuser}" + echo -e "${lightblue}Web Interface password:\t${default}${httppassword}" + } | column -s $'\t' -t +} + +fn_info_messages_rtcw() { + { + fn_port "header" + fn_port "Game" port udp + } | column -s $'\t' -t +} + +fn_info_messages_rust() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "RCON" rconport tcp + fn_port "App" appport tcp + } | column -s $'\t' -t +} + +fn_info_messages_rw() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport tcp + fn_port "RCON" rconport tcp + } | column -s $'\t' -t +} + +fn_info_messages_samp() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "RCON" rconport udp + } | column -s $'\t' -t +} + +fn_info_messages_sb() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport tcp + fn_port "RCON" rconport tcp + } | column -s $'\t' -t +} + +fn_info_messages_sbots() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_scpsl() { + { + fn_port "header" + fn_port "Game" port tcp + } | column -s $'\t' -t +} + +fn_info_messages_sdtd() { + fn_info_messages_password_strip + { + fn_port "header" + fn_port "Game" port udp + fn_port "Game+2" port3 udp + fn_port "Query" queryport tcp + fn_port "Web Interface" httpport tcp + fn_port "Telnet" telnetport tcp + } | column -s $'\t' -t + echo -e "" + echo -e "${bold}${lightgreen}${gamename} Web Interface${default}" + fn_messages_separator + { + echo -e "${lightblue}Web Interface enabled:\t${default}${httpenabled}" + echo -e "${lightblue}Web Interface url:\t${default}http://${httpip}:${httpport}/index.html" + echo -e "${lightblue}Web Interface password:\t${default}${httppassword}" + } | column -s $'\t' -t + echo -e "" + echo -e "${bold}${lightgreen}${gamename} Telnet${default}" + fn_messages_separator + { + echo -e "${lightblue}Telnet enabled:\t${default}${telnetenabled}" + echo -e "${lightblue}Telnet address:\t${default}${telnetip} ${telnetport}" + echo -e "${lightblue}Telnet password:\t${default}${telnetpass}" + } | column -s $'\t' -t +} + +fn_info_messages_sf() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "Beacon" beaconport udp + } | column -s $'\t' -t +} + +fn_info_messages_sof2() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_sol() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "Files" filesport tcp + } | column -s $'\t' -t +} + +fn_info_messages_prism3d() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_source() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport tcp + fn_port "RCON" rconport tcp + fn_port "SourceTV" sourcetvport udp + # Will not show if unaviable + if [ "${steamport}" == "0" ] || [ -v "${steamport}" ]; then + fn_port "Steam" steamport udp + fi + fn_port "Client" clientport udp + } | column -s $'\t' -t +} + +fn_info_messages_spark() { + fn_info_messages_password_strip + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "Web Interface" httpport tcp + } | column -s $'\t' -t + echo -e "" + echo -e "${bold}${lightgreen}${gamename} Web Interface${default}" + fn_messages_separator + { + echo -e "${lightblue}Web Interface url:\t${default}http://${httpip}:${httpport}/index.html" + echo -e "${lightblue}Web Interface username:\t${default}${httpuser}" + echo -e "${lightblue}Web Interface password:\t${default}${httppassword}" + } | column -s $'\t' -t +} + +fn_info_messages_squad() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "RCON" rconport tcp + } | column -s $'\t' -t +} + +fn_info_messages_st() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_ti() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Queue" queueport tcp + fn_port "RCON" rconport tcp + } | column -s $'\t' -t +} + +fn_info_messages_ts3() { + { + fn_port "header" + fn_port "Voice" port udp + fn_port "Query" queryport tcp + fn_port "Query (SSH)" querysshport tcp + fn_port "Query (http)" queryhttpport tcp + fn_port "Query (https)" queryhttpsport tcp + fn_port "File Transfer" fileport tcp + fn_port "Telnet" telnetport tcp + } | column -s $'\t' -t +} + +fn_info_messages_tw() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_terraria() { + { + fn_port "header" + fn_port "Game" port tcp + fn_port "Query" queryport tcp + } | column -s $'\t' -t +} + +fn_info_messages_tu() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "Steam" steamport udp + } | column -s $'\t' -t +} + +fn_info_messages_tf() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport tcp + fn_port "Beacon" beaconport udp + fn_port "Shutdown" shutdownport tcp + } | column -s $'\t' -t +} + +fn_info_messages_ut2k4() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "Query (GameSpy)" queryportgs udp + fn_port "Web Interface" httpport tcp + fn_port "LAN" lanport udp + } | column -s $'\t' -t + echo -e "" + echo -e "${bold}${lightgreen}${gamename} Web Interface${default}" + fn_messages_separator + { + echo -e "${lightblue}Web Interface enabled:\t${default}${httpenabled}" + echo -e "${lightblue}Web Interface url:\t${default}http://${httpip}:${httpport}" + echo -e "${lightblue}Web Interface username:\t${default}${httpuser}" + echo -e "${lightblue}Web Interface password:\t${default}${httppassword}" + } | column -s $'\t' -t +} + +fn_info_messages_unreal() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "LAN Beacon" beaconport udp + fn_port "Web Interface" httpport tcp + } | column -s $'\t' -t + echo -e "" + echo -e "${bold}${lightgreen}${gamename} Web Interface${default}" + fn_messages_separator + { + echo -e "${lightblue}Web Interface enabled:\t${default}${httpenabled}" + echo -e "${lightblue}Web Interface url:\t${default}http://${httpip}:${httpport}" + echo -e "${lightblue}Web Interface username:\t${default}${httpuser}" + echo -e "${lightblue}Web Interface password:\t${default}${httppassword}" + } | column -s $'\t' -t +} + +fn_info_messages_unt() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "Steam" steamport udp + } | column -s $'\t' -t +} + +fn_info_messages_ut() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_ut3() { + fn_info_messages_password_strip + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + fn_port "Web Interface" httpport tcp + } | column -s $'\t' -t + echo -e "" + echo -e "${bold}${lightgreen}${gamename} Web Interface${default}" + fn_messages_separator + { + echo -e "${lightblue}Web Interface enabled:\t${default}${httpenabled}" + echo -e "${lightblue}Web Interface url:\t${default}http://${httpip}:${httpport}" + echo -e "${lightblue}Web Interface username:\t${default}${httpuser}" + echo -e "${lightblue}Web Interface password:\t${default}${httppassword}" + } | column -s $'\t' -t +} + +fn_info_messages_vh() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_vints() { + { + fn_port "header" + fn_port "Game" port tcp + } | column -s $'\t' -t +} + +fn_info_messages_vpmc() { + { + fn_port "header" + fn_port "Game" port tcp + } | column -s $'\t' -t +} + +fn_info_messages_wet() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_wf() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "HTTP" httpport tcp + } | column -s $'\t' -t +} + +fn_info_messages_wurm() { + { + fn_port "header" + fn_port "Game" port tcp + fn_port "Query" queryport udp + fn_port "RMI" rmiport tcp + fn_port "RMI Registry" rmiregport tcp + } | column -s $'\t' -t +} + +fn_info_messages_stn() { + { + fn_port "header" + fn_port "Game" port udp + fn_port "Query" queryport udp + } | column -s $'\t' -t +} + +fn_info_messages_select_engine() { + # Display details depending on game or engine. + if [ "${shortname}" == "ac" ]; then + fn_info_messages_ac + elif [ "${shortname}" == "ark" ]; then + fn_info_messages_ark + elif [ "${shortname}" == "arma3" ]; then + fn_info_messages_arma3 + elif [ "${shortname}" == "armar" ]; then + fn_info_messages_armar + elif [ "${shortname}" == "av" ]; then + fn_info_messages_av + elif [ "${shortname}" == "bf1942" ]; then + fn_info_messages_bf1942 + elif [ "${shortname}" == "bfv" ]; then + fn_info_messages_bfv + elif [ "${shortname}" == "bo" ]; then + fn_info_messages_bo + elif [ "${shortname}" == "bt" ]; then + fn_info_messages_bt + elif [ "${shortname}" == "btl" ]; then + fn_info_messages_btl + elif [ "${shortname}" == "cd" ]; then + fn_info_messages_cd + elif [ "${shortname}" == "ck" ]; then + fn_info_messages_ck + elif [ "${shortname}" == "cs2" ]; then + fn_info_messages_cs2 + elif [ "${shortname}" == "csgo" ]; then + fn_info_messages_csgo + elif [ "${shortname}" == "cmw" ]; then + fn_info_messages_cmw + elif [ "${shortname}" == "cod" ]; then + fn_info_messages_cod + elif [ "${shortname}" == "coduo" ]; then + fn_info_messages_coduo + elif [ "${shortname}" == "cod2" ]; then + fn_info_messages_cod2 + elif [ "${shortname}" == "cod4" ]; then + fn_info_messages_cod4 + elif [ "${shortname}" == "codwaw" ]; then + fn_info_messages_codwaw + elif [ "${shortname}" == "col" ]; then + fn_info_messages_col + elif [ "${shortname}" == "ct" ]; then + fn_info_messages_ct + elif [ "${shortname}" == "dayz" ]; then + fn_info_messages_dayz + elif [ "${shortname}" == "dodr" ]; then + fn_info_messages_dodr + elif [ "${shortname}" == "dst" ]; then + fn_info_messages_dst + elif [ "${shortname}" == "eco" ]; then + fn_info_messages_eco + elif [ "${shortname}" == "etl" ]; then + fn_info_messages_etl + elif [ "${shortname}" == "fctr" ]; then + fn_info_messages_fctr + elif [ "${shortname}" == "hcu" ]; then + fn_info_messages_hcu + elif [ "${shortname}" == "hw" ]; then + fn_info_messages_hw + elif [ "${shortname}" == "ins" ]; then + fn_info_messages_ins + elif [ "${shortname}" == "inss" ]; then + fn_info_messages_inss + elif [ "${shortname}" == "jc2" ]; then + fn_info_messages_jc2 + elif [ "${shortname}" == "jc3" ]; then + fn_info_messages_jc3 + elif [ "${shortname}" == "jk2" ]; then + fn_info_messages_jk2 + elif [ "${shortname}" == "kf" ]; then + fn_info_messages_kf + elif [ "${shortname}" == "kf2" ]; then + fn_info_messages_kf2 + elif [ "${shortname}" == "mc" ] || [ "${shortname}" == "pmc" ] || [ "${shortname}" == "wmc" ]; then + fn_info_messages_mc + elif [ "${shortname}" == "mcb" ]; then + fn_info_messages_mcb + elif [ "${shortname}" == "mh" ]; then + fn_info_messages_mh + elif [ "${shortname}" == "mohaa" ]; then + fn_info_messages_mohaa + elif [ "${shortname}" == "mom" ]; then + fn_info_messages_mom + elif [ "${shortname}" == "mta" ]; then + fn_info_messages_mta + elif [ "${shortname}" == "nec" ]; then + fn_info_messages_nec + elif [ "${shortname}" == "ohd" ]; then + fn_info_messages_ohd + elif [ "${shortname}" == "onset" ]; then + fn_info_messages_onset + elif [ "${shortname}" == "pc" ]; then + fn_info_messages_pc + elif [ "${shortname}" == "pc2" ]; then + fn_info_messages_pc2 + elif [ "${shortname}" == "ps" ]; then + fn_info_messages_ps + elif [ "${shortname}" == "pvr" ]; then + fn_info_messages_pvr + elif [ "${shortname}" == "pz" ]; then + fn_info_messages_pz + elif [ "${shortname}" == "q2" ]; then + fn_info_messages_q2 + elif [ "${shortname}" == "q3" ]; then + fn_info_messages_q3 + elif [ "${shortname}" == "ql" ]; then + fn_info_messages_ql + elif [ "${shortname}" == "qw" ]; then + fn_info_messages_qw + elif [ "${shortname}" == "ro" ]; then + fn_info_messages_ro + elif [ "${shortname}" == "rtcw" ]; then + fn_info_messages_rtcw + elif [ "${shortname}" == "samp" ]; then + fn_info_messages_samp + elif [ "${shortname}" == "sb" ]; then + fn_info_messages_sb + elif [ "${shortname}" == "sbots" ]; then + fn_info_messages_sbots + elif [ "${shortname}" == "scpsl" ] || [ "${shortname}" == "scpslsm" ]; then + fn_info_messages_scpsl + elif [ "${shortname}" == "sdtd" ]; then + fn_info_messages_sdtd + elif [ "${shortname}" == "sf" ]; then + fn_info_messages_sf + elif [ "${shortname}" == "sof2" ]; then + fn_info_messages_sof2 + elif [ "${shortname}" == "sol" ]; then + fn_info_messages_sol + elif [ "${shortname}" == "squad" ]; then + fn_info_messages_squad + elif [ "${shortname}" == "st" ]; then + fn_info_messages_st + elif [ "${shortname}" == "stn" ]; then + fn_info_messages_stn + elif [ "${shortname}" == "terraria" ]; then + fn_info_messages_terraria + elif [ "${shortname}" == "tf" ]; then + fn_info_messages_tf + elif [ "${shortname}" == "ti" ]; then + fn_info_messages_ti + elif [ "${shortname}" == "ts3" ]; then + fn_info_messages_ts3 + elif [ "${shortname}" == "tu" ]; then + fn_info_messages_tu + elif [ "${shortname}" == "tw" ]; then + fn_info_messages_tw + elif [ "${shortname}" == "unt" ]; then + fn_info_messages_unt + elif [ "${shortname}" == "vh" ]; then + fn_info_messages_vh + elif [ "${shortname}" == "vints" ]; then + fn_info_messages_vints + elif [ "${shortname}" == "rust" ]; then + fn_info_messages_rust + elif [ "${shortname}" == "rw" ]; then + fn_info_messages_rw + elif [ "${shortname}" == "ut" ]; then + fn_info_messages_ut + elif [ "${shortname}" == "ut2k4" ]; then + fn_info_messages_ut2k4 + elif [ "${shortname}" == "ut3" ]; then + fn_info_messages_ut3 + elif [ "${shortname}" == "vpmc" ]; then + fn_info_messages_vpmc + elif [ "${shortname}" == "wet" ]; then + fn_info_messages_wet + elif [ "${shortname}" == "wf" ]; then + fn_info_messages_wf + elif [ "${shortname}" == "wurm" ]; then + fn_info_messages_wurm + elif [ "${engine}" == "goldsrc" ]; then + fn_info_messages_goldsrc + elif [ "${engine}" == "prism3d" ]; then + fn_info_messages_prism3d + elif [ "${engine}" == "source" ]; then + fn_info_messages_source + elif [ "${engine}" == "spark" ]; then + fn_info_messages_spark + elif [ "${engine}" == "unreal" ]; then + fn_info_messages_unreal + else + fn_print_error_nl "Unable to detect game server." + fi +} diff --git a/lgsm/modules/info_stats.sh b/lgsm/modules/info_stats.sh new file mode 100644 index 0000000..8f01195 --- /dev/null +++ b/lgsm/modules/info_stats.sh @@ -0,0 +1,167 @@ +#!/bin/bash +# LinuxGSM info_stats.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Collect optional Stats sent to LinuxGSM project. +# Uses Google analytics. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +info_distro.sh + +# remove uuid that was used in v20.2.0 and below +if [ -f "${datadir}/uuid.txt" ]; then + rm -f "${datadir:?}/uuid.txt" +fi + +# generate uuid's +# this consists of a standard uuid and a docker style name +# to allow human readable uuid's. +# e.g angry_proskuriakova_38a9ef76-4ae3-46a6-a895-7af474831eba + +if [ ! -f "${datadir}/uuid-${selfname}.txt" ] || [ ! -f "${datadir}/uuid-install.txt" ]; then + # download dictionary words + if [ ! -f "${datadir}/name-left.csv" ]; then + fn_fetch_file_github "lgsm/data" "name-left.csv" "${datadir}" "nochmodx" "norun" "forcedl" "nohash" + fi + if [ ! -f "${datadir}/name-right.csv" ]; then + fn_fetch_file_github "lgsm/data" "name-right.csv" "${datadir}" "nochmodx" "norun" "forcedl" "nohash" + fi + + # generate instance uuid + if [ -n "$(command -v uuidgen 2> /dev/null)" ]; then + uuid="$(uuidgen)" + else + uuid="$(cat /proc/sys/kernel/random/uuid)" + fi + + nameleft="$(shuf -n 1 "${datadir}/name-left.csv")" + nameright="$(shuf -n 1 "${datadir}/name-right.csv")" + echo "instance_${nameleft}_${nameright}_${uuid}" > "${datadir}/uuid-${selfname}.txt" + # generate install uuid if missing + if [ ! -f "${datadir}/uuid-install.txt" ]; then + echo "${nameleft}_${nameright}_${uuid}" > "${datadir}/uuid-install.txt" + fi +fi + +uuidinstance=$(cat "${datadir}/uuid-${selfname}.txt") +uuidinstall=$(cat "${datadir}/uuid-install.txt") +# machine-id is a unique id set on OS install +uuidhardware=$(cat "/etc/machine-id") + +# results are rounded up to reduce number of different results in analytics. +# nearest 100Mhz. +cpuusedmhzroundup="$(((cpuusedmhz + 99) / 100 * 100))" +# nearest 100MB +memusedroundup="$(((memused + 99) / 100 * 100))" + +apisecret="A-OzP02TSMWt4_vHi6ZpUw" +measurementid="G-0CR8V7EMT5" + +# Sending stats to Google Analytics GA4 +payload="{ + \"client_id\": \"${uuidinstance}\", + \"events\": [ + { + \"name\": \"LinuxGSM\", + \"params\": { + \"cpuusedmhzroundup\": \"${cpuusedmhzroundup}MHz\", + \"diskused\": \"${serverfilesdu}\", + \"distro\": \"${distroname}\", + \"game\": \"${gamename}\", + \"memusedroundup\": \"${memusedroundup}MB\", + \"ramused\": \"${memusedroundup}MB\", + \"servercpu\": \"${cpumodel} ${cpucores} cores\", + \"servercpufreq\": \"${cpufreqency} x${cpucores}\", + \"serverdisk\": \"${totalspace}\", + \"serverfilesdu\": \"${serverfilesdu}\", + \"serverram\": \"${physmemtotal}\", + \"uuidhardware\": \"${uuidhardware}\", + \"uuidinstall\": \"${uuidinstall}\", + \"uuidinstance\": \"${uuidinstance}\", + \"version\": \"${version}\", + \"virtualenvironment\": \"${virtualenvironment}\" + } + } + ] +}" + +fn_alert_payload() { + alertpayload="{ + \"client_id\": \"${uuidinstance}\", + \"events\": [ + { + \"name\": \"LinuxGSM\", + \"params\": { + \"alert\": \"${alerttype}\" + } + } + ] +}" +} + +curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=A-OzP02TSMWt4_vHi6ZpUw&measurement_id=G-0CR8V7EMT5" -H "Content-Type: application/json" -d "${payload}" + +if [ "${discordalert}" == "on" ]; then + alerttype="discord" + fn_alert_payload + curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}" +fi +if [ "${emailalert}" == "on" ]; then + alerttype="email" + fn_alert_payload + curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}" +fi +if [ "${gotifyalert}" == "on" ]; then + alerttype="gotify" + fn_alert_payload + curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}" +fi +if [ "${iftttalert}" == "on" ]; then + alerttype="ifttt" + fn_alert_payload + curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}" +fi +if [ "${pushbulletalert}" == "on" ]; then + alerttype="pushbullet" + fn_alert_payload + curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}" +fi +if [ "${pushoveralert}" == "on" ]; then + alerttype="pushover" + fn_alert_payload + curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}" +fi +if [ "${rocketchatalert}" == "on" ]; then + alerttype="rocketchat" + fn_alert_payload + curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}" +fi +if [ "${slackalert}" == "on" ]; then + alerttype="slack" + fn_alert_payload + curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}" +fi +if [ "${telegramalert}" == "on" ]; then + alerttype="telegram" + fn_alert_payload + curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}" +fi + +fn_script_log_info "Send LinuxGSM stats" +fn_script_log_info "* uuid-${selfname}: ${uuidinstance}" +fn_script_log_info "* uuid-install: ${uuidinstall}" +fn_script_log_info "* uuid-hardware: ${uuidhardware}" +fn_script_log_info "* Game Name: ${gamename}" +fn_script_log_info "* Distro Name: ${distroname}" +fn_script_log_info "* Game Server CPU Used: ${cpuusedmhzroundup}MHz" +fn_script_log_info "* Game Server RAM Used: ${memusedroundup}MB" +fn_script_log_info "* Game Server Disk Used: ${serverfilesdu}" +fn_script_log_info "* Server CPU Model: ${cpumodel}" +fn_script_log_info "* Server CPU Frequency: ${cpufreqency}" +fn_script_log_info "* Server RAM: ${physmemtotal}" +fn_script_log_info "* Server Disk: ${totalspace}" +fn_script_log_info "* Virtual Environment: ${virtualenvironment}" +fn_script_log_info "* LinuxGSM Version: ${version}" +fn_script_log_info "* Enabled Alerts" diff --git a/lgsm/modules/install_complete.sh b/lgsm/modules/install_complete.sh new file mode 100644 index 0000000..5a98730 --- /dev/null +++ b/lgsm/modules/install_complete.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# LinuxGSM install_complete.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Prints installation completion message and hints. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +echo -e "" +fn_messages_separator + +if [ "${exitcode}" == "1" ]; then + echo -e "${bold}${red}Install Failed!${default}" + fn_script_log_fail "Install Failed!" +elif [ "${exitcode}" == "2" ]; then + echo -e "${bold}${red}Install Completed with Errors!${default}}" + fn_script_log_error "Install Completed with Errors!" +elif [ "${exitcode}" == "3" ]; then + echo -e "${bold}${lightyellow}Install Completed with Warnings!${default}}" + fn_script_log_warn "Install Completed with Warnings!" +elif [ -z "${exitcode}" ] || [ "${exitcode}" == "0" ]; then + echo -e "${bold}${green}Install Complete!${default}" + fn_script_log_pass "Install Complete!" +fi + +fn_script_log_info "Install Complete!" +echo -e "" +echo -e "To start server type:" +echo -e "./${selfname} start" +echo -e "" +core_exit.sh diff --git a/lgsm/modules/install_config.sh b/lgsm/modules/install_config.sh new file mode 100644 index 0000000..59bcd90 --- /dev/null +++ b/lgsm/modules/install_config.sh @@ -0,0 +1,850 @@ +#!/bin/bash +# LinuxGSM install_config.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Creates default server configs. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Checks if server cfg dir exists, creates it if it doesn't. +fn_check_cfgdir() { + if [ ! -d "${servercfgdir}" ]; then + echo -e "creating ${servercfgdir} config directory." + fn_script_log_info "Creating ${servercfgdir} config directory." + mkdir -pv "${servercfgdir}" + fi +} + +# Downloads default configs from Game-Server-Configs repo to lgsm/config-default. +fn_fetch_default_config() { + echo -e "" + echo -e "${bold}${lightyellow}Downloading ${gamename} Configs${default}" + fn_messages_separator + echo -e "Downloading default configs from:" + echo -e "" + echo -e "${italic}https://github.com/GameServerManagers/Game-Server-Configs${default}" + echo -e "" + fn_sleep_time_1 + mkdir -p "${lgsmdir}/config-default/config-game" + githuburl="https://raw.githubusercontent.com/GameServerManagers/Game-Server-Configs/main" + for config in "${array_configs[@]}"; do + fn_fetch_file "${githuburl}/${shortname}/${config}" "${remote_fileurl_backup}" "GitHub" "Bitbucket" "${lgsmdir}/config-default/config-game" "${config}" "nochmodx" "norun" "forcedl" "nohash" + done +} + +# Copys default configs from Game-Server-Configs repo to server config location. +fn_default_config_remote() { + for config in "${array_configs[@]}"; do + # every config is copied + echo -e "copying ${config} config file." + fn_script_log_info "Copying ${servercfg} config file." + if [ "${config}" == "${servercfgdefault}" ]; then + mkdir -p "${servercfgdir}" + cp -nv "${lgsmdir}/config-default/config-game/${config}" "${servercfgfullpath}" + elif [ "${shortname}" == "arma3" ] && [ "${config}" == "${networkcfgdefault}" ]; then + mkdir -p "${servercfgdir}" + cp -nv "${lgsmdir}/config-default/config-game/${config}" "${networkcfgfullpath}" + elif [ "${shortname}" == "dst" ] && [ "${config}" == "${clustercfgdefault}" ]; then + cp -nv "${lgsmdir}/config-default/config-game/${clustercfgdefault}" "${clustercfgfullpath}" + else + mkdir -p "${servercfgdir}" + cp -nv "${lgsmdir}/config-default/config-game/${config}" "${servercfgdir}/${config}" + fi + done + fn_sleep_time +} + +# Copys local default config to server config location. +fn_default_config_local() { + echo -e "" + echo -e "${bold}${lightyellow}Copying ${gamename} Configs${default}" + fn_messages_separator + echo -e "Copying default configs." + fn_check_cfgdir + echo -en "copying config file [ ${italic}${servercfgdefault}${default} ]" + cp -n "${servercfgdir}/${servercfgdefault}" "${servercfgfullpath}" + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol + fn_script_log_fail "copying config file [ ${servercfgdefault} ]" + else + fn_print_ok_eol + fn_script_log_pass "copying config file [ ${servercfgdefault} ]" + fi +} + +# Changes some variables within the default configs. +# SERVERNAME to LinuxGSM +# PASSWORD to random password +fn_set_config_vars() { + if [ -f "${servercfgfullpath}" ]; then + randomstring=$(tr -dc 'A-Za-z0-9_' < /dev/urandom 2> /dev/null | head -c 8 | xargs) + servername="LinuxGSM" + rconpass="admin${randomstring}" + echo -e "changing hostname." + fn_script_log_info "Changing hostname." + fn_sleep_time + # prevents var from being overwritten with the servername. + if grep -q "SERVERNAME=SERVERNAME" "${lgsmdir}/config-default/config-game/${config}" 2> /dev/null; then + sed -i "s/SERVERNAME=SERVERNAME/SERVERNAME=${servername}/g" "${servercfgfullpath}" + elif grep -q "SERVERNAME=\"SERVERNAME\"" "${lgsmdir}/config-default/config-game/${config}" 2> /dev/null; then + sed -i "s/SERVERNAME=\"SERVERNAME\"/SERVERNAME=\"${servername}\"/g" "${servercfgfullpath}" + else + sed -i "s/SERVERNAME/${servername}/g" "${servercfgfullpath}" + fi + echo -e "changing rcon/admin password." + fn_script_log_info "Changing rcon/admin password." + if [ "${shortname}" == "squad" ]; then + sed -i "s/ADMINPASSWORD/${rconpass}/g" "${servercfgdir}/Rcon.cfg" + else + sed -i "s/ADMINPASSWORD/${rconpass}/g" "${servercfgfullpath}" + fi + fn_sleep_time + else + fn_script_log_warn "Config file not found, cannot alter it." + echo -e "Config file not found, cannot alter it." + fn_sleep_time + fi +} + +# Changes some variables within the default Don't Starve Together configs. +fn_set_dst_config_vars() { + ## cluster.ini + if grep -Fq "SERVERNAME" "${clustercfgfullpath}"; then + echo -e "changing server name." + fn_script_log_info "Changing server name." + sed -i "s/SERVERNAME/LinuxGSM/g" "${clustercfgfullpath}" + fn_sleep_time + echo -e "changing shard mode." + fn_script_log_info "Changing shard mode." + sed -i "s/USESHARDING/${sharding}/g" "${clustercfgfullpath}" + fn_sleep_time + echo -e "randomizing cluster key." + fn_script_log_info "Randomizing cluster key." + randomstring=$(tr -dc 'A-Za-z0-9_' < /dev/urandom 2> /dev/null | head -c 8 | xargs) + sed -i "s/CLUSTERKEY/${randomstring}/g" "${clustercfgfullpath}" + fn_sleep_time + else + echo -e "${clustercfg} is already configured." + fn_script_log_info "${clustercfg} is already configured." + fi + + ## server.ini + # removing unnecessary options (dependent on sharding & shard type). + if [ "${sharding}" == "false" ]; then + sed -i "s/ISMASTER//g" "${servercfgfullpath}" + sed -i "/SHARDNAME/d" "${servercfgfullpath}" + elif [ "${master}" == "true" ]; then + sed -i "/SHARDNAME/d" "${servercfgfullpath}" + fi + + echo -e "changing shard name." + fn_script_log_info "Changing shard name." + sed -i "s/SHARDNAME/${shard}/g" "${servercfgfullpath}" + fn_sleep_time + echo -e "changing master setting." + fn_script_log_info "Changing master setting." + sed -i "s/ISMASTER/${master}/g" "${servercfgfullpath}" + fn_sleep_time + + ## worldgenoverride.lua + if [ "${cave}" == "true" ]; then + echo -e "defining ${shard} as cave in ${servercfgdir}/worldgenoverride.lua." + fn_script_log_info "Defining ${shard} as cave in ${servercfgdir}/worldgenoverride.lua." + echo 'return { override_enabled = true, preset = "DST_CAVE", }' > "${servercfgdir}/worldgenoverride.lua" + fi + fn_sleep_time + echo -e "" +} + +# Lists local config file locations +fn_list_config_locations() { + echo -e "" + echo -e "${bold}${lightyellow}Config Locations${default}" + fn_messages_separator + if [ -n "${servercfgfullpath}" ]; then + if [ -f "${servercfgfullpath}" ]; then + echo -e "Game Server Config File: ${servercfgfullpath}" + elif [ -d "${servercfgfullpath}" ]; then + echo -e "Game Server Config Dir: ${servercfgfullpath}" + else + echo -e "Config file: ${red}${servercfgfullpath}${default} (${red}FILE MISSING${default})" + fi + fi + echo -e "LinuxGSM Config: ${lgsmdir}/config-lgsm/${gameservername}" + echo -e "Documentation: https://docs.linuxgsm.com/configuration/game-server-config" +} + +if [ "${shortname}" == "sdtd" ]; then + fn_default_config_local + fn_list_config_locations +elif [ "${shortname}" == "ac" ]; then + array_configs+=(server_cfg.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ahl" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ahl2" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ark" ]; then + fn_check_cfgdir + array_configs+=(GameUserSettings.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "arma3" ]; then + fn_check_cfgdir + array_configs+=(server.cfg network.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "armar" ]; then + fn_check_cfgdir + array_configs+=(server.json) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ats" ]; then + fn_check_cfgdir + array_configs+=(server_config.sii) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "bo" ]; then + array_configs+=(config.txt) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "bd" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "bt" ]; then + fn_check_cfgdir + array_configs+=(serversettings.xml) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "btl" ]; then + fn_check_cfgdir + array_configs+=(DefaultGame.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "bf1942" ]; then + array_configs+=(serversettings.con) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "bfv" ]; then + array_configs+=(serversettings.con) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "bs" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "bb" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "bb2" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "bmdm" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "cd" ]; then + array_configs+=(properties.json) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ck" ]; then + array_configs+=(ServerConfig.json) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "cod" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "coduo" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "cod2" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "cod4" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "codwaw" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "cc" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "col" ]; then + array_configs+=(colserver.json) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "cs" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "cs2" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "cscz" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "csgo" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "css" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ct" ]; then + array_configs+=(ServerSetting.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "dayz" ]; then + fn_check_cfgdir + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "dod" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "dodr" ]; then + array_configs+=(Game.ini) + fn_fetch_default_config + fn_default_config_remote + fn_list_config_locations +elif [ "${shortname}" == "dods" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "doi" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "dmc" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "dst" ]; then + fn_check_cfgdir + array_configs+=(cluster.ini server.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_dst_config_vars + fn_list_config_locations +elif [ "${shortname}" == "dab" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "dys" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "eco" ]; then + array_configs+=(Network.eco) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "em" ]; then + fn_default_config_local + fn_list_config_locations +elif [ "${shortname}" == "etl" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ets2" ]; then + fn_check_cfgdir + array_configs+=(server_config.sii) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "fctr" ]; then + array_configs+=(server-settings.json) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "fof" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "gmod" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "hldm" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "hldms" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ohd" ]; then + array_configs+=(Game.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "opfor" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "hl2dm" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ins" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ios" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "jc2" ]; then + array_configs+=(config.lua) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "jc3" ]; then + array_configs+=(config.json) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "kf" ]; then + array_configs+=(Default.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "l4d" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "l4d2" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "mc" ] || [ "${shortname}" == "pmc" ]; then + array_configs+=(server.properties) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "mcb" ]; then + array_configs+=(server.properties) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "mohaa" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "mh" ]; then + fn_check_cfgdir + array_configs+=(Game.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ns" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "nmrih" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "nd" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "mta" ]; then + fn_check_cfgdir + array_configs+=(acl.xml mtaserver.conf vehiclecolors.conf) + fn_fetch_default_config + fn_default_config_remote + fn_list_config_locations +elif [ "${shotname}" == "mom" ]; then + array_configs+=(DedicatedServerConfig.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "pvr" ]; then + fn_check_cfgdir + array_configs+=(Game.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars +elif [ "${shortname}" == "pvkii" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "pz" ]; then + fn_check_cfgdir + array_configs+=(server.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "nec" ]; then + fn_check_cfgdir + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "pc" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "pc2" ]; then + fn_default_config_local + fn_list_config_locations +elif [ "${shortname}" == "q2" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "q3" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ql" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "jk2" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars +elif [ "${shortname}" == "qw" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ricochet" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "rtcw" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "rust" ]; then + fn_check_cfgdir + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_list_config_locations +elif [ "${shortname}" == "scpsl" ] || [ "${shortname}" == "scpslsm" ]; then + array_configs+=(config_gameplay.txt config_localadmin.txt) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "sf" ]; then + array_configs+=(GameUserSettings.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "sol" ]; then + array_configs+=(soldat.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "sof2" ]; then + array_configs+=(server.cfg mapcycle.txt) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "sfc" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "squad" ]; then + array_configs+=(Admins.cfg Bans.cfg License.cfg Server.cfg Rcon.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "sb" ]; then + array_configs+=(starbound_server.config) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "stn" ]; then + array_configs+=(ServerConfig.txt ServerUsers.txt TpPresets.json UserPermissions.json) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "sven" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "tf2" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "tfc" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ti" ]; then + array_configs+=(Game.ini Engine.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ts" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ts3" ]; then + array_configs+=(ts3server.ini) + fn_fetch_default_config + fn_default_config_remote + fn_list_config_locations +elif [ "${shortname}" == "tw" ]; then + array_configs+=(server.cfg ctf.cfg dm.cfg duel.cfg tdm.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "terraria" ]; then + array_configs+=(serverconfig.txt) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "tu" ]; then + fn_check_cfgdir + array_configs+=(TowerServer.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ut" ]; then + array_configs+=(Game.ini Engine.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ut2k4" ]; then + array_configs+=(UT2004.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "ut99" ]; then + array_configs+=(Default.ini) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "unt" ]; then + # Config is generated on first run + : +elif [ "${shortname}" == "vints" ]; then + # Config is generated on first run + : +elif [ "${shortname}" == "vs" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "wet" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "wf" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "wmc" ]; then + array_configs+=(config.yml) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars +elif [ "${shortname}" == "wurm" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "zmr" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +elif [ "${shortname}" == "zps" ]; then + array_configs+=(server.cfg) + fn_fetch_default_config + fn_default_config_remote + fn_set_config_vars + fn_list_config_locations +fi diff --git a/lgsm/modules/install_dst_token.sh b/lgsm/modules/install_dst_token.sh new file mode 100644 index 0000000..89ec00a --- /dev/null +++ b/lgsm/modules/install_dst_token.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# LinuxGSM install_dst_token.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Configures Don't Starve Together cluster with given token. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +echo -e "" +echo -e "${bold}${lightyellow}Enter ${gamename} Cluster Token${default}" +fn_messages_separator +echo -e "A cluster token is required to run this server!" +echo -e "Follow the instructions in this link to obtain this key:" +echo -e "https://linuxgsm.com/dst-auth-token" +echo -e "" +if [ -z "${autoinstall}" ]; then + overwritetoken="true" + if [ -s "${clustercfgdir}/cluster_token.txt" ]; then + echo -e "The cluster token is already set. Do you want to overwrite it?" + fn_script_log_info "Don't Starve Together cluster token is already set" + if fn_prompt_yn "Continue?" N; then + overwritetoken="true" + else + overwritetoken="false" + fi + fi + if [ "${overwritetoken}" == "true" ]; then + echo -e "Once you have the cluster token, enter it below" + echo -n "Cluster Token: " + read -r token + mkdir -pv "${clustercfgdir}" + echo -e "${token}" > "${clustercfgdir}/cluster_token.txt" + if [ -f "${clustercfgdir}/cluster_token.txt" ]; then + echo -e "Don't Starve Together cluster token created" + fn_script_log_info "Don't Starve Together cluster token created" + fi + unset overwritetoken + fi +else + echo -e "You can add your cluster token using the following command" + echo -e "./${selfname} cluster-token" +fi +echo -e "" diff --git a/lgsm/modules/install_eula.sh b/lgsm/modules/install_eula.sh new file mode 100644 index 0000000..7f7f95f --- /dev/null +++ b/lgsm/modules/install_eula.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# LinuxGSM install_eula.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Gets user to accept the EULA. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +if [ "${shortname}" == "ts3" ]; then + eulaurl="https://www.teamspeak.com/en/privacy-and-terms" +elif [ "${shortname}" == "mc" ] || [ "${shortname}" == "pmc" ]; then + eulaurl="https://account.mojang.com/documents/minecraft_eula" +elif [ "${shortname}" == "ut" ]; then + eulaurl="https://www.epicgames.com/unrealtournament/unreal-tournament-pre-alpha-test-development-build-eula" +fi + +echo -e "" +echo -e "${bold}${lightyellow}Accept ${gamename} EULA${default}" +fn_messages_separator +echo -e "You are required to accept the EULA:" +echo -e "${eulaurl}" +echo -e "" +if [ -z "${autoinstall}" ]; then + echo -e "By continuing you are indicating your agreement to the EULA." + echo -e "" + if ! fn_prompt_yn "Continue?" Y; then + exitcode=0 + core_exit.sh + fi +elif [ "${commandname}" == "START" ]; then + fn_print_info "By continuing you are indicating your agreement to the EULA." + fn_sleep_time_5 +else + echo -e "By using auto-install you are indicating your agreement to the EULA." + fn_sleep_time_5 +fi + +if [ "${shortname}" == "ts3" ]; then + touch "${executabledir}/.ts3server_license_accepted" +elif [ "${shortname}" == "mc" ] || [ "${shortname}" == "pmc" ]; then + touch "${serverfiles}/eula.txt" + echo -e "eula=true" > "${serverfiles}/eula.txt" +elif [ "${shortname}" == "ut" ]; then + : +fi diff --git a/lgsm/modules/install_factorio_save.sh b/lgsm/modules/install_factorio_save.sh new file mode 100644 index 0000000..589a9d8 --- /dev/null +++ b/lgsm/modules/install_factorio_save.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# LinuxGSM install_factorio_save.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Creates the initial save file for Factorio. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +echo -e "" +echo -e "${bold}${lightyellow}Creating initial Factorio savefile${default}" +fn_messages_separator +check_glibc.sh +"${executabledir}"/factorio --create "${serverfiles}/save1" diff --git a/lgsm/modules/install_gslt.sh b/lgsm/modules/install_gslt.sh new file mode 100644 index 0000000..aa8d89d --- /dev/null +++ b/lgsm/modules/install_gslt.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# LinuxGSM install_gslt.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Configures GSLT. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +echo -e "" +echo -e "${bold}${lightyellow}Game Server Login Token${default}" +fn_messages_separator +if [ "${shortname}" == "csgo" ] || [ "${shortname}" == "css" ] || [ "${shortname}" == "nmrih" ] || [ "${shortname}" == "bs" ]; then + echo -e "GSLT is required to run a public ${gamename} server" + fn_script_log_info "GSLT is required to run a public ${gamename} server" +else + echo -e "GSLT is an optional feature for ${gamename} server" + fn_script_log_info "GSLT is an optional feature for ${gamename} server" +fi + +echo -e "Get more info and a token here:" +echo -e "https://docs.linuxgsm.com/steamcmd/gslt" +fn_script_log_info "Get more info and a token here:" +fn_script_log_info "https://docs.linuxgsm.com/steamcmd/gslt" +echo -e "" +if [ -z "${autoinstall}" ]; then + if [ "${shortname}" != "tu" ]; then + echo -e "Enter token below (Can be blank)." + echo -n "GSLT TOKEN: " + read -r token + if ! grep -q "^gslt=" "${configdirserver}/${selfname}.cfg" > /dev/null 2>&1; then + echo -e "\ngslt=\"${token}\"" >> "${configdirserver}/${selfname}.cfg" + else + sed -i -e "s/gslt=\"[^\"]*\"/gslt=\"${token}\"/g" "${configdirserver}/${selfname}.cfg" + fi + fi +fi + +if [ "${shortname}" == "tu" ]; then + echo -e "The GSLT can be changed by editing ${servercfgdir}/${servercfg}." + fn_script_log_info "The GSLT can be changed by editing ${servercfgdir}/${servercfg}." +else + echo -e "The GSLT can be changed by editing ${configdirserver}/${selfname}.cfg." + fn_script_log_info "The GSLT can be changed by editing ${configdirserver}/${selfname}.cfg." +fi +fn_sleep_time_1 +echo -e "" diff --git a/lgsm/modules/install_header.sh b/lgsm/modules/install_header.sh new file mode 100644 index 0000000..a7f1f9d --- /dev/null +++ b/lgsm/modules/install_header.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# LinuxGSM install_header.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Prints installation header. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +clear +fn_print_ascii_logo +fn_messages_separator +echo -e "${bold}${lightyellow}Linux${default}${bold}GSM_${default}" +echo -e "${italic}by Daniel Gibbs${default}" +echo -e "${lightblue}Version:${default} ${version}" +echo -e "${lightblue}Game:${default} ${gamename}" +echo -e "${lightblue}Website:${default} https://linuxgsm.com" +echo -e "${lightblue}Contributors:${default} https://linuxgsm.com/contrib" +echo -e "${lightblue}Sponsor:${default} https://linuxgsm.com/sponsor" +fn_messages_separator diff --git a/lgsm/modules/install_logs.sh b/lgsm/modules/install_logs.sh new file mode 100644 index 0000000..294bc1e --- /dev/null +++ b/lgsm/modules/install_logs.sh @@ -0,0 +1,99 @@ +#!/bin/bash +# LinuxGSM install_logs.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Creates log directories. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +if [ "${checklogs}" != "1" ]; then + echo -e "" + echo -e "${bold}${lightyellow}Creating Log Directories${default}" + fn_messages_separator +fi +# Create LinuxGSM logs. +echo -en "installing log dir: ${logdir}..." +mkdir -p "${logdir}" +if [ $? != 0 ]; then + fn_print_fail_eol_nl + core_exit.sh +else + fn_print_ok_eol_nl +fi + +echo -en "installing LinuxGSM log dir: ${lgsmlogdir}..." +mkdir -p "${lgsmlogdir}" +if [ $? != 0 ]; then + fn_print_fail_eol_nl + core_exit.sh +else + fn_print_ok_eol_nl +fi +echo -en "creating LinuxGSM log: ${lgsmlog}..." +touch "${lgsmlog}" +if [ $? != 0 ]; then + fn_print_fail_eol_nl + core_exit.sh +else + fn_print_ok_eol_nl +fi +# Create Console logs. +if [ "${consolelogdir}" ]; then + echo -en "installing console log dir: ${consolelogdir}..." + mkdir -p "${consolelogdir}" + if [ $? != 0 ]; then + fn_print_fail_eol_nl + core_exit.sh + else + fn_print_ok_eol_nl + fi + echo -en "creating console log: ${consolelog}..." + if ! touch "${consolelog}"; then + fn_print_fail_eol_nl + core_exit.sh + else + fn_print_ok_eol_nl + fi +fi + +# Create Game logs. +if [ "${gamelogdir}" ] && [ ! -d "${gamelogdir}" ]; then + echo -en "installing game log dir: ${gamelogdir}..." + if ! mkdir -p "${gamelogdir}"; then + fn_print_fail_eol_nl + core_exit.sh + else + fn_print_ok_eol_nl + fi +fi + +# Symlink to gamelogdir +# unless gamelogdir is within logdir. +# e.g serverfiles/log is not within log/: symlink created +# log/server is in log/: symlink not created +if [ "${gamelogdir}" ]; then + if [ "${gamelogdir:0:${#logdir}}" != "${logdir}" ]; then + echo -en "creating symlink to game log dir: ${logdir}/server -> ${gamelogdir}..." + if ! ln -nfs "${gamelogdir}" "${logdir}/server"; then + fn_print_fail_eol_nl + core_exit.sh + else + fn_print_ok_eol_nl + fi + fi +fi + +# If server uses SteamCMD create a symbolic link to the Steam logs. +if [ -d "${HOME}/.steam/steam/logs" ]; then + if [ ! -L "${logdir}/steam" ]; then + echo -en "creating symlink to steam log dir: ${logdir}/steam -> ${HOME}/.steam/steam/logs..." + if ! ln -nfs "${HOME}/.steam/steam/logs" "${logdir}/steam"; then + fn_print_fail_eol_nl + core_exit.sh + else + fn_print_ok_eol_nl + fi + fi +fi +fn_script_log_info "Logs installed" diff --git a/lgsm/modules/install_mta_resources.sh b/lgsm/modules/install_mta_resources.sh new file mode 100644 index 0000000..bafdbdb --- /dev/null +++ b/lgsm/modules/install_mta_resources.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# LinuxGSM install_mta_resources.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Installs the libmysqlclient for database functions on the server and optionally installs default resources required to run the server. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_print_information_nl "${gamename} will not function without resources!" +echo -e " * install default resources using ./${selfname} install-default-resources" +echo -e " * download resources from https://community.multitheftauto.com" diff --git a/lgsm/modules/install_retry.sh b/lgsm/modules/install_retry.sh new file mode 100644 index 0000000..1fc4bf3 --- /dev/null +++ b/lgsm/modules/install_retry.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# LinuxGSM install_retry.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Asks for installation retry after failure. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +if fn_prompt_yn "Retry install?" Y; then + command_install.sh + core_exit.sh +else + exitcode=0 + core_exit.sh +fi diff --git a/lgsm/modules/install_server_dir.sh b/lgsm/modules/install_server_dir.sh new file mode 100644 index 0000000..0703e0c --- /dev/null +++ b/lgsm/modules/install_server_dir.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# LinuxGSM install_server_dir.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Creates the server directory. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +echo -e "" +echo -e "${bold}${lightyellow}Server Directory${default}" +fn_messages_separator +if [ -d "${serverfiles}" ]; then + fn_print_warning_nl "A server is already installed here." +fi +pwd +if [ -z "${autoinstall}" ]; then + if ! fn_prompt_yn "Continue?" Y; then + exitcode=0 + core_exit.sh + fi +fi +if [ ! -d "${serverfiles}" ]; then + mkdir -v "${serverfiles}" +fi diff --git a/lgsm/modules/install_server_files.sh b/lgsm/modules/install_server_files.sh new file mode 100644 index 0000000..2763f47 --- /dev/null +++ b/lgsm/modules/install_server_files.sh @@ -0,0 +1,256 @@ +#!/bin/bash +# LinuxGSM install_server_files.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Installs server files. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_install_server_files() { + if [ "${shortname}" == "ahl" ]; then + remote_fileurl="http://linuxgsm.download/ActionHalfLife/action_halflife-1.0.tar.xz" + local_filedir="${tmpdir}" + local_filename="action_halflife-1.0.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="61d7b79fd714888b6d65944fdaafa94a" + elif [ "${shortname}" == "bf1942" ]; then + remote_fileurl="http://linuxgsm.download/BattleField1942/bf1942_lnxded-1.61-hacked-to-1.612.full.tar.xz" + local_filedir="${tmpdir}" + local_filename="bf1942_lnxded-1.61-hacked-to-1.612.full.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="4223bf4ed85f5162c24b2cba51249b9e" + elif [ "${shortname}" == "bfv" ]; then + remote_fileurl="http://linuxgsm.download/BattlefieldVietnam/bfv_linded-v1.21-20041207_patch.tar.xz" + local_filedir="${tmpdir}" + local_filename="bfv_linded-v1.21-20041207_patch.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="e3b4962cdd9d41e23c6fed65101bccde" + elif [ "${shortname}" == "bb" ]; then + remote_fileurl="http://linuxgsm.download/BrainBread/brainbread-v1.2-linuxserver.tar.xz" + local_filedir="${tmpdir}" + local_filename="brainbread-v1.2-linuxserver.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="55f227183b736397806d5b6db6143f15" + elif [ "${shortname}" == "cod" ]; then + remote_fileurl="http://linuxgsm.download/CallOfDuty/cod-lnxded-1.5b-full.tar.xz" + local_filedir="${tmpdir}" + local_filename="cod-lnxded-1.5-large.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="ee0ad1ccbfa1fd27fde01a4a431a5c2f" + elif [ "${shortname}" == "coduo" ]; then + remote_fileurl="http://linuxgsm.download/CallOfDutyUnitedOffensive/coduo-lnxded-1.51b-full.tar.xz" + local_filedir="${tmpdir}" + local_filename="coduo-lnxded-1.51b-full.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="35cabccd67adcda44aaebc59405915b9" + elif [ "${shortname}" == "cod2" ]; then + remote_fileurl="http://linuxgsm.download/CallOfDuty2/cod2-lnxded-1.3-full.tar.xz" + local_filedir="${tmpdir}" + local_filename="cod2-lnxded-1.3-full.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="b8c4c611f01627dd43348e78478a3d41" + elif [ "${shortname}" == "cod4" ]; then + remote_fileurl="http://linuxgsm.download/CallOfDuty4/cod4x18_lnxded.tar.xz" + local_filedir="${tmpdir}" + local_filename="cod4x18_lnxded.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="d255b59b9756d7dbead67718208512ee" + elif [ "${shortname}" == "codwaw" ]; then + remote_fileurl="http://linuxgsm.download/CallOfDutyWorldAtWar/codwaw-lnxded-1.7-full.tar.xz" + local_filedir="${tmpdir}" + local_filename="codwaw-lnxded-1.7-full.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="2c6be1bb66ea631b9b2e7ae6216c6680" + elif [ "${shortname}" == "etl" ]; then + remote_fileurl="http://linuxgsm.download/WolfensteinEnemyTerritory/etlegacy-v2.78.1-i386-et-260b.tar.xz" + local_filedir="${tmpdir}" + local_filename="etlegacy-v2.78.1-i386-et-260b.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="7c08b52cb09b30eadb98ea05ef780fc7" + elif [ "${shortname}" == "mohaa" ]; then + remote_fileurl="http://linuxgsm.download/MedalofHonorAlliedAssault/moh_revival_v1.12_RC3.5.1.tar.xz" + local_filedir="${tmpdir}" + local_filename="moh_revival_v1.12_RC3.5.1.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="7c664538999252eeaf2b6d9949416480" + elif [ "${shortname}" == "ns" ]; then + remote_fileurl="http://linuxgsm.download/NaturalSelection/ns_dedicated_server_v32.tar.xz" + local_filedir="${tmpdir}" + local_filename="ns_dedicated_server_v32.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="23ec3cadd93d8bb1c475bad5b9cce370" + elif [ "${shortname}" == "q2" ]; then + remote_fileurl="http://linuxgsm.download/Quake2/quake2-3.20-glibc-i386-full-linux2.0.tar.xz" + local_filedir="${tmpdir}" + local_filename="quake2-3.20-glibc-i386-full-linux2.0.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="2908164a32d4808bb720f2161f6b0c82" + elif [ "${shortname}" == "q3" ]; then + remote_fileurl="http://linuxgsm.download/Quake3/quake3-1.32c-x86-full-linux.tar.xz" + local_filedir="${tmpdir}" + local_filename="quake3-1.32c-x86-full-linux.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="b0e26d8919fe9313fb9d8ded2360f3db" + elif [ "${shortname}" == "qw" ]; then + remote_fileurl="http://linuxgsm.download/QuakeWorld/nquake.server.linux.190506.full.tar.xz" + local_filedir="${tmpdir}" + local_filename="nquake.server.linux.190506.full.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="82055b7d973206c13a606db8ba288d03" + elif [ "${shortname}" == "rtcw" ]; then + remote_fileurl="http://linuxgsm.download/ReturnToCastleWolfenstein/iortcw-1.51c-x86_64-server-linux-20190507.tar.xz" + local_filedir="${tmpdir}" + local_filename="iortcw-1.51c-x86_64-server-linux-20190507.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="df6ff664d37dd0d22787848bdb3cac5f" + elif [ "${shortname}" == "sfc" ]; then + remote_fileurl="http://linuxgsm.download/SourceFortsClassic/SFClassic-1.0-RC7-fix.tar.xz" + local_filedir="${tmpdir}" + local_filename="SFClassic-1.0-RC7-fix.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="70077137185700e28fe6bbb6021d12bc" + elif [ "${shortname}" == "sof2" ]; then + remote_fileurl="http://linuxgsm.download/SoldierOfFortune2/sof2gold-1.03.tar.xz" + local_filedir="${tmpdir}" + local_filename="sof2gold-1.03.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="201e23bab04207d00ce813d001c483d9" + elif [ "${shortname}" == "ts" ]; then + remote_fileurl="http://linuxgsm.download/TheSpecialists/ts-3-linux-final.tar.xz" + local_filedir="${tmpdir}" + local_filename="ts-3-linux-final.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="3c66ecff6e3644f7ac88015732a0fb93" + elif [ "${shortname}" == "ut2k4" ]; then + remote_fileurl="http://linuxgsm.download/UnrealTournament2004/ut2004-server-3369-3-ultimate-linux.tar.xz" + local_filedir="${tmpdir}" + local_filename="ut2004-server-3369-3-ultimate-linux.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="9fceaab68554749f4b45be66613b9a15" + elif [ "${shortname}" == "ut99" ]; then + remote_fileurl="http://linuxgsm.download/UnrealTournament99/ut99-server-469b-ultimate-linux.tar.xz" + local_filedir="${tmpdir}" + local_filename="ut99-server-469b-ultimate-linux.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="dba3f1122a5e60ee45ece7422fcf78f5" + elif [ "${shortname}" == "ut" ]; then + remote_fileurl="http://linuxgsm.download/UnrealTournament/UnrealTournament-Server-XAN-3525360-Linux.tar.xz" + local_filedir="${tmpdir}" + local_filename="UnrealTournament-Server-XAN-3525360-Linux.tar.xz" + chmodx="noexecute" run="norun" + force="noforce" + md5="41dd92015713a78211eaccf503b72393" + elif [ "${shortname}" == "ut3" ]; then + remote_fileurl="http://linuxgsm.download/UnrealTournament3/UT3-linux-server-2.1.tar.xz" + local_filedir="${tmpdir}" + local_filename="UT3-linux-server-2.1.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="8876cca61e3f83ea08db25208bde6ac6" + elif [ "${shortname}" == "vs" ]; then + remote_fileurl="http://linuxgsm.download/VampireSlayer/vs_l-6.0_full.tar.xz" + local_filedir="${tmpdir}" + local_filename="vs_l-6.0_full.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="b322f79e0abd31847493c52acf802667" + elif [ "${shortname}" == "wet" ]; then + remote_fileurl="http://linuxgsm.download/WolfensteinEnemyTerritory/enemy-territory.260b.tar.xz" + local_filedir="${tmpdir}" + local_filename="enemy-territory.260b.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="581a333cc7eacda2f56d5a00fe11eafa" + elif [ "${shortname}" == "samp" ]; then + remote_fileurl="https://files.sa-mp.com/samp037svr_R2-1.tar.gz" + local_filedir="${tmpdir}" + local_filename="samp037svr_R2-1.tar.gz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="93705e165550c97484678236749198a4" + elif [ "${shortname}" == "zmr" ]; then + remote_fileurl="http://linuxgsm.download/ZombieMasterReborn/zombie_master_reborn_b6_1.tar.xz" + local_filedir="${tmpdir}" + local_filename="zombie_master_reborn_b6_1.tar.xz" + chmodx="nochmodx" run="norun" + force="noforce" + md5="0188ae86dbc9376f11ae3032dba2d665" + else + fn_print_fail_nl "Installing ${gamename} Server failed, missing default configuration" + fn_script_log_fail "Installing ${gamename} Server failed, missing default configuration" + fi + fn_fetch_file "${remote_fileurl}" "" "" "" "${local_filedir}" "${local_filename}" "${chmodx}" "${run}" "${forcedl}" "${md5}" + fn_dl_extract "${local_filedir}" "${local_filename}" "${serverfiles}" +} + +echo -e "" +echo -e "${bold}${lightyellow}Installing ${gamename} Server${default}" +fn_messages_separator + +if [ "${appid}" ]; then + remotelocation="SteamCMD" + forceupdate=1 + update_steamcmd.sh + fn_check_steamcmd_appmanifest +fi + +if [ "${shortname}" == "ts3" ]; then + update_ts3.sh +elif [ "${shortname}" == "mc" ]; then + install_eula.sh + update_mc.sh +elif [ "${shortname}" == "mcb" ]; then + update_mcb.sh +elif [ "${shortname}" == "pmc" ]; then + install_eula.sh + update_pmc.sh +elif [ "${shortname}" == "wmc" ] || [ "${shortname}" == "vpmc" ]; then + update_pmc.sh +elif [ "${shortname}" == "mta" ]; then + update_mta.sh +elif [ "${shortname}" == "fctr" ]; then + update_fctr.sh + install_factorio_save.sh +elif [ "${shortname}" == "jk2" ]; then + update_jk2.sh +elif [ "${shortname}" == "vints" ]; then + update_vints.sh +elif [ "${shortname}" == "ut99" ]; then + fn_install_server_files + update_ut99.sh +elif [ -z "${appid}" ] || [ "${shortname}" == "ahl" ] || [ "${shortname}" == "bb" ] || [ "${shortname}" == "ns" ] || [ "${shortname}" == "sfc" ] || [ "${shortname}" == "ts" ] || [ "${shortname}" == "vs" ] || [ "${shortname}" == "zmr" ]; then + if [ "${shortname}" == "ut" ]; then + install_eula.sh + fi + fn_install_server_files +fi + +if [ -z "${autoinstall}" ]; then + echo -e "" + fn_messages_separator + if ! fn_prompt_yn "Was the install successful?" Y; then + install_retry.sh + fi +fi diff --git a/lgsm/modules/install_squad_license.sh b/lgsm/modules/install_squad_license.sh new file mode 100644 index 0000000..28f4456 --- /dev/null +++ b/lgsm/modules/install_squad_license.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# LinuxGSM install_squad_license.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Configures the Squad server's license. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +echo -e "" +echo -e "${bold}${lightyellow}${gamename} Server License${default}" +fn_messages_separator +echo -e "Server license is an optional feature for ${gamename} server" +fn_script_log_info "Server license is an optional feature for ${gamename} server" + +echo -e "Get more info and a server license here:" +echo -e "https://squad.fandom.com/wiki/Server_licensing" +fn_script_log_info "Get more info and a server license here:" +fn_script_log_info "https://squad.fandom.com/wiki/Server_licensing" +echo -e "" +fn_sleep_time_1 +echo -e "The Squad server license can be changed by editing ${servercfgdir}/License.cfg." +fn_script_log_info "The Squad server license can be changed by editing ${selfname}." +echo -e "" diff --git a/lgsm/modules/install_stats.sh b/lgsm/modules/install_stats.sh new file mode 100644 index 0000000..40a1343 --- /dev/null +++ b/lgsm/modules/install_stats.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# LinuxGSM install_stats.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Enabled LinuxGSM Stats. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +echo -e "" +echo -e "${bold}${lightyellow}LinuxGSM Stats${default}" +fn_messages_separator +echo -e "Assist LinuxGSM development by sending anonymous stats to developers." +echo -e "Collected data is publicly available: ${italic}https://linuxgsm.com/data/usage${default}" +echo -e "More info: ${italic}https://docs.linuxgsm.com/configuration/linuxgsm-stats${default}" +echo -e "The following info will be sent: " +echo -e "* game server" +echo -e "* distro" +echo -e "* game server resource usage" +echo -e "* server hardware info" +if [ -z "${autoinstall}" ]; then + if fn_prompt_yn "Allow anonymous usage statistics?" Y; then + echo "stats=\"on\"" >> "${configdirserver}/common.cfg" + fn_print_information_nl "Stats setting is now enabled in common.cfg." + fi +else + fn_print_information_nl "auto-install leaves stats off by default. Stats can be enabled in common.cfg" +fi diff --git a/lgsm/modules/install_steamcmd.sh b/lgsm/modules/install_steamcmd.sh new file mode 100644 index 0000000..50599eb --- /dev/null +++ b/lgsm/modules/install_steamcmd.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# LinuxGSM install_steamcmd.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Downloads SteamCMD on install. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +echo -e "" +echo -e "${bold}${lightyellow}Installing SteamCMD${default}" +fn_messages_separator +check_steamcmd.sh diff --git a/lgsm/modules/install_ts3db.sh b/lgsm/modules/install_ts3db.sh new file mode 100644 index 0000000..464bd68 --- /dev/null +++ b/lgsm/modules/install_ts3db.sh @@ -0,0 +1,73 @@ +#!/bin/bash +# LinuxGSM install_ts3db.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Installs the database server MariaDB for TeamSpeak 3. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_install_ts3db_mariadb() { + if [ ! -f "${serverfiles}/libts3db_mariadb.so" ]; then + echo -e "copying libmariadb.so.2...\c" + cp "${serverfiles}/redist/libmariadb.so.2" "${serverfiles}" + local exitcode=$? + if [ "${exitcode}" != "0" ]; then + fn_print_fail_eol_nl + fn_script_log_fail "copying libmariadb.so.2" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "copying libmariadb.so.2" + fi + fi + + echo -e "" + echo -e "${bold}${lightyellow}Configure ${gamename} Server for MariaDB${default}" + fn_messages_separator + read -rp "Enter MariaDB hostname: " mariahostname + read -rp "Enter MariaDB port: " mariaport + read -rp "Enter MariaDB username: " mariausername + read -rp "Enter MariaDB password: " mariapassword + read -rp "Enter MariaDB database name: " mariadbname + read -rp "Enter MariaDB socket path: " mariadbsocket + + { + echo -e "[config]" + echo -e "host='${mariahostname}'" + echo -e "port='${mariaport}'" + echo -e "username='${mariausername}'" + echo -e "password='${mariapassword}'" + echo -e "database='${mariadbname}'" + echo -e "socket='${mariadbsocket}'" + } >> "${servercfgdir}/ts3db_mariadb.ini" + sed -i "s/dbplugin=ts3db_sqlite3/dbplugin=ts3db_mariadb/g" "${servercfgfullpath}" + sed -i "s/dbpluginparameter=/dbpluginparameter=ts3db_mariadb.ini/g" "${servercfgfullpath}" + sed -i "s/dbsqlcreatepath=create_sqlite\//dbsqlcreatepath=create_mariadb\//g" "${servercfgfullpath}" + echo -e "updating ts3db_mariadb.ini." + fn_sleep_time_1 +} + +echo -e "" +echo -e "${bold}${lightyellow}Select Database${default}" +fn_messages_separator +if [ -z "${autoinstall}" ]; then + if fn_prompt_yn "Do you want to use MariaDB instead of sqlite? (MariaDB must be pre-configured)" N; then + fn_install_ts3db_mariadb + fi +else + fn_print_information_nl "./${selfname} auto-install is uses sqlite. For MariaDB use ./${selfname} install" +fi + +install_eula.sh + +echo -e "" +echo -e "${bold}${lightyellow}Getting Privilege Key${default}" +fn_messages_separator +fn_print_information_nl "Save these details for later." +fn_print_information_nl "Key also saved in:" +echo -e "${serverfiles}/privilege_key.txt" +cd "${executabledir}" || exit +./ts3server_startscript.sh start inifile=ts3-server.ini 2>&1 | tee "${serverfiles}/privilege_key.txt" +fn_sleep_time_5 +./ts3server_startscript.sh stop diff --git a/lgsm/modules/install_ut2k4_key.sh b/lgsm/modules/install_ut2k4_key.sh new file mode 100644 index 0000000..6fbd2a8 --- /dev/null +++ b/lgsm/modules/install_ut2k4_key.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# LinuxGSM install_ut2k4_key.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Activates ut2k4 server with given key. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +echo -e "" +echo -e "${bold}${lightyellow}Enter ${gamename} CD Key${default}" +fn_messages_separator +echo -e "To get your server listed on the Master Server list" +echo -e "you must get a free CD key. Get a key here:" +echo -e "https://www.epicgames.com/unrealtournament/forums/cdkey.php?2004" +echo -e "" +if [ -z "${autoinstall}" ]; then + echo -e "Once you have the key enter it below" + echo -n "KEY: " + read -r CODE + echo -e ""\""CDKey"\""="\""${CODE}"\""" > "${systemdir}/cdkey" + if [ -f "${systemdir}/cdkey" ]; then + fn_script_log_info "UT2K4 Server CD Key created" + fi +else + echo -e "You can add your key using the following command" + echo -e "./${selfname} server-cd-key" +fi +echo -e "" diff --git a/lgsm/modules/mods_core.sh b/lgsm/modules/mods_core.sh new file mode 100644 index 0000000..1b85a95 --- /dev/null +++ b/lgsm/modules/mods_core.sh @@ -0,0 +1,755 @@ +#!/bin/bash +# LinuxGSM command_mods_install.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Core modules for mods list/install/update/remove + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Files and Directories. +modsdir="${lgsmdir}/mods" +modstmpdir="${modsdir}/tmp" +extractdest="${modstmpdir}/extract" +modsinstalledlist="installed-mods.txt" +modsinstalledlistfullpath="${modsdir}/${modsinstalledlist}" + +## Installation. + +# Download management. +fn_mod_install_files() { + fn_fetch_file "${modurl}" "" "" "" "${modstmpdir}" "${modfilename}" + # Check if variable is valid checking if file has been downloaded and exists. + if [ ! -f "${modstmpdir}/${modfilename}" ]; then + fn_print_failure "An issue occurred downloading ${modprettyname}" + fn_script_log_fail "An issue occurred downloading ${modprettyname}" + core_exit.sh + fi + if [ ! -d "${extractdest}" ]; then + mkdir -p "${extractdest}" + fi + fn_dl_extract "${modstmpdir}" "${modfilename}" "${extractdest}" +} + +# Convert mod files to lowercase if needed. +fn_mod_lowercase() { + # Checking lowercase settings from mods array definition + if [ "${modlowercase}" == "LowercaseOn" ]; then + echo -en "converting ${modprettyname} files to lowercase..." + fn_sleep_time + fn_script_log_info "Converting ${modprettyname} files to lowercase" + # Total files and directories for the mod, to output to the user + fileswc=$(find "${extractdest}" | wc -l) + # Total uppercase files and directories for the mod, to output to the user + filesupperwc=$(find "${extractdest}" -name '*[[:upper:]]*' | wc -l) + fn_script_log_info "Found ${filesupperwc} uppercase files out of ${fileswc}, converting" + echo -en "Found ${filesupperwc} uppercase files out of ${fileswc}, converting..." + # Convert files and directories starting from the deepest to prevent issues (-depth argument) + while read -r src; do + # We have to convert only the last file from the path, otherwise we will fail to convert anything if a parent dir has any uppercase + # therefore, we have to separate the end of the filename to only lowercase it rather than the whole line + # Gather parent dir, filename lowercase filename, and set lowercase destination name + latestparentdir=$(dirname "${src}") + latestfilelc=$(basename "${src}" | tr '[:upper:]' '[:lower:]') + dst="${latestparentdir}/${latestfilelc}" + # Only convert if destination does not already exist for some reason + if [ ! -e "${dst}" ]; then + # Finally we can rename the file + mv "${src}" "${dst}" + # Exit if it fails for any reason + local exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + core_exit.sh + fi + fi + done < <(find "${extractdest}" -depth -name '*[[:upper:]]*') + fn_print_ok_eol_nl + fi +} + +# Create ${modcommand}-files.txt containing the full extracted file/directory list. +fn_mod_create_filelist() { + echo -en "building ${modcommand}-files.txt..." + fn_sleep_time + # ${modsdir}/${modcommand}-files.txt. + find "${extractdest}" -mindepth 1 -printf '%P\n' > "${modsdir}/${modcommand}-files.txt" + local exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Building ${modsdir}/${modcommand}-files.txt" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Building ${modsdir}/${modcommand}-files.txt" + fi + # Adding removed files if needed. + if [ -f "${modsdir}/.removedfiles.tmp" ]; then + cat "${modsdir}/.removedfiles.tmp" >> "${modsdir}/${modcommand}-files.txt" + fi +} + +# Copy the mod into serverfiles. +fn_mod_copy_destination() { + echo -en "copying ${modprettyname} to ${modinstalldir}..." + fn_sleep_time + cp -Rf "${extractdest}/." "${modinstalldir}/" + local exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Copying ${modprettyname} to ${modinstalldir}" + else + fn_print_ok_eol_nl + fn_script_log_pass "Copying ${modprettyname} to ${modinstalldir}" + fi +} + +# Add the mod to the installed-mods.txt. +fn_mod_add_list() { + if [ -z "$(sed -n "/^${modcommand}$/p" "${modsinstalledlistfullpath}")" ]; then + echo -e "${modcommand}" >> "${modsinstalledlistfullpath}" + fn_script_log_info "${modcommand} added to ${modsinstalledlist}" + fi +} + +# Prevent sensitive directories from being erased upon uninstall by removing them from: ${modcommand}-files.txt. +fn_mod_tidy_files_list() { + # Check file list validity. + fn_check_mod_files_list + # Output to the user + echo -en "tidy up ${modcommand}-files.txt..." + fn_sleep_time + fn_script_log_info "Tidy up ${modcommand}-files.txt" + # Lines/files to remove from file list (end with ";" separator). + removefromlist="cfg;addons;RustDedicated_Data;RustDedicated_Data\/Managed;RustDedicated_Data\/Managed\/x86;RustDedicated_Data\/Managed\/x64;" + # Loop through files to remove from file list, + # generate elements to remove from list. + removefromlistamount=$(echo -e "${removefromlist}" | awk -F ';' '{ print NF }') + # Test all subvalue of "removefromlist" using the ";" separator. + for ((filesindex = 1; filesindex < removefromlistamount; filesindex++)); do + # Put current file into test variable. + removefilevar=$(echo -e "${removefromlist}" | awk -F ';' -v x=${filesindex} '{ print $x }') + # Delete line(s) matching exactly. + sed -i "/^${removefilevar}$/d" "${modsdir}/${modcommand}-files.txt" + # Exit on error. + local exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Error while tidying line: ${removefilevar} from: ${modsdir}/${modcommand}-files.txt" + core_exit.sh + break + fi + done + fn_print_ok_eol_nl + # Sourcemod fix + # Remove metamod from sourcemod fileslist. + if [ "${modcommand}" == "sourcemod" ]; then + # Remove addons/metamod & addons/metamod/sourcemod.vdf from ${modcommand}-files.txt. + sed -i "/^addons\/metamod$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/metamod\/sourcemod.vdf$/d" "${modsdir}/${modcommand}-files.txt" + fi + + # Remove common paths from deletion list (Add your sourcemod mod here) + if [ "${modcommand}" == "gokz" ] || [ "${modcommand}" == "ttt" ] || [ "${modcommand}" == "steamworks" ] || [ "${modcommand}" == "get5" ]; then + sed -i "/^addons\/sourcemod$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/sourcemod\/configs$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/sourcemod\/extensions$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/sourcemod\/logs$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/sourcemod\/plugins$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/sourcemod\/plugins\/disabled$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/sourcemod\/scripting$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/sourcemod\/scripting\/include$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/sourcemod\/translations$/d" "${modsdir}/${modcommand}-files.txt" + # Don't delete directories of translations like 'fr', 'sv', 'de', etc + sed -i "/^addons\/sourcemod\/translations\/[A-Za-z0-9_]*$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^cfg\/sourcemod$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^maps$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^materialss$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^materials\/models$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^materials\/models\/weapons$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^materials\/darkness$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^materials\/decals$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^materials\/overlays$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^models$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^models\/weapons$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^sound$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^sound\/weapons$/d" "${modsdir}/${modcommand}-files.txt" + fi + + # Remove paths of specific mods from deletion list + if [ "${modcommand}" == "gokz" ]; then + sed -i "/^addons\/sourcemod\/scripting\/include\/smjansson.inc$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/sourcemod\/scripting\/include\/GlobalAPI-Core.inc$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/sourcemod\/scripting\/include\/sourcebanspp.inc$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/sourcemod\/scripting\/include\/autoexecconfig.inc$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/sourcemod\/scripting\/include\/colorvariables.inc$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/sourcemod\/scripting\/include\/movementapi.inc$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/sourcemod\/scripting\/include\/movement.inc$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/sourcemod\/scripting\/include\/dhooks.inc$/d" "${modsdir}/${modcommand}-files.txt" + sed -i "/^addons\/sourcemod\/scripting\/include\/updater.inc$/d" "${modsdir}/${modcommand}-files.txt" + fi +} + +## Information Gathering. + +# Get details of a mod any (relevant and unique, such as full mod name or install command) value. +fn_mod_get_info() { + # Variable to know when job is done. + modinfocommand="0" + # Find entry in global array. + for ((index = 0; index <= ${#mods_global_array[@]}; index++)); do + # When entry is found. + if [ "${mods_global_array[index]}" == "${currentmod}" ]; then + # Go back to the previous "MOD" separator. + for ((index = index; index <= ${#mods_global_array[@]}; index--)); do + # When "MOD" is found. + if [ "${mods_global_array[index]}" == "MOD" ]; then + # Get info. + fn_mods_define + modinfocommand="1" + break + fi + done + fi + # Exit the loop if job is done. + if [ "${modinfocommand}" == "1" ]; then + break + fi + done + + # What happens if mod is not found. + if [ "${modinfocommand}" == "0" ]; then + fn_script_log_error "Could not find information for ${currentmod}" + fn_print_error_nl "Could not find information for ${currentmod}" + core_exit.sh + fi +} + +# Define all variables for a mod at once when index is set to a separator. +fn_mods_define() { + if [ -z "$index" ]; then + fn_script_log_fail "index variable not set. Please report an issue." + fn_print_error "index variable not set. Please report an issue." + echo -e "* https://github.com/GameServerManagers/LinuxGSM/issues" + core_exit.sh + fi + modcommand="${mods_global_array[index + 1]}" + modprettyname="${mods_global_array[index + 2]}" + modurl="${mods_global_array[index + 3]}" + modfilename="${mods_global_array[index + 4]}" + modsubdirs="${mods_global_array[index + 5]}" + modlowercase="${mods_global_array[index + 6]}" + modinstalldir="${mods_global_array[index + 7]}" + modkeepfiles="${mods_global_array[index + 8]}" + modengines="${mods_global_array[index + 9]}" + modgames="${mods_global_array[index + 10]}" + modexcludegames="${mods_global_array[index + 11]}" + modsite="${mods_global_array[index + 12]}" + moddescription="${mods_global_array[index + 13]}" +} + +# Builds list of installed mods. +# using installed-mods.txt grabing mod info from mods_list.sh. +fn_mods_installed_list() { + fn_mods_count_installed + # Set/reset variables. + installedmodsline="1" + installedmodslist=() + modprettynamemaxlength="0" + modsitemaxlength="0" + moddescriptionmaxlength="0" + modcommandmaxlength="0" + # Loop through every line of the installed mods list ${modsinstalledlistfullpath}. + while [ "${installedmodsline}" -le "${installedmodscount}" ]; do + currentmod=$(sed "${installedmodsline}q;d" "${modsinstalledlistfullpath}") + # Get mod info to make sure mod exists. + fn_mod_get_info + # Add the mod to available commands. + installedmodslist+=("${modcommand}") + # Increment line check. + ((installedmodsline++)) + done + if [ "${installedmodscount}" ]; then + fn_script_log_info "${installedmodscount} addons/mods are currently installed" + fi +} + +# Loops through mods_global_array to define available mods & provide available commands for mods installation. +fn_mods_available() { + # First, reset variables. + compatiblemodslist=() + availablemodscommands=() + # Find compatible games. + # Find separators through the global array. + for ((index = "0"; index <= ${#mods_global_array[@]}; index++)); do + # If current value is a separator; then. + if [ "${mods_global_array[index]}" == "${modseparator}" ]; then + # Set mod variables. + fn_mods_define + # Test if game is compatible. + fn_mod_compatible_test + # If game is compatible. + if [ "${modcompatibility}" == "1" ]; then + # Put it into an array to prepare user output. + compatiblemodslist+=("${modprettyname}" "${modcommand}" "${modsite}" "${moddescription}") + # Keep available commands in an array to make life easier. + availablemodscommands+=("${modcommand}") + fi + fi + done +} + +## Mod compatibility check. + +# Find out if a game is compatible with a mod from a modgames (list of games supported by a mod) variable. +fn_compatible_mod_games() { + # Reset test value. + modcompatiblegame="0" + # If value is set to GAMES (ignore). + if [ "${modgames}" != "GAMES" ]; then + # How many games we need to test. + gamesamount=$(echo -e "${modgames}" | awk -F ';' '{ print NF }') + # Test all subvalue of "modgames" using the ";" separator. + for ((gamevarindex = 1; gamevarindex < gamesamount; gamevarindex++)); do + # Put current game name into modtest variable. + gamemodtest=$(echo -e "${modgames}" | awk -F ';' -v x=${gamevarindex} '{ print $x }') + # If game name matches. + if [ "${gamemodtest}" == "${gamename}" ]; then + # Mod is compatible. + modcompatiblegame="1" + fi + done + fi +} + +# Find out if an engine is compatible with a mod from a modengines (list of engines supported by a mod) variable. +fn_compatible_mod_engines() { + # Reset test value. + modcompatibleengine="0" + # If value is set to ENGINES (ignore). + if [ "${modengines}" != "ENGINES" ]; then + # How many engines we need to test. + enginesamount=$(echo -e "${modengines}" | awk -F ';' '{ print NF }') + # Test all subvalue of "modengines" using the ";" separator. + for ((gamevarindex = 1; gamevarindex < ${enginesamount}; gamevarindex++)); do + # Put current engine name into modtest variable. + enginemodtest=$(echo -e "${modengines}" | awk -F ';' -v x=${gamevarindex} '{ print $x }') + # If engine name matches. + if [ "${enginemodtest}" == "${engine}" ]; then + # Mod is compatible. + modcompatibleengine="1" + fi + done + fi +} + +# Find out if a game is not compatible with a mod from a modnotgames (list of games not supported by a mod) variable. +fn_not_compatible_mod_games() { + # Reset test value. + modeincompatiblegame="0" + # If value is set to NOTGAMES (ignore). + if [ "${modexcludegames}" != "NOTGAMES" ]; then + # How many engines we need to test. + excludegamesamount=$(echo -e "${modexcludegames}" | awk -F ';' '{ print NF }') + # Test all subvalue of "modexcludegames" using the ";" separator. + for ((gamevarindex = 1; gamevarindex < excludegamesamount; gamevarindex++)); do + # Put current engine name into modtest variable. + excludegamemodtest=$(echo -e "${modexcludegames}" | awk -F ';' -v x=${gamevarindex} '{ print $x }') + # If engine name matches. + if [ "${excludegamemodtest}" == "${gamename}" ]; then + # Mod is compatible. + modeincompatiblegame="1" + fi + done + fi +} + +# Sums up if a mod is compatible or not with modcompatibility=0/1. +fn_mod_compatible_test() { + # Test game and engine compatibility. + fn_compatible_mod_games + fn_compatible_mod_engines + fn_not_compatible_mod_games + if [ "${modeincompatiblegame}" == "1" ]; then + modcompatibility="0" + elif [ "${modcompatibleengine}" == "1" ] || [ "${modcompatiblegame}" == "1" ]; then + modcompatibility="1" + else + modcompatibility="0" + fi +} + +## Directory management. + +# Create mods files and directories if it doesn't exist. +fn_create_mods_dir() { + # Create lgsm data modsdir. + if [ ! -d "${modsdir}" ]; then + echo -en "creating LinuxGSM mods data directory ${modsdir}..." + mkdir -p "${modsdir}" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Creating mod download dir ${modsdir}" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Creating mod download dir ${modsdir}" + fi + fi + # Create mod install directory. + if [ ! -d "${modinstalldir}" ]; then + echo -en "creating mods install directory ${modinstalldir}..." + mkdir -p "${modinstalldir}" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Creating mod install directory ${modinstalldir}" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Creating mod install directory ${modinstalldir}" + fi + fi + + # Create lgsm/data/${modsinstalledlist}. + if [ ! -f "${modsinstalledlistfullpath}" ]; then + touch "${modsinstalledlistfullpath}" + fn_script_log_info "Created ${modsinstalledlistfullpath}" + fi +} + +# Create tmp download mod directory. +fn_mods_create_tmp_dir() { + if [ ! -d "${modstmpdir}" ]; then + mkdir -p "${modstmpdir}" + exitcode=$? + echo -en "creating mod download directory ${modstmpdir}..." + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Creating mod download directory ${modstmpdir}" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Creating mod download directory ${modstmpdir}" + fi + fi +} + +# Remove the tmp mod download directory when finished. +fn_mods_clear_tmp_dir() { + if [ -d "${modstmpdir}" ]; then + echo -en "clearing mod download directory ${modstmpdir}..." + rm -rf "${modstmpdir:?}" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Clearing mod download directory ${modstmpdir}" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Clearing mod download directory ${modstmpdir}" + fi + + fi + # Clear temp file list as well. + if [ -f "${modsdir}/.removedfiles.tmp" ]; then + rm -f "${modsdir:?}/.removedfiles.tmp" + fi +} + +# Counts how many mods were installed. +fn_mods_count_installed() { + if [ -f "${modsinstalledlistfullpath}" ]; then + installedmodscount=$(wc -l < "${modsinstalledlistfullpath}") + else + installedmodscount=0 + fi +} + +# Exits if no mods were installed. +fn_mods_check_installed() { + # Count installed mods. + fn_mods_count_installed + # If no mods are found. + if [ ${installedmodscount} -eq 0 ]; then + echo -e "" + fn_print_failure_nl "No installed mods or addons were found" + echo -e " * Install mods using LinuxGSM first with: ./${selfname} mods-install" + fn_script_log_error "No installed mods or addons were found." + core_exit.sh + fi +} + +# Checks that mod files list exists and isn't empty. +fn_check_mod_files_list() { + # File list must exist and be valid before any operation on it. + if [ -f "${modsdir}/${modcommand}-files.txt" ]; then + # How many lines is the file list. + modsfilelistsize=$(wc -l < "${modsdir}/${modcommand}-files.txt") + # If file list is empty. + if [ "${modsfilelistsize}" -eq 0 ]; then + fn_print_failure "${modcommand}-files.txt is empty" + echo -e "* Unable to remove ${modprettyname}" + fn_script_log_fail "${modcommand}-files.txt is empty: Unable to remove ${modprettyname}." + core_exit.sh + fi + else + fn_print_failure "${modsdir}/${modcommand}-files.txt does not exist" + fn_script_log_fail "${modsdir}/${modcommand}-files.txt does not exist: Unable to remove ${modprettyname}." + core_exit.sh + fi +} + +fn_mod_exist() { + modreq=$1 + # requires one parameter, the mod + if [ -f "${modsdir}/${modreq}-files.txt" ]; then + # how many lines is the file list + modsfilelistsize=$(wc -l < "${modsdir}/${modreq}-files.txt") + # if file list is empty + if [ "${modsfilelistsize}" -eq 0 ]; then + fn_mod_required_fail_exist "${modreq}" + fi + else + fn_mod_required_fail_exist "${modreq}" + fi +} + +fn_mod_required_fail_exist() { + modreq=$1 + # requires one parameter, the mod + fn_script_log_fail "${modreq}-files.txt is empty: unable to find ${modreq} installed" + echo -en "* Unable to find '${modreq}' which is required prior to installing this mod..." + fn_print_fail_eol_nl + core_exit.sh +} + +fn_mod_liblist_gam_filenames() { + # clear variables just in case + moddll="" + modso="" + moddylib="" + + # default libraries + case ${gamename} in + "Counter-Strike 1.6") + moddll="mp.dll" + modso="cs.so" + moddylib="cs.dylib" + ;; + "Day of Defeat") + moddll="dod.dll" + modso="dod.so" + moddylib="dod.dylib" + ;; + "Team Fortress Classic") + moddll="tfc.dll" + modso="tfc.so" + moddylib="tfc.dylib" + ;; + "Natural Selection") + moddll="ns.dll" + modso="ns_i386.so" + moddylib="" + ;; + "The Specialists") + moddll="mp.dll" + modso="ts_i386.so" + moddylib="" + ;; + "Half-Life: Deathmatch") + moddll="hl.dll" + modso="hl.so" + moddylib="hl.dylib" + ;; + esac +} + +# modifers for liblist.gam to add/remote metamod binaries +fn_mod_install_liblist_gam_file() { + + fn_mod_liblist_gam_filenames + + if [ -f "${modinstalldir}/liblist.gam" ]; then + # modify the liblist.gam file to initialize Metamod + logentry="sed replace (dlls\\${moddll}) ${modinstalldir}/liblist.gam" + echo -en "modifying gamedll in liblist.gam..." + rpldll="s/dlls\\\\${moddll}/addons\/metamod\/dlls\/metamod.dll/g" + sed -i $rpldll "${modinstalldir}/liblist.gam" + grep -q "addons/metamod/dlls/metamod.dll" "${modinstalldir}/liblist.gam" + exitcode=$? + # if replacement back didn't happen, error out. + if [ "${exitcode}" != 0 ]; then + fn_script_log_fail "${logentry}" + fn_print_fail_eol_nl + else + fn_script_log_pass "${logentry}" + fn_print_ok_eol_nl + fi + + # modify the liblist.gam file to initialize metamod + logentry="sed replace (dlls\\${modso}) ${modinstalldir}/liblist.gam" + echo -en "modifying gamedll_linux in liblist.gam..." + rplso="s/dlls\/${modso}/addons\/metamod\/dlls\/metamod.so/g" + sed -i $rplso "${modinstalldir}/liblist.gam" + grep -q "addons/metamod/dlls/metamod.so" "${modinstalldir}/liblist.gam" + exitcode=$? + # if replacement back didn't happen, error out + if [ "${exitcode}" != 0 ]; then + fn_script_log_fail "${logentry}" + fn_print_fail_eol_nl + else + fn_script_log_pass "${logentry}" + fn_print_ok_eol_nl + fi + + # mac os needs to be checked not all mods support mac os + if [ -n "${moddylib}" ]; then + # modify the liblist.gam file to initialize metamod + logentry="sed replace (dlls\\${moddylib}) ${modinstalldir}/liblist.gam" + echo -en "modifying gamedll_osx in liblist.gam..." + rpldylib="s/dlls\/${moddylib}/addons\/metamod\/dlls\/metamod.dylib/g" + sed -i $rpldylib "${modinstalldir}/liblist.gam" + grep -q "addons/metamod/dlls/metamod.dylib" "${modinstalldir}/liblist.gam" + exitcode=$? + # if replacement back didn't happen, error out. + if [ "${exitcode}" != 0 ]; then + fn_script_log_fail "${logentry}" + fn_print_fail_eol_nl + else + fn_script_log_pass ${logentry} + fn_print_ok_eol_nl + fi + fi + fi +} + +fn_mod_remove_liblist_gam_file() { + + fn_mod_liblist_gam_filenames + + if [ -f "${modinstalldir}/liblist.gam" ]; then + # modify the liblist.gam file back to defaults + logentry="sed replace (addons/metamod/dlls/metamod.dll) ${modinstalldir}/liblist.gam" + echo -en "modifying gamedll in liblist.gam..." + rpldll="s/addons\/metamod\/dlls\/metamod.dll/dlls\\\\${moddll}/g" + sed -i $rpldll "${modinstalldir}/liblist.gam" + grep -q "${moddll}" "${modinstalldir}/liblist.gam" + exitcode=$? + # if replacement back didn't happen, error out. + if [ "${exitcode}" != 0 ]; then + fn_script_log_fail "${logentry}" + fn_print_fail_eol_nl + else + fn_script_log_pass ${logentry} + fn_print_ok_eol_nl + fi + + # modify the liblist.gam file back to defaults + logentry="sed replace (addons/metamod/dlls/metamod.so) ${modinstalldir}/liblist.gam" + echo -en "modifying gamedll_linux in liblist.gam..." + rplso="s/addons\/metamod\/dlls\/metamod.so/dlls\/${modso}/g" + sed -i $rplso "${modinstalldir}/liblist.gam" + grep -q "${modso}" "${modinstalldir}/liblist.gam" + exitcode=$? + # if replacement back didn't happen, error out + if [ "${exitcode}" != 0 ]; then + fn_script_log_fail "${logentry}" + fn_print_fail_eol_nl + else + fn_script_log_pass ${logentry} + fn_print_ok_eol_nl + fi + + # mac os needs to be checked not all mods support mac os + if [ -n "${moddylib}" ]; then + # modify the liblist.gam file back to defaults + logentry="sed replace (addons/metamod/dlls/metamod.dylib) ${modinstalldir}/liblist.gam" + echo -en "modifying gamedll_osx in liblist.gam..." + rpldylib="s/addons\/metamod\/dlls\/metamod.dylib/dlls\/${moddylib}/g" + sed -i $rpldylib "${modinstalldir}/liblist.gam" + grep -q "${moddylib}" "${modinstalldir}/liblist.gam" + # if replacement back didn't happen, error out. + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_script_log_fail "${logentry}" + fn_print_fail_eol_nl + else + fn_script_log_pass ${logentry} + fn_print_ok_eol_nl + fi + fi + fi +} + +fn_mod_install_amxmodx_file() { + # does plugins.ini exist? + if [ -f "${modinstalldir}/addons/metamod/plugins.ini" ]; then + # since it does exist, is the entry already in plugins.ini + logentry="line (linux addons/amxmodx/dlls/amxmodx_mm_i386.so) inserted into ${modinstalldir}/addons/metamod/plugins.ini" + echo -en "adding amxmodx_mm_i386.so in plugins.ini..." + grep -q "amxmodx_mm_i386.so" "${modinstalldir}/addons/metamod/plugins.ini" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + # file exists but the entry does not, let's add it + echo "linux addons/amxmodx/dlls/amxmodx_mm_i386.so" >> "${modinstalldir}/addons/metamod/plugins.ini" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_script_log_fail "${logentry}" + fn_print_fail_eol_nl + else + fn_script_log_pass ${logentry} + fn_print_ok_eol_nl + fi + fi + else + # create new file and add the mod to it + echo "linux addons/amxmodx/dlls/amxmodx_mm_i386.so" > "${modinstalldir}/addons/metamod/plugins.ini" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_script_log_fail "${logentry}" + fn_print_fail_eol_nl + core_exit.sh + else + fn_script_log_pass ${logentry} + fn_print_ok_eol_nl + fi + fi +} + +fn_mod_remove_amxmodx_file() { + if [ -f "${modinstalldir}/addons/metamod/plugins.ini" ]; then + # since it does exist, is the entry already in plugins.ini + logentry="line (linux addons/amxmodx/dlls/amxmodx_mm_i386.so) removed from ${modinstalldir}/addons/metamod/plugins.ini" + echo -en "removing amxmodx_mm_i386.so in plugins.ini..." + grep -q "linux addons/amxmodx/dlls/amxmodx_mm_i386.so" "${modinstalldir}/addons/metamod/plugins.ini" + # iIs it found? If so remove it and clean up + exitcode=$? + if [ "${exitcode}" == 0 ]; then + # delete the line we inserted + sed -i '/linux addons\/amxmodx\/dlls\/amxmodx_mm_i386.so/d' "${modinstalldir}/addons/metamod/plugins.ini" + # remove empty lines + sed -i '/^$/d' "${modinstalldir}/addons/metamod/plugins.ini" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_script_log_fail "${logentry}" + fn_print_fail_eol_nl + else + fn_script_log_pass ${logentry} + fn_print_ok_eol_nl + fi + + # if file is empty, remove it. + if [ -f "${modinstalldir}/addons/metamod/plugins.ini" ]; then + rm -f "${modinstalldir}/addons/metamod/plugins.ini" + fn_script_log_pass "file removed ${modinstalldir}/addons/metamod/plugins.ini because it was empty" + fi + fi + fi +} + +## Database initialisation. + +mods_list.sh +fn_mods_available diff --git a/lgsm/modules/mods_list.sh b/lgsm/modules/mods_list.sh new file mode 100644 index 0000000..e093124 --- /dev/null +++ b/lgsm/modules/mods_list.sh @@ -0,0 +1,209 @@ +#!/bin/bash +# LinuxGSM mods_list.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Lists and defines available mods for LinuxGSM supported servers; works along with mods_core.sh. +# Usage: To add a mod, you need to add an array variable following the guide to set proper values; +# Usage: Then add this array to the mods_global_array. +# Usage: If needed, you can scrape the download URL first. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Get a proper URL for mods that don't provide a good one (optional) +fn_script_log_info "Retrieving latest mods URLs" + +# Metamod (Half-life 1 Classic Engine) +metamodversion="1.21.1-am" +metamodlatestfile="metamod-${metamodversion}.zip" +metamoddownloadurl="https://www.amxmodx.org/release/${metamodlatestfile}" +metamodurl="${metamoddownloadurl}" +# AMX Mod X: Base +amxxbaseversion="1.8.2" +amxxbasemod="base" +amxxbaselatestfile="amxmodx-${amxxbaseversion}-${amxxbasemod}-linux.tar.gz" +amxxbasedownloadurl="https://www.amxmodx.org/release/${amxxbaselatestfile}" +amxxbaseurl="${amxxbasedownloadurl}" +# AMX Mod X: Counter-Strike +amxxcsversion="1.8.2" +amxxcsmod="cstrike" +amxxcslatestfile="amxmodx-${amxxbaseversion}-${amxxcsmod}-linux.tar.gz" +amxxcsdownloadurl="https://www.amxmodx.org/release/${amxxcslatestfile}" +amxxcsurl="${amxxcsdownloadurl}" +# AMX Mod X: Day of Defeat +amxxdodversion="1.8.2" +amxxdodmod="dod" +amxxdodlatestfile="amxmodx-${amxxdodversion}-${amxxdodmod}-linux.tar.gz" +amxxdoddownloadurl="https://www.amxmodx.org/release/${amxxdodlatestfile}" +amxxdodurl="${amxxdoddownloadurl}" +# AMX Mod X: Team Fortress Classic +amxxtfcversion="1.8.2" +amxxtfcmod="tfc" +amxxtfclatestfile="amxmodx-${amxxtfcversion}-${amxxtfcmod}-linux.tar.gz" +amxxtfcdownloadurl="https://www.amxmodx.org/release/${amxxtfclatestfile}" +amxxtfcurl="${amxxtfcdownloadurl}" +# AMX Mod X: Natural Selection +amxxnsversion="1.8.2" +amxxnsmod="ns" +amxxnslatestfile="amxmodx-${amxxnsversion}-${amxxnsmod}-linux.tar.gz" +amxxnsdownloadurl="https://www.amxmodx.org/release/${amxxnslatestfile}" +amxxnsurl="${amxxnsdownloadurl}" +# AMX Mod X: The Specialists +amxxtsversion="1.8.2" +amxxtsmod="ts" +amxxtslatestfile="amxmodx-${amxxtsversion}-${amxxtsmod}-linux.tar.gz" +amxxtsdownloadurl="https://www.amxmodx.org/release/${amxxtslatestfile}" +amxxtsurl="${amxxtsdownloadurl}" +# Metamod:Source +metamodsourceversion="1.11" +metamodsourcescrapeurl="https://mms.alliedmods.net/mmsdrop/${metamodsourceversion}/mmsource-latest-linux" +metamodsourcelatestfile=$(wget "${metamodsourcescrapeurl}" -q -O -) +metamodsourcedownloadurl="https://www.metamodsource.net/latest.php?os=linux&version=${metamodsourceversion}" +metamodsourceurl="${metamodsourcedownloadurl}" +# Sourcemod +sourcemodversion="1.11" +sourcemodscrapeurl="https://sm.alliedmods.net/smdrop/${sourcemodversion}/sourcemod-latest-linux" +sourcemodlatestfile=$(wget "${sourcemodscrapeurl}" -q -O -) +sourcemoddownloadurl="https://www.sourcemod.net/latest.php?os=linux&version=${sourcemodversion}" +sourcemodurl="${sourcemoddownloadurl}" +# Steamworks +steamworksscrapeurl="https://users.alliedmods.net/~kyles/builds/SteamWorks" +steamworkslatestfile=$(curl --connect-timeout 10 -sL ${steamworksscrapeurl} | grep -m 1 linux | cut -d '"' -f 4) +steamworksdownloadurl="${steamworksscrapeurl}/${steamworkslatestfile}" +steamworksurl="${steamworksdownloadurl}" +# CS:GO Mods +get5lastbuild=$(curl --connect-timeout 10 -sL https://api.github.com/repos/splewis/get5/releases/latest | jq '.assets[] |select(.browser_download_url | endswith(".tar.gz"))') +get5latestfile=$(echo -e "${get5lastbuild}" | jq -r '.name') +get5latestfilelink=$(echo -e "${get5lastbuild}" | jq -r '.browser_download_url') +csgopracticelatest=$(curl --connect-timeout 10 -sL https://api.github.com/repos/splewis/csgo-practice-mode/releases/latest | jq '.assets[]') +csgopracticelatestfile=$(echo -e "${csgopracticelatest}" | jq -r '.name') +csgopracticelatestlink=$(echo -e "${csgopracticelatest}" | jq -r '.browser_download_url') +csgopuglatest=$(curl --connect-timeout 10 -sL https://api.github.com/repos/splewis/csgo-pug-setup/releases/latest | jq '.assets[]') +csgopuglatestfile=$(echo -e "${csgopuglatest}" | jq -r '.name') +csgopuglatestlink=$(echo -e "${csgopuglatest}" | jq -r '.browser_download_url') +gokzlatestversion=$(curl --connect-timeout 10 -s https://api.github.com/repos/KZGlobalTeam/gokz/releases/latest | grep "tag_name" | cut -d : -f 2,3 | sed -E 's/.*"([^"]+)".*/\1/') +gokzlatestfile="GOKZ-v${gokzlatestversion}.zip" +gokzlatestlink="https://github.com/KZGlobalTeam/gokz/releases/download/${gokzlatestversion}/${gokzlatestfile}" +movementapilatestversion=$(curl --connect-timeout 10 -s https://api.github.com/repos/danzayau/MovementAPI/releases/latest | grep "tag_name" | cut -d : -f 2,3 | sed -E 's/.*"([^"]+)".*/\1/') +movementapilatestfile="MovementAPI-v${movementapilatestversion}.zip" +movementapilatestlink="https://github.com/danzayau/MovementAPI/releases/download/${movementapilatestversion}/${movementapilatestfile}" + +# Rust +carbonrustapilatestfile="Carbon.Linux.Release.tar.gz" +carbonrustlatestlink=$(curl --connect-timeout 10 -sL https://api.github.com/repos/CarbonCommunity/Carbon.Core/releases/tags/production_build | jq -r '.assets[]|select(.name == "Carbon.Linux.Release.tar.gz") | .browser_download_url') + +# Oxide +oxiderustlatestlink=$(curl --connect-timeout 10 -sL https://api.github.com/repos/OxideMod/Oxide.Rust/releases/latest | jq -r '.assets[]|select(.browser_download_url | contains("linux")) | .browser_download_url') +oxidehurtworldlatestlink=$(curl --connect-timeout 10 -sL https://api.github.com/repos/OxideMod/Oxide.Hurtworld/releases/latest | jq -r '.assets[].browser_download_url') +oxidesdtdlatestlink=$(curl --connect-timeout 10 -sL https://api.github.com/repos/OxideMod/Oxide.SevenDaysToDie/releases/latest | jq -r '.assets[]|select(.browser_download_url | contains("linux")) | .browser_download_url') +# Valheim Plus +valeimpluslatestlink=$(curl --connect-timeout 10 -sL https://api.github.com/repos/valheimPlus/ValheimPlus/releases/latest | jq -r '.assets[]|select(.browser_download_url | contains("UnixServer.tar.gz")) | .browser_download_url') +# Valheim BepInEx +bepinexvhlatestlink=$(curl --connect-timeout 10 -sL "https://valheim.thunderstore.io/api/experimental/package/denikson/BepInExPack_Valheim/" -H "accept: application/json" | jq -r '.latest.download_url') + +# Define mods information (required) + +# Separator name +modseparator="MOD" + +# REQUIRED: mod_info_name=( MOD "modcommand" "Pretty Name" "URL" "filename" "modsubdirs" "LowercaseOn/Off" "/files/to/keep;" "/install/path" "ENGINES" "GAMES" "NOTGAMES" "AUTHOR_URL" "Short Description" ) +# Example 1) Well made mod: mod_info_name=( MOD "awesomemod" "This is an Awesome Mod" "https://awesomemod.com/latest.zip" "awesomemod.zip" "0" "LowercaseOff" "OVERWRITE" "${systemdir}/addons" "source;unity3d;" "GAMES" "NOTGAMES" "https://awesomemod.com/" "This mod knows that 42 is the answer" ) +# Example 2) Poorly made mod: mod_info_name=( MOD "stupidmod" "This is a stupid mod" "${crappymodurl}" "StupidMod.zip" "2" "LowercaseOn" "cfg;data/crappymod;" "${systemdir}" "source;" "GAMES" "Garry's mod;Counter-Strike: Source;" "This mod is dumber than dumb" ) +# None of those values can be empty +# index | Usage +# [0] | MOD: separator, all mods must begin with it +# [1] | "modcommand": the LGSM name and command to install the mod (must be unique and lowercase) +# [2] | "Pretty Name": the common name people use to call the mod that will be displayed to the user +# [3] | "URL": link to the mod archive file; can be a variable previously defined while scraping a URL +# [4] | "filename": the output filename +# [5] | "modsubdirs": in how many subdirectories is the mod (none is 0) (not used at release, but could be in the future) +# [6] | "LowercaseOn/Off": LowercaseOff or LowercaseOn: enable/disable converting extracted files and directories to lowercase (some games require it) +# [7] | "modinstalldir": the directory in which to install the mode (use LGSM dir variables such as ${systemdir}) +# [8] | "/files/to/keep;", files & directories that should not be overwritten upon update, separated and ended with a semicolon; you can also use "OVERWRITE" value to ignore the value or "NOUPDATE" to disallow updating; for files to keep upon uninstall, see fn_mod_tidy_files_list from mods_core.sh +# [9] | "Supported Engines;": list them according to LGSM ${engine} variables, separated and ended with a semicolon, or use ENGINES to ignore the value +# [10] | "Supported Games;": list them according to LGSM ${gamename} variables, separated and ended with a semicolon, or use GAMES to ignore the value +# [11] | "Unsupported Games;": list them according to LGSM ${gamename} variables, separated and ended with a semicolon, or use NOTGAMES to ignore the value (useful to exclude a game when using Supported Engines) +# [12] | "AUTHOR_URL" is the author's website, displayed to the user when chosing mods to install +# [13] | "Short Description" a description showed to the user upon installation/removal + +# Half-life 1 Engine Mods +mod_info_metamod=(MOD "metamod" "Metamod" "${metamodurl}" "${metamodlatestfile}" "0" "LowercaseOff" "${systemdir}" "addons/metamod/plugins.ini;" "ENGINES" "Counter-Strike 1.6;Day of Defeat;Team Fortress Classic;Natural Selection;The Specialists;Half-Life: Deathmatch;" "NOTGAMES" "https://github.com/alliedmodders/metamod-hl1" "Plugins Framework") +mod_info_base_amxx=(MOD "amxmodx" "AMX Mod X: Base" "${amxxbaseurl}" "${amxxbaselatestfile}" "0" "LowercaseOff" "${systemdir}" "addons/amxmodx/configs;" "ENGINES" "Counter-Strike 1.6;Day of Defeat;Team Fortress Classic;Natural Selection;The Specialists;Half-Life: Deathmatch;" "NOTGAMES" "https://www.amxmodx.org" "Admin Features (requires Metamod)") + +# CS 1.6 (HL1) Engine Mods +mod_info_cs_amxx=(MOD "amxmodxcs" "AMX Mod X: Counter-Strike" "${amxxcsurl}" "${amxxcslatestfile}" "0" "LowercaseOff" "${systemdir}" "addons/amxmodx/configs;" "ENGINES" "Counter-Strike 1.6;" "NOTGAMES" "https://www.amxmodx.org" "Admin Features (requires Metamod & AMX Mod X: Base)") + +# DOD (HL1) Engine Mods +mod_info_dod_amxx=(MOD "amxmodxdod" "AMX Mod X: Day of Defeat" "${amxxdodurl}" "${amxxdodlatestfile}" "0" "LowercaseOff" "${systemdir}" "addons/amxmodx/configs;" "ENGINES" "Day of Defeat;" "NOTGAMES" "https://www.amxmodx.org" "Admin Features (requires Metamod & AMX Mod X: Base)") + +# TFC (HL1) Engine Mods +mod_info_tfc_amxx=(MOD "amxmodxtfc" "AMX Mod X: Team Fortress Classic" "${amxxtfcurl}" "${amxxtfclatestfile}" "0" "LowercaseOff" "${systemdir}" "addons/amxmodx/configs;" "ENGINES" "Team Fortress Classic;" "NOTGAMES" "https://www.amxmodx.org" "Admin Features (requires Metamod & AMX Mod X: Base)") + +# NS (Natural Selection) (HL1) Engine Mods +mod_info_ns_amxx=(MOD "amxmodxns" "AMX Mod X: Natural Selection" "${amxxnsurl}" "${amxxnslatestfile}" "0" "LowercaseOff" "${systemdir}" "addons/amxmodx/configs;" "ENGINES" "Natural Selection;" "NOTGAMES" "https://www.amxmodx.org" "Admin Features (requires Metamod & AMX Mod X: Base)") + +# TS (The Specialists) (HL1) Engine Mods +mod_info_ts_amxx=(MOD "amxmodxts" "AMX Mod X: The Specialists" "${amxxtsurl}" "${amxxtslatestfile}" "0" "LowercaseOff" "${systemdir}" "addons/amxmodx/configs;" "ENGINES" "The Specialists;" "NOTGAMES" "https://www.amxmodx.org" "Admin Features (requires Metamod & AMX Mod X: Base)") + +# Source mods +mod_info_metamodsource=(MOD "metamodsource" "Metamod: Source" "${metamodsourceurl}" "${metamodsourcelatestfile}" "0" "LowercaseOff" "${systemdir}" "addons/metamod/metaplugins.ini;" "source;" "GAMES" "NOTGAMES" "https://www.sourcemm.net" "Plugins Framework") +mod_info_sourcemod=(MOD "sourcemod" "SourceMod" "${sourcemodurl}" "${sourcemodlatestfile}" "0" "LowercaseOff" "${systemdir}" "cfg;addons/sourcemod/configs;" "source;" "GAMES" "NOTGAMES" "http://www.sourcemod.net" "Admin Features (requires Metamod: Source)") +mod_info_steamworks=(MOD "steamworks" "SteamWorks" "${steamworksurl}" "${steamworkslatestfile}" "0" "LowercaseOff" "${systemdir}" "OVERWRITE" "ENGINES" "Counter-Strike: Global Offensive;" "NOTGAMES" "https://github.com/KyleSanderson/SteamWorks" "Exposing SteamWorks functions to SourcePawn") +mod_info_stripper=(MOD "stripper" "Stripper Source" "http://www.bailopan.net/stripper/snapshots/1.2/stripper-1.2.2-git129-linux.tar.gz" "stripper-1.2.2-git129-linux.tar.gz" "0" "LowercaseOff" "${systemdir}" "addons/stripper/maps;" "ENGINES" "Counter-Strike: Global Offensive;Counter-Strike: Source;Day of Defeat: Source;Half Life: Deathmatch;Half Life 2: Deathmatch;Insurgency;Left 4 Dead;Left 4 Dead 2;Nuclear Dawn;Team Fortress 2;" "NOTGAMES" "http://www.bailopan.net/stripper/" "Add or remove objects from map (requires MetaMod)") + +# CS:GO Mods +mod_info_gokz=(MOD "gokz" "GOKZ" "${gokzlatestlink}" "${gokzlatestfile}" "0" "LowercaseOff" "${systemdir}" "cfg;addons/sourcemod/configs;" "ENGINES" "Counter-Strike: Global Offensive;" "NOTGAMES" "https://github.com/KZGlobalTeam/gokz" "GOKZ ${gokzlatestversion} - Implements the KZ game mode (requires SourceMod and MetaMod)") +mod_info_ttt=(MOD "ttt" "Trouble in Terrorist Town" "https://csgottt.com/downloads/ttt-latest-dev-${sourcemodversion}.zip" "ttt-latest.zip" "0" "LowercaseOff" "${systemdir}" "cfg;addons/sourcemod/configs;" "ENGINES" "Counter-Strike: Global Offensive;" "NOTGAMES" "https://github.com/Bara/TroubleinTerroristTown" "Implements the TTT game mode (requires SourceMod and MetaMod)") +mod_info_get5=(MOD "get5" "Get 5" "${get5latestfilelink}" "${get5latestfile}" "0" "LowercaseOff" "${systemdir}" "cfg;addons/sourcemod/configs;" "ENGINES" "Counter-Strike: Global Offensive;" "NOTGAMES" "https://github.com/splewis/get5" "Plugin for competitive matches/scrims (requires SourceMod and MetaMod)") +mod_info_prac=(MOD "prac" "csgo practice mode" "${csgopracticelatestlink}" "${csgopracticelatestfile}" "0" "LowercaseOff" "${systemdir}" "cfg;addons/sourcemod/configs;" "ENGINES" "Counter-Strike: Global Offensive;" "NOTGAMES" "https://github.com/splewis/csgo-practice-mode" "Practice Mode is a sourcemod plugin for helping players/teams run practices.") +mod_info_pug=(MOD "pug" "PUG" "${csgopuglatestlink}" "${csgopuglatestfile}" "0" "LowercaseOff" "${systemdir}" "cfg;addons/sourcemod/configs;" "ENGINES" "Counter-Strike: Global Offensive;" "NOTGAMES" "https://github.com/splewis/csgo-pug-setup" "plugin for setting up private pug/10man games") +mod_info_dhook=(MOD "dhook" "dhook" "https://forums.alliedmods.net/attachment.php?attachmentid=190123&d=1625050030" "dhooks-2.2.0d17.zip" "0" "LowercaseOff" "${systemdir}" "cfg;addons/sourcemod/configs;" "ENGINES" "Counter-Strike: Global Offensive;" "NOTGAMES" "https://forums.alliedmods.net/showpost.php?p=2588686&postcount=589" "DHooks 2.2.0 - Required for GOKZ") +mod_info_movement=(MOD "movementapi" "movementapi" "${movementapilatestlink}" "${movementapilatestfile}" "0" "LowercaseOff" "${systemdir}" "cfg;addons/sourcemod/configs;" "ENGINES" "Counter-Strike: Global Offensive;" "NOTGAMES" "https://github.com/danzayau/MovementAPI" "Movement API ${movementapilatestversion} - Required for GOKZ") +mod_info_cleaner=(MOD "cleaner" "cleaner" "https://github.com/e54385991/console-cleaner/archive/refs/heads/master.zip" "console-cleaner.zip" "0" "LowercaseOff" "${systemdir}" "cfg;addons/sourcemod/configs;" "ENGINES" "Counter-Strike: Global Offensive;" "NOTGAMES" "https://github.com/e54385991/console-cleaner" "Console Cleaner - Optional for GOKZ") + +# Garry's Mod Addons +mod_info_ulib=(MOD "ulib" "ULib" "https://codeload.github.com/TeamUlysses/ulib/zip/master" "ulib-master.zip" "0" "LowercaseOff" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "http://ulyssesmod.net" "Complete Framework") +mod_info_ulx=(MOD "ulx" "ULX" "https://codeload.github.com/TeamUlysses/ulx/zip/master" "ulx-master.zip" "0" "LowercaseOff" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "http://ulyssesmod.net" "Admin Panel (requires ULib)") +mod_info_utime=(MOD "utime" "UTime" "https://github.com/TeamUlysses/utime/archive/master.zip" "utime-master.zip" "0" "LowercaseOff" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "http://ulyssesmod.net" "Keep track of players play time") +mod_info_uclip=(MOD "uclip" "UClip" "https://github.com/TeamUlysses/uclip/archive/master.zip" "uclip-master.zip" "0" "LowercaseOff" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "http://ulyssesmod.net" "An alternative to noclip") +mod_info_acf=(MOD "acf" "Armoured Combat Framework" "https://github.com/nrlulz/ACF/archive/master.zip" "acf-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "acf-master/lua/acf/shared/guns;" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/nrlulz/ACF" "Realistic Wepons & Engines") +mod_info_acf_missiles=(MOD "acfmissiles" "ACF Missiles" "https://github.com/Bubbus/ACF-Missiles/archive/master.zip" "acf-missiles-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/Bubbus/ACF-Missiles" "More missiles for ACF") +mod_info_advdupe2=(MOD "advdupe2" "Advanced Duplicator 2" "https://github.com/wiremod/advdupe2/archive/master.zip" "advdupe2-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "http://www.wiremod.com" "Save your constructions. Second version") +mod_info_pac3=(MOD "pac3" "PAC3" "https://github.com/CapsAdmin/pac3/archive/master.zip" "pac3-master.zip" "0" "LowercaseOff" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/CapsAdmin/pac3" "Advanced player model customization") +mod_info_wiremod=(MOD "wiremod" "Wiremod" "https://github.com/wiremod/wire/archive/master.zip" "wire-master.zip" "0" "LowercaseOff" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/wiremod/wire" "Base Wiremod Addon") +mod_info_wiremodextras=(MOD "wiremod-extras" "Wiremod Extras" "https://github.com/wiremod/wire-extras/archive/master.zip" "wire-extras-master.zip" "0" "LowercaseOff" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/wiremod/wire-extras/" "Addition to Wiremod, Extra Content") +mod_info_advduplicator=(MOD "advdupe1" "Advanced Duplicator 1" "https://github.com/wiremod/advduplicator/archive/master.zip" "advduplicator-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/wiremod/advduplicator" "Save your constructions. First version") +mod_info_trackassemblytool=(MOD "trackassemblytool" "Track Assembly Tool" "https://github.com/dvdvideo1234/trackassemblytool/archive/master.zip" "trackassemblytool-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/dvdvideo1234/TrackAssemblyTool" "Assembles segmented track. Supports wire") +mod_info_physpropertiesadv=(MOD "physpropertiesadv" "Phys Properties Adv" "https://github.com/dvdvideo1234/physpropertiesadv/archive/master.zip" "physpropertiesadv-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/dvdvideo1234/PhysPropertiesAdv" "Advanced configurable properties") +mod_info_controlsystemse2=(MOD "controlsystemse2" "Control Systems E2" "https://github.com/dvdvideo1234/controlsystemse2/archive/master.zip" "controlsystemse2-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/dvdvideo1234/ControlSystemsE2" "PID controllers and fast traces for E2. Minor included in wire-extas") +mod_info_e2pistontiming=(MOD "e2pistontiming" "E2 Piston Timing" "https://github.com/dvdvideo1234/e2pistontiming/archive/master.zip" "e2pistontiming-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/dvdvideo1234/E2PistonTiming" "Routine driven piston engine timings for E2") +mod_info_propcannontool=(MOD "propcannontool" "Prop Cannon Tool" "https://github.com/dvdvideo1234/propcannontool/archive/master.zip" "propcannontool-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/dvdvideo1234/PropCannonTool" "Cannon entity that can fire props. Supports wire") +mod_info_gearassemblytool=(MOD "gearassemblytool" "Gear Assembly Tool" "https://github.com/dvdvideo1234/gearassemblytool/archive/master.zip" "gearassemblytool-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/dvdvideo1234/GearAssemblyTool" "Assembles segmented gearbox") +mod_info_spinnertool=(MOD "spinnertool" "Spinner Tool" "https://github.com/dvdvideo1234/spinnertool/archive/master.zip" "spinnertool-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/dvdvideo1234/SpinnerTool" "Torque lever controlled spinner. Supports wire") +mod_info_surfacefrictiontool=(MOD "surfacefrictiontool" "Surface Friction Tool" "https://github.com/dvdvideo1234/surfacefrictiontool/archive/master.zip" "surfacefrictiontool-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/dvdvideo1234/SurfaceFrictionTool" "Controls the surface friction of a prop") +mod_info_magneticdipole=(MOD "magneticdipole" "Magnetic Dipole" "https://github.com/dvdvideo1234/magneticdipole/archive/master.zip" "magneticdipole-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/dvdvideo1234/MagneticDipole" "Magnet entity that runs forces on its poles. Supports wire") +mod_info_environmentorganizer=(MOD "environmentorganizer" "Environment Organizer" "https://github.com/dvdvideo1234/environmentorganizer/archive/master.zip" "environmentorganizer-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/dvdvideo1234/EnvironmentOrganizer" "Installs routines designed for server settings adjustment") +mod_info_precision_alignment=(MOD "precision-alignment" "Precision Alignment" "https://github.com/Mista-Tea/precision-alignment/archive/master.zip" "precision-alignment-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/Mista-Tea/precision-alignment" "Creates precise constraints and aligments") +mod_info_improved_stacker=(MOD "improved-stacker" "Improved Stacker" "https://github.com/Mista-Tea/improved-stacker/archive/master.zip" "improved-stacker-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/Mista-Tea/improved-stacker" "Stacks entities in the direction chosen") +mod_info_improved_weight=(MOD "improved-weight" "Improved Weight" "https://github.com/Mista-Tea/improved-weight/archive/master.zip" "improved-weight-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/Mista-Tea/improved-weight" "Weight tool but with more features") +mod_info_improved_antinoclip=(MOD "improved-antinoclip" "Improved Antinoclip" "https://github.com/Mista-Tea/improved-antinoclip/archive/master.zip" "improved-antinoclip-master.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/Mista-Tea/improved-antinoclip" "Controls clipping trough an object") +mod_info_darkrp=(MOD "darkrp" "DarkRP" "https://github.com/FPtje/DarkRP/archive/master.zip" "darkrp-master.zip" "0" "LowercaseOn" "${systemdir}/gamemodes" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "http://darkrp.com" "Most popular gamemode") +mod_info_darkrpmodification=(MOD "darkrpmodification" "DarkRP Modification" "https://github.com/FPtje/darkrpmodification/archive/master.zip" "darkrpmodification-master.zip" "0" "LowercaseOff" "${systemdir}/addons" "NOUPDATE" "ENGINES" "Garry's Mod;" "NOTGAMES" "http://darkrp.com" "Customize DarkRP settings") +mod_info_laserstool=(MOD "laserstool" "Laser STool" "https://github.com/dvdvideo1234/laserstool/archive/main.zip" "laserstool-main.zip" "0" "LowercaseOn" "${systemdir}/addons" "OVERWRITE" "ENGINES" "Garry's Mod;" "NOTGAMES" "https://github.com/dvdvideo1234/LaserSTool" "Scripted tool that spawns laser entities, simulates light rays and even kill players") + +# Rust +mod_info_rustcarbon=(MOD "rustcarbon" "Carbon for Rust" "${carbonrustlatestlink}" "Carbon.Linux.Release.tar.gz" "0" "LowercaseOff" "${systemdir}" "OVERWRITE" "ENGINES" "Rust;" "NOTGAMES" "carbonmod.gg" "Allows for the use of both plugins and harmony mods") + +# Oxidemod +mod_info_rustoxide=(MOD "rustoxide" "Oxide for Rust" "${oxiderustlatestlink}" "Oxide.Rust-linux.zip" "0" "LowercaseOff" "${systemdir}" "OVERWRITE" "ENGINES" "Rust;" "NOTGAMES" "https://umod.org/games/rust" "Allows for the use of plugins") +mod_info_hwoxide=(MOD "hwoxide" "Oxide for Hurtworld" "${oxidehurtworldlatestlink}" "Oxide.Hurtworld.zip" "0" "LowercaseOff" "${systemdir}" "OVERWRITE" "ENGINES" "Hurtworld;" "NOTGAMES" "https://umod.org/games/hurtworld" "Allows for the use of plugins") +mod_info_sdtdoxide=(MOD "sdtdoxide" "Oxide for 7 Days To Die" "${oxidesdtdlatestlink}" "Oxide.SevenDaysToDie.zip" "0" "LowercaseOff" "${systemdir}" "OVERWRITE" "ENGINES" "7 Days To Die;" "NOTGAMES" "https://umod.org/games/7-days-to-die" "Allows for the use of plugins") + +# ValheimPlus +mod_info_valheimplus=(MOD "valheimplus" "Valheim PLUS" "${valeimpluslatestlink}" "ValheimPlus.tar.gz" "0" "LowercaseOff" "${systemdir}" "OVERWRITE" "ENGINES" "Valheim;" "NOTGAMES" "https://github.com/valheimPlus/ValheimPlus" "Mod to improve Valheim gameplay") + +# BepInEx Valheim +mod_info_bepinexvh=(MOD "bepinexvh" "BepInEx Valheim" "${bepinexvhlatestlink}" "denikson-BepInExPack_Valheim.zip" "0" "LowercaseOff" "${systemdir}" "OVERWRITE" "ENGINES" "Valheim;" "NOTGAMES" "https://valheim.thunderstore.io/package/denikson/BepInExPack_Valheim/" "Unity / XNA game patcher and plugin framework") + +# REQUIRED: Set all mods info into the global array +mods_global_array=("${mod_info_metamod[@]}" "${mod_info_base_amxx[@]}" "${mod_info_cs_amxx[@]}" "${mod_info_dod_amxx[@]}" "${mod_info_tfc_amxx[@]}" "${mod_info_ns_amxx[@]}" "${mod_info_ts_amxx[@]}" "${mod_info_metamodsource[@]}" "${mod_info_sourcemod[@]}" "${mod_info_steamworks[@]}" "${mod_info_gokz[@]}" "${mod_info_ttt[@]}" "${mod_info_get5[@]}" "${mod_info_prac[@]}" "${mod_info_pug[@]}" "${mod_info_dhook[@]}" "${mod_info_movement[@]}" "${mod_info_cleaner[@]}" "${mod_info_ulib[@]}" "${mod_info_ulx[@]}" "${mod_info_utime[@]}" "${mod_info_uclip[@]}" "${mod_info_acf[@]}" "${mod_info_acf_missiles[@]}" "${mod_info_acf_sweps[@]}" "${mod_info_advdupe2[@]}" "${mod_info_pac3[@]}" "${mod_info_wiremod[@]}" "${mod_info_wiremodextras[@]}" "${mod_info_darkrp[@]}" "${mod_info_darkrpmodification[@]}" "${mod_info_rustcarbon[@]}" "${mod_info_rustoxide[@]}" "${mod_info_hwoxide[@]}" "${mod_info_sdtdoxide[@]}" "${mod_info_advduplicator[@]}" "${mod_info_trackassemblytool[@]}" "${mod_info_physpropertiesadv[@]}" "${mod_info_controlsystemse2[@]}" "${mod_info_e2pistontiming[@]}" "${mod_info_propcannontool[@]}" "${mod_info_gearassemblytool[@]}" "${mod_info_spinnertool[@]}" "${mod_info_surfacefrictiontool[@]}" "${mod_info_magneticdipole[@]}" "${mod_info_environmentorganizer[@]}" "${mod_info_precision_alignment[@]}" "${mod_info_improved_stacker[@]}" "${mod_info_improved_weight[@]}" "${mod_info_improved_antinoclip[@]}" "${mod_info_laserstool[@]}" "${mod_info_valheimplus[@]}" "${mod_info_bepinexvh[@]}") diff --git a/lgsm/modules/query_gamedig.sh b/lgsm/modules/query_gamedig.sh new file mode 100644 index 0000000..28f70a3 --- /dev/null +++ b/lgsm/modules/query_gamedig.sh @@ -0,0 +1,88 @@ +#!/bin/bash +# LinuxGSM query_gamedig.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Querys a gameserver using node-gamedig. +# https://github.com/gamedig/node-gamedig + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" +# Default query status to failure. Will be changed to 0 if query is successful. +querystatus="2" +# Check if gamedig and jq are installed. +if [ "$(command -v gamedig 2> /dev/null)" ] && [ "$(command -v jq 2> /dev/null)" ]; then + + # will bypass query if server offline. + check_status.sh + if [ "${status}" != "0" ]; then + # GameDig requires you use the voice port when querying. + if [ "${querytype}" == "teamspeak3" ]; then + queryport="${port}" + fi + # checks if query is working null = pass. + gamedigcmd=$(echo -e "gamedig --type \"${querytype}\" \"${queryip}:${queryport}\"|jq") + gamedigraw=$(gamedig --type "${querytype}" "${queryip}:${queryport}") + querystatus=$(echo "${gamedigraw}" | jq '.error|length') + + if [ "${querytype}" == "teamspeak3" ]; then + fn_info_game_ts3 + fi + + # server name. + gdname=$(echo "${gamedigraw}" | jq -re '.name') + if [ "${gdname}" == "null" ]; then + unset gdname + fi + + # numplayers. + if [ "${querytype}" == "minecraft" ]; then + gdplayers=$(echo "${gamedigraw}" | jq -re '.players | length-1') + elif [ "${querytype}" == "teamspeak3" ]; then + gdplayers=$(echo "${gamedigraw}" | jq -re '.raw.virtualserver_clientsonline') + else + gdplayers=$(echo "${gamedigraw}" | jq -re '.players | length') + fi + if [ "${gdplayers}" == "null" ]; then + unset gdplayers + elif [ "${gdplayers}" == "[]" ] || [ "${gdplayers}" == "-1" ]; then + gdplayers=0 + fi + + # maxplayers. + gdmaxplayers=$(echo "${gamedigraw}" | jq -re '.maxplayers') + if [ "${gdmaxplayers}" == "null" ]; then + unset gdmaxplayers + elif [ "${gdmaxplayers}" == "[]" ]; then + gdmaxplayers=0 + fi + + # current map. + gdmap=$(echo "${gamedigraw}" | jq -re '.map') + if [ "${gdmap}" == "null" ]; then + unset gdmap + fi + + # current gamemode. + gdgamemode=$(echo "${gamedigraw}" | jq -re '.raw.rules.GameMode_s') + if [ "${gdgamemode}" == "null" ]; then + unset gdgamemode + fi + + # numbots. + gdbots=$(echo "${gamedigraw}" | jq -re '.bots | length') + if [ "${gdbots}" == "null" ] || [ "${gdbots}" == "0" ]; then + unset gdbots + fi + + # server version. + if [ "${querytype}" == "teamspeak3" ]; then + gdversion=$(echo "${gamedigraw}" | jq -re '.raw.virtualserver_version') + else + gdversion=$(echo "${gamedigraw}" | jq -re '.raw.version') + fi + + if [ "${gdversion}" == "null" ] || [ "${gdversion}" == "0" ]; then + unset gdversion + fi + fi +fi diff --git a/lgsm/modules/query_gsquery.py b/lgsm/modules/query_gsquery.py new file mode 100644 index 0000000..9fbb6a2 --- /dev/null +++ b/lgsm/modules/query_gsquery.py @@ -0,0 +1,151 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# LinuxGSM query_gsquery.py module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Allows querying of various game servers. + +import argparse +import socket +import sys + +engine_types=('protocol-valve','protocol-quake3','protocol-quake3','protocol-gamespy1','protocol-unreal2','ut3','minecraft','minecraftbe','jc2mp','mumbleping','soldat','teeworlds') + +class gsquery: + server_response_timeout = 2 + default_buffer_length = 1024 + sourcequery=('protocol-valve','avalanche3.0','barotrauma','madness','quakelive','realvirtuality','refractor','source','goldsrc','spark','starbound','unity3d','unreal4','wurm') + idtech2query=('protocol-quake3','idtech2','quake','iw2.0') + idtech3query=('protocol-quake3','iw3.0','ioquake3','qfusion') + minecraftquery=('minecraft','lwjgl2') + minecraftbequery=('minecraftbe',) + jc2mpquery=('jc2mp',) + mumblequery=('mumbleping',) + soldatquery=('soldat',) + twquery=('teeworlds',) + unrealquery=('protocol-gamespy1','unreal') + unreal2query=('protocol-unreal2','unreal2') + unreal3query=('ut3','unreal3') + + def __init__(self, arguments): + self.argument = arguments + # + if self.argument.engine in self.sourcequery: + self.query_prompt_string = b'\xFF\xFF\xFF\xFFTSource Engine Query\0' + elif self.argument.engine in self.idtech2query: + self.query_prompt_string = b'\xff\xff\xff\xffstatus\x00' + elif self.argument.engine in self.idtech3query: + self.query_prompt_string = b'\xff\xff\xff\xffgetstatus' + elif self.argument.engine in self.jc2mpquery: + self.query_prompt_string = b'\xFE\xFD\x09\x10\x20\x30\x40' + elif self.argument.engine in self.minecraftquery: + self.query_prompt_string = b'\xFE\xFD\x09\x3d\x54\x1f\x93' + elif self.argument.engine in self.minecraftbequery: + self.query_prompt_string = b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\x12\x34\x56\x78\x00\x00\x00\x00\x00\x00\x00\x00' + elif self.argument.engine in self.mumblequery: + self.query_prompt_string = b'\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08' + elif self.argument.engine in self.soldatquery: + self.query_prompt_string = b'\x69\x00' + elif self.argument.engine in self.twquery: + self.query_prompt_string = b'\x04\x00\x00\xff\xff\xff\xff\x05' + bytearray(511) + elif self.argument.engine in self.unrealquery: + self.query_prompt_string = b'\x5C\x69\x6E\x66\x6F\x5C' + elif self.argument.engine in self.unreal2query: + self.query_prompt_string = b'\x79\x00\x00\x00\x00' + elif self.argument.engine in self.unreal3query: + self.query_prompt_string = b'\xFE\xFD\x09\x00\x00\x00\x00' + + self.connected = False + self.response = None + + @staticmethod + def fatal_error(error_message, error_code=1): + sys.stderr.write('ERROR: ' + str(error_message) + '\n') + sys.exit(error_code) + + @staticmethod + def exit_success(success_message=''): + sys.stdout.write('OK: ' + str(success_message) + '\n') + sys.exit(0) + + def responding(self): + # Connect. + connection = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + connection.settimeout(self.server_response_timeout) + try: + self.connected = connection.connect((self.argument.address, int(self.argument.port))) + except socket.timeout: + self.fatal_error('Request timed out', 1) + except Exception: + self.fatal_error('Unable to connect', 1) + # Send. + connection.send(self.query_prompt_string) + # Receive. + try: + self.response = connection.recv(self.default_buffer_length) + except socket.error: + self.fatal_error('Unable to receive', 2) + connection.close() + # Response. + if self.response is None: + self.fatal_error('No response', 3) + if len(self.response) < 5: + sys.exit('Short response.', 3) + else: + self.exit_success(str(self.response)) + +def parse_args(): + parser = argparse.ArgumentParser( + description='Allows querying of various game servers.', + usage='usage: python3 %(prog)s [options]', + add_help=False + ) + parser.add_argument( + '-a', '--address', + type=str, + required=True, + help='The IPv4 address of the server.' + ) + parser.add_argument( + '-p', '--port', + type=int, + required=True, + help='The IPv4 port of the server.' + ) + parser.add_argument( + '-e', '--engine', + metavar='ENGINE', + choices=engine_types, + help='Engine type: ' + ' '.join(engine_types) + ) + parser.add_argument( + '-v', '--verbose', + action='store_true', + help='Display verbose output.' + ) + parser.add_argument( + '-d', '--debug', + action='store_true', + help='Display debugging output.' + ) + parser.add_argument( + '-V', '--version', + action='version', + version='%(prog)s 0.0.1', + help='Display version and exit.' + ) + parser.add_argument( + '-h', '--help', + action='help', + help='Display help and exit.' + ) + return parser.parse_args() + +def main(): + arguments = parse_args() + server = gsquery(arguments) + server.responding() + +if __name__ == '__main__': + main() diff --git a/lgsm/modules/update_fctr.sh b/lgsm/modules/update_fctr.sh new file mode 100644 index 0000000..8fb78ed --- /dev/null +++ b/lgsm/modules/update_fctr.sh @@ -0,0 +1,171 @@ +#!/bin/bash +# LinuxGSM update_fctr.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Handles updating of Factorio servers. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_update_dl() { + # Download and extract files to serverfiles. + fn_fetch_file "${remotebuildurl}" "" "" "" "${tmpdir}" "${remotebuildfilename}" "nochmodx" "norun" "force" "nohash" + fn_dl_extract "${tmpdir}" "factorio_headless_${factorioarch}-${remotebuildversion}.tar.xz" "${serverfiles}" "factorio" + fn_clear_tmp +} + +fn_update_localbuild() { + # Gets local build info. + fn_print_dots "Checking local build: ${remotelocation}" + # Uses executable to get local build. + if [ -d "${executabledir}" ]; then + cd "${executabledir}" || exit + localbuild=$(${executable} --version | grep "Version:" | awk '{print $2}') + fi + if [ -z "${localbuild}" ]; then + fn_print_error "Checking local build: ${remotelocation}: missing local build info" + fn_script_log_error "Missing local build info" + fn_script_log_error "Set localbuild to 0" + localbuild="0" + else + fn_print_ok "Checking local build: ${remotelocation}" + fn_script_log_pass "Checking local build" + fi +} + +fn_update_remotebuild() { + # Get remote build info. + apiurl="https://factorio.com/get-download/${branch}/headless/${factorioarch}" + remotebuildresponse=$(curl -s "${apiurl}") + remotebuildversion=$(echo "${remotebuildresponse}" | grep -o '[0-9]\.[0-9]\{1,\}\.[0-9]\{1,\}' | head -1) + remotebuildurl="https://factorio.com/get-download/${branch}/headless/${factorioarch}" + remotebuildfilename="factorio_headless_${factorioarch}-${remotebuildversion}.tar.xz" + + if [ "${firstcommandname}" != "INSTALL" ]; then + fn_print_dots "Checking remote build: ${remotelocation}" + # Checks if remotebuildversion variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_fail "Checking remote build: ${remotelocation}" + fn_script_log_fail "Checking remote build" + core_exit.sh + else + fn_print_ok "Checking remote build: ${remotelocation}" + fn_script_log_pass "Checking remote build" + fi + else + # Checks if remotebuild variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_failure "Unable to get remote build" + fn_script_log_fail "Unable to get remote build" + core_exit.sh + fi + fi +} + +fn_update_compare() { + fn_print_dots "Checking for update: ${remotelocation}" + # Update has been found or force update. + if [ "${localbuild}" != "${remotebuildversion}" ] || [ "${forceupdate}" == "1" ]; then + # Create update lockfile. + date '+%s' > "${lockdir:?}/update.lock" + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "Update available" + echo -e "* Local build: ${red}${localbuild} ${factorioarch}${default}" + echo -e "* Remote build: ${green}${remotebuildversion} ${factorioarch}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + echo -en "\n" + fn_script_log_info "Update available" + fn_script_log_info "Local build: ${localbuild} ${factorioarch}" + fn_script_log_info "Remote build: ${remotebuildversion} ${factorioarch}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + fn_script_log_info "${localbuild} > ${remotebuildversion}" + + if [ "${commandname}" == "UPDATE" ]; then + date +%s > "${lockdir}/last-updated.lock" + unset updateonstart + check_status.sh + # If server stopped. + if [ "${status}" == "0" ]; then + fn_update_dl + if [ "${localbuild}" == "0" ]; then + exitbypass=1 + command_start.sh + fn_firstcommand_reset + exitbypass=1 + fn_sleep_time_5 + command_stop.sh + fn_firstcommand_reset + fi + # If server started. + else + fn_print_restart_warning + exitbypass=1 + command_stop.sh + fn_firstcommand_reset + exitbypass=1 + fn_update_dl + exitbypass=1 + command_start.sh + fn_firstcommand_reset + fi + unset exitbypass + alert="update" + elif [ "${commandname}" == "CHECK-UPDATE" ]; then + alert="check-update" + fi + alert.sh + else + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "No update available" + echo -e "* Local build: ${green}${localbuild} ${factorioarch}${default}" + echo -e "* Remote build: ${green}${remotebuildversion} ${factorioarch}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + echo -en "\n" + fn_script_log_info "No update available" + fn_script_log_info "Local build: ${localbuild} ${factorioarch}" + fn_script_log_info "Remote build: ${remotebuildversion} ${factorioarch}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + fi +} + +# Game server architecture. +factorioarch="linux64" + +# The location where the builds are checked and downloaded. +remotelocation="factorio.com" + +if [ "${firstcommandname}" == "INSTALL" ]; then + fn_update_remotebuild + fn_update_dl +else + fn_print_dots "Checking for update" + fn_print_dots "Checking for update: ${remotelocation}" + fn_script_log_info "Checking for update: ${remotelocation}" + fn_update_localbuild + fn_update_remotebuild + fn_update_compare +fi diff --git a/lgsm/modules/update_jk2.sh b/lgsm/modules/update_jk2.sh new file mode 100644 index 0000000..e2715c0 --- /dev/null +++ b/lgsm/modules/update_jk2.sh @@ -0,0 +1,166 @@ +#!/bin/bash +# LinuxGSM update_jk2.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Handles updating of Jedi Knight 2 servers. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_update_dl() { + # Download and extract files to serverfiles. + fn_fetch_file "${remotebuildurl}" "" "" "" "${tmpdir}" "${remotebuildfilename}" "nochmodx" "norun" "force" "nohash" + fn_dl_extract "${tmpdir}" "${remotebuildfilename}" "${serverfiles}/GameData" "linux-amd64" + fn_clear_tmp +} + +fn_update_localbuild() { + # Gets local build info. + fn_print_dots "Checking local build: ${remotelocation}" + # Uses log file to get local build. + localbuild=$(grep "\"version\"" "${consolelogdir}"/* 2> /dev/null | sed 's/.*://' | awk '{print $1}' | head -n 1 | sed 's/v//') + if [ -z "${localbuild}" ]; then + fn_print_error "Checking local build: ${remotelocation}: missing local build info" + fn_script_log_error "Missing local build info" + fn_script_log_error "Set localbuild to 0" + localbuild="0" + else + fn_print_ok "Checking local build: ${remotelocation}" + fn_script_log_pass "Checking local build" + fi +} + +fn_update_remotebuild() { + # Get remote build info. + apiurl="https://api.github.com/repos/mvdevs/jk2mv/releases/latest" + remotebuildresponse=$(curl -s "${apiurl}") + remotebuildfilename=$(echo "${remotebuildresponse}" | jq -r '.assets[]|select(.browser_download_url | contains("dedicated.zip")) | .name') + remotebuildurl=$(echo "${remotebuildresponse}" | jq -r '.assets[]|select(.browser_download_url | contains("dedicated.zip")) | .browser_download_url') + remotebuildversion=$(echo "${remotebuildresponse}" | jq -r '.tag_name') + + if [ "${firstcommandname}" != "INSTALL" ]; then + fn_print_dots "Checking remote build: ${remotelocation}" + # Checks if remotebuildversion variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_fail "Checking remote build: ${remotelocation}" + fn_script_log_fail "Checking remote build" + core_exit.sh + else + fn_print_ok "Checking remote build: ${remotelocation}" + fn_script_log_pass "Checking remote build" + fi + else + # Checks if remotebuild variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_failure "Unable to get remote build" + fn_script_log_fail "Unable to get remote build" + core_exit.sh + fi + fi +} + +fn_update_compare() { + fn_print_dots "Checking for update: ${remotelocation}" + # Update has been found or force update. + if [ "${localbuild}" != "${remotebuildversion}" ] || [ "${forceupdate}" == "1" ]; then + # Create update lockfile. + date '+%s' > "${lockdir:?}/update.lock" + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "Update available" + echo -e "* Local build: ${red}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + echo -en "\n" + fn_script_log_info "Update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + fn_script_log_info "${localbuild} > ${remotebuildversion}" + + if [ "${commandname}" == "UPDATE" ]; then + unset updateonstart + check_status.sh + # If server stopped. + if [ "${status}" == "0" ]; then + fn_update_dl + if [ "${localbuild}" == "0" ]; then + exitbypass=1 + command_start.sh + fn_firstcommand_reset + exitbypass=1 + fn_sleep_time_5 + command_stop.sh + fn_firstcommand_reset + fi + # If server started. + else + fn_print_restart_warning + exitbypass=1 + command_stop.sh + fn_firstcommand_reset + exitbypass=1 + fn_update_dl + exitbypass=1 + command_start.sh + fn_firstcommand_reset + fi + unset exitbypass + date +%s > "${lockdir}/last-updated.lock" + alert="update" + elif [ "${commandname}" == "CHECK-UPDATE" ]; then + alert="check-update" + fi + alert.sh + else + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "No update available" + echo -e "* Local build: ${green}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + echo -en "\n" + fn_script_log_info "No update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + fi +} + +# The location where the builds are checked and downloaded. +remotelocation="github.com" + +if [ "${firstcommandname}" == "INSTALL" ]; then + fn_update_remotebuild + fn_update_dl +else + update_steamcmd.sh + fn_print_dots "Checking for update" + fn_print_dots "Checking for update: ${remotelocation}" + fn_script_log_info "Checking for update: ${remotelocation}" + fn_update_localbuild + fn_update_remotebuild + fn_update_compare +fi diff --git a/lgsm/modules/update_mc.sh b/lgsm/modules/update_mc.sh new file mode 100644 index 0000000..4a0bdde --- /dev/null +++ b/lgsm/modules/update_mc.sh @@ -0,0 +1,180 @@ +#!/bin/bash +# LinuxGSM update_mc.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Handles updating of Minecraft: Java Edition servers. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_update_dl() { + # Download and extract files to serverfiles. + fn_fetch_file "${remotebuildurl}" "" "" "" "${tmpdir}" "${remotebuildfilename}" "chmodx" "norun" "noforce" "nohash" + cp -f "${tmpdir}/${remotebuildfilename}" "${serverfiles}/${executable#./}" + fn_clear_tmp +} + +fn_update_localbuild() { + # Gets local build info. + fn_print_dots "Checking local build: ${remotelocation}" + # Uses executable to get local build. + if [ -d "${executabledir}" ]; then + cd "${executabledir}" || exit + localbuild=$(unzip -p "minecraft_server.jar" version.json | jq -r '.id') + fi + if [ -z "${localbuild}" ]; then + fn_print_error "Checking local build: ${remotelocation}: missing local build info" + fn_script_log_error "Missing local build info" + fn_script_log_error "Set localbuild to 0" + localbuild="0" + else + fn_print_ok "Checking local build: ${remotelocation}" + fn_script_log_pass "Checking local build" + fi +} + +fn_update_remotebuild() { + # Get remote build info. + apiurl="https://launchermeta.mojang.com/mc/game/version_manifest.json" + remotebuildresponse=$(curl -s "${apiurl}") + # Latest release. + if [ "${branch}" == "release" ] && [ "${mcversion}" == "latest" ]; then + remotebuildversion=$(echo "${remotebuildresponse}" | jq -r '.latest.release') + # Latest snapshot. + elif [ "${branch}" == "snapshot" ] && [ "${mcversion}" == "latest" ]; then + remotebuildversion=$(echo "${remotebuildresponse}" | jq -r '.latest.snapshot') + # Specific release/snapshot. + else + remotebuildversion=$(echo "${remotebuildresponse}" | jq -r --arg branch "${branch}" --arg mcversion "${mcversion}" '.versions | .[] | select(.type==$branch and .id==$mcversion) | .id') + fi + remotebuildfilename="minecraft_server.${remotebuildversion}.jar" + # Generate link to version manifest json. + remotebuildmanifest=$(echo "${remotebuildresponse}" | jq -r --arg branch "${branch}" --arg mcversion "${remotebuildversion}" '.versions | .[] | select(.type==$branch and .id==$mcversion) | .url') + # Generate link to server.jar + remotebuildurl=$(curl -s "${remotebuildmanifest}" | jq -r '.downloads.server.url') + + if [ "${firstcommandname}" != "INSTALL" ]; then + fn_print_dots "Checking remote build: ${remotelocation}" + # Checks if remotebuildversion variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_fail "Checking remote build: ${remotelocation}" + fn_script_log_fail "Checking remote build" + core_exit.sh + else + fn_print_ok "Checking remote build: ${remotelocation}" + fn_script_log_pass "Checking remote build" + fi + else + # Checks if remotebuild variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_failure "Unable to get remote build" + fn_script_log_fail "Unable to get remote build" + core_exit.sh + fi + fi +} + +fn_update_compare() { + fn_print_dots "Checking for update: ${remotelocation}" + # Update has been found or force update. + if [ "${localbuild}" != "${remotebuildversion}" ] || [ "${forceupdate}" == "1" ]; then + # Create update lockfile. + date '+%s' > "${lockdir:?}/update.lock" + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "Update available" + echo -e "* Local build: ${red}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + echo -en "\n" + fn_script_log_info "Update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + fn_script_log_info "${localbuild} > ${remotebuildversion}" + + if [ "${commandname}" == "UPDATE" ]; then + date +%s > "${lockdir}/last-updated.lock" + unset updateonstart + check_status.sh + # If server stopped. + if [ "${status}" == "0" ]; then + fn_update_dl + if [ "${localbuild}" == "0" ]; then + exitbypass=1 + command_start.sh + fn_firstcommand_reset + exitbypass=1 + fn_sleep_time_5 + command_stop.sh + fn_firstcommand_reset + fi + # If server started. + else + fn_print_restart_warning + exitbypass=1 + command_stop.sh + fn_firstcommand_reset + exitbypass=1 + fn_update_dl + exitbypass=1 + command_start.sh + fn_firstcommand_reset + fi + unset exitbypass + alert="update" + elif [ "${commandname}" == "CHECK-UPDATE" ]; then + alert="check-update" + fi + alert.sh + else + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "No update available" + echo -e "* Local build: ${green}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + echo -en "\n" + fn_script_log_info "No update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + fi +} + +# The location where the builds are checked and downloaded. +remotelocation="mojang.com" + +if [ "${firstcommandname}" == "INSTALL" ]; then + fn_update_remotebuild + fn_update_dl +else + fn_print_dots "Checking for update" + fn_print_dots "Checking for update: ${remotelocation}" + fn_script_log_info "Checking for update: ${remotelocation}" + fn_update_localbuild + fn_update_remotebuild + fn_update_compare +fi diff --git a/lgsm/modules/update_mcb.sh b/lgsm/modules/update_mcb.sh new file mode 100644 index 0000000..7bd273d --- /dev/null +++ b/lgsm/modules/update_mcb.sh @@ -0,0 +1,186 @@ +#!/bin/bash +# LinuxGSM update_mcb.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Handles updating of Minecraft Bedrock servers. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_update_dl() { + fn_fetch_file "${remotebuildurl}" "" "" "" "${tmpdir}" "bedrock_server.${remotebuildversion}.zip" "nochmodx" "norun" "noforce" "nohash" + echo -e "Extracting to ${serverfiles}...\c" + if [ "${firstcommandname}" == "INSTALL" ]; then + unzip -oq "${tmpdir}/bedrock_server.${remotebuildversion}.zip" -x "server.properties" -d "${serverfiles}" + else + unzip -oq "${tmpdir}/bedrock_server.${remotebuildversion}.zip" -x "permissions.json" "server.properties" "allowlist.json" -d "${serverfiles}" + fi + local exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fail "Extracting ${local_filename}" + if [ -f "${lgsmlog}" ]; then + echo -e "${extractcmd}" >> "${lgsmlog}" + fi + echo -e "${extractcmd}" + fn_clear_tmp + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Extracting ${local_filename}" + fn_clear_tmp + fi +} + +fn_update_localbuild() { + # Gets local build info. + fn_print_dots "Checking local build: ${remotelocation}" + # Uses log file to get local build. + localbuild=$(grep Version "${consolelogdir}"/* 2> /dev/null | tail -1 | sed 's/.*Version: //' | tr -d '\000-\011\013-\037') + if [ -z "${localbuild}" ]; then + fn_print_error "Checking local build: ${remotelocation}: missing local build info" + fn_script_log_error "Missing local build info" + fn_script_log_error "Set localbuild to 0" + localbuild="0" + else + fn_print_ok "Checking local build: ${remotelocation}" + fn_script_log_pass "Checking local build" + fi +} + +fn_update_remotebuild() { + # Random number for userAgent + randomint=$(tr -dc 0-9 < /dev/urandom 2> /dev/null | head -c 4 | xargs) + # Get remote build info. + if [ "${mcversion}" == "latest" ]; then + remotebuildversion=$(curl -H "Accept-Encoding: identity" -H "Accept-Language: en" -Ls -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.${randomint}.212 Safari/537.36" "https://www.minecraft.net/en-us/download/server/bedrock/" | grep -o 'https://minecraft.azureedge.net/bin-linux/[^"]*' | sed 's/.*\///' | grep -Eo "[.0-9]+[0-9]") + else + remotebuildversion="${mcversion}" + fi + remotebuildurl="https://minecraft.azureedge.net/bin-linux/bedrock-server-${remotebuildversion}.zip" + + if [ "${firstcommandname}" != "INSTALL" ]; then + fn_print_dots "Checking remote build: ${remotelocation}" + # Checks if remotebuildversion variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_fail "Checking remote build: ${remotelocation}" + fn_script_log_fail "Checking remote build" + core_exit.sh + else + fn_print_ok "Checking remote build: ${remotelocation}" + fn_script_log_pass "Checking remote build" + fi + else + # Checks if remotebuild variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_failure "Unable to get remote build" + fn_script_log_fail "Unable to get remote build" + core_exit.sh + fi + fi +} + +fn_update_compare() { + fn_print_dots "Checking for update: ${remotelocation}" + # Update has been found or force update. + if [ "${localbuild}" != "${remotebuildversion}" ] || [ "${forceupdate}" == "1" ]; then + # Create update lockfile. + date '+%s' > "${lockdir:?}/update.lock" + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "Update available" + echo -e "* Local build: ${red}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + echo -en "\n" + fn_script_log_info "Update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + fn_script_log_info "${localbuild} > ${remotebuildversion}" + + if [ "${commandname}" == "UPDATE" ]; then + date +%s > "${lockdir}/last-updated.lock" + unset updateonstart + check_status.sh + # If server stopped. + if [ "${status}" == "0" ]; then + fn_update_dl + if [ "${localbuild}" == "0" ]; then + exitbypass=1 + command_start.sh + fn_firstcommand_reset + exitbypass=1 + fn_sleep_time_5 + command_stop.sh + fn_firstcommand_reset + fi + # If server started. + else + fn_print_restart_warning + exitbypass=1 + command_stop.sh + fn_firstcommand_reset + exitbypass=1 + fn_update_dl + exitbypass=1 + command_start.sh + fn_firstcommand_reset + fi + unset exitbypass + alert="update" + elif [ "${commandname}" == "CHECK-UPDATE" ]; then + alert="check-update" + fi + alert.sh + else + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "No update available" + echo -e "* Local build: ${green}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + echo -en "\n" + fn_script_log_info "No update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + fi +} + +# The location where the builds are checked and downloaded. +remotelocation="minecraft.net" + +if [ "${firstcommandname}" == "INSTALL" ]; then + fn_update_remotebuild + fn_update_dl +else + fn_print_dots "Checking for update" + fn_print_dots "Checking for update: ${remotelocation}" + fn_script_log_info "Checking for update: ${remotelocation}" + fn_update_localbuild + fn_update_remotebuild + fn_update_compare +fi diff --git a/lgsm/modules/update_mta.sh b/lgsm/modules/update_mta.sh new file mode 100644 index 0000000..c6f7dfc --- /dev/null +++ b/lgsm/modules/update_mta.sh @@ -0,0 +1,173 @@ +#!/bin/bash +# LinuxGSM update_mta.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Handles updating of Multi Theft Auto servers. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_update_dl() { + # Download and extract files to tmpdir. + fn_fetch_file "http://linux.mtasa.com/dl/multitheftauto_linux_x64.tar.gz" "" "" "" "${tmpdir}" "multitheftauto_linux_x64.tar.gz" "nochmodx" "norun" "force" "nohash" + fn_dl_extract "${tmpdir}" "multitheftauto_linux_x64.tar.gz" "${serverfiles}" "multitheftauto_linux_x64" + fn_clear_tmp +} + +fn_update_localbuild() { + # Gets local build info. + fn_print_dots "Checking local build: ${remotelocation}" + # Uses executable to get local build. + if [ -d "${executabledir}" ]; then + cd "${executabledir}" || exit + localbuild=$(${executable} -v 2> /dev/null) + fi + if [ -z "${localbuild}" ]; then + fn_print_error "Checking local build: ${remotelocation}: missing local build info" + fn_script_log_error "Missing local build info" + fn_script_log_error "Set localbuild to 0" + localbuild="0" + else + fn_print_ok "Checking local build: ${remotelocation}" + fn_script_log_pass "Checking local build" + fi +} + +fn_update_remotebuild() { + # Get remote build info. + apiurl="https://linux.multitheftauto.com/revision/latest.txt" + remotebuildresponse=$(curl -s "${apiurl}") + remotebuildfilename="multitheftauto_linux_x64.tar.gz" + remotebuildurl="http://linux.mtasa.com/dl/multitheftauto_linux_x64.tar.gz" + remotebuildversion=$(echo "${remotebuildresponse}") + if [ "${firstcommandname}" != "INSTALL" ]; then + fn_print_dots "Checking remote build: ${remotelocation}" + # Checks if remotebuildversion variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_fail "Checking remote build: ${remotelocation}" + fn_script_log_fail "Checking remote build" + core_exit.sh + else + fn_print_ok "Checking remote build: ${remotelocation}" + fn_script_log_pass "Checking remote build" + fi + else + # Checks if remotebuild variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_failure "Unable to get remote build" + fn_script_log_fail "Unable to get remote build" + core_exit.sh + fi + fi +} + +fn_update_compare() { + fn_print_dots "Checking for update: ${remotelocation}" + # Update has been found or force update. + if [ "${localbuild}" != "${remotebuildversion}" ] || [ "${forceupdate}" == "1" ]; then + # Create update lockfile. + date '+%s' > "${lockdir:?}/update.lock" + if [ "${forceupdate}" == "1" ]; then + # forceupdate bypasses checks, useful for small build changes + mtaupdatestatus="forced" + else + mtaupdatestatus="available" + fi + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "Update available" + echo -e "* Local build: ${red}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + echo -en "\n" + fn_script_log_info "Update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + fn_script_log_info "${localbuild} > ${remotebuildversion}" + + if [ "${commandname}" == "UPDATE" ]; then + unset updateonstart + check_status.sh + # If server stopped. + if [ "${status}" == "0" ]; then + fn_update_dl + if [ "${localbuild}" == "0" ]; then + exitbypass=1 + command_start.sh + fn_firstcommand_reset + exitbypass=1 + fn_sleep_time_5 + command_stop.sh + fn_firstcommand_reset + fi + # If server started. + else + fn_print_restart_warning + exitbypass=1 + command_stop.sh + fn_firstcommand_reset + exitbypass=1 + fn_update_dl + exitbypass=1 + command_start.sh + fn_firstcommand_reset + fi + unset exitbypass + date +%s > "${lockdir}/last-updated.lock" + alert="update" + elif [ "${commandname}" == "CHECK-UPDATE" ]; then + alert="check-update" + fi + alert.sh + else + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "No update available" + echo -e "* Local build: ${green}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + echo -en "\n" + fn_script_log_info "No update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + fi +} + +# The location where the builds are checked and downloaded. +remotelocation="linux.mtasa.com" + +if [ "${firstcommandname}" == "INSTALL" ]; then + fn_update_remotebuild + fn_update_dl +else + fn_print_dots "Checking for update" + fn_print_dots "Checking for update: ${remotelocation}" + fn_script_log_info "Checking for update: ${remotelocation}" + fn_update_localbuild + fn_update_remotebuild + fn_update_compare +fi diff --git a/lgsm/modules/update_pmc.sh b/lgsm/modules/update_pmc.sh new file mode 100644 index 0000000..5d44bee --- /dev/null +++ b/lgsm/modules/update_pmc.sh @@ -0,0 +1,198 @@ +#!/bin/bash +# LinuxGSM update_pmc.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Handles updating of PaperMC and Waterfall servers. + +module_selfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_update_dl() { + # Download and extract files to serverfiles. + fn_fetch_file "${remotebuildurl}" "" "" "" "${tmpdir}" "${remotebuildfilename}" "chmodx" "norun" "force" "${remotebuildhash}" + cp -f "${tmpdir}/${remotebuildfilename}" "${serverfiles}/${executable#./}" + echo "${remotebuildversion}" > "${serverfiles}/build.txt" + fn_clear_tmp +} + +fn_update_localbuild() { + # Gets local build info. + fn_print_dots "Checking local build: ${remotelocation}" + # Uses build file to get local build. + localbuild=$(head -n 1 "${serverfiles}/build.txt" 2> /dev/null) + if [ -z "${localbuild}" ]; then + fn_print_error "Checking local build: ${remotelocation}: missing local build info" + fn_script_log_error "Missing local build info" + fn_script_log_error "Set localbuild to 0" + localbuild="0" + else + fn_print_ok "Checking local build: ${remotelocation}" + fn_script_log_pass "Checking local build" + fi +} + +fn_update_remotebuild() { + # Get remote build info. + apiurl="https://papermc.io/api/v2/projects" + # Get list of projects. + remotebuildresponse=$(curl -s "${apiurl}") + # Get list of Minecraft versions for project. + remotebuildresponseproject=$(curl -s "${apiurl}/${paperproject}") + # Get latest Minecraft: Java Edition version or user specified version. + if [ "${mcversion}" == "latest" ]; then + remotebuildmcversion=$(echo "${remotebuildresponseproject}" | jq -r '.versions[-1]') + else + # Checks if user specified version exists. + remotebuildmcversion=$(echo "${remotebuildresponseproject}" | jq -r -e --arg mcversion "${mcversion}" '.versions[]|select(. == $mcversion)') + if [ -z "${remotebuildmcversion}" ]; then + # user passed version does not exist + fn_print_error_nl "Version ${mcversion} not available from ${remotelocation}" + fn_script_log_error "Version ${mcversion} not available from ${remotelocation}" + core_exit.sh + fi + fi + # Get list of paper builds for specific Minecraft: Java Edition version. + remotebuildresponsemcversion=$(curl -s "${apiurl}/${paperproject}/versions/${remotebuildmcversion}") + # Get latest paper build for specific Minecraft: Java Edition version. + remotebuildpaperversion=$(echo "${remotebuildresponsemcversion}" | jq -r '.builds[-1]') + # Get various info about the paper build. + remotebuildresponseversion=$(curl -s "${apiurl}/${paperproject}/versions/${remotebuildmcversion}/builds/${remotebuildpaperversion}") + remotebuildfilename=$(echo "${remotebuildresponseversion}" | jq -r '.downloads.application.name') + remotebuildhash=$(echo "${remotebuildresponseversion}" | jq -r '.downloads.application.sha256') + remotebuildurl="${apiurl}/${paperproject}/versions/${remotebuildmcversion}/builds/${remotebuildpaperversion}/downloads/${remotebuildfilename}" + # Combines Minecraft: Java Edition version and paper build. e.g 1.16.5-456 + remotebuildversion="${remotebuildmcversion}-${remotebuildpaperversion}" + + if [ "${firstcommandname}" != "INSTALL" ]; then + fn_print_dots "Checking remote build: ${remotelocation}" + # Checks if remotebuildversion variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_fail "Checking remote build: ${remotelocation}" + fn_script_log_fail "Checking remote build" + core_exit.sh + else + fn_print_ok "Checking remote build: ${remotelocation}" + fn_script_log_pass "Checking remote build" + fi + else + # Checks if remotebuild variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_failure "Unable to get remote build" + fn_script_log_fail "Unable to get remote build" + core_exit.sh + fi + fi +} + +fn_update_compare() { + fn_print_dots "Checking for update: ${remotelocation}" + # Update has been found or force update. + if [ "${localbuild}" != "${remotebuildversion}" ] || [ "${forceupdate}" == "1" ]; then + # Create update lockfile. + date '+%s' > "${lockdir:?}/update.lock" + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "Update available" + echo -e "* Local build: ${red}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + echo -en "\n" + fn_script_log_info "Update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + fn_script_log_info "${localbuild} > ${remotebuildversion}" + + if [ "${commandname}" == "UPDATE" ]; then + date +%s > "${lockdir}/last-updated.lock" + unset updateonstart + check_status.sh + # If server stopped. + if [ "${status}" == "0" ]; then + fn_update_dl + if [ "${localbuild}" == "0" ]; then + exitbypass=1 + command_start.sh + fn_firstcommand_reset + exitbypass=1 + fn_sleep_time_5 + command_stop.sh + fn_firstcommand_reset + fi + # If server started. + else + fn_print_restart_warning + exitbypass=1 + command_stop.sh + fn_firstcommand_reset + exitbypass=1 + fn_update_dl + exitbypass=1 + command_start.sh + fn_firstcommand_reset + fi + unset exitbypass + alert="update" + elif [ "${commandname}" == "CHECK-UPDATE" ]; then + alert="check-update" + fi + alert.sh + else + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "No update available" + echo -e "* Local build: ${green}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + echo -en "\n" + fn_script_log_info "No update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + fi +} + +# The location where the builds are checked and downloaded. +remotelocation="papermc.io" + +if [ "${shortname}" == "pmc" ]; then + paperproject="paper" +elif [ "${shortname}" == "vpmc" ]; then + paperproject="velocity" +elif [ "${shortname}" == "wmc" ]; then + paperproject="waterfall" +fi + +if [ "${firstcommandname}" == "INSTALL" ]; then + fn_update_remotebuild + fn_update_dl +else + fn_print_dots "Checking for update" + fn_print_dots "Checking for update: ${remotelocation}" + fn_script_log_info "Checking for update: ${remotelocation}" + fn_update_localbuild + fn_update_remotebuild + fn_update_compare +fi diff --git a/lgsm/modules/update_steamcmd.sh b/lgsm/modules/update_steamcmd.sh new file mode 100644 index 0000000..20a85ab --- /dev/null +++ b/lgsm/modules/update_steamcmd.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# LinuxGSM update_steamcmd.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Handles updating using SteamCMD. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# init steamcmd functions +core_steamcmd.sh + +# The location where the builds are checked and downloaded. +remotelocation="SteamCMD" +check.sh + +fn_print_dots "${remotelocation}" + +if [ "${forceupdate}" == "1" ]; then + # forceupdate bypasses update checks. + if [ "${status}" != "0" ] && [ -v "${status}" ]; then + fn_print_restart_warning + exitbypass=1 + command_stop.sh + fn_firstcommand_reset + date '+%s' > "${lockdir:?}/update.lock" + fn_dl_steamcmd + date +%s > "${lockdir}/last-updated.lock" + exitbypass=1 + command_start.sh + fn_firstcommand_reset + else + fn_dl_steamcmd + date +%s > "${lockdir}/last-updated.lock" + fi +else + fn_update_steamcmd_localbuild + fn_update_steamcmd_remotebuild + fn_update_steamcmd_compare +fi diff --git a/lgsm/modules/update_ts3.sh b/lgsm/modules/update_ts3.sh new file mode 100644 index 0000000..1fa77f4 --- /dev/null +++ b/lgsm/modules/update_ts3.sh @@ -0,0 +1,184 @@ +#!/bin/bash +# LinuxGSM command_ts3.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Handles updating of Teamspeak 3 servers. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_update_dl() { + # Download and extract files to serverfiles. + fn_fetch_file "${remotebuildurl}" "" "" "" "${tmpdir}" "${remotebuildfilename}" "nochmodx" "norun" "force" "${remotebuildhash}" + fn_dl_extract "${tmpdir}" "${remotebuildfilename}" "${serverfiles}" "teamspeak3-server_linux_${ts3arch}" + fn_clear_tmp +} + +fn_update_localbuild() { + # Gets local build info. + fn_print_dots "Checking local build: ${remotelocation}" + # Uses log file to get local build. + localbuild=$(grep -Eo "TeamSpeak 3 Server ((\.)?[0-9]{1,3}){1,3}\.[0-9]{1,3}" "$(find "${serverfiles}"/* -name "ts3server*_0.log" 2> /dev/null | sort | tail -1)" | grep -Eo "((\.)?[0-9]{1,3}){1,3}\.[0-9]{1,3}" | tail -1) + if [ -z "${localbuild}" ]; then + fn_print_error "Checking local build: ${remotelocation}: missing local build info" + fn_script_log_error "Missing local build info" + fn_script_log_error "Set localbuild to 0" + localbuild="0" + else + fn_print_ok "Checking local build: ${remotelocation}" + fn_script_log_pass "Checking local build" + fi +} + +fn_update_remotebuild() { + # Get remote build info. + apiurl="https://www.teamspeak.com/versions/server.json" + remotebuildresponse=$(curl -s "${apiurl}") + + if [ "${ts3arch}" == "amd64" ]; then + remotebuildurl=$(echo -e "${remotebuildresponse}" | jq -r '.linux.x86_64.mirrors."teamspeak.com"') + remotebuildhash=$(echo -e "${remotebuildresponse}" | jq -r '.linux.x86_64.checksum') + elif [ "${ts3arch}" == "x86" ]; then + remotebuildurl=$(echo -e "${remotebuildresponse}" | jq -r '.linux.x86.mirrors."teamspeak.com"') + remotebuildhash=$(echo -e "${remotebuildresponse}" | jq -r '.linux.x86.checksum') + fi + remotebuildfilename=$(basename "${remotebuildurl}") + remotebuildversion=$(echo -e "${remotebuildresponse}" | jq -r '.linux.x86_64.version') + + if [ "${firstcommandname}" != "INSTALL" ]; then + fn_print_dots "Checking remote build: ${remotelocation}" + # Checks if remotebuildversion variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_fail "Checking remote build: ${remotelocation}" + fn_script_log_fail "Checking remote build" + core_exit.sh + else + fn_print_ok "Checking remote build: ${remotelocation}" + fn_script_log_pass "Checking remote build" + fi + else + # Checks if remotebuild variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_failure "Unable to get remote build" + fn_script_log_fail "Unable to get remote build" + core_exit.sh + fi + fi +} + +fn_update_compare() { + fn_print_dots "Checking for update: ${remotelocation}" + # Update has been found or force update. + if [ "${localbuild}" != "${remotebuildversion}" ] || [ "${forceupdate}" == "1" ]; then + # Create update lockfile. + date '+%s' > "${lockdir:?}/update.lock" + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "Update available" + echo -e "* Local build: ${red}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + echo -en "\n" + fn_script_log_info "Update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + fn_script_log_info "${localbuild} > ${remotebuildversion}" + + if [ "${commandname}" == "UPDATE" ]; then + date +%s > "${lockdir}/last-updated.lock" + unset updateonstart + check_status.sh + # If server stopped. + if [ "${status}" == "0" ]; then + fn_update_dl + if [ "${localbuild}" == "0" ]; then + exitbypass=1 + command_start.sh + fn_firstcommand_reset + exitbypass=1 + fn_sleep_time_5 + command_stop.sh + fn_firstcommand_reset + fi + # If server started. + else + fn_print_restart_warning + exitbypass=1 + command_stop.sh + fn_firstcommand_reset + exitbypass=1 + fn_update_dl + exitbypass=1 + command_start.sh + fn_firstcommand_reset + fi + unset exitbypass + alert="update" + elif [ "${commandname}" == "CHECK-UPDATE" ]; then + alert="check-update" + fi + alert.sh + else + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "No update available" + echo -e "* Local build: ${green}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + echo -en "\n" + fn_script_log_info "No update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + fi +} + +# Game server architecture. +info_distro.sh +if [ "${arch}" == "x86_64" ]; then + ts3arch="amd64" +elif [ "${arch}" == "i386" ] || [ "${arch}" == "i686" ]; then + ts3arch="x86" +else + fn_print_failure "Unknown or unsupported architecture: ${arch}" + fn_script_log_fail "Unknown or unsupported architecture: ${arch}" + core_exit.sh +fi + +# The location where the builds are checked and downloaded. +remotelocation="teamspeak.com" + +if [ "${firstcommandname}" == "INSTALL" ]; then + fn_update_remotebuild + fn_update_dl +else + fn_print_dots "Checking for update" + fn_print_dots "Checking for update: ${remotelocation}" + fn_script_log_info "Checking for update: ${remotelocation}" + fn_update_localbuild + fn_update_remotebuild + fn_update_compare +fi diff --git a/lgsm/modules/update_ut99.sh b/lgsm/modules/update_ut99.sh new file mode 100644 index 0000000..6d0be19 --- /dev/null +++ b/lgsm/modules/update_ut99.sh @@ -0,0 +1,166 @@ +#!/bin/bash +# LinuxGSM command_ut99.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Handles updating of Unreal Tournament 99 servers. + +module_selfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_update_dl() { + # Download and extract files to serverfiles. + fn_fetch_file "${remotebuildurl}" "" "" "" "${tmpdir}" "${remotebuildfilename}" "nochmodx" "norun" "force" "nohash" + fn_dl_extract "${tmpdir}" "${remotebuildfilename}" "${serverfiles}" + echo "${remotebuildversion}" > "${serverfiles}/build.txt" + fn_clear_tmp +} + +fn_update_localbuild() { + # Gets local build info. + fn_print_dots "Checking local build: ${remotelocation}" + # Uses build file to get local build. + localbuild=$(head -n 1 "${serverfiles}/build.txt" 2> /dev/null) + if [ -z "${localbuild}" ]; then + fn_print_error "Checking local build: ${remotelocation}: missing local build info" + fn_script_log_error "Missing local build info" + fn_script_log_error "Set localbuild to 0" + localbuild="0" + else + fn_print_ok "Checking local build: ${remotelocation}" + fn_script_log_pass "Checking local build" + fi +} + +fn_update_remotebuild() { + # Get remote build info. + apiurl="https://api.github.com/repos/OldUnreal/UnrealTournamentPatches/releases/latest" + remotebuildresponse=$(curl -s "${apiurl}") + remotebuildfilename=$(echo "${remotebuildresponse}" | jq -r '.assets[]|select(.browser_download_url | contains("Linux-amd64")) | .name') + remotebuildurl=$(echo "${remotebuildresponse}" | jq -r '.assets[]|select(.browser_download_url | contains("Linux-amd64")) | .browser_download_url') + remotebuildversion=$(echo "${remotebuildresponse}" | jq -r '.tag_name') + + if [ "${firstcommandname}" != "INSTALL" ]; then + fn_print_dots "Checking remote build: ${remotelocation}" + # Checks if remotebuildversion variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_fail "Checking remote build: ${remotelocation}" + fn_script_log_fail "Checking remote build" + core_exit.sh + else + fn_print_ok "Checking remote build: ${remotelocation}" + fn_script_log_pass "Checking remote build" + fi + else + # Checks if remotebuild variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_failure "Unable to get remote build" + fn_script_log_fail "Unable to get remote build" + core_exit.sh + fi + fi +} + +fn_update_compare() { + fn_print_dots "Checking for update: ${remotelocation}" + # Update has been found or force update. + if [ "${localbuild}" != "${remotebuildversion}" ] || [ "${forceupdate}" == "1" ]; then + # Create update lockfile. + date '+%s' > "${lockdir:?}/update.lock" + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "Update available" + echo -e "* Local build: ${red}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + echo -en "\n" + fn_script_log_info "Update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + fn_script_log_info "${localbuild} > ${remotebuildversion}" + + if [ "${commandname}" == "UPDATE" ]; then + date +%s > "${lockdir}/last-updated.lock" + unset updateonstart + check_status.sh + # If server stopped. + if [ "${status}" == "0" ]; then + fn_update_dl + if [ "${localbuild}" == "0" ]; then + exitbypass=1 + command_start.sh + fn_firstcommand_reset + exitbypass=1 + fn_sleep_time_5 + command_stop.sh + fn_firstcommand_reset + fi + # If server started. + else + fn_print_restart_warning + exitbypass=1 + command_stop.sh + fn_firstcommand_reset + exitbypass=1 + fn_update_dl + exitbypass=1 + command_start.sh + fn_firstcommand_reset + fi + unset exitbypass + alert="update" + elif [ "${commandname}" == "CHECK-UPDATE" ]; then + alert="check-update" + fi + alert.sh + else + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "No update available" + echo -e "* Local build: ${green}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + echo -en "\n" + fn_script_log_info "No update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + fi +} + +# The location where the builds are checked and downloaded. +remotelocation="github.com" + +if [ "${firstcommandname}" == "INSTALL" ]; then + fn_update_remotebuild + fn_update_dl +else + fn_print_dots "Checking for update" + fn_print_dots "Checking for update: ${remotelocation}" + fn_script_log_info "Checking for update: ${remotelocation}" + fn_update_localbuild + fn_update_remotebuild + fn_update_compare +fi diff --git a/lgsm/modules/update_vints.sh b/lgsm/modules/update_vints.sh new file mode 100644 index 0000000..403917e --- /dev/null +++ b/lgsm/modules/update_vints.sh @@ -0,0 +1,173 @@ +#!/bin/bash +# LinuxGSM update_vints.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Handles updating of Vintage Story servers. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_update_dl() { + # Download and extract files to serverfiles. + fn_fetch_file "${remotebuildurl}" "" "" "" "${tmpdir}" "${remotebuildfilename}" "nochmodx" "norun" "force" "${remotebuildhash}" + fn_dl_extract "${tmpdir}" "${remotebuildfilename}" "${serverfiles}" + fn_clear_tmp +} + +fn_update_localbuild() { + # Gets local build info. + fn_print_dots "Checking local build: ${remotelocation}" + # Uses executable to get local build. + if [ -d "${executabledir}" ]; then + cd "${executabledir}" || exit + localbuild="$(${preexecutable} ${executable} --version 2> /dev/null | sed '/^[[:space:]]*$/d')" + fi + if [ -z "${localbuild}" ]; then + fn_print_error "Checking local build: ${remotelocation}: missing local build info" + fn_script_log_error "Missing local build info" + fn_script_log_error "Set localbuild to 0" + localbuild="0" + else + fn_print_ok "Checking local build: ${remotelocation}" + fn_script_log_pass "Checking local build" + fi +} + +fn_update_remotebuild() { + # Get remote build info. + apiurl="http://api.vintagestory.at/stable-unstable.json" + remotebuildresponse=$(curl -s "${apiurl}") + if [ "${branch}" == "stable" ]; then + remotebuildversion=$(echo "${remotebuildresponse}" | jq -r '[ to_entries[] ] | .[].key' | grep -Ev "\-rc|\-pre" | sort -r -V | head -1) + else + remotebuildversion=$(echo "${remotebuildresponse}" | jq -r '[ to_entries[] ] | .[].key' | grep -E "\-rc|\-pre" | sort -r -V | head -1) + fi + remotebuildfilename=$(echo "${remotebuildresponse}" | jq --arg remotebuildversion "${remotebuildversion}" -r '.[$remotebuildversion].linuxserver.filename') + remotebuildurl=$(echo "${remotebuildresponse}" | jq --arg remotebuildversion "${remotebuildversion}" -r '.[$remotebuildversion].linuxserver.urls.cdn') + remotebuildhash=$(echo "${remotebuildresponse}" | jq --arg remotebuildversion "${remotebuildversion}" -r '.[$remotebuildversion].linuxserver.md5') + + if [ "${firstcommandname}" != "INSTALL" ]; then + fn_print_dots "Checking remote build: ${remotelocation}" + # Checks if remotebuildversion variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_fail "Checking remote build: ${remotelocation}" + fn_script_log_fail "Checking remote build" + core_exit.sh + else + fn_print_ok "Checking remote build: ${remotelocation}" + fn_script_log_pass "Checking remote build" + fi + else + # Checks if remotebuild variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_failure "Unable to get remote build" + fn_script_log_fail "Unable to get remote build" + core_exit.sh + fi + fi +} + +fn_update_compare() { + fn_print_dots "Checking for update: ${remotelocation}" + # Update has been found or force update. + if [ "${localbuild}" != "${remotebuildversion}" ] || [ "${forceupdate}" == "1" ]; then + # Create update lockfile. + date '+%s' > "${lockdir:?}/update.lock" + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "Update available" + echo -e "* Local build: ${red}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + echo -en "\n" + fn_script_log_info "Update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + fn_script_log_info "${localbuild} > ${remotebuildversion}" + + if [ "${commandname}" == "UPDATE" ]; then + date +%s > "${lockdir}/last-updated.lock" + unset updateonstart + check_status.sh + # If server stopped. + if [ "${status}" == "0" ]; then + fn_update_dl + if [ "${localbuild}" == "0" ]; then + exitbypass=1 + command_start.sh + fn_firstcommand_reset + exitbypass=1 + fn_sleep_time_5 + command_stop.sh + fn_firstcommand_reset + fi + # If server started. + else + fn_print_restart_warning + exitbypass=1 + command_stop.sh + fn_firstcommand_reset + exitbypass=1 + fn_update_dl + exitbypass=1 + command_start.sh + fn_firstcommand_reset + fi + unset exitbypass + alert="update" + elif [ "${commandname}" == "CHECK-UPDATE" ]; then + alert="check-update" + fi + alert.sh + else + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "No update available" + echo -e "* Local build: ${green}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + echo -en "\n" + fn_script_log_info "No update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "Remote build info" + echo -e "* apiurl: ${apiurl}" + echo -e "* remotebuildfilename: ${remotebuildfilename}" + echo -e "* remotebuildurl: ${remotebuildurl}" + echo -e "* remotebuildversion: ${remotebuildversion}" + fi + fi +} + +# The location where the builds are checked and downloaded. +remotelocation="vintagestory.at" + +if [ "${firstcommandname}" == "INSTALL" ]; then + fn_update_remotebuild + fn_update_dl +else + fn_print_dots "Checking for update" + fn_print_dots "Checking for update: ${remotelocation}" + fn_script_log_info "Checking for update: ${remotelocation}" + fn_update_localbuild + fn_update_remotebuild + fn_update_compare +fi diff --git a/linuxgsm.sh b/linuxgsm.sh new file mode 100755 index 0000000..1765658 --- /dev/null +++ b/linuxgsm.sh @@ -0,0 +1,513 @@ +#!/bin/bash +# Project: Linux Game Server Managers - LinuxGSM +# Author: Daniel Gibbs +# License: MIT License, see LICENSE.md +# Purpose: Linux Game Server Management Script +# Contributors: https://linuxgsm.com/contrib +# Documentation: https://docs.linuxgsm.com +# Website: https://linuxgsm.com + +# DO NOT EDIT THIS FILE +# LinuxGSM configuration is no longer edited here +# To update your LinuxGSM config go to: +# lgsm/config-lgsm +# https://docs.linuxgsm.com/configuration/linuxgsm-config + +# Debugging +if [ -f ".dev-debug" ]; then + if [ -f /.dockerenv ]; then + exec 5> /data/log/dev-debug.log + else + exec 5> dev-debug.log + fi + BASH_XTRACEFD="5" + set -x +fi + +version="v23.6.2" +shortname="core" +gameservername="core" +commandname="CORE" +rootdir=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")") +selfname=$(basename "$(readlink -f "${BASH_SOURCE[0]}")") +lgsmdir="${rootdir}/lgsm" +[ -n "${LGSM_LOGDIR}" ] && logdir="${LGSM_LOGDIR}" || logdir="${rootdir}/log" +lgsmlogdir="${logdir}/lgsm" +steamcmddir="${HOME}/.steam/steamcmd" +[ -n "${LGSM_SERVERFILES}" ] && serverfiles="${LGSM_SERVERFILES}" || serverfiles="${rootdir}/serverfiles" +modulesdir="${lgsmdir}/modules" +tmpdir="${lgsmdir}/tmp" +[ -n "${LGSM_DATADIR}" ] && datadir="${LGSM_DATADIR}" || datadir="${lgsmdir}/data" +lockdir="${lgsmdir}/lock" +sessionname="${selfname}" +[ -f "${datadir}/${selfname}.uid" ] && socketname="${sessionname}-$(cat "${datadir}/${selfname}.uid")" +serverlist="${datadir}/serverlist.csv" +serverlistmenu="${datadir}/serverlistmenu.csv" +[ -n "${LGSM_CONFIG}" ] && configdir="${LGSM_CONFIG}" || configdir="${lgsmdir}/config-lgsm" +configdirserver="${configdir}/${gameservername}" +configdirdefault="${lgsmdir}/config-default" +userinput="${1}" +userinput2="${2}" + +## GitHub Branch Select +# Allows for the use of different function files +# from a different repo and/or branch. +[ -n "${LGSM_GITHUBUSER}" ] && githubuser="${LGSM_GITHUBUSER}" || githubuser="WindyMadman" +[ -n "${LGSM_GITHUBREPO}" ] && githubrepo="${LGSM_GITHUBREPO}" || githubrepo="LinuxGSM" +[ -n "${LGSM_GITHUBBRANCH}" ] && githubbranch="${LGSM_GITHUBBRANCH}" || githubbranch="master" + +# Check that curl is installed before doing anything +if [ ! "$(command -v curl 2> /dev/null)" ]; then + echo -e "[ FAIL ] Curl is not installed" + exit 1 +fi + +# Core module that is required first. +core_modules.sh() { + modulefile="${FUNCNAME[0]}" + fn_bootstrap_fetch_file_github "lgsm/modules" "core_modules.sh" "${modulesdir}" "chmodx" "run" "noforcedl" "nomd5" +} + +# Bootstrap +# Fetches the core modules required before passed off to core_dl.sh. +fn_bootstrap_fetch_file() { + remote_fileurl="${1}" + remote_fileurl_backup="${2}" + remote_fileurl_name="${3}" + remote_fileurl_backup_name="${4}" + local_filedir="${5}" + local_filename="${6}" + chmodx="${7:-0}" + run="${8:-0}" + forcedl="${9:-0}" + md5="${10:-0}" + # Download file if missing or download forced. + if [ ! -f "${local_filedir}/${local_filename}" ] || [ "${forcedl}" == "forcedl" ]; then + # If backup fileurl exists include it. + if [ -n "${remote_fileurl_backup}" ]; then + # counter set to 0 to allow second try + counter=0 + remote_fileurls_array=(remote_fileurl remote_fileurl_backup) + else + # counter set to 1 to not allow second try + counter=1 + remote_fileurls_array=(remote_fileurl) + fi + + for remote_fileurl_array in "${remote_fileurls_array[@]}"; do + if [ "${remote_fileurl_array}" == "remote_fileurl" ]; then + fileurl="${remote_fileurl}" + fileurl_name="${remote_fileurl_name}" + elif [ "${remote_fileurl_array}" == "remote_fileurl_backup" ]; then + fileurl="${remote_fileurl_backup}" + fileurl_name="${remote_fileurl_backup_name}" + fi + counter=$((counter + 1)) + if [ ! -d "${local_filedir}" ]; then + mkdir -p "${local_filedir}" + fi + # Trap will remove part downloaded files if canceled. + trap fn_fetch_trap INT + # Larger files show a progress bar. + + echo -en "fetching ${fileurl_name} ${local_filename}...\c" + curlcmd=$(curl --connect-timeout 10 -s --fail -L -o "${local_filedir}/${local_filename}" "${fileurl}" 2>&1) + + local exitcode=$? + + # Download will fail if downloads a html file. + if [ -f "${local_filedir}/${local_filename}" ]; then + if [ -n "$(head "${local_filedir}/${local_filename}" | grep "DOCTYPE")" ]; then + rm -f "${local_filedir:?}/${local_filename:?}" + local exitcode=2 + fi + fi + + # On first try will error. On second try will fail. + if [ "${exitcode}" != 0 ]; then + if [ ${counter} -ge 2 ]; then + echo -e "FAIL" + if [ -f "${lgsmlog}" ]; then + fn_script_log_fail "Downloading ${local_filename}" + fn_script_log_fail "${fileurl}" + fi + core_exit.sh + else + echo -e "ERROR" + if [ -f "${lgsmlog}" ]; then + fn_script_log_error "Downloading ${local_filename}" + fn_script_log_error "${fileurl}" + fi + fi + else + echo -en "OK" + sleep 0.3 + echo -en "\033[2K\\r" + if [ -f "${lgsmlog}" ]; then + fn_script_log_pass "Downloading ${local_filename}" + fi + + # Make file executable if chmodx is set. + if [ "${chmodx}" == "chmodx" ]; then + chmod +x "${local_filedir}/${local_filename}" + fi + + # Remove trap. + trap - INT + + break + fi + done + fi + + if [ -f "${local_filedir}/${local_filename}" ]; then + # Execute file if run is set. + if [ "${run}" == "run" ]; then + # shellcheck source=/dev/null + source "${local_filedir}/${local_filename}" + fi + fi +} + +fn_bootstrap_fetch_file_github() { + github_file_url_dir="${1}" + github_file_url_name="${2}" + # By default modules will be downloaded from the version release to prevent potential version mixing. Only update-lgsm will allow an update. + if [ "${githubbranch}" == "master" ] && [ "${githubuser}" == "WindyMadman" ] && [ "${commandname}" != "UPDATE-LGSM" ]; then + remote_fileurl="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/tag/${version}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/tag/${version}/${github_file_url_dir}/${github_file_url_name}" + echo $remote_fileurl + echo $remote_fileurl_backup + else + remote_fileurl="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://ct.windycloud.cn:3000/${githubuser}/${githubrepo}/raw/branch/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + echo $remote_fileurl + echo $remote_fileurl_backup + fi + remote_fileurl_name="GitHub" + remote_fileurl_backup_name="Bitbucket" + local_filedir="${3}" + local_filename="${github_file_url_name}" + chmodx="${4:-0}" + run="${5:-0}" + forcedl="${6:-0}" + md5="${7:-0}" + # Passes vars to the file download module. + fn_bootstrap_fetch_file "${remote_fileurl}" "${remote_fileurl_backup}" "${remote_fileurl_name}" "${remote_fileurl_backup_name}" "${local_filedir}" "${local_filename}" "${chmodx}" "${run}" "${forcedl}" "${md5}" +} + +# Installer menu. + +fn_print_center() { + columns=$(tput cols) + line="$*" + printf "%*s\n" $(((${#line} + columns) / 2)) "${line}" +} + +fn_print_horizontal() { + printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' "=" +} + +# Bash menu. +fn_install_menu_bash() { + local resultvar=$1 + title=$2 + caption=$3 + options=$4 + fn_print_horizontal + fn_print_center "${title}" + fn_print_center "${caption}" + fn_print_horizontal + menu_options=() + while read -r line || [[ -n "${line}" ]]; do + var=$(echo -e "${line}" | awk -F "," '{print $2 " - " $3}') + menu_options+=("${var}") + done < "${options}" + menu_options+=("Cancel") + select option in "${menu_options[@]}"; do + if [ "${option}" ] && [ "${option}" != "Cancel" ]; then + eval "$resultvar=\"${option/%\ */}\"" + fi + break + done +} + +# Whiptail/Dialog menu. +fn_install_menu_whiptail() { + local menucmd=$1 + local resultvar=$2 + title=$3 + caption=$4 + options=$5 + height=${6:-40} + width=${7:-80} + menuheight=${8:-30} + IFS="," + menu_options=() + while read -r line; do + key=$(echo -e "${line}" | awk -F "," '{print $3}') + val=$(echo -e "${line}" | awk -F "," '{print $2}') + menu_options+=("${val//\"/}" "${key//\"/}") + done < "${options}" + OPTION=$(${menucmd} --title "${title}" --menu "${caption}" "${height}" "${width}" "${menuheight}" "${menu_options[@]}" 3>&1 1>&2 2>&3) + if [ $? == 0 ]; then + eval "$resultvar=\"${OPTION}\"" + else + eval "$resultvar=" + fi +} + +# Menu selector. +fn_install_menu() { + local resultvar=$1 + local selection="" + title=$2 + caption=$3 + options=$4 + # Get menu command. + for menucmd in whiptail dialog bash; do + if [ "$(command -v "${menucmd}")" ]; then + menucmd=$(command -v "${menucmd}") + break + fi + done + case "$(basename "${menucmd}")" in + whiptail | dialog) + fn_install_menu_whiptail "${menucmd}" selection "${title}" "${caption}" "${options}" 40 80 30 + ;; + *) + fn_install_menu_bash selection "${title}" "${caption}" "${options}" + ;; + esac + eval "$resultvar=\"${selection}\"" +} + +# Gets server info from serverlist.csv and puts in to array. +fn_server_info() { + IFS="," + server_info_array=($(grep -aw "${userinput}" "${serverlist}")) + shortname="${server_info_array[0]}" # csgo + gameservername="${server_info_array[1]}" # csgoserver + gamename="${server_info_array[2]}" # Counter Strike: Global Offensive +} + +fn_install_getopt() { + userinput="empty" + echo -e "Usage: $0 [option]" + echo -e "" + echo -e "Installer - Linux Game Server Managers - Version ${version}" + echo -e "https://linuxgsm.com" + echo -e "" + echo -e "Commands" + echo -e "install\t\t| Select server to install." + echo -e "servername\t| Enter name of game server to install. e.g $0 csgoserver." + echo -e "list\t\t| List all servers available for install." + exit +} + +fn_install_file() { + local_filename="${gameservername}" + if [ -e "${local_filename}" ]; then + i=2 + while [ -e "${local_filename}-${i}" ]; do + ((i++)) + done + local_filename="${local_filename}-${i}" + fi + cp -R "${selfname}" "${local_filename}" + sed -i -e "s/shortname=\"core\"/shortname=\"${shortname}\"/g" "${local_filename}" + sed -i -e "s/gameservername=\"core\"/gameservername=\"${gameservername}\"/g" "${local_filename}" + echo -e "Installed ${gamename} server as ${local_filename}" + echo -e "" + if [ ! -d "${serverfiles}" ]; then + echo -e "./${local_filename} install" + else + echo -e "Remember to check server ports" + echo -e "./${local_filename} details" + fi + echo -e "" + exit +} + +# Prevent LinuxGSM from running as root. Except if doing a dependency install. +if [ "$(whoami)" == "root" ]; then + if [ -f "${modulesdir}/core_modules.sh" ] || [ -f "${modulesdir}/check_root.sh" ] || [ -f "${modulesdir}/core_messages.sh" ]; then + if [ "${userinput}" != "install" ] && [ "${userinput}" != "auto-install" ] && [ "${userinput}" != "i" ] && [ "${userinput}" != "ai" ]; then + core_modules.sh + core_messages.sh + fn_ansi_loader + check_root.sh + fi + else + if [ "${userinput}" != "install" ] && [ "${userinput}" != "auto-install" ] && [ "${userinput}" != "i" ] && [ "${userinput}" != "ai" ]; then + echo -e "[ FAIL ] Do NOT run as root!" + exit 1 + fi + fi +fi + +# LinuxGSM installer mode. +if [ "${shortname}" == "core" ]; then + # Download the latest serverlist. This is the complete list of all supported servers. + fn_bootstrap_fetch_file_github "lgsm/data" "serverlist.csv" "${datadir}" "nochmodx" "norun" "forcedl" "nomd5" + if [ ! -f "${serverlist}" ]; then + echo -e "[ FAIL ] serverlist.csv could not be loaded." + exit 1 + fi + + if [ "${userinput}" == "list" ] || [ "${userinput}" == "l" ]; then + { + tail -n +2 "${serverlist}" | awk -F "," '{print $2 "\t" $3}' + } | column -s $'\t' -t | more + exit + elif [ "${userinput}" == "install" ] || [ "${userinput}" == "i" ]; then + tail -n +2 "${serverlist}" | awk -F "," '{print $1 "," $2 "," $3}' > "${serverlistmenu}" + fn_install_menu result "LinuxGSM" "Select game server to install." "${serverlistmenu}" + userinput="${result}" + fn_server_info + if [ "${result}" == "${gameservername}" ]; then + fn_install_file + elif [ "${result}" == "" ]; then + echo -e "Install canceled" + else + echo -e "[ FAIL ] menu result does not match gameservername" + echo -e "result: ${result}" + echo -e "gameservername: ${gameservername}" + fi + elif [ "${userinput}" ]; then + fn_server_info + if [ "${userinput}" == "${gameservername}" ] || [ "${userinput}" == "${gamename}" ] || [ "${userinput}" == "${shortname}" ]; then + fn_install_file + else + echo -e "[ FAIL ] Unknown game server" + exit 1 + fi + else + fn_install_getopt + fi + +# LinuxGSM server mode. +else + core_modules.sh + if [ "${shortname}" != "core-dep" ]; then + # Load LinuxGSM configs. + # These are required to get all the default variables for the specific server. + # Load the default config. If missing download it. If changed reload it. + if [ ! -f "${configdirdefault}/config-lgsm/${gameservername}/_default.cfg" ]; then + mkdir -p "${configdirdefault}/config-lgsm/${gameservername}" + fn_fetch_config "lgsm/config-default/config-lgsm/${gameservername}" "_default.cfg" "${configdirdefault}/config-lgsm/${gameservername}" "_default.cfg" "nochmodx" "norun" "noforcedl" "nomd5" + fi + if [ ! -f "${configdirserver}/_default.cfg" ]; then + mkdir -p "${configdirserver}" + echo -en "copying _default.cfg...\c" + cp -R "${configdirdefault}/config-lgsm/${gameservername}/_default.cfg" "${configdirserver}/_default.cfg" + if [ $? != 0 ]; then + echo -e "FAIL" + exit 1 + else + echo -e "OK" + fi + else + config_file_diff=$(diff -q "${configdirdefault}/config-lgsm/${gameservername}/_default.cfg" "${configdirserver}/_default.cfg") + if [ "${config_file_diff}" != "" ]; then + fn_print_warn_nl "_default.cfg has altered. reloading config." + echo -en "copying _default.cfg...\c" + cp -R "${configdirdefault}/config-lgsm/${gameservername}/_default.cfg" "${configdirserver}/_default.cfg" + if [ $? != 0 ]; then + echo -e "FAIL" + exit 1 + else + echo -e "OK" + fi + fi + fi + fi + + # Load the IP details before the first config is loaded. + check_ip.sh + # Configs have to be loaded twice to allow start startparameters to pick up all vars + # shellcheck source=/dev/null + source "${configdirserver}/_default.cfg" + # Load the common.cfg config. If missing download it. + if [ ! -f "${configdirserver}/common.cfg" ]; then + fn_fetch_config "lgsm/config-default/config-lgsm" "common-template.cfg" "${configdirserver}" "common.cfg" "${chmodx}" "nochmodx" "norun" "noforcedl" "nomd5" + # shellcheck source=/dev/null + source "${configdirserver}/common.cfg" + else + # shellcheck source=/dev/null + source "${configdirserver}/common.cfg" + fi + # Load the secrets-common.cfg config. If missing download it. + if [ ! -f "${configdirserver}/secrets-common.cfg" ]; then + fn_fetch_config "lgsm/config-default/config-lgsm" "secrets-common-template.cfg" "${configdirserver}" "secrets-common.cfg" "${chmodx}" "nochmodx" "norun" "noforcedl" "nomd5" + # shellcheck source=/dev/null + source "${configdirserver}/secrets-common.cfg" + else + # shellcheck source=/dev/null + source "${configdirserver}/secrets-common.cfg" + fi + # Load the instance.cfg config. If missing download it. + if [ ! -f "${configdirserver}/${selfname}.cfg" ]; then + fn_fetch_config "lgsm/config-default/config-lgsm" "instance-template.cfg" "${configdirserver}" "${selfname}.cfg" "nochmodx" "norun" "noforcedl" "nomd5" + # shellcheck source=/dev/null + source "${configdirserver}/${selfname}.cfg" + else + # shellcheck source=/dev/null + source "${configdirserver}/${selfname}.cfg" + fi + # Load the secrets-instance.cfg config. If missing download it. + if [ ! -f "${configdirserver}/secrets-${selfname}.cfg" ]; then + fn_fetch_config "lgsm/config-default/config-lgsm" "secrets-instance-template.cfg" "${configdirserver}" "secrets-${selfname}.cfg" "nochmodx" "norun" "noforcedl" "nomd5" + # shellcheck source=/dev/null + source "${configdirserver}/secrets-${selfname}.cfg" + else + # shellcheck source=/dev/null + source "${configdirserver}/secrets-${selfname}.cfg" + fi + + # Reloads start parameter to ensure all vars in startparameters are set. + # Will reload the last defined startparameter. + fn_reload_startparameters() { + # reload Wurm config. + if [ "${shortname}" == "wurm" ]; then + # shellcheck source=/dev/null + source "${servercfgfullpath}" + fi + # reload startparameters. + if grep -qE "^[[:blank:]]*startparameters=" "${configdirserver}/secrets-${selfname}.cfg"; then + eval startparameters="$(sed -nr 's/^ *startparameters=(.*)$/\1/p' "${configdirserver}/secrets-${selfname}.cfg")" + elif grep -qE "^[[:blank:]]*startparameters=" "${configdirserver}/${selfname}.cfg"; then + eval startparameters="$(sed -nr 's/^ *startparameters=(.*)$/\1/p' "${configdirserver}/${selfname}.cfg")" + elif grep -qE "^[[:blank:]]*startparameters=" "${configdirserver}/secrets-common.cfg"; then + eval startparameters="$(sed -nr 's/^ *startparameters=(.*)$/\1/p' "${configdirserver}/secrets-common.cfg")" + elif grep -qE "^[[:blank:]]*startparameters=" "${configdirserver}/common.cfg"; then + eval startparameters="$(sed -nr 's/^ *startparameters=(.*)$/\1/p' "${configdirserver}/common.cfg")" + elif grep -qE "^[[:blank:]]*startparameters=" "${configdirserver}/_default.cfg"; then + eval startparameters="$(sed -nr 's/^ *startparameters=(.*)$/\1/p' "${configdirserver}/_default.cfg")" + fi + + # reload preexecutable. + if grep -qE "^[[:blank:]]*preexecutable=" "${configdirserver}/secrets-${selfname}.cfg"; then + eval preexecutable="$(sed -nr 's/^ *preexecutable=(.*)$/\1/p' "${configdirserver}/secrets-${selfname}.cfg")" + elif grep -qE "^[[:blank:]]*preexecutable=" "${configdirserver}/${selfname}.cfg"; then + eval preexecutable="$(sed -nr 's/^ *preexecutable=(.*)$/\1/p' "${configdirserver}/${selfname}.cfg")" + elif grep -qE "^[[:blank:]]*preexecutable=" "${configdirserver}/secrets-common.cfg"; then + eval preexecutable="$(sed -nr 's/^ *preexecutable=(.*)$/\1/p' "${configdirserver}/secrets-common.cfg")" + elif grep -qE "^[[:blank:]]*preexecutable=" "${configdirserver}/common.cfg"; then + eval preexecutable="$(sed -nr 's/^ *preexecutable=(.*)$/\1/p' "${configdirserver}/common.cfg")" + elif grep -qE "^[[:blank:]]*preexecutable=" "${configdirserver}/_default.cfg"; then + eval preexecutable="$(sed -nr 's/^ *preexecutable=(.*)$/\1/p' "${configdirserver}/_default.cfg")" + fi + } + + # Load the linuxgsm.sh in to tmpdir. If missing download it. + if [ ! -f "${tmpdir}/linuxgsm.sh" ]; then + fn_fetch_file_github "" "linuxgsm.sh" "${tmpdir}" "chmodx" "norun" "noforcedl" "nomd5" + fi + + # Enables ANSI colours from core_messages.sh. Can be disabled with ansi=off. + fn_ansi_loader + + getopt=$1 + core_getopt.sh +fi diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..669e4f5 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,76 @@ +{ + "name": "linuxgsm", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "linuxgsm", + "license": "MIT", + "devDependencies": { + "prettier": "^3.0.3", + "prettier-plugin-sh": "^0.13.1" + } + }, + "node_modules/mvdan-sh": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/mvdan-sh/-/mvdan-sh-0.10.1.tgz", + "integrity": "sha512-kMbrH0EObaKmK3nVRKUIIya1dpASHIEusM13S4V1ViHFuxuNxCo+arxoa6j/dbV22YBGjl7UKJm9QQKJ2Crzhg==", + "dev": true + }, + "node_modules/prettier": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", + "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-sh": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/prettier-plugin-sh/-/prettier-plugin-sh-0.13.1.tgz", + "integrity": "sha512-ytMcl1qK4s4BOFGvsc9b0+k9dYECal7U29bL/ke08FEUsF/JLN0j6Peo0wUkFDG4y2UHLMhvpyd6Sd3zDXe/eg==", + "dev": true, + "dependencies": { + "mvdan-sh": "^0.10.1", + "sh-syntax": "^0.4.1" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + }, + "peerDependencies": { + "prettier": "^3.0.0" + } + }, + "node_modules/sh-syntax": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/sh-syntax/-/sh-syntax-0.4.1.tgz", + "integrity": "sha512-MW/ZsCYTu11EIYYTSZcfAgMFszAodCmQVB27XssHoIN6L4EG0KSA3h32x8whaSOKuYBX5wz9EybfnPBUFQMCKA==", + "dev": true, + "dependencies": { + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..89bb702 --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "linuxgsm", + "description": "


\"LinuxGSM\"

", + "directories": { + "test": "tests" + }, + "devDependencies": { + "prettier": "^3.0.3", + "prettier-plugin-sh": "^0.13.1" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/GameServerManagers/LinuxGSM.git" + }, + "author": "", + "license": "MIT", + "bugs": { + "url": "https://github.com/GameServerManagers/LinuxGSM/issues" + }, + "homepage": "https://github.com/GameServerManagers/LinuxGSM#readme" +}

{f(C0Ed41R}%7Pk;NHU;NTjZ(NZNT{txxf9t`E5B|sZu8LY% z#@0c%@A>X(W$E1yM8JJu?bX+cq18Up*!WFbq~&fposM5a>i-v`c2wU>_5)cxHnIz1 zWR8uG6e`jrptHq}cj?6+Kk(?2um09N_Q(hJUfW(>ylXhnZ!kPz5~l$H8?NC zFN4G1IqcJGmv7(m!M_7p|D0Gq-K*Dr@#AkbI!=6h|KQ+O zUK~y){jJ;A#*;pv;L4jbxG(l!$&w4_&fYtxH-7q?XZ>a*-(({#H~W?)tjwEY`wG zV}HMQ&#`ky_pcvpZ@mP2HT#I*W>=wvMDrS*?;IAaed$GlV>8X){`LNhb5ezAFY@yo zf^x^(t$*gJ-aq}rPA?CpjgT}orGf@__g%+#sO$TQtb%&Hxp#Mq)koLg_qoR97hcv? zyHs_K4wI2Qy^Mj`c=LAuXxOj%Mg8J*so}t4GN!tsf?_a4kLOSSuyRu~7DP>%l99o# zgE%MG*6CEhqcuh5!mVtwSem6u^?e`s>{EaHbue%J`~UvY!=0n;1%EEXonNqPl^JL^>V$C3>;ZX z_bxwQ4OmFLIG`RGyEV@~6TS8AwQ_n;?Ht`dJgAv~Rea_cJacoH4@Q!NRE$%kpc@<= z@B}f1k&!vi<4om>A_5{8k;$|hdroV9Ka<0dj<}qZBA+C@pqXFUeMbZ~+1pae!2rio zlE_Jxf=#JigAw$!47ea}I@_zV6s3yjGRInRgFzV=T7h!3k7`FwHBT>%*`X4JGqIH| zN5omIX0fZ^y3thzIndqDVyh=L5QHnKRiI^I69saG^N=EmDJn&TgeU<3003i*)>XFs|0X>4Q8C?yZ}^7>1M?YW19;hl@?NS&H(@zB4Z3@j)ee#Mq&gB#@ZMo6-GF) zteC5XJKy_XFJ93~F{89)O>#wHP?&5|CK_0f5+QY7V6C-=5E!Hl&<0?P2_X07m24#xPfsKmv?{s?eD%TxM~V0N^3) z=jANVxe(AGAOzsNFaQd!w9x>-vd9rat!4w?fB$=mJS&SCBp4C=X9I%soSWR(9@NGZ zNe(P4uzd`(gt%0RfM8$fnE?bMTSGp}N=6x>L~DaEp_Bq+8gp~^+;i$rtVOw<-k^vV z0000bbVXQnWMOn=I%9HWVRU5xGB7eTEio`HF*Z~&H##smIx{sZFfckWFhpv$^8f$< zC3HntbYx+4WjbwdWNBu305UK#Gc7SNEipD!F*iCeIXW{nD=;uRFfcVY4o?68002ov JPDHLkV1fdEQ2YP@ literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/ns2c-icon.png b/lgsm/data/gameicons/ns2c-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c519b771d1c6e080489554a1d1b58e086c9e5152 GIT binary patch literal 2603 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/onset-icon.png b/lgsm/data/gameicons/onset-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..598455658fd8dc52ca0860ad6dbd9402b86b9e59 GIT binary patch literal 2927 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/pc2-icon.png b/lgsm/data/gameicons/pc2-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8a20b75c8a80d2266c4726a1b99caca33baea066 GIT binary patch literal 2504 zcmZ`*dpOhkAODgvx|mXDB)Oltwjm5*%WZD4Bu3Jiky|E0h}D^n%O=Mq%q`?nnQOBh zEIE!TmnpQ|HpO95*{P+)sdd($zdwG@=Xrfz&+~deulMtQJ_xjdVWh1210Y%H{T1@QUP^KiNG~J+bllqg^}@~{MVuSP3jk8}0f0yXfNiNnTmyhB zFaTH&1pu2e0QiYe+2d;`E$sTm!_^7+{^Q(XH5Ew}1%g{(0s!or`2iVux8ED3qI@FS z%UNEa2v$}+%5Ye!1ON~N?S%Am8$RKWjtO&BZSChWJ}ouymh;o>s>gKq6_HenJoTZv zL=~AL%`B*!=1zs2!vxgQ$dQ4aGW!X+Ou`b;5v2{%zRqmVjwu?O(Kv=<%qJ!HGF}Q< zbBO6zHpS~N)3!^6i}uWK>qfjw$rfrC$O>BgH0d;P2{+f(jB;X0_k*!H5r_i|O64Iw zPvyMouifB$|~6L?Z+wFd5E<0C&r9M#wUZLnUDQGHY#cI}=A+ul_?$MwIx!Tzj)DAObuh<^a z&b6`B^Bc3Mqh4nppTi^>LMjSyp69|2$XEYMQuAu2P3N)Pe`&l*x$D=V7_PBkQ8O8Z zk^yjJ@JGJ1P8+TiYj^We_xY;-WVR&Q}T?hJQAtv4NXGaG z{M|XT#g=10!P*$tD#ubkH_b6J)*elaVPF)b*0k&TU3Mv=e*b--GH zQd93*eCywTwZBt^!8cn;IG;@pAvE2btTy^5%Lzex6OVc&wcIW@P*8tw$k?DW5kR8XBf- zHzyu_`g3w&h#x2{nXfsqq0}_>CSK5-KnQs7!dl=GdGFvRu`;0yOyJx8MqVi+jAYE% zJSzR?n)1;zW$M$NHHrGz;GV~(Cpsi+^c5?9dhFJp>q8}<=i|Oh+8GVJQkKIY@eC$Bd4e$9hs5Ss`uET=&Y0_gd)1nET{>Ct2W$j>*AVxE2$8 zu>RMK(bcyiqiQ{?{_XPlHXeI?eT7RGXMXj#bN6Lc=riuvHcvvK?A1Bf%wn-l=#+H% zgD$X&u)avB(YPbt!^1-vf9+0*P+8Y$OuYUwl}a{L|PKm3@gZ|2|2E2;M(8ns$q2X%O!03r3D~8fz~w z(<8g*i!%I&-w>u_+nq1P@B22Bt@#Ke;N_=4ba{@;d z_mKOo=rp+i&PE6-MSNR9djbc0I75x%G9E5k8p@k`W070;nhBfesmQ(Z*yCe<*2ScqbVC^gDSXy|OL4ykFolux2 zEG;cn&_ZQTO-(^_)hIW)Ho0|!gD16|x@Ildf5oR?p5`s`aAbs_C0P*v>Qx$38TCFX z2&C-)?CDblK`_Wy#hDf2fI!F)t@Dja+zWMWZEY(>QFLl!B+b9KpMH%iG-vmTm2_a- zv{O~m7&x*ob$3Tk4;5c7w$H7ThSo)^I74uptrWXUW5+Jib{J*XHP6Ou2!+CTLcPeI ztKwFSqMhQKJx_E<&2+A91lb_$`9+Ji5EfN{U^Ah)#-pa^dsQqyhr$42QtvqxXYtxa ztNulym?f5eD%1&6<6}bpq85?P#l9tO4F-nMcHX+t$7C|QyBk{`_!)l7SVS;7J15^H zHsbjXhsiGW1EB=5gcW0>2YSdYo~(mPL)c^pBQdt-V1CHL~}39ZH20J@NL z@27Mbq7P)CmPiMq42BR&Fgab6EOmU9a@a~DZ`wG#H>2{|k5xx6(K#S7>_Q^m26q`R zCBO`3W^Mw9nZPam;8r#;gpK)eBN)sE26Kw)7X6PQHZCkO{ObQV9JktcN@@Vm&fZR~ IsL&h#0sWDtWB>pF literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/pmc-icon.png b/lgsm/data/gameicons/pmc-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c58cb7aed3ad978f08b9b80a0d4ec962e2cf55fe GIT binary patch literal 1312 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 e{7>K!(Z;DH(GHklE0Dw``L6_XN2>LJ8d)0&h literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/q3-icon.png b/lgsm/data/gameicons/q3-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7d111da1e115035b14c2f9e34f74622660048d32 GIT binary patch literal 2734 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 T8cPe_C;(VnIAH5A-l_iuYp(db literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/ql-icon.png b/lgsm/data/gameicons/ql-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5b0e5ceffccd10b9201b2a5ca7937c4c62df9013 GIT binary patch literal 2974 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�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 IG4T3-0YBcB#Q*>R literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/rtcw-icon.png b/lgsm/data/gameicons/rtcw-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d0fb797a7a368a3eddd3731240c4a0849f025e50 GIT binary patch literal 2244 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/samp-icon.png b/lgsm/data/gameicons/samp-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d20d3faf74fc1ef829114dd3836e944b1abf5ed4 GIT binary patch literal 3026 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 N(A6}8y;paL{x9xjx`O}! literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/sb-icon.png b/lgsm/data/gameicons/sb-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3baf0a116c838149b4f331b9bd105a1985d5d313 GIT binary patch literal 2598 zcmZ`*X*AT08~xd0cx6b4N=BBlPId~T!A#y!WJ$)Jv6p?{mn<*YH5wvIGGQz+mTZYP z%E-;yx>0H7w7V(0>Htk6!{YX{Nw@Pmn{IOV*!BQGq2g` z=BaVU-asD?(Em(fYgy*00`f#y_yEA!i9cXqMWnwz6v+rrcLQpXux=yl<%dhqYF4j#DLiiyTA$_}gLxK+YD z{1!{}hGz03!mgx)LFbq%rx zCmZH7`$LI#&KLt?#&TQ{8v69FfJ*))oS6nu2~fujDGE8P*=1m*18e;&pRe-OQ$t14 z#R~096WFk6ERmpkV@2!}+5ye-TTsk^i6KKsew8Zz7xG0&rJB02y57Ui!mw`MU~yD5 z@6$~5%CnlQiHv+Tj#+vP+#-zJQ34Ec0@xQj1;;_l2gNbnxB5l3CXBJ7V#u*d4u_$8 zbNmW#XSG0c1S_&MRFOC*u`PNp&xoCfjG{xk`OFhXk~5IJP4kqp{zp=F{e^b zQ=H8v=^)%=EXbpGMi<~x9dRUG)FdPcM9iPw>zke~CcbxEXg7Zn@-4UJ@6vWvu>s_V7nDQ_!jF7}3QnfldflYT3fyc0QNk6$1Bc;9eb9?$7UYu5hE`j`(R>*> zBFJ|=`<$iuMeD@Q@I~R*pT~Z;hpy;%_XGunP~M<*?(2$_$dc;0_L>JKn|m}9a`aem z5x<|=M0_upd8jNQd=l=zTq);7MKh%J$g(};Sy!{6t}+rz%&c4bZuSe%#lJ4Za1 z=B^c?aim7+ccANu^XrmG9#UW@_K~r6g0<08-i+k%brVyRxPDcOyUE%1?QJNJMSI!S zz>i6qD#N%MWhmtCv9Z?4-od|`(U)Z9RJRne(P(}11J2AS@Z^vSq^Bd78sapR^%seW ztDa`qBi8lherl?Kb?XViNi%T%XgWY{!S9u2kU-bpH)LH69k}|($`vqaW6v)>Zae6| zgu|6(peF?#Odi&FutNw+K7GSR*I5(_&5KlK$S|jfc~Z@gR*>RkyT|gHU)>?*pODpo zWK_A8@~FI90soO;lJ|#!%Ra;~e~Po?c6S-^Z9-BMIFF^$5{dtX`53da-=J4?S_MKq zCoE+u^;~_OEkS2{mP>`cW$d@jiZN^pJ@{Cj?})y?(%rwVm*MQoPIWhRdTwn`|0Oes zs$8LbgF&6l|78$V-Y&U5Zy)AvHT;uFjeVl_c%egy2h?t+H z?Jso@r^cwE)t~%2VdhN?IT9yz)UB;c!oR=yu7F3VLk&YE9LnNf0|vR@BUPWiGw2#L zBln)nCCzu%w;g`nQBy#M=#la-IOWvYifiy><7XBpxOUq(2)EQXw-iE>@nI~Ibt%b` z(}DM4m1BL#3|x~}cPVAJD&WX-X=jYT{f+xHQ?BnQt%oyZ=3!;+XD$yLH4P!+*rCZ{ zn@DX<{pF36Sdj8w1PA=bwzSA+Mg8_?jn%aA0gp1q$=RdA$IYrAq?hYf z(6~`e-;Ez1b7}rWMpZq?z2~KLwX=;%@_LMct!>{<_!PU>{HaB}Tb4tomd9ifeYo#1 zn*N!}6d}~+lj_x#?r9n`73{FH)77gRzmYxuR3d`<7Hg~-g~4~%)!Q_fw3cf-sKj!n zfj;J`G6{U{i`aNy*}(xY$gnS~jIHaD@j@%UobL`%@#o9k6DgafO(6=Oob~YbhhZ+h z{8#jOu3=YGOY`kTyRh!7Uiz+2i+h7J`Ws6E??*YN{rq^4W0+;>*~n|@k2dPXleHQed&f_rNiCiyD|J3$_Cq7HUVboeHjc0@xrAWET$@nt>R*fxiHB!)i zpz_g73%CfeH+>yYUj?tx9~UGb=1l7}OK6P~&6~xnnwx~f-=1+{v{o@4OmZXu0RxQJ z3I#;D-Llh+p^SitcQVg99maO$L5B+-*V3kiUFMHzlAy#?)x3Csh~Zxi6$2wg+-zC$ zJhjf)VK6H(`ruMF?xF`#SHMMq>1!eP-YbUZO#D8NjciHR!ak4Xv* z9lW{}=&p7(D#DT^&Ev4OxjD>lv!PFCdS`Jj7vcD%>-1+5^VNOe`^e7MQQg7Y@sxlY z@;4M@pz<6{Bj!2x@ew9j#ry zMkz%#X7JOO{}=yr&vT!1p65LG#Xa}MO)^Ai-JoWp1_0oOj<&k-6?6Xsi1exxS#~O} zh}=b0Uljlv)2|clDgK#{wT<-wAXoqZB4YvI^h%2S2>^jm0N6qT04x^(Zu%5rjqY6; z*Btb;)Pc)?RoeAB^Gc!e(SGO;0JPu#frL`~Mb(u^8K9%DLAgN0JW`- zx~i%65Jm4pk9kxPu(!K=Tyk(Zs#Lt6GL*LSJt>z8`qq4Vdc;2#XuvLG1r>LWKxg3@L> zQFzq{jrKwMISZP9Q2VsJTIsK4)Pk;mdF1(Jo4^6o{=y>dKi+r!IevR+a&lv8-iYDr zTk{DhFPqs!6?tTjZvp;KDRx6%xA|)VfiTLw%?m^)Woc_yAwd+c{58mhr7C|X@L0S_ zrax?_3s~LGTb-%5p1JQ4kSrkeh#w-Y7nhg@`bA+(KLvTP4=cLp^}==H>tD*>tZ&X? z4)}D>5M8G0UCOf;7as|%k>9@c5ey|2lRTTSFmV}i*|3A^PeOUgMSA!_v2AE$S||AK>A^M_|d`ry!}zu(~Ti;<5>Yoe9zL`P~itbaBfZ(ubxXj<<+#LN#^ zq!qTOK+3_uh}x2>luzeHxT`k`B|opZU@Ps&2?mi%GbGWHE_Zp4@tR zv%wRk)F53*`9u86j{W!ZG=gkJ`AT;MxNNLX79upjzEsQHXkFP?+;**Z#Ji*j6Y|dD zUF0eC3teFw3v}~db3GndbUw!@f^KN=-MGiZ`hFxYG%1>5J&GoDhATEED#E>sxU?%q zc)uMWsnO!4)O|rIlk^M$EaW4L3&JGLt#<0f+`6^s|3lI_ z8Q3ZNZqKmqKEg;Ww)wRLtr6h}j*@~zh7KsU2^VoW(sf7VTTU>K@U!S_C76IwdZ{u` z68b1p?J({@B774sqI@fK({bA%{cUj|PskRRmBHuSscNQi{EG_na5rDy_KUq~I=iro z0cpmY>&}EkT*KZ>2QKWfZ=({!eVfytCHOoC$weE1F6xH#bG-TCRAFneW%aT@u_6W+X~RI(@u?o&3*o;Fkj?t>Zg) zh0H60c~&Uu7&L?4V`zGqFi8@1aDV<6$#g~pFBNsq$>6`6)(5je${NJqy^GUHClXcZ zBLTwfQ=G!o(oNV?7I4H#d!F==0If)fcjtc9bRZ-2d)|ev|Eh)v=oXF_Cpn@;G zlZ+8d=Y6OlEyw^FJo4clvGG&-(>ofbtEq(C8Z+4NfYxw7i#ipB2>X{*jJL;-e#Uzl zHjWFt_aaSn>C4aJ_m1irE39N*JSgj~J{!(Eee!3e8h&Y793BS4yq7O3B2=1gEZWzO z33s9qRf@Jqjhz+48e=L&CD;CBY*EF2UmIQWoaeenHZL-GyL5&rI!ua?YI0z7U2BVJ zv9`T9BZ;92x;&k5aCmdfj&&vosOp(vyLAce;nuN8}}(*)uf zXZbkVY?bAilhdo+YQP|pj5u;NV*kN-_~rEAVr79hmpA5An84U{weisM=B{qbqMELf zMQaox^xC5zsqydf?dBj$In(f1 zYI)KSnc~}DiuiH^z%txSuGs2}8SOe!8f4K-L~7_xWwMU&m1WQ;+W)BCgCzO)#>L~b{r&e5h78N$BEArGRS)p#J6ruyR47IgDhFVDUg&Gjx23u z=)@{PORT~QNS067Ts9WWEb4_075*auKkZe;^d?%>nfCRxW^DGLx<*I{vw@JO!`p2p z!SBonB?loV`_+#c4eL4mMqL*5jfB)MRakk%{ zHN5-tW-6ksQQv{JdH{>TJ@gRc>1>8#0R$CRr8MQ}+vd-Wz<< zu<-kkO8j$f#n5oWJ>bHL9~B@11soyj7( zR1S7MMA~Z8$?^jM#`v;dCp)&7Z%3zTjM!9N4B`FsjC3p)2!%S$40;|qi12a#) zxZrv)(ux{I7E2tta0@vqL-5})Q!RXnYisZ{;FG|G@1Mb4z3=g?HEUwTT;FUWf3o$$ zIZ$_SJ2T^*)6Bnl0HD1bG~`uo{!z2Uuds2NkrFB)`*p8OvfmOr+91 zStngsc1oe$pgbEe6#J*+;J-0 zBr#)5tj&fn#H6I4`p1fbRz1|BUB|xGmV5(PKnKi6udNDVu*F%;imprVc)>01aWcu8 zaWBW9Rm_Ghf6_!lO`-c}a7IFG!ZjzI>o;b=-}0t+#k($Z78G~IE|(;dLbP+qRc@J- z>%C&5mjIExO6x!T?8jT)6wX1nCSub$rx7+H15;5A`=P*79yO}45$#X$B?}{<&qtZ+ z?Bq@;!g+{wwmvtPouPC8F@rQ4X)V|HZxTNJ31{;iX`0nabu(w zT73sTm=8WIi9OlH6(FrO#F(h3xVY#d_Tj}|u0v;QH5yFD)+B-UzP<5ky!LiPMA z9Wx>)14=b}a=qSsYK!V7W`Fy=gtM80k3pj2wi2SB}{Sn>%c9iX$8YjJFPMEo*rta{MLSay-x?9V^{|R_{JGweQ`~L&7 S^0Wq50YFCsp004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x010qNS#tmY4%h$y4%h()NRg%h000McNliru=L!%J3Lm#W z;+y~g3js+)K~zY`CDHkxRaF51@N>@Hmv`U0Z=E+YZ}t@i*#`=j8o?#P3^K%|6my9! zl-x*MFeCC4shN~1g$6EQhK7K+Fd{XI1fs|)3=Fd{GjG59z2}^M==(2xVO?Ea5Cjav zP)Y#+48s6Kecwlb;Rt8SjE6?_(IzO2IAXy0m}1G75#tzP0!yxn6bupesLDYHW6VGh z5DXziEJFee0AL9r9LHgdA%q;q5kiWEQam2FU4v(dSvG4yqI!M}7_BrJU*w_4GC|G? zqAAxMWV6UTb1Yjnqg<}!g?Pl^fIx&W0=y^~g`&*ztnd4xC}NBWA)e=9jCEZ%P1DDU zfN&Huw|D%k>fTIYht121YvcfL10w_#rCo}@Gj89DHy%=iSRSL83_TLKzAuYn;Q7Ui zqhURQDPeh@cN_;HWLcK3>$d5*w#RdV#|IAb9f-rtsn>VE)V=NiHb7KWp%E!YZLv6f zNu+b}M=PJlTf#*fg`klwV})lmrBE_8%BI87oMi?QizuZCAxf#DD30Yq2vt=r7K<^% zV=TI0!7W#=ob&a8en;|c)*o=pW9-3_KV+2A0r%w8cP2mn!aeY6Xu2M+hgg=ivjv4^ z0|ZXtVndPUd5@0@&*Id+vdN&@Qt6qnBv)16bg(_9F7dQWk%p5l!J}U4MxcnMbWiARaFs1 zxm<4X;>DfUOkDQR{e^+iqV1+A=lFrdFga`?pHp!);0D-0E+!+;wwhS{$Ty!*S2jGb z?Cy)beR4?4yA~&iAy)7U7Ne-LBua!3ffr5Fq=c?mv7)uPb;Yt3MyVj=?Wh|ku1Rn> zSy7oDS6h*coQw3SMb@DL@1Dh6AY`@Ia{IlZfmOeH?5+JDW($QV6ciVD1eaI}GnENR zi`s@y>;P-v-i{^g!{Q(2KRaxXdae`U)VLE_bnl&4-Z;0uJ{`g$<^XW5gXGg4Z-4dL z3#(2XbsD{R7P&GK)=pbD`q0qRH>@jgeAGq~Oy=3IVQXWPVH+L`IV4PRI+nh*@)r-? z*7sjq^srBuIjysw`Ntob8f=`&{cG&y+#S8_~haVi=2Pc5~V-gd8gJOMfGqz8CyE`=Wm?amK>+o zRJYbuXKLyzL1leqbH$kIRMq7AaUXa0)Qk@$Vs(+~$ThKRjUnqRzo%hg*YwSD~FyR)9`0x@t&vSr}!BMvRjSaVe<9j;9!B2}s5YrklDaBOXTyrp)0 zRb>JRK(c_z%5YBOysblj7e+&-SCY!&WA{F$M1(sYeaQT0dCzZm$d{%D_YADP^XYl_ zUo&C+Br_9!x38KxhY+iTEs+rsH4v0t3z%1b zWA4Wvy>r2F!YXbT#&_N|^>61lAAV}zM0=Vvg?;9ewKw0teA9h@4z^NRkMTL22L{L+ zuS)Okd}`-Rb4J_TrUJf*3Fh5Etw4kxRcEE7JM~;+_fRms-H7;K<;yaj1h@M6;MFdgAE@c%W7O>sywim1N zA#CDoI*1R6tN{E%z=|eYh}h)W;s)+o|F=7SW9`=d)wMwa67m#|112;jPdA`20tzAs zhgocckdq$}xd>5#4MsJpvy8`uV{#4`xHF6k7#gz+u2srg6ftU@;$xxAUKB8T^6)z4 z2JrBn-;~!E2nT%Zc^)6tq!J!VGBpV%Qbfbn1qtdV8^i-dB$df|jKpK)v4K@8X5?lm zjS8NN2#yM=?o)dqBXv!lq?x75;mj|-Ix_jm&W-zDh5Nvy)+vk&MBepz&tL-C5iV=K z!fW?GJM>vdic2Ox8geU$q}Mbg1vy8{pz)HLTc`i@?BTwyA5T{rB9-x)M6_yRbfWnQ z*>1g@7%S8%W5{2eJsDU~D;GV>Rm zBU00kwGX!Z8#L9nOs?+Svu*qI<(D?6+G4S)WIB>aR?JXl(A~7`n%6z|133c|T0#J# zETa&RLzOWgYH?JtWX5ggm&IXvx^-@IB9RE|kz^)WmkxKfUUl@P?$#S7G__SSY9vx- z2h(3RPyP9Xp2G*2B0(N>c-M2z9ee-lZ(sI<>*rhtI_$o~y;hj|Wg$>Z$>zqkOnCI3 z`yN=cdayD3y<6w>zCEN08iBURL<5d4zv8x@ai5=f{=YdAz(jLZti&TE{_WvcerZ2= z=(!KHY^5dGCB_F{ai)0vy7jBt=1v@ThW>Nrv*A;{5!i4^x~6(+nnm=>Q|E7b@b=Q) zex9%vOGJ)0s5vY7ou$8DFz?Bml@ly)S1@`s>Wa3@@^EkV`>W<2`r`NnYg8`_K5_^J zL)L|DufKKnKfUdt_GvW}JEwiKt*u4R#6RlkdF0nmJpQZ4M~)2%qT&a{4?)&0RV0%4 z&A#(l_-g-~7Z|8%*oBSh`aEx|zAlJ`O$%P!H15;xwXd{Cn}=(%CwHEuc_7G~eiO;LRh14?yW zzwGkMmo8nJ%xIX%gXiPj@H#IahH#Yt7rumbmPFVHGFS~bb zZ;nmPTwedrU0W;5Q4d%J)s)OMY^`p(APmMpTr!vSU&+vCZ?mzrOV1#?2c8>L~$hm3djSkW#6`k_Get4{;~~ zE9!KKl`)CIQm-A=BCczI2=t3G7s7<}yS);UCvwxrG-f>*pM83; zum1w#kSO!6?=VCK5>`BfsZ@j`J{Hnqr0C>fsxBl1)zB)JVp#Jj@&zJ6*YKc6d4*GG zC004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x010qNS#tmY4%h$y4%h()NRg%h000McNliru=L!%J3Lm#W z;+y~g3js+)K~zY`CDHkxRaF51@N>@Hmv`U0Z=E+YZ}t@i*#`=j8o?#P3^K%|6my9! zl-x*MFeCC4shN~1g$6EQhK7K+Fd{XI1fs|)3=Fd{GjG59z2}^M==(2xVO?Ea5Cjav zP)Y#+48s6Kecwlb;Rt8SjE6?_(IzO2IAXy0m}1G75#tzP0!yxn6bupesLDYHW6VGh z5DXziEJFee0AL9r9LHgdA%q;q5kiWEQam2FU4v(dSvG4yqI!M}7_BrJU*w_4GC|G? zqAAxMWV6UTb1Yjnqg<}!g?Pl^fIx&W0=y^~g`&*ztnd4xC}NBWA)e=9jCEZ%P1DDU zfN&Huw|D%k>fTIYht121YvcfL10w_#rCo}@Gj89DHy%=iSRSL83_TLKzAuYn;Q7Ui zqhURQDPeh@cN_;HWLcK3>$d5*w#RdV#|IAb9f-rtsn>VE)V=NiHb7KWp%E!YZLv6f zNu+b}M=PJlTf#*fg`klwV})lmrBE_8%BI87oMi?QizuZCAxf#DD30Yq2vt=r7K<^% zV=TI0!7W#=ob&a8en;|c)*o=pW9-3_KV+2A0r%w8cP2mn!aeY6Xu2M+hgg=ivjv4^ z0|ZXtVndPUd5@0@&*Id+vdN&@Qt6qnBv)16bg(_9F7dQWk%p5l!J}U4MxcnMbWiARaFs1 zxm<4X;>DfUOkDQR{e^+iqV1+A=lFrdFga`?pHp!);0D-0E+!+;wwhS{$Ty!*S2jGb z?Cy)beR4?4yA~&iAy)7U7Ne-LBua!3ffr5Fq=c?mv7)uPb;Yt3MyVj=?Wh|ku1Rn> zSy7oDS6h*coQw3SMb@DL@1Dh6AY`@Ia{IlZfmOeH?5+JDW($QV6ciVD1eaI}GnENR zi`s@y>;P-v-i{^g!{Q(2KRaxXdae`U)VLE_bnl&4-Z;0uJ{`g$<^XW5gXGg4Z-4dL z3#(2XbsD{R7P&GK)=pbD`q0qRH>@jgeAGq~Oy=3IVQXWPVH+L`IV4PRI+nh*@)r-? z*7sjq^srBuIjysw`Ntob8f=`&{cG&y+#S8_~haVi=2Pc5~V-gd8gJOMfGqz8CyE`=Wm?amK>+o zRJYbuXKLyzL1leqbH$kIRMq7AaUXa0)Qk@$Vs(+~$ThKRjUnqRzo%hg*YwSD~FyR)9`0x@t&vSr}!BMvRjSaVe<9j;9!B2}s5YrklDaBOXTyrp)0 zRb>JRK(c_z%5YBOysblj7e+&-SCY!&WA{F$M1(sYeaQT0dCzZm$d{%D_YADP^XYl_ zUo&C+Br_9!x38KxhY+iTEs+rsH4v0t3z%1b zWA4Wvy>r2F!YXbT#&_N|^>61lAAV}zM0=Vvg?;9ewKw0teA9h@4z^NRkMTL22L{L+ zuS)Okd}`-Rb4J_TrUJf*3Fh5Etw4kxRcEE7JM~;+_fRms-H7;K<;yaj1h@M6;MFdgAE@c%W7O>sywim1N zA#CDoI*1R6tN{E%z=|eYh}h)W;s)+o|F=7SW9`=d)wMwa67m#|112;jPdA`20tzAs zhgocckdq$}xd>5#4MsJpvy8`uV{#4`xHF6k7#gz+u2srg6ftU@;$xxAUKB8T^6)z4 z2JrBn-;~!E2nT%Zc^)6tq!J!VGBpV%Qbfbn1qtdV8^i-dB$df|jKpK)v4K@8X5?lm zjS8NN2#yM=?o)dqBXv!lq?x75;mj|-Ix_jm&W-zDh5Nvy)+vk&MBepz&tL-C5iV=K z!fW?GJM>vdic2Ox8geU$q}Mbg1vy8{pz)HLTc`i@?BTwyA5T{rB9-x)M6_yRbfWnQ z*>1g@7%S8%W5{2eJsDU~D;GV>Rm zBU00kwGX!Z8#L9nOs?+Svu*qI<(D?6+G4S)WIB>aR?JXl(A~7`n%6z|133c|T0#J# zETa&RLzOWgYH?JtWX5ggm&IXvx^-@IB9RE|kz^)WmkxKfUUl@P?$#S7G__SSY9vx- z2h(3RPyP9Xp2G*2B0(N>c-M2z9ee-lZ(sI<>*rhtI_$o~y;hj|Wg$>Z$>zqkOnCI3 z`yN=cdayD3y<6w>zCEN08iBURL<5d4zv8x@ai5=f{=YdAz(jLZti&TE{_WvcerZ2= z=(!KHY^5dGCB_F{ai)0vy7jBt=1v@ThW>Nrv*A;{5!i4^x~6(+nnm=>Q|E7b@b=Q) zex9%vOGJ)0s5vY7ou$8DFz?Bml@ly)S1@`s>Wa3@@^EkV`>W<2`r`NnYg8`_K5_^J zL)L|DufKKnKfUdt_GvW}JEwiKt*u4R#6RlkdF0nmJpQZ4M~)2%qT&a{4?)&0RV0%4 z&A#(l_-g-~7Z|8%*oBSh`aEx|zAlJ`O$%P!H15;xwXd{Cn}=(%CwHEuc_7G~eiO;LRh14?yW zzwGkMmo8nJ%xIX%gXiPj@H#IahH#Yt7rumbmPFVHGFS~bb zZ;nmPTwedrU0W;5Q4d%J)s)OMY^`p(APmMpTr!vSU&+vCZ?mzrOV1#?2c8>L~$hm3djSkW#6`k_Get4{;~~ zE9!KKl`)CIQm-A=BCczI2=t3G7s7<}yS);UCvwxrG-f>*pM83; zum1w#kSO!6?=VCK5>`BfsZ@j`J{Hnqr0C>fsxBl1)zB)JVp#Jj@&zJ6*YKc6d4*GG zCEk~9?2Eu#>z z+t7m~beW`AQMyGpB{#agN^UCUw_d-$?jPs-Ip1?W@7MXhUf*+G=ZLS!9fKyJ0RR|J z55B)f&3+6mm?rY;3I{X-|JhaO3P4+l&T<6e$7Ym=zYu_57y!r)0Psb#B%1{wjSaw? zT>$VZ0WeCgzUsFL02uJ~77M&Y-V_QMi9{mc2rVRP6$A#=FlZP;R|gFs+7J|g!jRf< zBoYck02l%dG)@GJNF-@oP^iX>0uapZGM(!T5LopCYhEK2ny2bULxKQ z2CxwA3+7fmB*r+=iiRa)^e~2I#yWU3(NH(YjM%Y}bA?SMYrzokAEk!{xmC;KPL}7Y z&gF;r@Y)qe>r0cfQe%FrO3Pelc5PooO={$@fcM;PgQn=HFpqXcu7^ACl02ii=3rCZ zFZHJm?+z99UMLP_5?d?dyFEA0&`4SOTA?0nb#FV}mR<=~mvmYsszsaG!!D}1i4UkCfJyAaQI^_YL&VO{C3>Lfgb(D#mIfoor z*L^)k0z5OR=$_DU4<}Yi{Pt)4ij6kwD@)Uo!^LC$X9imf1G&_(FrVA&S?41nNAEOb z?vKn&4OUd-X6*?c>aBQk;c!NzD9VvG8z!_Mftji9xxap|I+A^F^nyAk`l7o_OMaBU zP}F<5YGP7#BYfK#=6Z?9JvC{Us=fGuTA6<+wfa2sj)Wyj|GURoc~EfEzAtB zJ&}A?kyU^8WV1XinrQZnzPc7dIFa<&^A712jh69 zpDVr$Ymji?gr+qVIohl6P!~oQd0Rc;*pe>|_enVw?d|KmLgJ^4E|q**{5;xl^WCTA zk*?SKa`Na$}tpfg^=jcVxu(XhVW7h(RF92MMG461F;{ku)b@wA7 zAvS$lj2>NCKZa~td%V(a6PM2A+S|WBu~hdE+u{)Bg?j-~Ap&nA*CJcGHFo>fnOVQ6 zcIBO!P@Wszcmf_if&eKjwff%RAbF$8%#vwqX_=dKVoY@0^e*I3DRk&np!eEphZO&T zm%Y7tc^^MoDvM-%2@l6V50iPOnK?Js6Q&fGt$Z@uCvouUhCCbiWBt+Y z;i=B(&o@4$H3xOYEq>FX&OSU&@%lpow60ap-m>3AZOq;uHn;k1iSzhRHD8y$Boc^!1dH8AeWH;+yw|F-#T?wo4o^S!%SIg9^t$8J}kS@CaPwiuAC;p_!J7sv7&oePRE7Ao-VWWd5u zQ|sF>WfMNY0*W(EkEkWyn0%yc%~~LT?Rc%1PT8HQeEt0476S~VvkSTt1)tiHyFdJ$ zs-wijX~*^rnYaG>o8mafj`5ai(-N<+;HoIwRg|gsBiEQ$C%v95+Q#ooWe={X^U(;RmP)W=!=*p8XZHG#4y2zI*xzhg((sIrd$1(#?fT*$2bD(AtM&^S;2~SKq%sK1mg= z|I)V5kiU85!=5dpfInTe9L;@_(WiXTF@-};uQ)tgdfhYlZ+5Q4gQS=`owgHsJ#%A#{Aw8%+tPD%)}{icE>CF=Ao*|c z^Rp(sNc=#-95j*^SqJyp_(n1t-&`hp`O2gPQ0yao!d!;ou;$g%rGg-7bc8g97nKsD5x`+{Y^`kARyOuxjxEo|hG);UWV3l} pHgvwN=s!S0QnVyC<39lB2Vm#$f1vNnpPG*s08fF4-{Q6_?|(sgEm{Bo literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/sf-icon.png b/lgsm/data/gameicons/sf-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8685b4ad5763607075c2091bcb5ae134180092a5 GIT binary patch literal 1649 zcmV-%29EiOP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 X|6RWS0^Oc-O=bWf5yJ3#93=h+Owouh literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/sol-icon.png b/lgsm/data/gameicons/sol-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e2589b0edcca248152abf5df25e4818ef3433d33 GIT binary patch literal 2978 zcmZ{mcQn}|yH9q#rx>sHEBDx6KJ1bd9wo6ta z6w10}MI_nL#aDm+{`j5OdA^?KJfG+B*Xy5G>}_KmHWoe>007wZbkUeI7yKs>?b)V+ zH;T@T-Wg?t0)X0tb5uKqeWj%o!xAr zdR8#n8|a{c(|?oSR+@a4FnjA-_yGX>#6Qt6=_Zw&g-j3ijI@|mSU9;@pbZ)e*#N+j zq=!bC>h`H6S-4xT*hQT#p9E&9$OSqfrJRX;p2Am6E)-*)N$Wg;Tp~Jl>)Ut0Ej#Xq z(}Si2Z)B=2UERQjy_L9qVdEyIgMsxc$QH@=q}$lR!1&tL=MJAz&_3uV)2z<(KLc$} z$sDeDf#I&s!=bP=o8zPJ-<=w!myzt)K`u_vis^5?f6Z|ic2hR-XCPaGASb(=P~)_dM5 zJD&?Bg@~0yjA6Q!w%HNKWAQ7#g&tdP?>N z0XMkpSxF!4kz7C0nj9+G+u%|P8b9TIuYgu)4~Xgoxfx)tY>pGCj5sT zvHhXe&At*z1#U@FgfATPw@2aPXgXWJcsNL?I0a7R#Ic~RGMt?W-V3q^LRXq{y&7|S ziy7x^Vymu^dEAED1}cyF(xLU66x6Ct1{WwyuzB+|K01aWG^)KnR!rL$^L%E+NtJgI z4w@;Du$SRv;=1WCN^AwRibEME7VOtFWqGey{>8&GS=4<6+OVE#6L5MFg}vq82*_6P z3agLb(f*#CTUXTu+%va;Adb?}$&S}A(q%Q@3r_`A{TE-;1u@;tewy)dH`0DkCLqoD zwTxQUtLza^Roscs#u)x<>r-*^Frv*=XX?Me?G>q3(T`#(CquhqyZ=D>iQp@C30 zS1wZ_pZQVTXsTZ_vmon}C@hN3;>GC(RJpkSPvJ|nXRsUj7TI6TXMN{Tq&6H9DGV!F z@BBge)X1zo(ka>_70P9P583|QJx6_%AL=_vZN#{@?j-P%Cl*hZ=QP@I()84C8-yoqDTKw%lX_f(-~F6K z?W%(s#Slj^ku7c2hJ*EW=A}p%(Mc%IJidR$Ic4(^VeMz!X=2Xtfcu(BUAstXAL6m6 z?hpTAD>l`?_0Z=8d{*L2NuOy!ebVRf-u0}!`R?^!bjvJ|q+7-pA3RbwGc1Yu?Auo9+4d)I6H477%pATc-@MzGr7#eHff7biOF0Nf z^AsVCq7s}B~5r$ePZ#kUg$taF}}PX>{cdd1br z!3Ab&*%#OO?`n^w(3Nh+z=I{1sD|7U-tMimN+r62BN3X{=|C@p5a2Oza!|LqdH$!3 zJZk7Cf`O!)p2k-9_xwvV2!RC=$rj9Y-0b`?u`;l&{6~KQZ87N}8UnxIFYO(J>Gk&C1Gor?7?C&Pp!Ld=w|(|f zo#M*nTbW!3pvgt62Ezhik%U?W!1XvvD3xz@R8u^ zp!!b#ySbBbdH`Yh(c3!>{VWF}xG{btGpMF+Qzj-Y+CvCYzSM-+4%{C#&&iZFlDQ&R z3X|-&M&>H$i+1aHm!Ne7hBZ}xDnj2ps-!357(P^#^fnF~2JUY!o5}n(Z({0t*9kch zsP2isM+}Vi^RtmZOpiE<&O7d;zVr-6Cg-6fB*jT(O+_^C8I7Mc$=76BwqPUDRkag% zcqM9}RjKw-m1)&4(s)EDmGA!s?rlcl6iBR$!HC@ZFix#x=HOMsvGZW+4R_NYq{E;9x?ZKe0u9L zCF8T)y_|{-i7Uc7q#PhFZafDcbhJ8@jALHu;jhtNF|OuUYNz%*kiMgzDvWBatJOG~ zF%mGyR!ZwPEKc|M^2N1&T{exUOtoaH^xoQY3ibEwf_k3v&-WEsB|4P4ZydsBr6_Y5x zs$i8vOxHcHB&j9LoNF{Zs9{c?byHF0JC^}(@y;xJ7M&8ISoLe4ZMN@&wf(y}3b&4k z*~KQ)f__YITKl1s+kv3c)X%SnB@Ugb%Nd6ArWLc+nX$mcu{~Dh_lF?iq?m-8g&qpO z?%=E;R%_`-1L9i_l4>SC$5UlREp~2)t(g1%iFZjl6SmP(+REn!ILx3{2O14dn2V^1 zM>{Rmi`bs@jyQflIrxQU;*|=1?&dvhw+k$A=aIgTMEK|UAj82Wi=tUi4=>Pm87xWC zC?4|VYoJ$LN3qC82YZ%((cZu*dy>rqb%q%0^}V=te8QFi?~qGX!0CxIw@_gUe+DvN zHQMK@2g7y#-9DC7$HHEABBT%l@1JHm$jFNmE2|o3v>H|Y0vCz_B@a8u`Et{4j06yi z-l5-?O?K8Zv0c+1tKZm2mXeBfX#es?I{yu^`ASb}3{2J_Oc0_>C+3P7dwpc5C?qqu zVwAP{5Fh?xY`xN2%NkcDD2_1%vjrdx4-6@+hl78(`myN8a-SYO9817u;ca?)^^G+faXj!=dvDa$EH!C=ZT7~1vi&i?^Cyc}Gdg8zR& T0l|Lj3;^`BjL}t^w&DK+&R2Qs literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/squad-icon.png b/lgsm/data/gameicons/squad-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..adc1464f8bc8e517df0fd2b8f50e44bf0523c6b4 GIT binary patch literal 2321 zcmZ`*dpOgJ8~++J3E+YY8 zApihS_W?jLhTiC6E-pw1Ii9rzL_fT^rR-<@Fb~S)Gb5 zHVT&dxz@=(!m;FyjgFyG2lqNg;UexyklCNLd5^e`_QiqW>()Qj>YpogMn})^sBb@>MckHgbWFy5V)Hu+f%BMi(P(HEE`sZ#57cOJ;WZ; zIHN3}p9KJUG&mtIjr9|ADCr~JvZv!F{`1s13DEGUq$s%}Uf5*hY<@#mB!yqHPS$dD zcu%*Sn-oND&WQM04^NYx5rkXc$}FWeKJ=8Q9FziP+Mj=d=frRW8>U;2pU%6veXRp( z&SRc7W$mtKoun-;bx%D3fq(`TS~ROWx!=j@JkXC*w5$GUb}-rMMu@5)=F{1$*l50p zeXQtr{}s(3Mc`Dbgwji>lFCtNeR;hXVi76sXfsiBmSzyTGTCA#w$rCuBSv&r19}T| z?&Y3h>6K_U7(LOU0MA+(=CD2dp7Z)HTKHWmuK9klkuXzOOC_^ z8eU#6otyP9!1mh{l_GE2WKyZ&6`D*Q-?Nfp^1qXw5x$As65|-LZNU4 z8t|8Lf3iIXlk!sYnH2WE{aGLd;ew&$Xu@UH zNRi|9gy7)djg<*7Trf`Tvk(l*zUaqg6)V?UOE0SY^3=w!dsIgyU3Z@2F<0K=w*Ps@ zXRgB&{_+-TTgprj&Mu5zdVS}(1+Txqzbi|z6ah*_+^XdP&d@#h-`ao8OD{%fIKNI? z*jldIUk2}8@bErwQr@~A9DM8JFMddgWi3D%U-;$%)NVL@{nLjRtk&;Zf^pLg;hpJatEPdlVy_cdJ zRxL47Be#EPXwmJ2>a)P{X}hvPnNu7!GJ?6Yvs328P(5_0A%2-ZPviTDT9oBX0z>EKyor`<9M+KXB4h(0~A3QkGI|eZZmGDhbDK687NsA-R=d;^3 zlV`pL4SF7C*EytnlH5H0$)|Nvs@1^e3KeYXTSIJ1p+2WMIwH!ufX7GNifnAmP}Gzu zx@N!oF-mzztL<7=Q#j_k`XWxlOi3MmgC8DJQKgK5Bhas$`h~*U=#K_{=FcuopdxfQ z-#FRISy@@6sUj0X&}`3LeTTctD^Y(XvF=vR+t$M;x4pKv?p`?YA<#Ta{RGDSBh84$ zJ{Ei6H}I3;aB|+_2#aBvGKm`-7^sdKJH<-HJ3IO82s0Gwt)UUG$2oqZvOYFsdUDDAG4zS^5`rjov;$pmwDh)T zTGb&1aEVa_FD^blap3FIJari~qHisnt;N*tt8@6k5xF_cXS_Pus@*F-Ctp{ZRxj~u zGl{xn2>PnG(6ui489C4kx(C-ry5{fCnBu6W6IbS`A%{5c+JvEh@CqRh+1xeroEh`J z2sW;K_)9Slho?Y(?OTg)ilWdMjIxV`t_~Rxt|^ns=5;T!?$6@ebF1Z@!5>0yxfZHt zLOSm}Ag=`enQTkMn6)WBfB0qeM)s0j3beXUJ{l{!RhTc-#gCB-4!(G-5_#dYX?5Y{JB|d~=YKmq+t3c{T^m2XU{+gOYiMj- zMopZ~JiaTJT5*tJ;n!&scEjEwg=i3NbY-8tJzbU^yQK4?~c literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/st-icon.png b/lgsm/data/gameicons/st-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..67ca7ade62ed03f47e5f339664e73d52a7448f80 GIT binary patch literal 3083 zcmV+m4D|DfP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/tfc-icon.png b/lgsm/data/gameicons/tfc-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f04580e2c3b7158e82b59652f0eb5b53710df0e2 GIT binary patch literal 2349 zcmZ{mdpy(oAIHBk%p#R!bT~8D!(m_MPT9uFV(wCjW|%{YTtYbRCzo6z8X=WSE+hBr z+#-o))KU~ub89HV8Od4w_xt1bem`EH=jZeKJYJ9Yzwaa)t5c#dX&3+iq6Bj@J01}~ z1>MIxzr&Xw{(QKb+Ytfax)K0H#{`nCn6}!-xJ~H@2{x^z|Z*=e8{~tX3E4q0``%rDs=RO zzXTqtP&kuNhLkN*fACE-=DeJZz+oISWkHAd@~JvqG1cCPATxbjcD(TGaDM&x?1!5~ zH;efN&d|B=)hOC7?FH&L`fiDnm4-Sa{A>~CW{(usz61jCLJ;!Kn>CnwnUiFry9KBS z$7FP#?JZ`KYJP1^*Un6j^?hS~OAH1B0Cnf&fK!XBX`>orS4!g!_S*fyz-wIc3I`x* zzRqfQLfR;GvawR}3Z(cL1RTG)Xv$uV45{)1^-gqRFbKhnS$Gkye)38u=NYa2^zoJ6 z@XzY@c`+cIuN%{Fo@m{NN!3ORkb;%L0>-D+cSRCp&wWRa6mw&Pp$#bpMN9=#~5~F+SeDR!dFg!ds9m%>9zD%Ce4o{ z)*4$a<$JSyawVQf`n@pD&`|89=`lh&}`7wO(zZ8UHn|r zV@3G`0RL96ccIR*12l%RQ>7wamR%(CJ2)G(@|?d@gu4ZDjSW-mAf9Bg5L# z!5UTC_8UgwDQuYo6bJ&8|Fau6m-(hy6uB2jBI+3b96W`)d@i~ij$h)x5b z67PWD2PnyM`G1$bX#pggy+gy%M;)6shD0W8$gFzw-gccw`yzDceTUY2o6Qsb ziOo!`qrUGu^tLH+n4?rak?NfA9e9YanlSTm+K&_|9~I%ViNR)Yrx!#Di*qreOyB1m zW{ie&vJ~`Cg&xjfIjS_oTOp<>RvWaVKo823j>>7GGfB5;lXdPQ-6CJ2aU^q=!aCb7NJ4EP~>s66KpYU5n!34Y~1W(5mK@ zuFjXXTUk%V2TE5B+xBYqs1fs=%(BH#2|jsWjJ7U>Z7ghN6wB1MKGxKJeEHExZZShm zmM;|$eS3f!_VHA1zi#UdPHxPL+v@zX@17~ zGg%uKqH68R=hkiI-&603UafVf--5B2R#$ z#Zqf(6k9J~^J5<0v0@Yyl;@o8A8ehN!OWvkH4*Hck6dzol{~Q^_v}$}Q*a-EvA4(* zWu4sHtS&89KbyiOV?XB8LwyY=%i;F?Sx2^xf7xEd8$@3H`x@S&gz>Ohgy!HJNcj62 z5h`!2z5j0Xri7VzV8QXp%+yAcAKb4yQR`dd(-nmmPlqgPbgs>PKZ#a^ka7IPzHhJk zCZ42s(gTaX?L;vw9lkT!MnAMW{26RJi(y1;Qd0kJc(Td%+Fy4rRac#AEFP5_$nJmoH7gKQ#84Bd z(gB}FLh9HuE&B{^SGSS}9E;*^N5@7!2pmC}vs zN2|)@*(*!WC)Sncp#0tk(U+%thPVH5@zgwT@seFqaY}o`bz@wtbHehjR3-_@2!9CB z)NM+!oxAnpZHDX3kyl1K-%q-RhMit3DDEN6B_4rT-Y5IV6(mdrxD}iH*lM8%`-Ck; z2n^%kg5pqMzM}$G6wNP+C?fdGPr0~OvnZ(2@rx$gHOkhzVi_{JJFF_}S(k9E8Jqy}NRx6h3aZf^7y6kN?oe?z%7 zNfthoJ>(hkk*J5Foyk;?K%F=&hMG!Z8Yth)Z)Rn;Z5iChb34SZulC^$Bu8_VERURs z6-P}O+>ul^$UHHRKg}+zHNCONUyEc!PnQ>wd3%H6&%MFJEy&Z*J;0L(Knv7Dt80Sl xnz{~}dWN8ZAzDWb1PwvZ%%^Gne*%~NJiIAk|39Fkcfgt#00?+1vuYeE_CK6_Lwf)K literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/ti-icon.png b/lgsm/data/gameicons/ti-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0c6e126dd700138fa7a6edb1122ea0167f961eae GIT binary patch literal 2163 zcmZ`)eK^x=AOCru8I7Y_qBc>crEQ4KODxLPS0(K$;h;aPt^e>~s&`rM!E`h2d>b$##qy1w^)mU3X9DcA}O z0Dvhmz>lhB_z!?|wflFNx=Bm=@xEkV0O+VN`A#$VVKM@!WB|zB3IK&{0Qjbr3TFWz z0}TN0V*mhu9st&-)b|E@Y7ImB{(XMH>W_6v(psfej8g(aPXK_~^B>SL3iz!>D;lK} z$^J%4Fw`8pxo7uuy;h+U{d|K1M#v%iljULSy$m2iJC#ahZ3_{Jk=AR_5LdFv5D&8#6i6Z>Ga_rKUIj(0^!V)V{dadnGQh__i!Z-`P5Myv3`s~f zwBO7JBSlLsLk^P$+l&#!${21&ft_)R*?ciyXEV~Cfhx6q)EO5SH|=i7 z+rZ#r;Grbq1_qowgpOGPK53M)n(As8gGypU5q=<@yJd~XT&xC}F@d8wlBneFFv>=E zG}#%l$B<`FwD3141jt=v8tah@b#+_VY}%DMeBtrhxc2cN(o7oe$_Q>BXklqNyoWWG z(7m?_!3I31-OC%#P)XFdO1o2XBJyxZNW?fK@y>FHl=llBlI5ar>E?PfW zHaZ&fXbSYl@svZPj!#JRzj0aC`;Z1v&CJ@^(7e37y1Kg4gh5TeMB+6muBoXpMzlvs zuw>_|2cG#~C~_B}Wf$nv;QWA|uFq)-aI_rbjl%_!T0p{`$|%vuDBA#){tEpGhl>3fo%FXylhR29TIA4i((rGm-dC z6H53)QLs9%g|V(8V}HY_fzVwb1Dk)&y+}=Sv2sG8EWxKEoN6A0wuMtkwtN_e(?KO! z6rJZk?L;XSy<~b1!mH28ltC4hR3|4V@9d9LA3h|qSbxpV&JLBViFr5P7TK2;`>^w0 zte$K9t|SkT?seB=21t87GwO_iZ_3QWwIiu_(VslqquR9-(Jm52N^&z25`L#R+-%F! z4rt=8CWq;I6GWcml}e>*@F+Osxb}$G+H=&>!NwThK+9O{h2dfUlrE7-w7k6hI>p_~ zOYLsf52+N?)}~o+1L=}f@82g_kJJZEipg?rBghIGQSO7}UFCO1I30Fet5`g#kSR63 zP$jE| zLi9YhL5AoZ_i@L2CbhNvOEjpXv(tienOPei9=^L^h5IHuGxN`kmuVB~h1@{PldCK0 z@%HHT>(^gTuib5lN0%|BM{XBVb)$h_5$A*U7ig=|^tU5=R z482yVkX?>%ax3jzzdI$nDuaT2dy>oVzFU;d@#^srL_ zg)deb(CEj$`h-PY{!}?M>EnyV;`Ei@u&0<+m=+$JU!p;t)>#7%tOuL8S2Tj&LOP6& z;L2~@xUuCYV{1AADt*7|e9-FU?cqHeK9Xp4XneEWA`v{GOPYEeA0JQfOSNtdLVZ9< zbcTaS=664C#^Z3tgZhbjnY=crZwj273gZmSZ)v`x_f&rkim}tew9(LSlIO8vuy@2mIOyF-89cq4l|w literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/ts-icon.png b/lgsm/data/gameicons/ts-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..271c5bc70b125dfcfd52e8bb7410ca8a6cf685a6 GIT binary patch literal 2922 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 Hu0mjfijhn* literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/tw-icon.png b/lgsm/data/gameicons/tw-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cd8ccd809cac1682a4b994c748189e9ae3555d70 GIT binary patch literal 2644 zcmV-a3aj;rP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/ut-icon.png b/lgsm/data/gameicons/ut-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8c81e418a3ae42c78294ae7f652b44e85c6f070c GIT binary patch literal 1134 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 A=>Px# literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/ut3-icon.png b/lgsm/data/gameicons/ut3-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1713a35319c5b3e86f8eabad2156cdf8a6f722db GIT binary patch literal 2749 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/ut99-icon.png b/lgsm/data/gameicons/ut99-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5ebe6c09c9ab1b0cb341ed608d253a307c0fd786 GIT binary patch literal 2797 zcmZ{mXE@vI8^?cYM-i)>sv{h2QDReSRbv$~iW*fTNo}H5ty-nDMiF!vC#X@viPWyW zYAd2zB(2mQEwNXQo_GHj|L3{B_vd-O_w~J=SI>3biDqzpcF;u-008WU1~7{=LVkPM# z19vYJBp?Khf;gkma`FJ^KY$?rEjcBSqN0kDvVyXUimI%vtlXIt&-5Fp-xWkwE@e4; z__ZPIrlmozZkBse-h5#EPyals`p=`s1K|o3ytEe+CE}0Ny<|B&ACFD~QH;B$9mQ5$ z3hhgUC0{HvDTjJod&{1D+n{WG4r3!K2@?02kn*-OTMz8Rh-x;{aa-}~GEI0v9WClh z9@)4fdV=HA`HvR%G&O_ zb!MJVA2R4(EG-p_KAGtWNnJbL|5bJ0q1Nk#X|NV&K6s%D%03pGM_(}P*Od|m}BOzWs}6l_T* z3#Vir<*V*yj|lf=4S$IsHe9eBmq9v8qJr5tSlfO1mT$%T1 zr}^QFFZVmq!83JZD7!Ql_A5WHGbLV0opBz#I7YASE!mXOiLYL~8iiR-AT$`Q=Z+nZdjcc4* zjfkVxOOKcFVYIcw9j=#py_BuK)f+yy<=v!}mM!BIHSyk`jA(ufEA_A!fo~_Hla4+S zI`bo428xwD^T_JdCR(6#!-iH+Ph-qy4yhHN{sQ)e?=|!eIr%T^L!n>IiN#a=CotAQ zvX^xV`-kht{V&(iv!TBD#&))&aBX|$SUc{V8Wf^HJS9(ad|t>jK&#$+N!mf3)<5tJ zxj(b~CYLr#e6uPi;k()1ZOrSy+SiU(ZB z4mZee4b9Gg^Q*{sWMkowdyN9#;b!{wjzOB=6E{$2&PxH|*$tSf-fQ@pwEzWS@{$iZbPV`AtuEyg$B{j)v%)Ops z+=L~Ir?T&HKm8l-5$&sen5K)Zk#j_j%vn8CE1q_l@Rgt!M0lE z63mbATOx_GPD@k`l!j~mv?x zDA=dM^^Z_%qX*yVtL{N<8v0GU1??)KDYJxCR;=VKOl42%o(n-jlIM=T_t>F8jJ{$S zq+tDujDrtzj6mnJYfpa+eIFOnr(YEu(4v}ksCo&-sqOETkiyoH&E@6h9`EW~f|fR- z;}Uz*zYtpR!RXb|*APY*_Z8M_MtO{-Gfx)LaU{W0H>ptf+nD~9*ZYK$1Dt;ebiz6! zl3dt&{op}k62^?&8I6x_mSm{rz81n8vD4 z=)s^8vv2w<{@$Ma(9PD!{R|#`(g`Y!|HMeYuCkHRmY7!+aga*e8O3|9Y^jC?qKA<^ zJCj7bYs!74camNK=8i(E3?rh>-7$1CwUiBB1Lr8~>~Dfc%HgYQ!mD&F68JWtBMOW# zr>&ikPc^_@V9So%S4S1(!yk8UwT7)_n5s9TeE8d7QA`H%+GGOtPQ7>UZqg{gbKXFO z_cVY!8%gcPRbXFmtw?W-f3#qnRgIkAzu=)GIJonsV@LV2NdIMw$$3=C~EI|9y34 zH8GeYC#Ut%@U989&TBoC=C%0=qQ97mspWD#JDObX*Au(Fw5gjH}`2MH1w{;yEDkmpv1wZWa`+NhMmh zw}jzda2=1t-MJSH(3Oh3yI831`%c?D@XS!p?COF0!aSyeR!rE9XX lYO=C0k6P;g1iXEb?hiu#e?Uov!}Kfw80x}dl{!u_{{m=9PH+GK literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/vh-icon.png b/lgsm/data/gameicons/vh-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e74f2604d93d5538d20f95ca9b2f054e01208f45 GIT binary patch literal 2598 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 B*Ma~5 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/vints-icon.png b/lgsm/data/gameicons/vints-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f6e6748c0387094221caf896ca964908300b5fc3 GIT binary patch literal 9075 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/vpmc-icon.png b/lgsm/data/gameicons/vpmc-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..95d3e0f8a1d8b046c620f2fa6f3ae9acbafa3485 GIT binary patch literal 1171 zcmV;E1Z?|>P)EX>4Tx04R}tkv&MmKpe$iTcuhm9V{rtAwzYti;6gwDi*;)X)CnqU~=gfG-*gu zTpR`0f`cE6RRl68#OK75I$eL`!^A?lhov576MXuEZ1p{A&DiVkcI#W4OCHsi5RUaDF!mMpK$RS{PEs%d^uJiv$2j2M1=>x^`aZU-_6gv72Cmeuzup4oK1pwO zwdfHL+6FGJyPC8IT zOq3~m-R0c_y}kW=rqkaKiqvwjts>H+00006VoOIv0RI600RN!9r;`8x010qNS#tmY z4#NNd4#NS*Z>VGd000McNliru=L!%N88m%m@{#}m02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00L`CL_t(o!|j*POVeQ-$6wF)``w&O)HR*+N0TILl}d!x zU>Cgv5=kl)LV?jiI&?_7btt?=oq~eukU@0te~_etmX_!+RFZydtu|frSNq|2Kb{U& zC!0d*F8iE6&*%N(c|OnQhv2t4oGliCa7mdN6pCtN2TW$t^Fk=S66x{Hj4c8PfaAP&$Z5H8_3*c{raH{VK5 zD7g{`5Q=J3$g$-C@&Gvp(6-`aw^?a*H&b0zMY+w6&+p^Ty+KkLxn9dR3akhU3k?4c zuoBl9x;;Q+;}Hr?Chk8Rq~~lG&I9$>Y-J!fJ{JrI>Fd9-Da57#7dlUJ_^^{glZiKD zh)W$ zUA=;)X_!@&Xf(>|>Q9D8UJ^^hDYcZM>pCmTtJ{|Yu~-~UQ|a#N!tHi5{QL#Sjy8Z0 z6q(H^ib6?AF-D^iyG?)-kNGs z=`?yW2@T{9y%ej{!>-udjDm5 z&UKSmTO+CKd=G~B^u@n%Kp?WX#K5h)TWd(00sMjJY;R*B{DV+9!qn_%QmNFx{S`rh zLEAond@0TY3)Uebz%Sj002ovPDHLkV1kvD5K;gD literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/vs-icon.png b/lgsm/data/gameicons/vs-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0817c14ebf0e891a5033483e283c1251f84ce1e0 GIT binary patch literal 500 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvmUKs7M+SzC{oH>NSwWJ?9znhg z3{`3j3=J&|48MRv4KElNN(~qoUL`OvSj}Ky5HFasE6@fgArasc;tEpG(D48N{{sgO zG%z#(c_0x6hNZ~`=0Fx>NswPKgTu2MX&_FLx4R2d8h1?!ki%Z$>Fdh=oJ&BEQ+adk z*&9HiGoCJvAsXkWPBi2@WWeJZyD;tCdciYGVh$L->UqHA;c>=s>W=?{1sY8%J{4YZ zZ~n{9&ggvT5L#lrZ%X-brX@@Im%vMjU^f&*Nd3wcPh-vzQ z(~|py1ix)Po$l|?U?9KdTdBu;pubd0Tq8 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/wet-icon.png b/lgsm/data/gameicons/wet-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e24d585a91d273974abd56e477a81508f7317c53 GIT binary patch literal 478 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvmUKs7M+SzC{oH>NSwWJ?9znhg z3{`3j3=J&|48MRv4KElNN(~qoUL`OvSj}Ky5HFasE6@fgAr#;f;tHgJ;J|?c|A7Fg zxS_#4k>e&%h_NKdFPOpM*^M+1C&}C0g;|it=M#{_UgGKN%Kn^7K#)^;bM4t1K%qUJ zE{-7@=UXQ>a<&-oxISjq7Tesa(QeGV?s$dlUfXOc0C+_zh*4k{*NW$DVLk;H_dOiezH{X)zmc}yFbZ#gPM9n zwccqf1~Iv1D`L$z^mWNE2v1Oc@8CL(c?Kg-s%^OBY46~w8-LkjtL)R}E;F85sQE{O1XZhTQy=%(O}@ Y8Vn#B?p(_ThA#tyr>mdKI;Vst00iKl7XSbN literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/wf-icon.png b/lgsm/data/gameicons/wf-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..21b6a98cc48f96ad8298f557b435f145fdb8a68d GIT binary patch literal 2494 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 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/wurm-icon.png b/lgsm/data/gameicons/wurm-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..248b42618902853cf25f0ed4e370dfe73a133c5f GIT binary patch literal 2643 zcmZ`*dpOe#8~&w*mt;y&z2B?mxXLkxk%`HM<&atq$sEQ)6mpo%F+_5%$!3v54wIO2 zm~#oAQ#93TL>l4U>p0o)>d)_w?|QELxv%Sfp8K!ox}N7rvAbv~C2>pw001d83hA)R zCw@a*WH$@t7mIfZe8}AlGJ*+K}z|QZWG0U=dl|O<|PQd_h;Nx%X5kqB`?uud|XpDszR{|^} zq3{YZRj}J;hDM%uMD?7@VW(2Kp>M~VS%T=Kt;Mba=`8$(>G-$l)#&e68tjYjgRN*v zIi)%G3{H|v>1HS7V&4mf?GCD`Gv_Rx%00!HSySv#C_+IznTWDElFg7ZvXPBCC z%WB5Omu?5<+U2vU54DjA$pB674(wDS^6G~}+^U1u^7KS~nm-Fzcl5-1PBvVY0^pd@ z_Bg9KrD9!0iV`|&#^TC%F4ip59-*)A;6A3sAr{GG_|}O%egF$ixjf?q%HQD{(D^~&Ask@@-LP0 zzv=ez>a`$^!O{^26?r4P>Ig$G=?JhVH~+e;cv=K0XHAfR$Kh@bYgSamEzf@IN-{Ds zDjxBjo+?>f3_!L-tl-^N*ZF+@x`}+@Uk!_^+gnVdFcWdN25R{Fvt{*X0qoDcDfO4x zcVJq|5z^>v*t1dNA%R7vufw0Wi|>SmU5}W_)r?-Ue&XVi{G<1@(Ic2<89dZ_ox;HB=G%^bF%s)c4PIF(_KF}FApSf`fynOzp^(U} zj-oxLqi0o)t`qUNx=YXD#N_*2eR|94m!2kq@j2rcUAZ$I?mk4KLD_{$Td9L(KU@u| z=NRF)!qIK(mCdp~c^V&VMh28_FH%xNRm#ancjxWsx5&hDG}YAuYE+ZLq_-EQ=a})l z>sNfrJfHuK$@(yH+-*Yb3Flk!_4J{OJ6t(wDry4$W?I7!0YjMNDd!%p&K-PAW3Z0N zSb$PcNRKqHkSwLQ@{s%5d8*kHQGDW~S0Pjq4J|-Thr3gr zv%6hP@hs;;$!GtV_g^ClH|lm)4z(GLTNrn+BTTNpxq zH4ky?>%!J|qbEb88#_z2$ux-P{(K}Pv;2P zUu~KH*pu#rZN7c*wI*ssvXD6SYhLn3{g^Q1?!4`{B?R;E_`R>Vw1Z~uq9w94k9|N) za(T`{8N6s`a2NpgT&T)t!;e?}kR}NSH|xeHp3t}7R7;BSc^|V2SEJYUSB2QX1&y6q z1W)#riBohqH{?Drsc6LYNaH%s6m$SGNF>ls~T5@YgC8T;r2i^r1pratt4?@tgoz@$_~_F)l`JL+(QyDNpH z7fZ_*sd8{MDeBdGOCHHiX!4L}%RV5J?N1GnC z#ete@@B0XJ0e)?*$7OoFmGN?u+KWI`3;U)DT%uu^$gro~+Cng{J=$-0*%dcm12blm3*m=o0}*gAMEoVN%ZOJSI%R2kw(C zjDd{7m+v}eLAhXuEG3#OlKZmE3x=POuPi#AyrU}C*0SYJ02#Or zJ))0cE)D$kt6|~iu#=qU^tGfSXzzV_^CE@=DjA&zbu7=A5*d7AQ19n6kQsPy&b93i z3{I8hyYsOr$oQ7z^PZwt!iD~9C=tv0pdD82_u7vl{UBKHg^Fhe>a+#KR7E);Ay(ED z^4;6SiOx7b{_&G`*`%wD@?hU`h_L)-Wum05W)%t9ZPQolcxXJ5*U0c5#TbHc?&8nD z=3dAW**M6N$#*Ca4Vj6~?zVe@al$~XS@RSs74PJrKk%knHDOs-Avb{iskE}cqQajY z((qvSI=0L|CTHm$PM1hQjYiBsz0*Wv-c1$zW~(_uh8xojHU2w<>HqX)+4)o7a$00gfulwDD-+)4<OCWEPH7LMVSwn2$;#RRVb!^!DBxsbkMK_1R;(?k&N0~OC#Ux z_s7zBCs}A2S5IE8NJY`Tc1r@iav{l1Hfn^(Cbz zvskQIRyE>Gu#`hAu7-HwLcHOgx4m}>(9zO4tFEo3t_^e4 v)`x2u!q4iR*3yD&X(4Ykto)B5Akd3|kNE!vJ^cf=y9NMlaS=&3bC3HMcK!fd literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/zmr-icon.png b/lgsm/data/gameicons/zmr-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d6c61b1d48f7489e4229153b6356bcfefadbf1a0 GIT binary patch literal 1696 zcmZXT2~ZPP7{}ip*@PsU-GqVApaY^Xn2SIAfa_Q_1AW7103f@&KSvQ-hVAlTksVUs|hc&8vf-zJ!~X{tsbn2!G^ z`!-I~)Ad0#4JCgUfsW08Ybi=jQLq?VsnwBD6qM55-sadwn(}!(=tDa#I0p2kP$X#+ zJbl`k_NODVcUhKDxELO1?W!P%QUvj2vx9j&e*hp;6aXHEu>gRYLJR;G00tPBC{%mC6oIwJCTp$SH^Ow+cG)*t!^Mm<(Ikfin3;Fyk4yT;KD8sNr zC|ZEy=`7X~in38EVzH_LSPsB@0C22FivSQ~SOAZgLXy>RRO>-p3==~jH2o2WlZc`Y z1OWj?()1b}cZbs=h%ZUTQB*#IF$(}UHX8zrrKkfe);yy5KB6T zv(oyELb&De){^7~1ew8N1yR%v415@qKcTza|p5>G6z6~<4f6W1&^1?<(`Gm0Pwb6%`5~7Wio@g+!QXi7D3hn z06!9VL9-YPe=helj;kR?f(Rr@M*s)}nVg(F*>k`I0j6tK#H<9kXIf3yz<8P`j>!zY zqochB879)1pXo$_EfW(hfuWt9p;D>QC_;6p+$_fonAiRLUg@LhHC=;)(!F$6{zu9mhoj}(W}Mz4eg7pog8>(4fwt~=xG)B9UR4N<>wrq9OCj_%(n!rmhWZI=aZ z+p0Cy|K#QRqD)!o!miR*mQ_V}+(W!>e|#zAqI%@hp!I~U3<3VR)LzZxv@x^?xr76eNd%#uQJAu)beVlX>fUI7dVJu0EIpihY|k4I|g?ekhi$`yv0) zpZA+wbGHbIc-fb4)?R$slOBeLP3m_KxhU~#Y06%ZBSRoeQ{QTF9e>J4<+`KI{_x}x&09%7evOE(ufT)O=@N+7)_8;#_?-l?6 literal 0 HcmV?d00001 diff --git a/lgsm/data/gameicons/zps-icon.png b/lgsm/data/gameicons/zps-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e37f37280fe02567579d2cfeec922ea75e689a74 GIT binary patch literal 2679 zcmV--3W)WIP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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