Browse Source

add all files from v23.2.3

should prevent failures on transition.
pull/4170/head
Daniel Gibbs 2 years ago
parent
commit
39bc190d1d
  1. 17
      lgsm/functions/README.md
  2. 238
      lgsm/functions/alert.sh
  3. 59
      lgsm/functions/alert_discord.sh
  4. 25
      lgsm/functions/alert_email.sh
  5. 30
      lgsm/functions/alert_gotify.sh
  6. 29
      lgsm/functions/alert_ifttt.sh
  7. 32
      lgsm/functions/alert_mailgun.sh
  8. 30
      lgsm/functions/alert_pushbullet.sh
  9. 33
      lgsm/functions/alert_pushover.sh
  10. 50
      lgsm/functions/alert_rocketchat.sh
  11. 75
      lgsm/functions/alert_slack.sh
  12. 30
      lgsm/functions/alert_telegram.sh
  13. 101
      lgsm/functions/check.sh
  14. 35
      lgsm/functions/check_config.sh
  15. 363
      lgsm/functions/check_deps.sh
  16. 20
      lgsm/functions/check_executable.sh
  17. 29
      lgsm/functions/check_glibc.sh
  18. 63
      lgsm/functions/check_ip.sh
  19. 26
      lgsm/functions/check_last_update.sh
  20. 233
      lgsm/functions/check_permissions.sh
  21. 10
      lgsm/functions/check_status.sh
  22. 22
      lgsm/functions/check_steamcmd.sh
  23. 22
      lgsm/functions/check_system_dir.sh
  24. 55
      lgsm/functions/check_system_requirements.sh
  25. 33
      lgsm/functions/check_tmuxception.sh
  26. 23
      lgsm/functions/check_version.sh
  27. 268
      lgsm/functions/command_backup.sh
  28. 39
      lgsm/functions/command_check_update.sh
  29. 58
      lgsm/functions/command_console.sh
  30. 142
      lgsm/functions/command_debug.sh
  31. 41
      lgsm/functions/command_details.sh
  32. 24
      lgsm/functions/command_dev_clear_functions.sh
  33. 23
      lgsm/functions/command_dev_debug.sh
  34. 231
      lgsm/functions/command_dev_detect_deps.sh
  35. 92
      lgsm/functions/command_dev_detect_glibc.sh
  36. 61
      lgsm/functions/command_dev_detect_ldd.sh
  37. 280
      lgsm/functions/command_dev_query_raw.sh
  38. 26
      lgsm/functions/command_donate.sh
  39. 442
      lgsm/functions/command_fastdl.sh
  40. 52
      lgsm/functions/command_install.sh
  41. 32
      lgsm/functions/command_install_resources_mta.sh
  42. 135
      lgsm/functions/command_mods_install.sh
  43. 153
      lgsm/functions/command_mods_remove.sh
  44. 109
      lgsm/functions/command_mods_update.sh
  45. 245
      lgsm/functions/command_monitor.sh
  46. 78
      lgsm/functions/command_postdetails.sh
  47. 18
      lgsm/functions/command_restart.sh
  48. 41
      lgsm/functions/command_send.sh
  49. 23
      lgsm/functions/command_skeleton.sh
  50. 224
      lgsm/functions/command_start.sh
  51. 283
      lgsm/functions/command_stop.sh
  52. 19
      lgsm/functions/command_test_alert.sh
  53. 57
      lgsm/functions/command_ts3_server_pass.sh
  54. 40
      lgsm/functions/command_update.sh
  55. 49
      lgsm/functions/command_validate.sh
  56. 183
      lgsm/functions/command_wipe.sh
  57. 35
      lgsm/functions/compress_unreal2_maps.sh
  58. 35
      lgsm/functions/compress_ut99_maps.sh
  59. 816
      lgsm/functions/core_modules copy.sh
  60. 88
      lgsm/functions/fix.sh
  61. 62
      lgsm/functions/fix_ark.sh
  62. 16
      lgsm/functions/fix_arma3.sh
  63. 17
      lgsm/functions/fix_armar.sh
  64. 19
      lgsm/functions/fix_av.sh
  65. 10
      lgsm/functions/fix_bo.sh
  66. 24
      lgsm/functions/fix_bt.sh
  67. 23
      lgsm/functions/fix_cmw.sh
  68. 42
      lgsm/functions/fix_csgo.sh
  69. 17
      lgsm/functions/fix_dst.sh
  70. 10
      lgsm/functions/fix_hw.sh
  71. 20
      lgsm/functions/fix_ins.sh
  72. 36
      lgsm/functions/fix_kf.sh
  73. 20
      lgsm/functions/fix_kf2.sh
  74. 17
      lgsm/functions/fix_lo.sh
  75. 11
      lgsm/functions/fix_mcb.sh
  76. 16
      lgsm/functions/fix_mta.sh
  77. 17
      lgsm/functions/fix_nmrih.sh
  78. 19
      lgsm/functions/fix_onset.sh
  79. 39
      lgsm/functions/fix_ro.sh
  80. 32
      lgsm/functions/fix_rust.sh
  81. 10
      lgsm/functions/fix_rw.sh
  82. 34
      lgsm/functions/fix_samp.sh
  83. 10
      lgsm/functions/fix_sdtd.sh
  84. 48
      lgsm/functions/fix_sfc.sh
  85. 11
      lgsm/functions/fix_sof2.sh
  86. 26
      lgsm/functions/fix_squad.sh
  87. 11
      lgsm/functions/fix_st.sh
  88. 141
      lgsm/functions/fix_steamcmd.sh
  89. 10
      lgsm/functions/fix_terraria.sh
  90. 16
      lgsm/functions/fix_tf2.sh
  91. 33
      lgsm/functions/fix_ts3.sh
  92. 10
      lgsm/functions/fix_unt.sh
  93. 13
      lgsm/functions/fix_ut.sh
  94. 36
      lgsm/functions/fix_ut2k4.sh
  95. 20
      lgsm/functions/fix_ut3.sh
  96. 35
      lgsm/functions/fix_vh.sh
  97. 23
      lgsm/functions/fix_wurm.sh
  98. 48
      lgsm/functions/fix_zmr.sh
  99. 281
      lgsm/functions/info_distro.sh
  100. 2600
      lgsm/functions/info_game.sh

17
lgsm/functions/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.

238
lgsm/functions/alert.sh

@ -0,0 +1,238 @@
#!/bin/bash
# LinuxGSM alert.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Overall function for managing alerts.
functionselfname="$(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_message_head
fn_info_message_distro
fn_info_message_server_resource
fn_info_message_gameserver_resource
fn_info_message_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 test alert"
alertsubject="Alert - ${selfname} - Test"
alertemoji="🚧"
alertsound="1"
alerturl="not enabled"
alertbody="Testing LinuxGSM Alert. No action to be taken."
}
fn_alert_restart() {
fn_script_log_info "Sending alert: Restarted: ${executable} not running"
alertsubject="Alert - ${selfname} - Restarted"
alertemoji="🚨"
alertsound="2"
alerturl="not enabled"
alertbody="${selfname} ${executable} not running"
}
fn_alert_restart_query() {
fn_script_log_info "Sending alert: Restarted: ${selfname}"
alertsubject="Alert - ${selfname} - Restarted"
alertemoji="🚨"
alertsound="2"
alerturl="not enabled"
alertbody="Unable to query: ${selfname}"
}
fn_alert_update() {
fn_script_log_info "Sending alert: Updated"
alertsubject="Alert - ${selfname} - Updated"
alertemoji="🎮"
alertsound="1"
alerturl="not enabled"
alertbody="${gamename} received update: ${remotebuildversion}"
}
fn_alert_check_update() {
fn_script_log_info "Sending alert: Update available"
alertsubject="Alert - ${selfname} - Update available"
alertemoji="🎮"
alertsound="1"
alerturl="not enabled"
alertbody="${gamename} update available: ${remotebuildversion}"
}
fn_alert_permissions() {
fn_script_log_info "Sending alert: Permissions error"
alertsubject="Alert - ${selfname}: Permissions error"
alertemoji="❗"
alertsound="2"
alerturl="not enabled"
alertbody="${selfname} has permissions issues"
}
fn_alert_config() {
fn_script_log_info "Sending alert: New _default.cfg"
alertsubject="Alert - ${selfname} - New _default.cfg"
alertemoji="🎮"
alertsound="1"
alerturl="not enabled"
alertbody="${selfname} has received a new _default.cfg. Check file for changes."
}
if [ "${alert}" == "permissions" ]; then
fn_alert_permissions
elif [ "${alert}" == "restart" ]; then
fn_alert_restart
elif [ "${alert}" == "restartquery" ]; then
fn_alert_restart_query
elif [ "${alert}" == "test" ]; then
fn_alert_test
elif [ "${alert}" == "update" ]; then
fn_alert_update
elif [ "${alert}" == "check-update" ]; then
fn_alert_check_update
elif [ "${alert}" == "config" ]; then
fn_alert_config
fi
# 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 [ "${mailgunalert}" == "on" ] && [ -n "${mailgunalert}" ]; then
alert_mailgun.sh
elif [ "${mailgunalert}" != "on" ] && [ "${commandname}" == "TEST-ALERT" ]; then
fn_print_warn_nl "Mailgun alerts not enabled"
fn_script_log_warn "Mailgun alerts not enabled"
elif [ -z "${mailguntoken}" ] && [ "${commandname}" == "TEST-ALERT" ]; then
fn_print_error_nl "Mailgun token not set"
echo -e "* https://docs.linuxgsm.com/alerts/mailgun"
fn_script_error "Mailgun 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 "${rocketchattoken}" ] && [ "${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

59
lgsm/functions/alert_discord.sh

@ -0,0 +1,59 @@
#!/bin/bash
# LinuxGSM alert_discord.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Sends Discord alert.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
json=$(
cat << EOF
{
"username":"LinuxGSM",
"avatar_url":"https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${githubbranch}/lgsm/data/alert_discord_logo.jpg",
"file":"content",
"embeds": [{
"color": "2067276",
"author": {
"name": "${alertemoji} ${alertsubject} ${alertemoji}",
"icon_url": "https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${githubbranch}/lgsm/data/alert_discord_logo.jpg"
},
"title": "${servername}",
"description": "${alertbody} \n More info: ${alerturl}",
"url": "",
"type": "content",
"thumbnail": {},
"fields": [
{
"name": "Game",
"value": "${gamename}",
"inline": true
},
{
"name": "Server IP",
"value": "[${alertip}:${port}](https://www.gametracker.com/server_info/${alertip}:${port})",
"inline": true
},
{
"name": "Hostname",
"value": "${HOSTNAME}",
"inline": true
}
]
}]
}
EOF
)
fn_print_dots "Sending Discord alert"
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_fatal "Sending Discord alert: ${discordsend}"
else
fn_print_ok_nl "Sending Discord alert"
fn_script_log_pass "Sending Discord alert"
fi

25
lgsm/functions/alert_email.sh

@ -0,0 +1,25 @@
#!/bin/bash
# LinuxGSM alert_email.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Sends email alert.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
fn_print_dots "Sending Email alert: ${email}"
fn_sleep_time
if [ -n "${emailfrom}" ]; then
mail -s "${alertsubject}" -r "${emailfrom}" "${email}" < "${alertlog}"
else
mail -s "${alertsubject}" "${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_fatal "Sending Email alert: ${email}"
fi

30
lgsm/functions/alert_gotify.sh

@ -0,0 +1,30 @@
#!/bin/bash
# LinuxGSM alert_gotify.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Sends Gotify alert.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
json=$(
cat << EOF
{
"title": "${alertemoji} ${alertsubject} ${alertemoji}",
"message": "Server name\n${servername}\n\nMessage\n${alertbody}\n\nGame\n${gamename}\n\nServer IP\n${alertip}:${port}\n\nHostname\n${HOSTNAME}\n\nMore info\n${alerturl}",
"priority": 5
}
EOF
)
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_fatal "Sending Gotify alert: ${gotifysend}"
fi

29
lgsm/functions/alert_ifttt.sh

@ -0,0 +1,29 @@
#!/bin/bash
# LinuxGSM alert_ifttt.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Sends IFTTT alert.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
json=$(
cat << EOF
{
"value1": "${selfname}",
"value2": "${alertemoji} ${alertsubject} ${alertemoji}",
"value3": "Message: \n${alertbody}\n\nGame: \n${gamename}\n\nServer name: \n${servername}\n\nHostname: \n${HOSTNAME}\n\nServer IP: \n${alertip}:${port}\n\nMore info: \n${alerturl}"
}
EOF
)
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_fatal "Sending IFTTT alert: ${pushbulletsend}"
else
fn_print_ok_nl "Sending IFTTT alert"
fn_script_log_pass "Sent IFTTT alert"
fi

32
lgsm/functions/alert_mailgun.sh

@ -0,0 +1,32 @@
#!/bin/bash
# LinuxGSM alert_mailgun.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Sends Mailgun Email alert.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
if [ "${mailgunapiregion}" == "eu" ]; then
mailgunapiurl="https://api.eu.mailgun.net"
else
mailgunapiurl="https://api.mailgun.net"
fi
fn_print_dots "Sending Email alert: Mailgun: ${mailgunemail}"
mailgunsend=$(curl --connect-timeout 10 -s --user "api:${mailguntoken}" \
-F from="LinuxGSM <${mailgunemailfrom}>" \
-F to="LinuxGSM Admin <${mailgunemail}>" \
-F subject="${alertemoji} ${alertsubject} ${alertemoji}" \
-F o:tag='alert' \
-F o:tag='LinuxGSM' \
-F text="$(cat "${alertlog}")" "${mailgunapiurl}/v3/${mailgundomain}/messages")
if [ -z "${mailgunsend}" ]; then
fn_print_fail_nl "Sending Email alert: Mailgun: ${mailgunemail}"
fn_script_log_fatal "Sending Email alert: Mailgun: ${mailgunemail}"
else
fn_print_ok_nl "Sending Email alert: Mailgun: ${mailgunemail}"
fn_script_log_pass "Sending Email alert: Mailgun: ${mailgunemail}"
fi

30
lgsm/functions/alert_pushbullet.sh

@ -0,0 +1,30 @@
#!/bin/bash
# LinuxGSM alert_pushbullet.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Sends Pushbullet Messenger alert.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
json=$(
cat << EOF
{
"channel_tag": "${channeltag}",
"type": "note",
"title": "${alertemoji} ${alertsubject} ${alertemoji}",
"body": "Server name\n${servername}\n\nMessage\n${alertbody}\n\nGame\n${gamename}\n\nServer IP\n${alertip}:${port}\n\nHostname\n${HOSTNAME}\n\nMore info\n${alerturl}"
}
EOF
)
fn_print_dots "Sending Pushbullet alert"
pushbulletsend=$(curl --connect-timeout 10 -sSL -u """${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_fatal "Sending Pushbullet alert: ${pushbulletsend}"
else
fn_print_ok_nl "Sending Pushbullet alert"
fn_script_log_pass "Sent Pushbullet alert"
fi

33
lgsm/functions/alert_pushover.sh

@ -0,0 +1,33 @@
#!/bin/bash
# LinuxGSM alert_pushover.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Sends Pushover alert.
functionselfname="$(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
pushoversend=$(curl --connect-timeout 10 -sS -F token="${pushovertoken}" -F user="${pushoveruserkey}" -F html="1" -F sound="${alertsound}" -F priority="${alertpriority}" -F title="${alertemoji} ${alertsubject} ${alertemoji}" -F message=" <b>Server name</b><br>${servername}<br><br><b>Message</b><br>${alertbody}<br><br><b>Game</b><br>${gamename}<br><br><b>Server IP</b><br><a href='https://www.gametracker.com/server_info/${alertip}:${port}'>${alertip}:${port}</a><br><br><b>Hostname</b><br>${HOSTNAME}<br><br><b>More info</b><br><a href='${alerturl}'>${alerturl}</a>" "https://api.pushover.net/1/messages.json" | grep errors)
if [ -n "${pushoversend}" ]; then
fn_print_fail_nl "Sending Pushover alert: ${pushoversend}"
fn_script_log_fatal "Sending Pushover alert: ${pushoversend}"
else
fn_print_ok_nl "Sending Pushover alert"
fn_script_log_pass "Sent Pushover alert"
fi

50
lgsm/functions/alert_rocketchat.sh

@ -0,0 +1,50 @@
#!/bin/bash
# LinuxGSM alert_rocketchat.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Sends Rocketchat alert.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
json=$(
cat << EOF
{
"alias": "LinuxGSM",
"text": "*${alertemoji} ${alertsubject} ${alertemoji}* \n *${servername}* \n ${alertbody} \n More info: ${alerturl}",
"attachments": [
{
"fields": [
{
"short": true,
"title": "Game:",
"value": "${gamename}"
},
{
"short": true,
"title": "Server IP:",
"value": "${alertip}:${port}"
},
{
"short": true,
"title": "Hostname:",
"value": "${HOSTNAME}"
}
]
}
]
}
EOF
)
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_fatal "Sending Rocketchat alert: ${rocketchatsend}"
fi

75
lgsm/functions/alert_slack.sh

@ -0,0 +1,75 @@
#!/bin/bash
# LinuxGSM alert_slack.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Sends Slack alert.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
json=$(
cat << EOF
{
"attachments": [
{
"color": "#36a64f",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*LinuxGSM Alert*"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*${alertemoji} ${alertsubject}* \n ${alertbody}"
}
},
{
"type": "divider"
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Game:* \n ${gamename}"
},
{
"type": "mrkdwn",
"text": "*Server IP:* \n ${alertip}:${port}"
},
{
"type": "mrkdwn",
"text": "*Server Name:* \n ${servername}"
}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Hostname: ${HOSTNAME} / More info: ${alerturl}"
}
}
]
}
]
}
EOF
)
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_fatal "Sending Slack alert: ${slacksend}"
fi

30
lgsm/functions/alert_telegram.sh

@ -0,0 +1,30 @@
#!/bin/bash
# LinuxGSM alert_telegram.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Sends Telegram Messenger alert.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
json=$(
cat << EOF
{
"chat_id": "${telegramchatid}",
"parse_mode": "HTML",
"text": "<b>${alertemoji} ${alertsubject} ${alertemoji}</b>\n\n<b>Server name</b>\n${servername}\n\n<b>Message</b>\n${alertbody}\n\n<b>Game</b>\n${gamename}\n\n<b>Server IP</b>\n<a href='https://www.gametracker.com/server_info/${alertip}:${port}'>${alertip}:${port}</a>\n\n<b>Hostname</b>\n${HOSTNAME}\n\n<b>More info</b>\n<a href='${alerturl}'>${alerturl}</a>",
"disable_web_page_preview": "yes"
}
EOF
)
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_fatal "Sending Telegram alert: ${telegramsend}"
else
fn_print_ok_nl "Sending Telegram alert"
fn_script_log_pass "Sent Telegram alert"
fi

101
lgsm/functions/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 function for managing checks.
# Runs checks that will either halt on or fix an issue.
functionselfname="$(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" ] || [ -f /.dockerenv ]; 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" ] || [ -f /.dockerenv ]; 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

35
lgsm/functions/check_config.sh

@ -0,0 +1,35 @@
#!/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.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
if [ -n "${servercfgfullpath}" ] && [ ! -f "${servercfgfullpath}" ]; then
fn_print_dots ""
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_dots ""
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_dots ""
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_fatal "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_fatal "serverpassword is to short (min 5 chars)"
fi

363
lgsm/functions/check_deps.sh

@ -0,0 +1,363 @@
#!/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.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
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"
sleep 1
echo -en "..\r"
sleep 1
echo -en "...\r"
sleep 1
echo -en " \r"
if [ "${distroid}" == "ubuntu" ]; then
if [ "${distroversion}" == "20.04" ]; then
cmd="sudo apt 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 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}" == "10" ]; then
cmd="sudo apt 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 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_fatal "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 dpkg-query 2> /dev/null)" ]; then
array_deps_required+=(mailutils postfix)
elif [ "$(command -v rpm 2> /dev/null)" ]; then
array_deps_required+=(mailx postfix)
fi
else
if [ "$(command -v dpkg-query 2> /dev/null)" ]; then
array_deps_required+=(mailutils postfix)
elif [ "$(command -v rpm 2> /dev/null)" ]; then
array_deps_required+=(mailx 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
fn_sleep_time
# 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 [ "${monostatus}" == "1" ]; then
fn_install_mono_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."
fn_script_log_warn "$(whoami) does not have sudo access. Manually install dependencies."
fi
fi
# Add sudo dpkg --add-architecture i386 if using i386 packages.
if [ "$(command -v dpkg-query 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"
sleep 1
echo -en "..\r"
sleep 1
echo -en "...\r"
sleep 1
echo -en " \r"
if [ "$(command -v dpkg-query 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 dpkg-query 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_fatal "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
monostatus=0
else
# Mono not installed or installed Mono < 5.0.0.
depstatus=1
monostatus=1
fi
elif [ "$(command -v dpkg-query 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}"
sleep 0.1
fi
elif [ "${depstatus}" != "0" ]; then
# If dependency is not found.
missingdep=1
if [ "${commandname}" == "INSTALL" ]; then
echo -e "${red}${deptocheck}${default}"
sleep 0.1
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" ] && [ ! -f /.dockerenv ]; then
echo -e ""
echo -e "${lightyellow}Checking Dependencies as root${default}"
echo -e "================================="
fn_print_information_nl "Checking any missing dependencies for ${gamename} server only."
fn_print_information_nl "This will NOT install a ${gamename} server."
fn_sleep_time
else
echo -e ""
echo -e "${lightyellow}Checking Dependencies${default}"
echo -e "================================="
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

20
lgsm/functions/check_executable.sh

@ -0,0 +1,20 @@
#!/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.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
# 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_fatal "Executable was not found: ${executabledir}/${execname}"
fi
unset exitbypass
core_exit.sh
fi

29
lgsm/functions/check_glibc.sh

@ -0,0 +1,29 @@
#!/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.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
info_distro.sh
if [ "${glibc}" == "null" ]; then
# Glibc is not required.
:
elif [ -z "${glibc}" ]; then
fn_print_dots "glibc"
fn_print_error_nl "glibc requirement unknown"
fn_script_log_error "glibc requirement unknown"
elif [ "$(printf '%s\n'${glibc}'\n' "${glibcversion}" | sort -V | head -n 1)" != "${glibc}" ]; then
fn_print_dots "glibc"
fn_print_error_nl "glibc requirements not met"
fn_script_log_error "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"
fi

63
lgsm/functions/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".
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
info_game.sh
ip_commands_array=("/bin/ip" "/usr/sbin/ip" "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=("/bin/ethtool" "/usr/sbin/ethtool" "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}")
webadminip=("${ip}")
telnetip=("${ip}")
# If game config does have an IP set.
elif fn_is_valid_ip "${configip}"; then
queryips=("${configip}")
ip="${configip}"
webadminip=("${configip}")
telnetip=("${configip}")
# If there is only 1 server IP address.
# Some IP details can automaticly use the one IP
elif [ "${#current_ips[@]}" == "1" ]; then
queryips=("127.0.0.1" "${current_ips[@]}")
ip="0.0.0.0"
webadminip=("${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"
webadminip=("${ip}")
telnetip=("${ip}")
fi

26
lgsm/functions/check_last_update.sh

@ -0,0 +1,26 @@
#!/bin/bash
# LinuxGSM check_last_update.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Checks lock file to see when last update happened.
# Will reboot server if instance not rebooted since update.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
if [ -f "${lockdir}/${selfname}-laststart.lock" ]; then
laststart=$(cat "${lockdir}/${selfname}-laststart.lock")
fi
if [ -f "${lockdir}/lastupdate.lock" ]; then
lastupdate=$(cat "${lockdir}/lastupdate.lock")
fi
check_status.sh
if [ -f "${lockdir}/lastupdate.lock" ] && [ "${status}" != "0" ]; then
if [ ! -f "${lockdir}/${selfname}-laststart.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"
command_restart.sh
fn_firstcommand_reset
fi
fi

233
lgsm/functions/check_permissions.sh

@ -0,0 +1,233 @@
#!/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.
functionselfname="$(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 "${functionsdir}" ]; then
if [ "$(find "${functionsdir}" -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_fatal "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 "${functionsdir}" -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 "${functionsdir}" ]; then
if [ "$(find "${functionsdir}" -type f -not -executable | wc -l)" -ne "0" ]; then
fn_print_fail_nl "Permissions issues found"
fn_script_log_fatal "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 "${functionsdir}" -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_fatal "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_* functions 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
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 "Automatically fixing /sys permissions"
fn_script_log_info "Automatically 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."
fn_sleep_time
# Show the user how to fix.
fn_sys_perm_fix_manually_msg
else
fn_print_ok_nl "Automatically 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_error_nl "Permission error(s) found in /sys"
fn_script_log_error "Permission error(s) found in /sys"
# Run the fix
fn_sys_perm_errors_fix
fi
}
## Run permisions checks when not root or docker.
if [ "$(whoami)" != "root" ] && [ ! -f /.dockerenv ]; then
fn_check_ownership
fn_check_permissions
if [ "${commandname}" == "START" ]; then
fn_sys_perm_error_process
fi
fi

10
lgsm/functions/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.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
status=$(tmux list-sessions -F "#{session_name}" 2> /dev/null | grep -Ecx "^${sessionname}")

22
lgsm/functions/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.
functionselfname="$(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

22
lgsm/functions/check_system_dir.sh

@ -0,0 +1,22 @@
#!/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.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
if [ "${commandname}" != "VALIDATE" ]; then
checkdir="${serverfiles}"
else
checkdir="${systemdir}"
fi
if [ ! -d "${checkdir}" ]; then
fn_print_fail_nl "Cannot access ${checkdir}: No such directory"
if [ -d "${lgsmlogdir}" ]; then
fn_script_log_fatal "Cannot access ${checkdir}: No such directory."
fi
core_exit.sh
fi

55
lgsm/functions/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.
functionselfname="$(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}" == "pstbs" ]; 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 "Check RAM"
# Warn the user.
fn_print_warn_nl "Check RAM: ${ramrequirementgb}G required, ${physmemtotal} available"
echo "* ${gamename} server may fail to run or experience poor performance."
fn_sleep_time
fi
fi

33
lgsm/functions/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.
functionselfname="$(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_fatal "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_fatal "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

23
lgsm/functions/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.
functionselfname="$(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_sleep_time
fn_script_log_error "LinuxGSM Version mismatch: ${selfname}: ${version}: modules: ${modulesversion}"
command_update_linuxgsm.sh
fn_firstcommand_reset
fi

268
lgsm/functions/command_backup.sh

@ -0,0 +1,268 @@
#!/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"
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
fn_firstcommand_set
check.sh
# 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 lock file.
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() {
if [ -f "${lockdir}/backup.lock" ]; then
fn_print_info_nl "Lock file found: Backup is currently running"
fn_script_log_error "Lock file 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 "Backup starting"
fn_script_log_info "Backup starting"
fn_print_ok_nl "Backup starting"
if [ ! -d "${backupdir}" ] || [ "${backupcount}" == "0" ]; then
fn_print_info_nl "There are no previous backups"
else
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
}
# Migrate Backups from old dir before refactor
fn_backup_migrate_olddir() {
# Check if old backup dir is there before the refactor and move the backups
if [ -d "${rootdir}/backups" ]; then
if [ "${rootdir}/backups" != "${backupdir}" ]; then
fn_print_dots "Backup directory is being migrated"
fn_script_log_info "Backup directory is being migrated"
fn_script_log_info "${rootdir}/backups > ${backupdir}"
mv "${rootdir}/backups/"* "${backupdir}" 2> /dev/null
exitcode=$?
if [ "${exitcode}" == 0 ]; then
rmdir "${rootdir}/backups" 2> /dev/null
exitcode=$?
fi
if [ "${exitcode}" != 0 ]; then
fn_print_error_nl "Backup directory is being migrated"
fn_script_log_error "Backup directory is being migrated"
else
fn_print_ok_nl "Backup directory is being migrated"
fn_script_log_pass "Backup directory is being migrated"
fi
fi
fi
}
fn_backup_create_lockfile() {
# Create lockfile.
date '+%s' > "${lockdir}/backup.lock"
fn_script_log_info "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_fatal "Problem identifying the previous backup directory for exclusion"
core_exit.sh
fi
tar -czf "${backupdir}/${backupname}.tar.gz" -C "${rootdir}" --exclude "${excludedir}" --exclude "${lockdir}/backup.lock" ./.
local exitcode=$?
if [ "${exitcode}" != 0 ]; then
fn_print_fail_eol
fn_script_log_fatal "Backup in progress: FAIL"
echo -e "${extractcmd}" | tee -a "${lgsmlog}"
fn_print_fail_nl "Starting backup"
fn_script_log_fatal "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}')"
fi
# Remove lock file
rm -f "${lockdir:?}/backup.lock"
}
# 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
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
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_fatal "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_fatal "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
}
# Run functions.
fn_backup_check_lockfile
fn_backup_init
fn_backup_stop_server
fn_backup_dir
fn_backup_migrate_olddir
fn_backup_create_lockfile
fn_backup_compression
fn_backup_prune
fn_backup_start_server
core_exit.sh

39
lgsm/functions/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"
functionselfname="$(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_minecraft.sh
elif [ "${shortname}" == "mcb" ]; then
update_minecraft_bedrock.sh
elif [ "${shortname}" == "pmc" ] || [ "${shortname}" == "vpmc" ] || [ "${shortname}" == "wmc" ]; then
update_papermc.sh
elif [ "${shortname}" == "fctr" ]; then
update_factorio.sh
elif [ "${shortname}" == "mta" ]; then
update_mta.sh
elif [ "${shortname}" == "jk2" ]; then
update_jediknight2.sh
elif [ "${shortname}" == "vints" ]; then
update_vintagestory.sh
elif [ "${shortname}" == "ut99" ]; then
update_ut99.sh
else
update_steamcmd.sh
fi
core_exit.sh

58
lgsm/functions/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"
functionselfname="$(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 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

142
lgsm/functions/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"
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
fn_firstcommand_set
# Trap to remove lockfile on quit.
fn_lockfile_trap() {
# Remove lockfile.
rm -f "${lockdir:?}/${selfname}.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 [ "${extip}" ]; then
if [ "${ip}" != "${extip}" ]; then
echo -e "${lightblue}Internet IP:\t${default}${extip}:${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."
echo -e ""
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 lockfile.
date '+%s' > "${lockdir}/${selfname}.lock"
echo "${version}" >> "${lockdir}/${selfname}.lock"
echo "${port}" >> "${lockdir}/${selfname}.lock"
fn_script_log_info "Lockfile generated"
fn_script_log_info "${lockdir}/${selfname}.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

41
lgsm/functions/command_details.sh

@ -0,0 +1,41 @@
#!/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"
functionselfname="$(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_message_distro
fn_info_message_server_resource
fn_info_message_gameserver_resource
fn_info_message_gameserver
fn_info_message_script
fn_info_message_backup
# Some game servers do not have parms.
if [ "${shortname}" != "jc2" ] && [ "${shortname}" != "dst" ] && [ "${shortname}" != "pz" ] && [ "${engine}" != "renderware" ]; then
fn_info_message_commandlineparms
fi
fn_info_message_ports_edit
fn_info_message_ports
fn_info_message_select_engine
fn_info_message_statusbottom
core_exit.sh

24
lgsm/functions/command_dev_clear_functions.sh

@ -0,0 +1,24 @@
#!/bin/bash
# LinuxGSM command_dev_clear_functions.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Deletes the contents of the functions dir.
commandname="DEV-CLEAR-MODULES"
commandaction="Clearing modules"
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
fn_firstcommand_set
echo -e "================================="
echo -e "Clear Functions"
echo -e "================================="
echo -e ""
if fn_prompt_yn "Do you want to delete all functions?" Y; then
rm -rfv "${functionsdir:?}/"*
rm -rfv "${configdirdefault:?}/"*
fn_script_log_info "Cleared modules directory"
fn_script_log_info "Cleared default config directory"
fi
core_exit.sh

23
lgsm/functions/command_dev_debug.sh

@ -0,0 +1,23 @@
#!/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"
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
fn_firstcommand_reset
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

231
lgsm/functions/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"
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
fn_firstcommand_set
echo -e "================================="
echo -e "Dependencies Checker"
echo -e "================================="
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 "Required Dependencies"
echo -e "================================="
echo -e "${executable}"
echo -e ""
echo -e "CentOS"
echo -e "================================="
cat "${tmpdir}/.depdetect_centos_line"
echo -e ""
echo -e ""
echo -e "Ubuntu"
echo -e "================================="
cat "${tmpdir}/.depdetect_ubuntu_line"
echo -e ""
echo -e ""
echo -e "Debian"
echo -e "================================="
cat "${tmpdir}/.depdetect_debian_line"
echo -e ""
if [ "${unknownlib}" == "1" ]; then
echo -e ""
echo -e "Unknown shared Library"
echo -e "================================="
cat "${tmpdir}/.depdetect_unknown"
fi
echo -e ""
echo -e "Required Librarys"
echo -e "================================="
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

92
lgsm/functions/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"
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
fn_firstcommand_set
echo -e "================================="
echo -e "glibc Requirements Checker"
echo -e "================================="
if [ ! "$(command -v objdump)" ]; then
fn_print_failure_nl "objdump is missing"
fn_script_log_fatal "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"
echo -e "================================="
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"
echo -e "================================="
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

61
lgsm/functions/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"
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
fn_firstcommand_set
echo -e "================================="
echo -e "Shared Object dependencies Checker"
echo -e "================================="
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"
echo -e "================================="
cat "${tmpdir}/detect_ldd.tmp"
echo -e ""
echo -e "Not Found"
echo -e "================================="
cat "${tmpdir}/detect_ldd_not_found.tmp"
rm -f "${tmpdir:?}/detect_ldd.tmp"
rm -f "${tmpdir:?}/detect_ldd_not_found.tmp"
core_exit.sh

280
lgsm/functions/command_dev_query_raw.sh

@ -0,0 +1,280 @@
#!/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"
functionselfname="$(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}Query IP Addresses${default}"
echo -e "=================================================================="
echo -e ""
for queryip in "${queryips[@]}"; do
echo -e "${queryip}"
done
echo -e ""
echo -e "${lightgreen}Game Server Ports${default}"
echo -e "=================================================================="
{
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}" == "rw" ]; then
if [ -v port2 ]; then
echo -e "Game+1: \t${port2} \t$(ss -tupl | grep -c ${port}) \t$(ss -tupl | grep ${port2} | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep ${port2} | grep udp | awk '{ print $2 }')"
else
echo -e "Game+1:"
fi
if [ -v port3 ]; then
echo -e "Game+2: \t${port3} \t$(ss -tupl | grep -c ${port}) \t$(ss -tupl | grep ${port3} | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep ${port3} | grep udp | awk '{ print $2 }')"
else
echo -e "Game+2:"
fi
if [ -v port4 ]; then
echo -e "Game+3: \t${port4} \t$(ss -tupl | grep -c ${port}) \t$(ss -tupl | grep ${port4} | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep ${port4} | grep udp | awk '{ print $2 }')"
else
echo -e "Game+3:"
fi
fi
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
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
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 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 webadminport ]; then
echo -e "Web Admin: \t${webadminport} \t$(ss -tupl | grep -c ${webadminport}) \t$(ss -tupl | grep ${webadminport} | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep ${webadminport} | grep udp | awk '{ print $2 }')"
else
echo -e "Web Admin:"
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 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 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 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 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 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 steammasterport ]; then
echo -e "Steam: Master: \t${steammasterport} \t$(ss -tupl | grep -c ${steammasterport}) \t$(ss -tupl | grep ${steammasterport} | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep ${steammasterport} | grep udp | awk '{ print $2 }')"
else
echo -e "Steam: Master:"
fi
if [ -v steamqueryport ]; then
echo -e "Steam: Query: \t${steamqueryport} \t$(ss -tupl | grep -c ${steamqueryport}) \t$(ss -tupl | grep ${steamqueryport} | grep tcp | awk '{ print $2 }') \t$(ss -tupl | grep ${steamqueryport} | grep udp | awk '{ print $2 }')"
else
echo -e "Steam: Query:"
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 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 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 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 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 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
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 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
} | column -s $'\t' -t
echo -e ""
echo -e "${lightgreen}SS Output${default}"
echo -e "================================="
fn_info_message_ports
echo -e ""
echo -e "${lightgreen}Query Port - Raw Output${default}"
echo -e "=================================================================="
echo -e ""
echo -e "PORT: ${port}"
echo -e "QUERY PORT: ${queryport}"
echo -e ""
echo -e "${lightgreen}Gamedig Raw Output${default}"
echo -e "================================="
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}"
echo -e "================================="
echo -e ""
for queryip in "${queryips[@]}"; do
echo -e "./query_gsquery.py -a \"${queryip}\" -p \"${queryport}\" -e \"${querytype}\""
echo -e ""
if [ ! -f "${functionsdir}/query_gsquery.py" ]; then
fn_fetch_file_github "lgsm/functions" "query_gsquery.py" "${functionsdir}" "chmodx" "norun" "noforce" "nohash"
fi
"${functionsdir}"/query_gsquery.py -a "${queryip}" -p "${queryport}" -e "${querytype}"
done
echo -e ""
echo -e "${lightgreen}TCP Raw Output${default}"
echo -e "================================="
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}"
echo -e "=================================================================="
echo -e ""
echo -e "${lightgreen}TCP Raw Output${default}"
echo -e "================================="
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}"
echo -e "=================================================================="
echo -e ""
echo -e "Response: ${displaymasterserver}"
echo -e ""
exitcode=0
core_exit.sh

26
lgsm/functions/command_donate.sh

@ -0,0 +1,26 @@
#!/bin/bash
# LinuxGSM command_donate.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Shows ways to donate.
commandname="DONATE"
commandaction="Donate"
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
fn_firstcommand_set
fn_print_ascii_logo
echo -e "${lightyellow}Support LinuxGSM${default}"
echo -e "================================="
echo -e ""
echo -e "Been using LinuxGSM?"
echo -e "Consider donating to support development."
echo -e ""
echo -e "* ${lightblue}Patreon:${default} https://linuxgsm.com/patreon"
echo -e "* ${lightblue}GitHub:${default} https://github.com/sponsors/dgibbs64"
echo -e "* ${lightblue}PayPal:${default} https://linuxgsm.com/paypal"
echo -e ""
echo -e "LinuxGSM est. 2012"
core_exit.sh

442
lgsm/functions/command_fastdl.sh

@ -0,0 +1,442 @@
#!/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"
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
fn_firstcommand_set
check.sh
# 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_fatal "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"
echo -e "================================="
# 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_fatal "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_fatal "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_fatal "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
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_fatal "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_fatal "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_fatal "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_fatal "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
rm -rf "${fastdldir:?}/addons"
exitcode=$?
if [ "${exitcode}" != 0 ]; then
fn_print_fail_eol_nl
fn_script_log_fatal "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
cp -Rf "${fastdldir}/lua/"* "${fastdldir}"
exitcode=$?
if [ "${exitcode}" != 0 ]; then
fn_print_fail_eol_nl
fn_script_log_fatal "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
# 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_fatal "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_fatal "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_fatal "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_fatal "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
}
# 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

52
lgsm/functions/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 function for the installer.
commandname="INSTALL"
commandaction="Installing"
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
fn_firstcommand_set
check.sh
if [ "$(whoami)" == "root" ] && [ ! -f /.dockerenv ]; 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

32
lgsm/functions/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"
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
fn_firstcommand_set
fn_install_resources() {
echo -e ""
echo -e "${lightyellow}Installing Default Resources${default}"
echo -e "================================="
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

135
lgsm/functions/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"
functionselfname="$(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"
echo -e "================================="
# 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"
echo -e "================================="
# 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}"
echo -e "================================="
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

153
lgsm/functions/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"
functionselfname="$(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"
echo -e "================================="
# 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
# 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_fatal "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
rm -rf "${modsdir:?}/${modcommand}-files.txt"
exitcode=$?
if [ "${exitcode}" != 0 ]; then
fn_script_log_fatal "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
sed -i "/^${modcommand}$/d" "${modsinstalledlistfullpath}"
exitcode=$?
if [ "${exitcode}" != 0 ]; then
fn_script_log_fatal "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

109
lgsm/functions/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"
functionselfname="$(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
# 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_fatal "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

245
lgsm/functions/command_monitor.sh

@ -0,0 +1,245 @@
#!/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"
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
fn_firstcommand_set
fn_monitor_check_lockfile() {
# Monitor does not run it lockfile is not found.
if [ ! -f "${lockdir}/${selfname}.lock" ]; then
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
# Fix if lockfile is not unix time or contains letters
if [ -f "${lockdir}/${selfname}.lock" ] && [[ "$(head -n 1 "${lockdir}/${selfname}.lock")" =~ [A-Za-z] ]]; then
date '+%s' > "${lockdir}/${selfname}.lock"
echo "${version}" >> "${lockdir}/${selfname}.lock"
echo "${port}" >> "${lockdir}/${selfname}.lock"
fi
}
fn_monitor_check_update() {
# Monitor will check if update is already running.
if [ "$(pgrep "${selfname} update" | wc -l)" != "0" ]; then
fn_print_dots "Checking active updates: "
fn_print_checking_eol
fn_script_log_info "Checking active updates: CHECKING"
fn_print_error_nl "Checking active updates: SteamCMD is currently checking for updates: "
fn_print_error_eol
fn_script_log_error "Checking active updates: SteamCMD is currently checking for updates: ERROR"
core_exit.sh
fi
}
fn_monitor_check_session() {
fn_print_dots "Checking session: "
fn_print_checking_eol
fn_script_log_info "Checking session: CHECKING"
# uses status var from check_status.sh
if [ "${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_fatal "Checking session: FAIL"
alert="restart"
alert.sh
fn_script_log_info "Checking session: Monitor is restarting ${selfname}"
command_restart.sh
core_exit.sh
fi
}
fn_monitor_check_queryport() {
# Monitor will check queryport is set before continuing.
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 "${functionsdir}/query_gsquery.py" ]; then
fn_fetch_file_github "lgsm/functions" "query_gsquery.py" "${functionsdir}" "chmodx" "norun" "noforce" "nohash"
fi
"${functionsdir}"/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}.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}.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="restartquery"
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}"
sleep 0.5
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
}
monitorflag=1
check.sh
core_logs.sh
info_game.sh
# query pre-checks
fn_monitor_check_lockfile
fn_monitor_check_update
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

78
lgsm/functions/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"
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
fn_firstcommand_set
posttarget="https://termbin.com"
# source all of the functions 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_message_distro
fn_info_message_server_resource
fn_info_message_gameserver_resource
fn_info_message_gameserver
fn_info_message_script
fn_info_message_backup
# Some game servers do not have parms.
if [ "${shortname}" != "jc2" ] && [ "${shortname}" != "jc3" ] && [ "${shortname}" != "dst" ] && [ "${shortname}" != "pz" ] && [ "${engine}" != "renderware" ]; then
fn_info_message_commandlineparms
fi
fn_info_message_ports_edit
fn_info_message_ports
fn_info_message_select_engine
fn_info_message_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

18
lgsm/functions/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="MODS-INSTALL"
commandaction="Restarting"
functionselfname="$(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

41
lgsm/functions/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"
functionselfname="$(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 send-keys -t "${servicename}" "${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

23
lgsm/functions/command_skeleton.sh

@ -0,0 +1,23 @@
#!/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.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
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_fatal "Creating skeleton directory"
else
fn_print_ok_nl "Creating skeleton directory: ./skel"
fn_script_log_pass "Creating skeleton directory: ./skel"
fi
core_exit.sh

224
lgsm/functions/command_start.sh

@ -0,0 +1,224 @@
#!/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"
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
addtimestamp="gawk '{ print strftime(\\\"[$logtimestampformat]\\\"), \\\$0 }'"
fn_firstcommand_set
fn_start_teamspeak3() {
if [ ! -f "${servercfgfullpath}" ]; then
fn_print_warn_nl "${servercfgfullpath} is missing"
fn_script_log_warn "${servercfgfullpath} is missing"
echo " * Creating blank ${servercfg}"
fn_script_log_info "Creating blank ${servercfg}"
fn_sleep_time
echo " * ${servercfg} can remain blank by default."
fn_script_log_info "${servercfgfullpath} can remain blank by default."
fn_sleep_time
echo " * ${servercfg} is located in ${servercfgfullpath}."
fn_script_log_info "${servercfg} is located in ${servercfgfullpath}."
sleep 5
touch "${servercfgfullpath}"
fi
# Accept license.
if [ ! -f "${executabledir}/.ts3server_license_accepted" ]; then
install_eula.sh
fi
fn_start_tmux
}
# 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 send -t "${sessionname}" version ENTER > /dev/null 2>&1
}
fn_start_tmux() {
if [ "${parmsbypass}" ]; then
startparameters=""
fi
# 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 lockfile
date '+%s' > "${lockdir}/${selfname}.lock"
echo "${version}" >> "${lockdir}/${selfname}.lock"
echo "${port}" >> "${lockdir}/${selfname}.lock"
fn_reload_startparameters
if [ "${shortname}" == "av" ]; then
cd "${systemdir}" || exit
else
cd "${executabledir}" || exit
fi
tmux new-session -d -x "${sessionwidth}" -y "${sessionheight}" -s "${sessionname}" "${preexecutable} ${executable} ${startparameters}" 2> "${lgsmlogdir}/.${selfname}-tmux-error.tmp"
# Create logfile.
touch "${consolelog}"
# Create last start lock file
date +%s > "${lockdir}/${selfname}-laststart.lock"
# 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 pipe-pane -o -t "${sessionname}" "exec bash -c \"cat | $addtimestamp\" >> '${consolelog}'"
else
tmux 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 pipe-pane -o -t "${sessionname}" "exec bash -c \"cat | $addtimestamp\" >> '${consolelog}'"
else
tmux 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 by user" >> "${consolelog}"
fn_script_log_info "Console logging disabled by user"
fi
fn_sleep_time
# If the server fails to start.
check_status.sh
if [ "${status}" == "0" ]; then
fn_print_fail_nl "Unable to start ${servername}"
fn_script_log_fatal "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_fatal "Unable to start ${servername}: tmux error:"
echo -e ""
echo -e "Command"
echo -e "================================="
echo -e "tmux new-session -d -s \"${sessionname}\" \"${preexecutable} ${executable} ${startparameters}\"" | tee -a "${lgsmlog}"
echo -e ""
echo -e "Error"
echo -e "================================="
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"
echo -e "================================="
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
core_exit.sh
else
fn_print_ok "${servername}"
fn_script_log_pass "Started ${servername}"
fi
rm -f "${lgsmlogdir:?}/.${selfname}-tmux-error.tmp" 2> /dev/null
echo -en "\n"
}
check.sh
# Is the server already started.
# $status comes from check_status.sh, which is run by check.sh for this command
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
core_exit.sh
fi
fi
if [ -z "${fixbypass}" ]; then
fix.sh
fi
info_game.sh
core_logs.sh
# Will check for updates is 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}" == "ts3" ]; then
fn_start_teamspeak3
elif [ "${shortname}" == "jk2" ]; then
fn_start_jk2
else
fn_start_tmux
fi
core_exit.sh

283
lgsm/functions/command_stop.sh

@ -0,0 +1,283 @@
#!/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"
functionselfname="$(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 quit.
tmux 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"
break
fi
sleep 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 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"
break
fi
sleep 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 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
sleep 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"
}
# 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"
break
fi
sleep 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 send-keys -t "${sessionname}" /save ENTER > /dev/null 2>&1
sleep 5
# Sends /quit.
tmux 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"
break
fi
sleep 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 kill-session -t "${sessionname}" > /dev/null 2>&1
sleep 0.5
check_status.sh
if [ "${status}" == "0" ]; then
fn_print_ok_nl "${servername}"
fn_script_log_pass "Stopped ${servername}"
else
fn_print_fail_nl "Unable to stop ${servername}"
fn_script_log_fatal "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_error "${servername} is already stopped"
else
# Select graceful shutdown.
fn_stop_graceful_select
fi
# Check status again, a kill tmux session if graceful shutdown failed.
check_status.sh
if [ "${status}" != "0" ]; then
fn_stop_tmux
fi
}
check.sh
fn_print_dots "${servername}"
info_game.sh
fn_stop_pre_check
# Remove lockfile.
if [ -f "${lockdir}/${selfname}.lock" ]; then
rm -f "${lockdir:?}/${selfname}.lock"
fi
if [ -z "${exitbypass}" ]; then
core_exit.sh
fi

19
lgsm/functions/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"
functionselfname="$(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

57
lgsm/functions/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"
functionselfname="$(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

40
lgsm/functions/command_update.sh

@ -0,0 +1,40 @@
#!/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"
functionselfname="$(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_minecraft.sh
elif [ "${shortname}" == "mcb" ]; then
update_minecraft_bedrock.sh
elif [ "${shortname}" == "pmc" ] || [ "${shortname}" == "vpmc" ] || [ "${shortname}" == "wmc" ]; then
update_papermc.sh
elif [ "${shortname}" == "fctr" ]; then
update_factorio.sh
elif [ "${shortname}" == "mta" ]; then
update_mta.sh
elif [ "${shortname}" == "jk2" ]; then
update_jediknight2.sh
elif [ "${shortname}" == "vints" ]; then
update_vintagestory.sh
elif [ "${shortname}" == "ut99" ]; then
update_ut99.sh
else
update_steamcmd.sh
fi
core_exit.sh

49
lgsm/functions/command_validate.sh

@ -0,0 +1,49 @@
#!/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"
functionselfname="$(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))
sleep 1
if [ "${seconds}" == "0" ]; then
break
fi
done
fn_print_warn_nl "Validate might overwrite some customised files"
fn_dl_steamcmd
}
# The location where the builds are checked and downloaded.
remotelocation="SteamCMD"
check.sh
fn_print_dots "${remotelocation}"
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
core_exit.sh

183
lgsm/functions/command_wipe.sh

@ -0,0 +1,183 @@
#!/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"
functionselfname="$(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))
sleep 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))
sleep 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}"
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}"
fi
else
fn_print_ok_nl "Wipe not required"
fn_script_log_pass "Wipe not required"
fi
core_exit.sh

35
lgsm/functions/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"
functionselfname="$(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

35
lgsm/functions/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"
functionselfname="$(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

816
lgsm/functions/core_modules copy.sh

@ -1,816 +0,0 @@
#!/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.2.0"
# 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_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_lo.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_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_mailgun.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_minecraft.sh() {
modulefile="${FUNCNAME[0]}"
fn_fetch_module
}
update_minecraft_bedrock.sh() {
modulefile="${FUNCNAME[0]}"
fn_fetch_module
}
update_papermc.sh() {
modulefile="${FUNCNAME[0]}"
fn_fetch_module
}
update_mta.sh() {
modulefile="${FUNCNAME[0]}"
fn_fetch_module
}
update_factorio.sh() {
modulefile="${FUNCNAME[0]}"
fn_fetch_module
}
update_jediknight2.sh() {
modulefile="${FUNCNAME[0]}"
fn_fetch_module
}
update_steamcmd.sh() {
modulefile="${FUNCNAME[0]}"
fn_fetch_module
}
update_vintagestory.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
# Calls on-screen messages (bootstrap)
core_messages.sh
#Calls file downloader (bootstrap)
core_dl.sh
# Calls the global Ctrl-C trap
core_trap.sh

88
lgsm/functions/fix.sh

@ -0,0 +1,88 @@
#!/bin/bash
# LinuxGSM fix.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Overall function for managing fixes.
# Runs functions that will fix an issue.
functionselfname="$(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 rust rw sdtd sfc sof2 squad st tf2 terraria ts3 mcb mta unt vh wurm zmr)
apply_post_install_fix=(av kf kf2 lo 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_functions.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}"
echo -e "================================="
fn_sleep_time
postinstall=1
fn_apply_fix "post install" "${shortname}"
fi
fi

62
lgsm/functions/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 various issues with ARK: Survival Evolved.
functionselfname="$(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

16
lgsm/functions/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 an issue with ARMA3.
functionselfname="$(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

17
lgsm/functions/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 an issue with Arma Reforger.
functionselfname="$(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

19
lgsm/functions/fix_av.sh

@ -0,0 +1,19 @@
#!/bin/bash
# LinuxGSM fix_av.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Resolves startup issue with Avorion
functionselfname="$(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."
fn_sleep_time
cd "${systemdir}" || exit
eval "${executable} ${startparameters}"
fi

10
lgsm/functions/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 various issues with Ballistic Overkill.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}:${serverfiles}/BODS_Data/Plugins/x86_64"

24
lgsm/functions/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 an issue with Barotrauma.
functionselfname="$(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

23
lgsm/functions/fix_cmw.sh

@ -0,0 +1,23 @@
#!/bin/bash
# LinuxGSM fix_cmw.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Resolves the issue of the not starting server on linux
functionselfname="$(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"
mkdir "${servercfgdir}"
cp "${systemdir}/UDKGame/Config/"*.ini "${servercfgdir}"
fn_fix_msg_end
fi

42
lgsm/functions/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 various issues with CS:GO.
functionselfname="$(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 -v "${libgccc_so}" "${libgccc_so}.bck"
fn_fix_msg_end
fi

17
lgsm/functions/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 various issues with Don't Starve Together.
functionselfname="$(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

10
lgsm/functions/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 various issues with Hurtworld.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}:${serverfiles}/Hurtworld_Data/Plugins/x86_64"

20
lgsm/functions/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 various issues with Insurgency.
functionselfname="$(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

36
lgsm/functions/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 various issues with Killing Floor.
functionselfname="$(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
sleep 5
exitbypass=1
command_stop.sh
fn_firstcommand_reset
exitbypass=1
command_start.sh
fn_firstcommand_reset
sleep 5
exitbypass=1
command_stop.sh
fn_firstcommand_reset

20
lgsm/functions/fix_kf2.sh

@ -0,0 +1,20 @@
#!/bin/bash
# LinuxGSM fix_kf2.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Resolves various issues with Killing Floor 2.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
startparameters="\"${defaultmap}?Game=KFGameContent.KFGameInfo_VersusSurvival\""
fn_print_information "starting ${gamename} server to generate configs."
fn_sleep_time
exitbypass=1
command_start.sh
fn_firstcommand_reset
sleep 10
exitbypass=1
command_stop.sh
fn_firstcommand_reset

17
lgsm/functions/fix_lo.sh

@ -0,0 +1,17 @@
#!/bin/bash
# LinuxGSM fix_lo.sh function
# Author: Daniel Gibbs
# Website: https://linuxgsm.com
# Description: Resolves installation issue with Last Oasis
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
appidfile=${executabledir}/steam_appid.txt
if [ ! -f "${appidfile}" ]; then
fn_print_information "adding ${appidfile} to ${gamename} server."
fn_sleep_time
echo "903950" > "${appidfile}"
else
fn_print_information "${appidfile} already exists. No action to be taken."
fn_sleep_time
fi

11
lgsm/functions/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 possible startup issue with Minecraft Bedrock.
functionselfname="$(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}"

16
lgsm/functions/fix_mta.sh

@ -0,0 +1,16 @@
#!/bin/bash
# LinuxGSM fix_mta.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Installs the libmysqlclient for database functions on the server.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
if [ ! -f "${lgsmdir}/lib/libmysqlclient.so.16" ]; then
fixname="libmysqlclient16"
fn_fix_msg_start_nl
fn_sleep_time
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

17
lgsm/functions/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/
functionselfname="$(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"

19
lgsm/functions/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.
functionselfname="$(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

39
lgsm/functions/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 various issues with Red Orchestra.
functionselfname="$(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 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
sleep 5
exitbypass=1
command_stop.sh
fn_firstcommand_reset
exitbypass=1
command_start.sh
fn_firstcommand_reset
sleep 5
exitbypass=1
command_stop.sh
fn_firstcommand_reset

32
lgsm/functions/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 startup issue with Rust.
functionselfname="$(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

10
lgsm/functions/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 various issues with Rising World.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}:${serverfiles}/linux64"

34
lgsm/functions/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
functionselfname="$(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."
random=$(tr -dc A-Za-z0-9_ < /dev/urandom | head -c 8 | xargs)
rconpass="admin${random}"
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

10
lgsm/functions/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 various issues with 7 Days to Die.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}/7DaysToDieServer_Data/Plugins/x86_64"

48
lgsm/functions/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 various issues with Source Forts Classic.
functionselfname="$(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

11
lgsm/functions/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 various issues with Soldier of Fortune 2.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
# Fixes: error while loading shared libraries: libcxa.so.1
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}"

26
lgsm/functions/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 various issues with Squad.
functionselfname="$(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

11
lgsm/functions/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 startup issue with Stationeers.
functionselfname="$(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"

141
lgsm/functions/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 various issues related to SteamCMD.
functionselfname="$(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

10
lgsm/functions/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 an issue with Terraria.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
export TERM=xterm

16
lgsm/functions/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 various issues with Team Fortress 2.
functionselfname="$(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

33
lgsm/functions/fix_ts3.sh

@ -0,0 +1,33 @@
#!/bin/bash
# LinuxGSM fix_ts3.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Resolves various issues with Teamspeak 3.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
# 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_fatal "File ${accountingfile} is not owned by $(whoami) and needs to be deleted manually"
core_exit.sh
fi
fi

10
lgsm/functions/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 startup issue with Unturned.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${serverfiles}:${serverfiles}/Unturned_Headless_Data/Plugins/x86_64"

13
lgsm/functions/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 various issues with Unreal Tournament.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
#Set Binary Executable
echo -e "chmod +x ${executabledir}/${executable}"
chmod +x "${executabledir}/${executable}"
fn_sleep_time

36
lgsm/functions/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 various issues with Unreal Tournament 2004.
functionselfname="$(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
sleep 5
exitbypass=1
command_stop.sh
fn_firstcommand_reset
exitbypass=1
command_start.sh
fn_firstcommand_reset
sleep 5
exitbypass=1
command_stop.sh
fn_firstcommand_reset

20
lgsm/functions/fix_ut3.sh

@ -0,0 +1,20 @@
#!/bin/bash
# LinuxGSM fix_ut2.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Resolves various issues with Unreal Tournament 3.
functionselfname="$(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."
fn_sleep_time
exitbypass=1
command_start.sh
fn_firstcommand_reset
sleep 10
exitbypass=1
command_stop.sh
fn_firstcommand_reset

35
lgsm/functions/fix_vh.sh

@ -0,0 +1,35 @@
#!/bin/bash
# LinuxGSM fix_rust.sh function
# Author: Alasdair Haig
# Website: https://linuxgsm.com
# Description: Resolves startup issue with Valheim
functionselfname="$(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

23
lgsm/functions/fix_wurm.sh

@ -0,0 +1,23 @@
#!/bin/bash
# LinuxGSM fix_wurm.sh module
# Author: Daniel Gibbs
# Contributors: http://linuxgsm.com/contrib
# Website: https://linuxgsm.com
# Description: Resolves various issues with Wurm Unlimited.
functionselfname="$(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
parmsbypass=1
fixbypass=1
exitbypass=1
command_start.sh
fn_firstcommand_reset
sleep 10
exitbypass=1
command_stop.sh
fn_firstcommand_reset
unset parmsbypass
fi

48
lgsm/functions/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 various issues with Zombie Master: Reborn.
functionselfname="$(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

281
lgsm/functions/info_distro.sh

@ -0,0 +1,281 @@
#!/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.
functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
### Game Server pid
if [ "${status}" == "1" ]; then
gameserverpid="$(tmux 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
# 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
## 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)"

2600
lgsm/functions/info_game.sh

File diff suppressed because it is too large

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save