@ -22,36 +22,68 @@ source /etc/kf2-srv/kf2-srv.conf
ScriptFullname=$(readlink -e "$0")
ScriptName=$(echo "$ScriptFullname" | awk -F '/' '{print $NF;}')
AppNum="232130"
InstallDir="/usr/games/kf2-srv"
ActiveBranch="$InstallDir/activebranch.txt"
AppBin="$InstallDir/Binaries/Win64/KFGameSteamServer.bin.x86_64"
DefaultConfigDir="$InstallDir/KFGame/Config"
CustomMapsDir="$InstallDir/KFGame/Cache"
InstanceConfigDir="$DefaultConfigDir/instances"
InstanceConfigLnk="/etc/kf2-srv/instances"
MainConfigTemplate="/etc/kf2-srv/main.conf.template"
DiffArray=('Normal' 'Hard' 'Suicide' 'Hell')
WaveArray=('4' '7' '10')
declare -A ModeArray
ModeArray['KFGameContent.KFGameInfo_Survival']='Survival'
ModeArray['KFGameContent.KFGameInfo_WeeklySurvival']='Weekly'
ModeArray['KFGameContent.KFGameInfo_Endless']='Endless'
ModeArray['KFGameContent.KFGameInfo_Objective']='Objective'
ModeArray['KFGameContent.KFGameInfo_VersusSurvival']='Versus'
function show_help ()
{
echo "kf2-srv "
echo ""
echo "$ScriptName "
echo "Централизование управление серверами Killing Floor 2 "
echo "Usage:"
echo "$ScriptName OPTION [INSTANCE]"
echo ""
echo "Mandatory arguments to long options are mandatory for short options too."
echo " -n, --new INSTANCE TODO: description"
echo " -d , --delete [ INSTANCE] TODO: description "
echo " -l , --list TODO: description "
echo " -s, --status [INSTANCE] TODO: description "
echo " -u , --update TODO: description "
echo " -r. --run TODO: description "
echo " --start [INSTANCE] TODO: description "
echo " --stop [INSTANCE] TODO: description "
echo " --enable [INSTANCE] TODO: description"
echo " --disable [INSTANCE] TODO: description "
echo " --map-sync TODO: description "
echo " --ban-sync TODO: description "
echo " --map-rotate-save TODO: description "
echo " --map-rotate-load TODO: description "
echo "TODO: English description"
echo " -n , --new INSTANCE создает новый ЭКЗЕМПЛЯР сервера "
echo " -d , --delete [INSTANCE] удаляет указанный ЭКЗМПЛЯР сервера; если "
echo " ЭКЗЕМПЛЯР не указан, удаляет все сервера "
echo " -s , --status [INSTANCE] отображает состояние указанного ЭКЗЕМПЛЯРА "
echo " сервера; если ЭКЗЕМПЛЯР не указан, "
echo " отображает состояние всех экземпляров сервера "
echo " -u, --update при первом запуске производит установку KF2; "
echo " в дальнейшем устанавливает обновления при их"
echo " наличии "
echo " -v, --validate проверяет целостность файлов, при "
echo " необходимости перекачивает их. "
echo " -r, --run [OPTIONS] запускает экземпляр сервера с указанными "
echo " ПАРАМЕТРАМИ "
echo " --start [INSTANCE] запускает указанный ЭКЗЕМПЛЯР сервера; если"
echo " ЭКЗЕМПЛЯР не указан, запускает все"
echo " автозапускаемые экземпляры сервера"
echo " --stop [INSTANCE] останавливает указанный ЭКЗЕМПЛЯР сервера;"
echo " если ЭКЗЕМПЛЯР не указан, останавливает все"
echo " экземпляры сервера"
echo " --restart [INSTANCE] перезапускает указанный ЭКЗЕМПЛЯР сервера;"
echo " если ЭКЗЕМПЛЯР не указан, перезапускает"
echo " все автозапускаемые экземпляры сервера"
echo " --enable [INSTANCE] добавляет указанный ЭКЗЕМПЛЯР сервера в"
echo " автозапуск; если ЭКЗЕМПЛЯР не указан,"
echo " добавляет все экземпляры сервера в автозапуск"
echo " --disable [INSTANCE] удаляет указанный ЭКЗЕМПЛЯР сервера из"
echo " автозапуска; если ЭКЗЕМПЛЯР не указан,"
echo " удаляет все экземпляры сервера из автозапуска"
echo " --map-sync [INSTANCE] синхронизирует список сторонних карт в"
echo " конфигурационном файле ЭКЗЕМПЛЯРА с "
echo " имеющимися файлами сторонних карт; если"
echo " ЭКЗЕМПЛЯР не указан, синхронизирует все"
echo " экземпляры серверов"
echo " -h, --help display this help and exit"
}
@ -135,7 +167,7 @@ function new_instance () # $1: InstanceName
cp -a "$DefaultConfigDir/LinuxServer/LinuxServerInput.ini" "$InstanceDir/LinuxServer"
cp -a "$DefaultConfigDir/LinuxServer/LinuxServerSystemSettings.ini" "$InstanceDir/LinuxServer"
echo "Instance $Instance created. See $InstanceDir for edit configuration"
echo "Instance $Instance created. See /etc/$ScriptName/instances/ $Instance for edit configuration"
}
function delete_instance () # $1: [InstanceName]
@ -176,10 +208,34 @@ function show_status_implementation () # $1: [InstanceName]
else
local IsRuning="dead"
fi
local Description=$(grep -P 'Description=' "$InstanceConfigDir/$Instance/main.conf" | sed -r 's/(Description=|")//g')
echo -e "$Instance:$IsEnabled:$IsRuning:$Description"
local GamePort=$(grep -Po '"-port=([0-9]+)' "$InstanceConfigDir/$Instance/main.conf" | grep -Po '[0-9]+$')
local WebAdminPort=$(grep -Po '"-webadminport=([0-9]+)' "$InstanceConfigDir/$Instance/main.conf" | grep -Po '[0-9]+$')
local QueryPort=$(grep -Po '"-queryport=([0-9]+)' "$InstanceConfigDir/$Instance/main.conf" | grep -Po '[0-9]+$')
local GameType=$(grep -Po 'Game=([^\?]+)' "$InstanceConfigDir/$Instance/main.conf" | sed -r 's/Game=([^?]+)/\1/g' )
local GameLength=$(grep -Po 'GameLength=([0-9]+)' "$InstanceConfigDir/$Instance/main.conf" | grep -Po '[0-9]+$')
local GameDifficulty=$(grep -Po 'Difficulty=([0-9]+)' "$InstanceConfigDir/$Instance/main.conf" | grep -Po '[0-9]+$')
local DisplayGameType=${ModeArray[$GameType]}
local DisplayGameLength=${WaveArray[$GameLength]}
local DisplayDifficulty=${DiffArray[$GameDifficulty]}
if [[ "$DisplayGameType" == 'Weekly' || \
"$DisplayGameType" == 'Endless' || \
"$DisplayGameType" == 'Versus' || \
"$DisplayGameType" == 'Objective' ]]; then
DisplayGameLength='-'
fi
if [[ "$DisplayGameType" == 'Weekly' || \
"$DisplayGameType" == 'Versus' ]]; then
DisplayDifficulty='-'
fi
echo -e "$Instance:$IsEnabled:$IsRuning:$GamePort:$QueryPort:$WebAdminPort:$DisplayGameType:$DisplayGameLength:$DisplayDifficulty:$Description"
else
echo -e "INSTANCE:AUTORUN:STATE:DESCRIPTION"
echo -e "INSTANCE:AUTORUN:STATE:P_GAME:P_QUERY:P_WEB:TYPE:LEN:DIFF: DESCRIPTION"
for Instance in $(show_instances)
do
show_status_implementation "$Instance"
@ -192,20 +248,35 @@ function show_status () # $1: [InstanceName]
show_status_implementation "$1" | column -t -s :
}
function validate ()
{
if [[ -n "$BranchName" ]]; then
local BetaArg="-beta $BranchName"
fi
stop_instance
steamcmd +login $SteamLogin +force_install_dir $InstallDir +app_update $AppNum $BetaArg validate +exit
echo "$BranchName" > "$ActiveBranch"
start_instance
}
function update_kf2 ()
{
if [[ -n "$BranchName" ]]; then
local BetaArg="-beta $BranchName"
fi
if ! server_exists; then # First install
chown "root :$SteamUser" "$InstallDir"
steamcmd +login $SteamLogin +force_install_dir $InstallDir +app_update $AppNum $BetaArg validate +exit
mkdir "$InstanceConfigDir" && chown "$SteamUser:$SteamUser" "$InstanceConfigDir"
mkdir -p "$InstanceConfigDir" "$CustomMapsDir" && chown -R "$SteamUser :$SteamUser" "$InstallDir/KFGame "
ln -s "$InstanceConfigDir" "$InstanceConfigLnk"
echo "$BranchName" > "$ActiveBranch"
steamcmd +login $SteamLogin +force_install_dir $InstallDir +app_update $AppNum $BetaArg validate +exit
elif updates_aviable; then # Update
stop_instance
steamcmd +login $SteamLogin +force_install_dir $InstallDir +app_update $AppNum $BetaArg +exit
start_instance
if [[ "$BranchName" == $(cat "$ActiveBranch") ]]; then
stop_instance
steamcmd +login $SteamLogin +force_install_dir $InstallDir +app_update $AppNum $BetaArg +exit
start_instance
else
validate
fi
fi
}
@ -245,6 +316,25 @@ function stop_instance () # $1: [InstanceName]
fi
}
function restart_instance () # $1: [InstanceName]
{
local Instance="$1"
if [[ -n "$Instance" ]] ; then
if instance_exists "$Instance"; then
systemctl restart $(service_name "$Instance")
else
echo "Instance $Instance not exitst"
fi
else
for Instance in $(show_instances)
do
if systemctl -q is-enabled $(service_name "$Instance") ; then
restart_instance "$Instance"
fi
done
fi
}
function enable_instance () # $1: [InstanceName]
{
local Instance="$1"
@ -290,19 +380,41 @@ function run ()
fi
}
function map_sync ()
function map_sync () # $1: [InstanceName]
{
# TODO: implementation
# подсмотреть в скрипте старого серва
# либо забить х е р и перевести всё на steamworkshop
# последний вариант наверное даже правильнее
echo "Dummy... "
}
function ban_sync ( )
{
# TODO: implementation
echo "Dummy..."
local Instance="$1"
if [[ -n "$Instance" ]]; then
if instance_exists "$Instance"; then
stop_instance "$Instance"
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFGame.ini "
for MapFile in $(find "$CustomMapsDir" -type f -name '*.kfm' -printf "%f\n")
do
MapName=$(echo "$MapFile" | sed -r 's|.kfm$||g' )
if [[ ! -f "$Config" ]]; then
echo "$Config does not exist!"
elif grep -qP "MapName=$MapName[ $]" "$Config"; then
echo "$MapName is already in $Config."
else
echo "Adding $MapName to $Config."
echo -e "
[$MapName KFMapSummary]
MapName=$MapName
bPlayableInSurvival=True
bPlayableInWeekly=True
bPlayableInVsSurvival=True
bPlayableInEndless=True
bPlayableInObjective=False" >> "$Config"
fi
done
else
echo "Instance $Instance not exitst"
fi
else
for Instance in $(show_instances)
do
map_sync "$Instance"
done
fi
}
function map_rotate_save ()
@ -322,16 +434,17 @@ case $1 in
-h|--help ) show_help; ;;
-n|--new ) if [[ "$EUID" -eq 0 ]]; then new_instance "$2"; else run_as_root $@; fi;;
-d|--delete ) if [[ "$EUID" -eq 0 ]]; then delete_instance "$2"; else run_as_root $@; fi;;
-l|--list ) show_instances; ;;
-s|--status ) show_status "$2"; ;;
-u|--update ) if [[ "$EUID" -eq 0 ]]; then update_kf2 ; else run_as_root $@; fi;;
-v|--validate ) if [[ "$EUID" -eq 0 ]]; then validate ; else run_as_root $@; fi;;
-r|--run ) run $@ ; ;;
--start ) if [[ "$EUID" -eq 0 ]]; then start_instance "$2"; else run_as_root $@; fi;;
--stop ) if [[ "$EUID" -eq 0 ]]; then stop_instance "$2"; else run_as_root $@; fi;;
--restart ) if [[ "$EUID" -eq 0 ]]; then restart_instance "$2"; else run_as_root $@; fi;;
--enable ) if [[ "$EUID" -eq 0 ]]; then enable_instance "$2"; else run_as_root $@; fi;;
--disable ) if [[ "$EUID" -eq 0 ]]; then disable_instance "$2"; else run_as_root $@; fi;;
--map-sync ) map_sync; ;;
--ban-sync ) ban_sync; ;;
--map-sync ) if [[ "$EUID" -eq 0 ]]; then map_sync "$2"; else run_as_root $@; fi ;;
--map-rotate-save ) map_rotate_save; ;;
--map-rotate-load ) map_rotate_load; ;;
* ) echo "Command not recognized: $1"; exit 1 ;;
esac