@ -17,39 +17,31 @@
# You should have received a copy of the GNU General Public License
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# along with this program. If not, see <https://www.gnu.org/licenses/>.
declare -a DiffArray
declare -a WaveArray
declare -A ModeArray
source /etc/steamcmd/steamcmd.conf
source /etc/steamcmd/steamcmd.conf
source /etc/kf2-srv/kf2-srv.conf
source /etc/kf2-srv/kf2-srv.conf
ScriptFullname=$(readlink -e "$0")
ScriptFullname=$(readlink -e "$0")
ScriptName=$(echo "$ScriptFullname" | awk -F '/' '{print $NF;}')
ScriptName=$(echo "$ScriptFullname" | awk -F '/' '{print $NF;}')
ScriptVersion="0.9.0"
AppNum="232130"
# Constants. Don't change.
AppServerNum="232130"
AppClientNum="232090"
StrangeConstUID="17825793"
StrangeConstUID="17825793"
InstallDir="/usr/games/kf2-srv"
ServerBotLogin="srvbot"
ActiveBranch="$InstallDir/activebranch.txt"
AppBin="$InstallDir/Binaries/Win64/KFGameSteamServer.bin.x86_64"
DefaultConfigDir="$InstallDir/KFGame/Config"
CustomMapsDir="$InstallDir/KFGame/Cache"
InstanceConfigDir="/etc/kf2-srv/instances"
InstanceConfigLnk="$DefaultConfigDir/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 ()
function show_help ()
{
{
# echo "TODO: English description"
# echo "TODO: English description"
echo "$ScriptName"
echo "$ScriptName v$ScriptVersion "
echo "Централизование управление серверами Killing Floor 2"
echo "Централизование управление серверами Killing Floor 2"
echo "Usage:"
echo "Usage:"
echo "$ScriptName OPTIONS "
echo "${ ScriptName} OPTIONS stable branch "
echo "${ScriptName}-beta OPTIONS beta branch"
echo ""
echo ""
echo "Mandatory arguments to long options are mandatory for short options too."
echo "Mandatory arguments to long options are mandatory for short options too."
echo " -n, --new INSTANCE создает новый ЭКЗЕМПЛЯР сервера"
echo " -n, --new INSTANCE создает новый ЭКЗЕМПЛЯР сервера"
@ -65,6 +57,7 @@ function show_help ()
echo " необходимости перекачивает их."
echo " необходимости перекачивает их."
echo " -r, --run [OPTIONS] запускает экземпляр сервера с указанными"
echo " -r, --run [OPTIONS] запускает экземпляр сервера с указанными"
echo " ПАРАМЕТРАМИ"
echo " ПАРАМЕТРАМИ"
echo " -c, --chat MSG [INSTANCE] отправляет сообщение в чат указанных экземпляров"
echo " -st, --start [INSTANCE] запускает указанный ЭКЗЕМПЛЯР сервера; если"
echo " -st, --start [INSTANCE] запускает указанный ЭКЗЕМПЛЯР сервера; если"
echo " ЭКЗЕМПЛЯР не указан, запускает все"
echo " ЭКЗЕМПЛЯР не указан, запускает все"
echo " автозапускаемые экземпляры сервера"
echo " автозапускаемые экземпляры сервера"
@ -80,14 +73,14 @@ function show_help ()
echo " -di, --disable [INSTANCE] удаляет указанный ЭКЗЕМПЛЯР сервера из"
echo " -di, --disable [INSTANCE] удаляет указанный ЭКЗЕМПЛЯР сервера из"
echo " автозапуска; если ЭКЗЕМПЛЯР не указан,"
echo " автозапуска; если ЭКЗЕМПЛЯР не указан,"
echo " удаляет все экземпляры сервера из автозапуска"
echo " удаляет все экземпляры сервера из автозапуска"
echo " -m l, --ma p-list отображает список карт из SteamWorkshop"
echo " -w l, --worksho p-list отображает список ресурсов из SteamWorkshop"
echo " -ms , --map-sync синхронизирует списки сторонних карт в "
echo " -wa , --workshop-add [MAP_ID] добавляет р е с у р с из SteamWorkshop по URL или "
echo " WorkshopID"
echo " -wd, --workshop-del [MAP_ID] удаляет р е с у р с SteamWorkshop по URL или WorkshopID"
echo " -ws, --workshop-sync синхронизирует списки сторонних карт в"
echo " конфигурационных файлах с имеющимися файлами"
echo " конфигурационных файлах с имеющимися файлами"
echo " сторонних карт; синхронизирует списки карт из"
echo " сторонних карт; синхронизирует списки карт из"
echo " SteamWorkshop между всеми экземплярами серверов"
echo " SteamWorkshop между всеми экземплярами серверов"
echo " -ma, --map-add [MAP_ID] добавляет карту из SteamWorkshop по URL или"
echo " WorkshopID"
echo " -md, --map-del [MAP_ID] удаляет карту SteamWorkshop по URL или WorkshopID"
echo "-mrs, --map-rotate-save [INSTANCE] сохраняет текущий порядок карт для"
echo "-mrs, --map-rotate-save [INSTANCE] сохраняет текущий порядок карт для"
echo " указанного ЭКЗЕМПЛЯРА сервера; если ЭКЗЕМПЛЯР"
echo " указанного ЭКЗЕМПЛЯРА сервера; если ЭКЗЕМПЛЯР"
echo " не указан, сохраняет порядок для всех ЭКЗЕМПЛЯРОВ"
echo " не указан, сохраняет порядок для всех ЭКЗЕМПЛЯРОВ"
@ -104,14 +97,22 @@ function show_help ()
echo " -bd, --ban-del [BAN_ID] удаляет пользователя из списка заблокированных"
echo " -bd, --ban-del [BAN_ID] удаляет пользователя из списка заблокированных"
echo " допустимо использовать ID3, SteamID, а также"
echo " допустимо использовать ID3, SteamID, а также"
echo " ссылку на профиль пользователя"
echo " ссылку на профиль пользователя"
echo " -fp, --fix-permissions [INSTANCE] поправить права на ini файлы"
echo " -as, --admin-sync синхронизировать всех админов (заглушка)"
echo " -pg, --password-game PASSWORD [INSTANCE] установить пароль игры для экземпляров"
echo " -pa, --password-admin PASSWORD [INSTANCE] установить пароль админа для экземпляров"
echo " -h, --help display this help and exit"
echo " -h, --help display this help and exit"
}
}
# Use this function with non-root user only!!!
# Use this function with non-root user only!!!
function run_as_root () # $*: Args
function run_as_root () # $*: Args
{
{
if [[ -n "$BetaPostfix" ]]; then
BetaPostfix="beta"
fi
if [[ -n $(groups "$USER" | grep -Fo 'wheel') ]]; then
if [[ -n $(groups "$USER" | grep -Fo 'wheel') ]]; then
sudo "$ScriptFullname" $*
sudo "$ScriptFullname" $BetaPostfix $*
else
else
echo "You must be root or sudo-user to run this command."
echo "You must be root or sudo-user to run this command."
return 1
return 1
@ -123,7 +124,7 @@ function service_name () # $*: Instance[s]
local Services=""
local Services=""
for Instance in $*
for Instance in $*
do
do
Services+=" kf2-srv@$Instance.service"
Services+=" kf2-srv$BetaPostfix @$Instance.service"
done
done
echo "$Services"
echo "$Services"
}
}
@ -156,7 +157,7 @@ function instance_exists () # $1: Instance
function server_exists ()
function server_exists ()
{
{
if [[ -n $(ls "$InstallDir") ]]; then
if [[ -x "$AppBin" ]]; then
return 0
return 0
else
else
return 1
return 1
@ -165,8 +166,22 @@ function server_exists ()
function updates_aviable ()
function updates_aviable ()
{
{
# TODO: implementation
return 0 # steamcmd does not show updates even if they are :(
# TODO: check updates correctly (but how?)
if [[ -n "$BetaPostfix" ]]; then
local BetaArg="-beta preview"
fi
if steamcmd +login anonymous \
+force_install_dir $InstallDir \
+app_info_update 1 \
+app_status $AppServerNum $BetaArg \
+quit | \
grep 'install state:' | \
grep -qiF 'Update Required'; then
return 0
return 0
else
return 1
fi
}
}
function new_instance () # $*: InstanceName[s]
function new_instance () # $*: InstanceName[s]
@ -186,9 +201,9 @@ function new_instance () # $*: InstanceName[s]
for Instance in $(show_instances)
for Instance in $(show_instances)
do
do
local Config="$InstanceConfigDir/$Instance/main.conf"
local Config="$InstanceConfigDir/$Instance/main.conf"
local GamePort=$(grep -Po '"-port=([0-9]+)' "$Config" | grep -Po '[0-9]+$ ')
local GamePort=$(multini --get "$Config" '' 'PortGame ')
local WebAdminPort=$(grep -Po '"-webadminport=([0-9]+)' "$Config" | grep -Po '[0-9]+$ ')
local WebAdminPort=$(multini --get "$Config" '' 'PortWeb ')
local QueryPort=$(grep -Po '"-queryport=([0-9]+)' "$Config" | grep -Po '[0-9]+$ ')
local QueryPort=$(multini --get "$Config" '' 'PortQuery ')
if [[ "$GamePort" -gt "$MaxGamePort" ]]; then MaxGamePort="$GamePort"; fi
if [[ "$GamePort" -gt "$MaxGamePort" ]]; then MaxGamePort="$GamePort"; fi
if [[ "$QueryPort" -gt "$MaxQueryPort" ]]; then MaxQueryPort="$QueryPort"; fi
if [[ "$QueryPort" -gt "$MaxQueryPort" ]]; then MaxQueryPort="$QueryPort"; fi
if [[ "$WebAdminPort" -gt "$MaxWebAdminPort" ]]; then MaxWebAdminPort="$WebAdminPort"; fi
if [[ "$WebAdminPort" -gt "$MaxWebAdminPort" ]]; then MaxWebAdminPort="$WebAdminPort"; fi
@ -202,28 +217,34 @@ function new_instance () # $*: InstanceName[s]
fi
fi
local InstanceDir="$InstanceConfigDir/$Instance"
local InstanceDir="$InstanceConfigDir/$Instance"
install -d -g "$SteamUser" -o "$SteamUser" -m 755 "$InstanceDir"
install -d -g "$SteamUser" -o "$SteamUser" -m 755 "$InstanceDir/LinuxServer"
cp -a "$MainConfigTemplate" "$InstanceDir/main.conf "
local DirMode="-d -g $SteamUser -o $SteamUser -m 775 "
cp -a "$DefaultConfigDir/KFAI.ini" "$InstanceDir "
local FileMode=" -g $SteamUser -o $SteamUser -m 664 "
cp -a "$DefaultConfigDir/KFWeb.ini" "$InstanceDir"
cp -a "$DefaultConfigDir/LinuxServer-KFEngine.ini" "$InstanceDir"
install $DirMode "$InstanceDir"
cp -a "$DefaultConfigDir/LinuxServer-KFGame.ini" "$InstanceDi r"
install $DirMode "$InstanceDir/LinuxServe r"
cp -a "$DefaultConfigDir/LinuxServer-KFInput.ini" "$InstanceDir"
cp -a "$DefaultConfigDir/LinuxServer-KFSystemSettings.ini" "$InstanceDir"
install $FileMode "$MainConfigTemplate" "$InstanceDir/main.conf "
cp -a "$DefaultConfigDir/LinuxServer/LinuxServerEngine.ini" "$InstanceDir/LinuxServe r"
install $FileMode "$DefaultConfigDir/KFAI.ini" "$InstanceDi r"
cp -a "$DefaultConfigDir/LinuxServer/LinuxServerGame.ini" "$InstanceDir/LinuxServe r"
install $FileMode "$DefaultConfigDir/KFWeb.ini" "$InstanceDi r"
cp -a "$DefaultConfigDir/LinuxServer/LinuxServerInput.ini" "$InstanceDir/LinuxServe r"
install $FileMode "$DefaultConfigDir/KFWebAdmin.ini" "$InstanceDi r"
cp -a "$DefaultConfigDir/LinuxServer/LinuxServerSystemSettings.ini" "$InstanceDir/LinuxServe r"
install $FileMode "$DefaultConfigDir/KFMultiAdmin.ini" "$InstanceDi r"
install $FileMode "$DefaultConfigDir/LinuxServer-KFEngine.ini" "$InstanceDir"
install $FileMode "$DefaultConfigDir/LinuxServer-KFGame.ini" "$InstanceDir"
install $FileMode "$DefaultConfigDir/LinuxServer-KFInput.ini" "$InstanceDir"
install $FileMode "$DefaultConfigDir/LinuxServer-KFSystemSettings.ini" "$InstanceDir"
install $FileMode "$DefaultConfigDir/LinuxServer/LinuxServerEngine.ini" "$InstanceDir/LinuxServer"
install $FileMode "$DefaultConfigDir/LinuxServer/LinuxServerGame.ini" "$InstanceDir/LinuxServer"
install $FileMode "$DefaultConfigDir/LinuxServer/LinuxServerInput.ini" "$InstanceDir/LinuxServer"
install $FileMode "$DefaultConfigDir/LinuxServer/LinuxServerSystemSettings.ini" "$InstanceDir/LinuxServer"
((MaxGamePort++)); ((MaxQueryPort++)); ((MaxWebAdminPort++))
((MaxGamePort++)); ((MaxQueryPort++)); ((MaxWebAdminPort++))
sed -i -r --follow-symlinks "s/-port=[0-9]+/-port=$MaxGamePort/g" "$InstanceDir/main.conf "
multini -s "$InstanceDir/main.conf" '' 'PortGame' "$MaxGamePort "
sed -i -r --follow-symlinks "s/-queryport=[0-9]+/-queryport=$MaxQueryPort/g" "$InstanceDir/main.conf "
multini -s "$InstanceDir/main.conf" '' 'PortQuery' "$MaxQueryPort "
sed -i -r --follow-symlinks "s/-webadminport=[0-9]+/-webadminport=$MaxWebAdminPort/g" "$InstanceDir/main.conf "
multini -s "$InstanceDir/main.conf" '' 'PortWeb' "$MaxWebAdminPort "
echo "Instance $Instance created. See /etc/$ScriptName/instances/$Instance for edit configuration"
echo "Instance $Instance created. See /etc/$ScriptName/instances$BetaPostfix /$Instance for edit configuration"
done
done
}
}
@ -270,31 +291,37 @@ function show_status_implementation_body () # $*: [InstanceName[s]]
local IsRuning="stopped"
local IsRuning="stopped"
fi
fi
local Description=$(grep -P 'Description=' "$InstanceConfigDir/$Instance/main.conf" | sed -r 's/(Description=|")//g' )
local Comment=$( multini -g "$InstanceConfigDir/$Instance/main.conf" '' "Comment" )
local GamePort=$(grep -Po '"-port=([0-9]+)' "$InstanceConfigDir/$Instance/main.conf" | grep -Po '[0-9]+$' )
local GamePort=$( multini -g "$InstanceConfigDir/$Instance/main.conf" '' "PortGame" )
local WebAdminPort=$(grep -Po '"-webadminport=([0-9]+)' "$InstanceConfigDir/$Instance/main.conf" | grep -Po '[0-9]+$' )
local WebAdminPort=$( multini -g "$InstanceConfigDir/$Instance/main.conf" '' "PortWeb" )
local QueryPort=$(grep -Po '"-queryport=([0-9]+)' "$InstanceConfigDir/$Instance/main.conf" | grep -Po '[0-9]+$' )
local QueryPort=$( multini -g "$InstanceConfigDir/$Instance/main.conf" '' "PortQuery" )
local GameType=$(grep -Po 'Game=([^\?]+)' "$InstanceConfigDir/$Instance/main.conf" | sed -r 's/Game=([^?]+)/\1/g' )
local GameType=$( multini -g "$InstanceConfigDir/$Instance/main.conf" '' "Game" )
local GameLength=$(grep -Po 'GameLength=([0-9]+)' "$InstanceConfigDir/$Instance/main.conf" | grep -Po '[0-9]+$' )
local GameLength=$( multini -g "$InstanceConfigDir/$Instance/main.conf" '' "Length" )
local GameDifficulty=$(grep -Po 'Difficulty=([0-9]+)' "$InstanceConfigDir/$Instance/main.conf" | grep -Po '[0-9]+$' )
local GameDifficulty=$( multini -g "$InstanceConfigDir/$Instance/main.conf" '' "Difficulty" )
local Map=$( multini -g "$InstanceConfigDir/$Instance/main.conf" '' "Map")
local Args=$( multini -g "$InstanceConfigDir/$Instance/main.conf" '' "Args")
local DisplayGameType=${ModeArray[$GameType]}
local DisplayGameType=${ModeArray[$GameType]}
local DisplayGameLength=${WaveArray[$GameLength]}
local DisplayGameLength=${WaveArray[$GameLength]}
local DisplayDifficulty=${DiffArray[$GameDifficulty]}
local DisplayDifficulty=${DiffArray[$GameDifficulty]}
if [[ "$DisplayGameType" == 'Weekly' || \
if [[ -z "$DisplayGameType" ]]; then
"$ DisplayGameType" == 'Endless' || \
DisplayGameType="$GameType"
"$DisplayGameType" == 'Versus' || \
fi
"$DisplayGameType" == 'Objective' ]]; then
if [[ "$GameType" == 'KFGameContent.KFGameInfo_WeeklySurvival' || \
"$GameType" == 'KFGameContent.KFGameInfo_Endless' || \
"$GameType" == 'KFGameContent.KFGameInfo_VersusSurvival' || \
"$GameType" == 'KFGameContent.KFGameInfo_Objective' ]]; then
DisplayGameLength='-'
DisplayGameLength='-'
fi
fi
if [[ "$Display GameType" == 'Weekly ' || \
if [[ "$GameType" == 'KFGameContent.KFGameInfo_WeeklySurvival ' || \
"$DisplayGameType" == 'Versus ' ]]; then
"$DisplayGameType" == 'KFGameContent.KFGameInfo_VersusSurvival ' ]]; then
DisplayDifficulty='-'
DisplayDifficulty='-'
fi
fi
echo -e "$Instance:$IsEnabled:$IsRuning:$GamePort:$QueryPort:$WebAdminPort:$DisplayGameType:$DisplayGameLength:$DisplayDifficulty:$Description "
echo -e "$Instance:$IsEnabled:$IsRuning:$GamePort:$QueryPort:$WebAdminPort:$DisplayGameType:$DisplayGameLength:$DisplayDifficulty:$Args:$Comment "
done
done
}
}
@ -312,7 +339,7 @@ function show_status_implementation_full () # $*: [InstanceName[s]]
done
done
fi
fi
echo -e "INSTANCE:AUTORUN:STATE:P_GAME:P_QUERY:P_WEB:TYPE:LEN:DIFF:DESCRIPTION "
echo -e "INSTANCE:AUTORUN:STATE:P_GAME:P_QUERY:P_WEB:TYPE:LEN:DIFF:ARGS:COMMENT "
show_status_implementation_body "$InstanceList" | sort -t : -k 4
show_status_implementation_body "$InstanceList" | sort -t : -k 4
}
}
@ -323,27 +350,26 @@ function show_status () # $*: [InstanceName[s]]
function validate ()
function validate ()
{
{
if [[ -n "$BranchName " ]]; then
if [[ -n "$BetaPostfix " ]]; then
local BetaArg="-beta $BranchName "
local BetaArg="-beta preview "
fi
fi
stop_instance
stop_instance
steamcmd +login $SteamLogin +force_install_dir $InstallDir +app_update $AppNum $BetaArg validate +exit
steamcmd +login $SteamLogin +force_install_dir $InstallDir +app_update $AppServer Num $BetaArg validate +exit
echo "$BranchName" > "$ActiveBranch"
fix_steamclient_so
start_instance
start_instance
}
}
function link _default_instance ()
function make _default_instance () # $1: Dir
{
{
local Instance=" default"
local InstanceDir="$InstanceConfigDir/ default"
if instance_exists "$Instance"; then
echo "Instance $Instance already exists - skip "
install -d -g "$SteamUser" -o "$SteamUser" -m 775 "$InstanceDir "
else
install -d -g "$SteamUser" -o "$SteamUser" -m 775 "$InstanceDir/LinuxServer"
local InstanceDir="$InstanceConfigDir/$Instance "
install -g "$SteamUser" -o "$SteamUser" -m 664 "$MainConfigTemplate" "$InstanceDir/main.conf "
install -d -g "$SteamUser" -o "$SteamUser" -m 755 "$InstanceDir"
install -d -g "$SteamUser" -o "$SteamUser" -m 755 "$InstanceDir/LinuxServer"
cp -a "$MainConfigTemplate" "$InstanceDir/main.conf"
ln -s "$DefaultConfigDir/KFAI.ini" "$InstanceDir/KFAI.ini"
ln -s "$DefaultConfigDir/KFAI.ini" "$InstanceDir/KFAI.ini"
ln -s "$DefaultConfigDir/KFWeb.ini" "$InstanceDir/KFWeb.ini"
ln -s "$DefaultConfigDir/KFWeb.ini" "$InstanceDir/KFWeb.ini"
ln -s "$DefaultConfigDir/KFWebAdmin.ini" "$InstanceDir/KFWebAdmin.ini"
ln -s "$DefaultConfigDir/KFMultiAdmin.ini" "$InstanceDir/KFMultiAdmin.ini"
ln -s "$DefaultConfigDir/LinuxServer-KFEngine.ini" "$InstanceDir/LinuxServer-KFEngine.ini"
ln -s "$DefaultConfigDir/LinuxServer-KFEngine.ini" "$InstanceDir/LinuxServer-KFEngine.ini"
ln -s "$DefaultConfigDir/LinuxServer-KFGame.ini" "$InstanceDir/LinuxServer-KFGame.ini"
ln -s "$DefaultConfigDir/LinuxServer-KFGame.ini" "$InstanceDir/LinuxServer-KFGame.ini"
ln -s "$DefaultConfigDir/LinuxServer-KFInput.ini" "$InstanceDir/LinuxServer-KFInput.ini"
ln -s "$DefaultConfigDir/LinuxServer-KFInput.ini" "$InstanceDir/LinuxServer-KFInput.ini"
@ -352,9 +378,38 @@ function link_default_instance ()
ln -s "$DefaultConfigDir/LinuxServer/LinuxServerGame.ini" "$InstanceDir/LinuxServer/LinuxServerGame.ini"
ln -s "$DefaultConfigDir/LinuxServer/LinuxServerGame.ini" "$InstanceDir/LinuxServer/LinuxServerGame.ini"
ln -s "$DefaultConfigDir/LinuxServer/LinuxServerInput.ini" "$InstanceDir/LinuxServer/LinuxServerInput.ini"
ln -s "$DefaultConfigDir/LinuxServer/LinuxServerInput.ini" "$InstanceDir/LinuxServer/LinuxServerInput.ini"
ln -s "$DefaultConfigDir/LinuxServer/LinuxServerSystemSettings.ini" "$InstanceDir/LinuxServer/LinuxServerSystemSettings.ini"
ln -s "$DefaultConfigDir/LinuxServer/LinuxServerSystemSettings.ini" "$InstanceDir/LinuxServer/LinuxServerSystemSettings.ini"
fix_ini_permissions "$InstanceDir"
fix_ini_eol "$InstanceDir"
}
function fix_permissions () # $*: Instance[s]
{
local InstanceList="$*"
if [[ -z "$InstanceList" ]] ; then
fix_ini_permissions "$InstanceConfigDir"
else
for Instance in $InstanceList
do
fix_ini_permissions "$InstanceConfigDir/$Instance"
done
fi
fi
}
}
function fix_ini_permissions () # $1: Dir
{
find "$1" \( -type l -o -type f \) -name '*.ini' | \
xargs --max-procs=$(nproc) -I {} \
sh -c "chmod 664 {}; chown $SteamUser:$SteamUser {}"
}
function fix_ini_eol () # $1: Dir
{
find "$1" \( -type l -o -type f \) -name '*.ini' | \
xargs --max-procs=$(nproc) -I {} \
sh -c "dos2unix -F {}"
}
function fix_steamclient_so ()
function fix_steamclient_so ()
{
{
rm -f "$InstallDir/linux64/steamclient.so"
rm -f "$InstallDir/linux64/steamclient.so"
@ -365,18 +420,49 @@ function fix_steamclient_so ()
ln -s "/usr/share/steamcmd/linux64/steamclient.so" "$InstallDir/Binaries/Win64/lib64/steamclient.so"
ln -s "/usr/share/steamcmd/linux64/steamclient.so" "$InstallDir/Binaries/Win64/lib64/steamclient.so"
}
}
function upd ate_kf2 ()
function cre ate_map_dirs ()
{
{
if [[ -n "$BranchName" ]]; then
# space saving
local BetaArg="-beta $BranchName "
local InstallDirOrig="/usr/games/kf2-srv "
local InstallDirBeta="/usr/games/kf2-srv-beta"
local DownloadDirOrig="$InstallDirOrig/Binaries/Win64/steamapps/workshop/content/$AppClientNum"
local CacheDirOrig="$InstallDirOrig/KFGame/Cache"
local DownloadDirBeta="$InstallDirBeta/Binaries/Win64/steamapps/workshop/content/$AppClientNum"
local CacheDirBeta="$InstallDirBeta/KFGame/Cache"
if [[ -z "$BetaPostfix" ]]; then # Orig
sudo -u "$SteamUser" install -d -m 775 "$DownloadDirOrig"
if [[ -d "$CacheDirBeta" ]]; then
ln -s "$CacheDirBeta" "$CacheDirOrig"
rm -rf "$DownloadDirOrig"
ln -s "$DownloadDirBeta" "$DownloadDirOrig"
else
sudo -u "$SteamUser" install -d -m 775 "$CacheDirOrig"
fi
fi
if ! server_exists; then # First install
else # Beta
echo "$BranchName" > "$ActiveBranch "
sudo -u "$SteamUser" install -d -m 775 "$DownloadDirBeta "
if ! steamcmd +login $SteamLogin +force_install_dir $InstallDir +app_update $AppNum $BetaArg validate +exit ; then
if [[ -d "$CacheDirOrig" ]] ; then
ln -s "$CacheDirOrig" "$CacheDirBeta"
rm -rf "$DownloadDirBeta"
ln -s "$DownloadDirOrig" "$DownloadDirBeta"
else
sudo -u "$SteamUser" install -d -m 775 "$CacheDirBeta"
fi
fi
}
function first_install ()
{
# TODO: Replace killall
# kill -INT $PID?
# sudo is stopping me from knowing pid
if ! steamcmd +login $SteamLogin +force_install_dir $InstallDir +app_update $AppServerNum $BetaArg validate +exit; then
echo "Errors during installation - exit"
echo "Errors during installation - exit"
exit 1
exit 1
fi
fi
sudo -u "$SteamUser" $AppBin &
echo "Creating base ini files"
sudo -u "$SteamUser" $AppBin &> /dev/null &
while true
while true
do
do
if [[ -e "$DefaultConfigDir/KFAI.ini" ]] &&
if [[ -e "$DefaultConfigDir/KFAI.ini" ]] &&
@ -393,22 +479,85 @@ function update_kf2 ()
fi
fi
sleep 2
sleep 2
done
done
killall -KILL KFGameSteamServer.bin.x86_64
killall -KILL KFGameSteamServer.bin.x86_64; sleep 1
#$InstallDir/Binaries/Win64/steamapps/workshop/content/232090/1078911795/BrewedPC/Maps/KF-HorzineArena-B2-v6.kfm
echo "Setting up WebAdmin"
#$InstallDir/KFGame/Cache/1078911795/0/BrewedPC/Maps/KF-HorzineArena-B2-v6.kfm
multini -s "$DefaultConfigDir/KFWeb.ini" "IpDrv.WebServer" "bEnabled" "true"
install -d -g "$SteamUser" -o "$SteamUser" -m 755 "$CustomMapsDir"
sudo -u "$SteamUser" $AppBin &> /dev/null &
while true
do
if [[ -e "$DefaultConfigDir/KFWebAdmin.ini" ]]; then
break
fi
sleep 2
done
killall -KILL KFGameSteamServer.bin.x86_64; sleep 1
multini -s "$DefaultConfigDir/KFWebAdmin.ini" "WebAdmin.WebAdmin" "AuthenticationClass" "WebAdmin.MultiWebAdminAuth"
multini -s "$DefaultConfigDir/KFWebAdmin.ini" "WebAdmin.WebAdmin" "bHttpAuth" "True"
echo "Wait while WebAdmin up"
sudo -u "$SteamUser" $AppBin &> /dev/null &
while ! curl -s -o "/dev/null" -u "Admin:Admin" "localhost:8080"
do
sleep 2
done
echo "Setting up server bot"
while ! curl -s -o "/dev/null" \
-u "Admin:Admin" \
"localhost:8080/ServerAdmin/multiadmin" \
--request POST \
--data adminid="$ServerBotLogin" \
--data action="create"
do sleep 2; done
while ! multini -gq \
"$DefaultConfigDir/KFMultiAdmin.ini" \
"$ServerBotLogin MultiAdminData" \
"Password"
do sleep 2; done
while ! curl -s -o "/dev/null" \
-u "Admin:Admin" \
"localhost:8080/ServerAdmin/multiadmin" \
--request POST \
--data adminid="$ServerBotLogin" \
--data displayname="ServerBot" \
--data enabled=1 \
--data password1="$ServerBotPassword" \
--data password2="$ServerBotPassword" \
--data order="DenyAllow" \
--data deny= \
--data allow= \
--data action="save"
do sleep 2; done
while [[ -z $(multini -g \
"$DefaultConfigDir/KFMultiAdmin.ini" \
"$ServerBotLogin MultiAdminData" \
"Password") ]]
do sleep 2; done
killall -KILL KFGameSteamServer.bin.x86_64; sleep 1
create_map_dirs
fix_steamclient_so
fix_steamclient_so
ln -s "$InstanceConfigDir" "$InstanceConfigLnk"
ln -s "$InstanceConfigDir" "$InstanceConfigLnk"
link _default_instance
make _default_instance
echo "KF2 succesfully installed"
echo "KF2 succesfully installed"
elif updates_aviable; then # Update
}
if [[ "$BranchName" == $(cat "$ActiveBranch") ]]; then
function update_kf2 ()
{
if [[ -n "$BetaPostfix" ]]; then
local BetaArg="-beta preview"
fi
if ! server_exists; then
first_install
elif updates_aviable; then
stop_instance
stop_instance
steamcmd +login $SteamLogin +force_install_dir $InstallDir +app_update $AppNum $BetaArg +exit
steamcmd +login $SteamLogin +force_install_dir $InstallDir +app_update $AppServer Num $BetaArg +exit
start_instance
start_instance
else
else
vali date
echo "Server is up to date"
fi
fi
fi
}
}
@ -548,34 +697,61 @@ function run ()
fi
fi
}
}
function map_list_ext () # $1: MaplistFile
function name_by_workshopID () # $1: WorkshopID
{
local WorkshopID="$1"
local Cache="$CacheDir/$WorkshopID"
local Result=""
if [[ -d "$Cache" ]]; then
Result=$(find "$Cache" -type f -name '*.kfm' -printf '%f\n' | head -n 1)
if [[ -z "$Result" ]]; then
Result=$(find "$Cache" -type f -name '*.u' -printf '%f\n' | head -n 1)
fi
fi
echo "$Result"
}
function workshop_list_body () # $1: WorkshopListFile
{
{
local Num=1
echo "NUM WORKSHOP_ID WORKSHOP_URL"
while read WorkshopID
while read WorkshopID
do
do
local Cache="$CacheDir/$WorkshopID"
local Downl="$DownloadDir/$WorkshopID"
local Url="https://steamcommunity.com/sharedfiles/filedetails/?id=$WorkshopID"
local Url="https://steamcommunity.com/sharedfiles/filedetails/?id=$WorkshopID"
echo "$Num $WorkshopID $Url"
local WsName=$(name_by_workshopID "$WorkshopID")
((Num++))
if [[ -n "$WsName" ]]; then
local WsSize=$(du -sch "$Downl" "$Cache" | tail -n 1 | grep -Po '^[^\s]+')
else
local WsSize="-"; WsName="-"
fi
echo "$WorkshopID $WsName $WsSize $Url"
done < "$1"
done < "$1"
}
}
function ma p_list () # $1: [--human-readab le]
function worksho p_list_full () # $1: WorkshoplistFi le
{
{
# TODO: Show map names (sizes?)
echo "WORKSHOP_ID NAME SIZE WORKSHOP_URL"
local MapList=$(mktemp)
workshop_list_body "$1" | sort -k 2
}
function workshop_list () # $1: [--human-readable]
{
# TODO: Multiple *.kfm/*u in folder
local WsList=$(mktemp)
for Instance in $(show_instances)
for Instance in $(show_instances)
do
do
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFEngine.ini"
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFEngine.ini"
grep -P 'ServerSubscribedWorkshopItems=' "$Config" | sed -r 's/.+=([0-9]+)$/\1/' >> "$MapList"
if multini -gq "$Config" "OnlineSubsystemSteamworks.KFWorkshopSteamworks" "ServerSubscribedWorkshopItems"; then
done
multini -g "$Config" "OnlineSubsystemSteamworks.KFWorkshopSteamworks" "ServerSubscribedWorkshopItems" >> "$WsList"
sort -u "$MapList" -o "$MapList"
if [[ -n "$1" ]]; then
map_list_ext "$MapList" | column -t
else
cat "$MapList"
fi
fi
rm -f "$MapList"
done
sort -u "$WsList" -o "$WsList"
if [[ -n "$1" ]]; then
workshop_list_full "$WsList" | column -t
else
cat "$WsList"
fi
rm -f "$WsList"
}
}
function any_to_workshopID () # $1: WorkshopID/URL
function any_to_workshopID () # $1: WorkshopID/URL
@ -588,83 +764,85 @@ function any_to_workshopID () # $1: WorkshopID/URL
echo "$WorkshopID"
echo "$WorkshopID"
}
}
function ma p_add () # $*: WorkshopID[s]
function worksho p_add () # $*: WorkshopID[s]
{
{
for Instance in $(show_instances)
for Instance in $(show_instances)
do
do
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFEngine.ini"
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFEngine.ini"
if ! grep -qF '[ OnlineSubsystemSteamworks.KFWorkshop Steamw orks]' "$Config"; then
multini -ar "$Config" "IpDrv.TcpNetDriver" "DownloadManagers" " OnlineSubsystemSteamworks.SteamW orkshopDownload"
echo -e '
[OnlineSubsystemSteamworks.KFWorkshopSteamworks]' >> "$Config"
fi
if ! grep -qF 'DownloadManagers=OnlineSubsystemSteamworks.SteamWorkshopDownload' "$Config"; then
sed -i --follow-symlinks -r '0,/DownloadManagers=/ s/^(DownloadManagers=.+)$/DownloadManagers=OnlineSubsystemSteamworks.SteamWorkshopDownload
\1/' "$Config"
fi
for Map in $*
for Map in $*
do
do
local WorkshopID=$(any_to_workshopID "$Map")
local WorkshopID=$(any_to_workshopID "$Map")
local MapStr= "ServerSubscribedWorkshopItems= $WorkshopID"
if ! multini -gq "$Config" "OnlineSubsystemSteamworks.KFWorkshopSteamworks" "ServerSubscribedWorkshopItems" " $WorkshopID"; then
if ! grep -qF "$MapStr" "$Config"; then
echo "Add workshop $WorkshopID to $Instance"
echo "Add map $WorkshopID to $Instance "
multini -ar "$Config" "OnlineSubsystemSteamworks.KFWorkshopSteamworks" "ServerSubscribedWorkshopItems" "$WorkshopID "
sed -i --follow-symlinks "/^\[OnlineSubsystemSteamworks\.KFWorkshopSteamworks\]/a $MapStr" "$Config"
fi
fi
done
done
done
done
}
}
function ma p_del () # $*: WorkshopID[s]
function worksho p_del () # $*: WorkshopID[s]
{
{
# TODO: Remove lines from LinuxServer-KFGame.ini, clear cache
for Map in $*
for Map in $*
do
do
local WorkshopID=$(any_to_workshopID "$Map")
local WorkshopID=$(any_to_workshopID "$Map")
local WsName=$(name_by_workshopID "$WorkshopID")
local Cache="$CacheDir/$WorkshopID"
local Downl="$DownloadDir/$WorkshopID"
echo -e "Clear cache:
$Cache
$Downl"
rm -rf "$Cache" "$Downl"
for Instance in $(show_instances)
for Instance in $(show_instances)
do
do
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFEngine.ini"
local ConfigEngine ="$InstanceConfigDir/$Instance/LinuxServer-KFEngine.ini"
local MapStr= "ServerSubscribedWorkshopItems= $WorkshopID"
multini -d "$ConfigEngine" "OnlineSubsystemSteamworks.KFWorkshopSteamworks" "ServerSubscribedWorkshopItems" " $WorkshopID"
if grep -qF "$MapStr" "$Config" ; then
if echo "$WsName" | grep -qP '\.kfm$' ; then
echo "Remove map $WorkshopID from $Instance"
echo "Remove map $WorkshopID ($WsName) from $Instance"
sed -i --follow-symlinks "/$MapStr/d" "$Config"
local WsNameShort=$(echo "$WsName" | sed 's/\.kfm$//')
local ConfigGame="$InstanceConfigDir/$Instance/LinuxServer-KFGame.ini"
multini -d "$ConfigGame" "$WsNameShort KFMapSummary"
fi
fi
done
done
done
done
}
}
function ma p_sync ()
function worksho p_sync ()
{
{
#local InstanceList="$*"
workshop_add $(workshop_list)
#if [[ -z "$InstanceList" ]] ; then
# InstanceList=$(show_instances)
#fi
map_add $(map_list)
# TODO: Make it faster
for Instance in $(show_instances)
for Instance in $(show_instances)
do
do
if instance_exists "$Instance"; then
local Service=$(service_name "$Instance")
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFGame.ini"
if ! instance_exists "$Instance"; then
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"
echo "Instance $Instance not exitst"
elif systemctl -q is-active $Service ; then
echo "Instance $Instance is running - skip."
else
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFGame.ini"
for MapFile in $(find -L "$CacheDir" -type f -name '*.kfm' -printf "%f\n")
do
MapName=$(echo "$MapFile" | sed -r 's|.kfm$||')
if ! multini -gq "$Config" "$MapName KFMapSummary"; then
echo "Adding $MapName to $Instance."
multini -s "$Config" "$MapName KFMapSummary" "MapName" "$MapName"
multini -s "$Config" "$MapName KFMapSummary" "bPlayableInSurvival" "True"
multini -s "$Config" "$MapName KFMapSummary" "bPlayableInWeekly" "True"
multini -s "$Config" "$MapName KFMapSummary" "bPlayableInVsSurvival" "True"
multini -s "$Config" "$MapName KFMapSummary" "bPlayableInEndless" "True"
multini -s "$Config" "$MapName KFMapSummary" "bPlayableInObjective" "False"
fi
done
for MutFile in $(find -L "$CacheDir" -type f -name '*.u' -printf "%f\n")
do
MutName=$(echo "$MutFile" | sed -r 's|.u$||')
if ! multini -gq "$Config" "$MutName KFMutatorSummary"; then
echo "Adding $MutName to $Instance."
multini -s "$Config" "$MutName KFMutatorSummary" "ClassName" ""
fi
done
fi
fi
done
done
}
}
@ -689,6 +867,15 @@ function map_rotate_save () # $*: Instance[s]
done
done
}
}
function map_rotate_to_webstring () # $1: MapRotate
{
local RN='%0D%0A'
echo "$1" | \
sed -r 's/^\(Maps=\("//' | \
sed -r 's/"\)\)$//' | \
sed "s/\",\"/${RN}/g"
}
function map_rotate_load () # $*: Instance[s]
function map_rotate_load () # $*: Instance[s]
{
{
local InstanceList="$*"
local InstanceList="$*"
@ -698,17 +885,42 @@ function map_rotate_load () # $*: Instance[s]
for Instance in $InstanceList
for Instance in $InstanceList
do
do
if instance_exists "$Instance"; then
local Service=$(service_name "$Instance")
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFGame.ini"
local MapRotate="$InstanceConfigDir/$Instance/MapRotate.ini"
local MapRotate="$InstanceConfigDir/$Instance/MapRotate.ini"
if [[ -e "$MapRotate" ]] ; then
if ! instance_exists "$Instance" ; then
sed -i --follow-symlinks -r "/(ActiveMapCycle=|GameMapCycles=)/d" "$Config "
echo "Instance $Instance not exists "
sed -i --follow-symlinks "/\[KFGame\.KFGameInfo\]/ r $MapRotate" "$Config"
elif ! [[ -e " $MapRotate" ]]; then
else
echo "$MapRotate not found - skip"
echo "$MapRotate not found - skip"
elif systemctl -q is-active $Service ; then
# TODO: Delete other cycles
# Example: maplistidx=1&mapcycle=KF-Airship%0D%0A&delete=doit
local ActiveCycleIndex=$(multini -g "$MapRotate" '' 'ActiveMapCycle')
local ActiveCycleWeb=''
local Index=0
while read MapCycle
do
local MapCycleWeb=$(map_rotate_to_webstring "$MapCycle")
admin_curl "$Instance" "ServerAdmin/settings/maplist" \
--request POST \
--data maplistidx="$Index" \
--data mapcycle="$MapCycleWeb" \
--data action="save"
if [[ "$Index" -eq "$ActiveCycleIndex" ]]; then
ActiveCycleWeb="$MapCycleWeb"
fi
((Index++))
done < <(multini -g "$MapRotate" '' 'GameMapCycles')
if [[ -n "$ActiveCycleWeb" ]]; then
admin_curl "$Instance" "ServerAdmin/settings/maplist" \
--request POST \
--data maplistidx="$ActiveCycleIndex" \
--data mapcycle="$ActiveCycleWeb" \
--data activate="activate"
fi
fi
else
else
echo "Instance $Instance not exitst "
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFGame.ini "
sed -i --follow-symlinks -r "/(ActiveMapCycle=|GameMapCycles=)/d" "$Config"
sed -i --follow-symlinks "/\[KFGame\.KFGameInfo\]/ r $MapRotate" "$Config"
fi
fi
done
done
}
}
@ -736,12 +948,16 @@ function steamID64_to_steamID3 () # $1: ID4
function ban_list_ext () # $1: BanlistFile
function ban_list_ext () # $1: BanlistFile
{
{
local Num=1
local Num=1
echo "NUM STEAM_ID3 STEAM_ID64 PROFILE_URL "
echo "NUM STEAM_ID3 STEAM_ID64 URL_CONST URL_EFFECTIVE "
while read ID3
while read ID3
do
do
local ID64=$(steamID3_to_steamID64 "$ID3")
local ID64=$(steamID3_to_steamID64 "$ID3")
local Url=$(curl "https://steamcommunity.com/profiles/$ID64" -s -L -I -o /dev/null -w '%{url_effective}')
local UrlConst= "https://steamcommunity.com/profiles/$ID64"
echo "$Num $ID3 $ID64 $Url"
local UrlEffective=$(curl "$UrlConst" -s -L -I -o /dev/null -w '%{url_effective}')
if [[ "$UrlConst" == "$UrlEffective" ]]; then
UrlEffective="-"
fi
echo "$Num $ID3 $ID64 $UrlConst $UrlEffective"
((Num++))
((Num++))
done < "$1"
done < "$1"
}
}
@ -752,7 +968,9 @@ function ban_list () # $1: [--human-readable]
for Instance in $(show_instances)
for Instance in $(show_instances)
do
do
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFGame.ini"
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFGame.ini"
grep -P 'BannedIDs=' "$Config" | sed -r 's/.+A=([0-9]+),.+/\1/' >> "$ BanList"
if multini -gq "$Config" "Engine.AccessControl" "BannedIDs"; then
multini -g "$Config" "Engine.AccessControl" "BannedIDs" | sed -r 's/.+A=([0-9]+),.+/\1/' >> "$BanList"
fi
done
done
sort -u "$BanList" -o "$BanList"
sort -u "$BanList" -o "$BanList"
if [[ -n "$1" ]]; then
if [[ -n "$1" ]]; then
@ -769,10 +987,19 @@ function ban_ID3 () # $1: ID3
for Instance in $(show_instances)
for Instance in $(show_instances)
do
do
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFGame.ini"
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFGame.ini"
local BanStr="BannedIDs= (Uid=(A=$ID3,B=$StrangeConstUID))"
local BanStr="(Uid=(A=$ID3,B=$StrangeConstUID))"
if ! grep -qF "$BanStr" "$Config"; then
local Service=$(service_name "$Instance")
if ! multini -gq "$Config" "Engine.AccessControl" "BannedIDs" "$BanStr"; then
echo "Add ban $ID3 to $Instance"
echo "Add ban $ID3 to $Instance"
sed -i --follow-symlinks "/^\[Engine\.AccessControl\]/a $BanStr" "$Config"
if systemctl -q is-active $Service ; then
admin_curl "$Instance" "ServerAdmin/policy/bans" \
--request POST \
--data action="add" \
--data steamint64=$(steamID3_to_steamID64 $ID3) \
--data uniqueid=
else
multini -a "$Config" "Engine.AccessControl" "BannedIDs" "$BanStr"
fi
fi
fi
done
done
}
}
@ -783,10 +1010,19 @@ function unban_ID3 () # $1: ID3
for Instance in $(show_instances)
for Instance in $(show_instances)
do
do
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFGame.ini"
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFGame.ini"
local BanStr="BannedIDs= (Uid=(A=$ID3,B=$StrangeConstUID))"
local BanStr="(Uid=(A=$ID3,B=$StrangeConstUID))"
if grep -qF "$BanStr" "$Config"; then
local Service=$(service_name "$Instance")
if systemctl -q is-active $Service ; then
echo "Instance $Instance is running - skip."
# TODO: delete ban with webadmin/curl
# POST Body example:
# banid=plainid%3A8&action=delete
# WTF is plainID?!
else
if multini -gq "$Config" "Engine.AccessControl" "BannedIDs" "$BanStr"; then
echo "Remove ban $ID3 from $Instance"
echo "Remove ban $ID3 from $Instance"
sed -i --follow-symlinks "/ $BanStr/d" "$Config "
multini -d "$Config" "Engine.AccessControl" "BannedIDs" "$BanStr"
fi
fi
fi
done
done
}
}
@ -842,6 +1078,129 @@ function ban_sync ()
done
done
}
}
function admin_sync ()
{
# TODO: Implementation
echo "Dummy"
}
function admin_curl () # $1: Instance, $2: URL, $*: Request
{
local Instance="$1"
local URL="$2"
local MainConf="$InstanceConfigDir/$Instance/main.conf"
local WebPort=$(multini --get "$MainConf" '' "PortWeb")
shift; shift
curl -s -o "/dev/null" -u "$ServerBotLogin:$ServerBotPassword" "localhost:$WebPort/$URL" $*
}
function password_game () # $1: Password (if empty, use: ''), $*: Instance[s]
{
if echo "$1" | grep -qP '\s'; then
echo "Password should not contain spaces"
return 1
fi
local Password="$1"; shift
local InstanceList="$*"
if [[ -z "$InstanceList" ]] ; then
InstanceList=$(show_instances)
fi
for Instance in $InstanceList
do
if instance_exists "$Instance"; then
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFGame.ini"
local Service=$(service_name "$Instance")
if systemctl -q is-active $Service ; then
admin_curl "$Instance" "ServerAdmin/policy/passwords" \
--request POST \
--data action="gamepassword" \
--data gamepw1="$Password" \
--data gamepw2="$Password"
else
multini -s "$Config" "Engine.AccessControl" "GamePassword" "$Password"
fi
else
echo "Instance $Instance not exitst"
fi
done
}
function password_admin () # $1: Password (if empty, use: ''), $*: Instance[s]
{
if echo "$1" | grep -qP '\s'; then
echo "Password should not contain spaces"
return 1
fi
local Password="$1"; shift
local InstanceList="$*"
if [[ -z "$InstanceList" ]] ; then
InstanceList=$(show_instances)
fi
for Instance in $InstanceList
do
if instance_exists "$Instance"; then
local Config="$InstanceConfigDir/$Instance/LinuxServer-KFGame.ini"
local Service=$(service_name "$Instance")
if systemctl -q is-active $Service ; then
admin_curl "$Instance" "ServerAdmin/policy/passwords" \
--request POST \
--data action="adminpassword" \
--data adminpw1="$Password" \
--data adminpw2="$Password"
else
multini -s "$Config" "Engine.AccessControl" "AdminPassword" "$Password"
fi
else
echo "Instance $Instance not exitst"
fi
done
}
function chat ()
{
local Message=$(echo "$1" | sed 's/ /+/g')
shift
local InstanceList="$*"
if [[ -z "$InstanceList" ]] ; then
InstanceList=$(show_instances)
fi
for Instance in $InstanceList
do
if instance_exists "$Instance"; then
local Service=$(service_name "$Instance")
if systemctl -q is-active $Service ; then
admin_curl "$Instance" "ServerAdmin/current/chat+frame+data" \
--request POST \
--data ajax=1 \
--data message="$Message" \
--data teamsay=-1
else
echo "Instance $Instance not running - skip"
fi
else
echo "Instance $Instance not exitst"
fi
done
}
if [[ "$1" == "beta" ]]; then
BetaPostfix="-beta"; shift
fi
InstallDir="/usr/games/kf2-srv$BetaPostfix"
AppBin="$InstallDir/Binaries/Win64/KFGameSteamServer.bin.x86_64"
DefaultConfigDir="$InstallDir/KFGame/Config"
DownloadDir="$InstallDir/Binaries/Win64/steamapps/workshop/content/$AppClientNum"
CacheDir="$InstallDir/KFGame/Cache"
InstanceConfigDir="/etc/kf2-srv/instances$BetaPostfix"
InstanceConfigLnk="$DefaultConfigDir/instances"
MainConfigTemplate="/etc/kf2-srv/main.conf.template"
if [[ $# -eq 0 ]]; then show_help; exit 0; fi
if [[ $# -eq 0 ]]; then show_help; exit 0; fi
case $1 in
case $1 in
-h|--help ) show_help; ;;
-h|--help ) show_help; ;;
@ -851,20 +1210,25 @@ case $1 in
-u|--update ) if [[ "$EUID" -eq 0 ]]; then update_kf2 ; else run_as_root $*; fi ;;
-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 ;;
-v|--validate ) if [[ "$EUID" -eq 0 ]]; then validate ; else run_as_root $*; fi ;;
-r|--run ) shift; run $*; ;;
-r|--run ) shift; run $*; ;;
-c|--chat ) shift; Msg="$1"; shift; chat "$Msg" $*; ;;
-st|--start ) if [[ "$EUID" -eq 0 ]]; then shift; start_instance $*; else run_as_root $*; fi ;;
-st|--start ) if [[ "$EUID" -eq 0 ]]; then shift; start_instance $*; else run_as_root $*; fi ;;
-sp|--stop ) if [[ "$EUID" -eq 0 ]]; then shift; stop_instance $*; else run_as_root $*; fi ;;
-sp|--stop ) if [[ "$EUID" -eq 0 ]]; then shift; stop_instance $*; else run_as_root $*; fi ;;
-rs|--restart ) if [[ "$EUID" -eq 0 ]]; then shift; restart_instance $*; else run_as_root $*; fi ;;
-rs|--restart ) if [[ "$EUID" -eq 0 ]]; then shift; restart_instance $*; else run_as_root $*; fi ;;
-en|--enable ) if [[ "$EUID" -eq 0 ]]; then shift; enable_instance $*; else run_as_root $*; fi ;;
-en|--enable ) if [[ "$EUID" -eq 0 ]]; then shift; enable_instance $*; else run_as_root $*; fi ;;
-di|--disable ) if [[ "$EUID" -eq 0 ]]; then shift; disable_instance $*; else run_as_root $*; fi ;;
-di|--disable ) if [[ "$EUID" -eq 0 ]]; then shift; disable_instance $*; else run_as_root $*; fi ;;
-m l|--ma p-list ) if [[ "$EUID" -eq 0 ]]; then shift; ma p_list "-h" ; else run_as_root $*; fi ;;
-w l|--worksho p-list ) if [[ "$EUID" -eq 0 ]]; then shift; worksho p_list "-h" ; else run_as_root $*; fi ;;
-ms |--map-sync ) if [[ "$EUID" -eq 0 ]]; then shift; map_sync ; else run_as_root $*; fi ;;
-wa |--workshop-add ) if [[ "$EUID" -eq 0 ]]; then shift; workshop_add $* ; else run_as_root $*; fi ;;
-ma |--map-add ) if [[ "$EUID" -eq 0 ]]; then shift; map_add $*; else run_as_root $*; fi ;;
-wd |--workshop-del ) if [[ "$EUID" -eq 0 ]]; then shift; workshop_del $*; else run_as_root $*; fi ;;
-md |--map-del ) if [[ "$EUID" -eq 0 ]]; then shift; map_del $* ; else run_as_root $*; fi ;;
-ws |--workshop-sync ) if [[ "$EUID" -eq 0 ]]; then shift; workshop_sync ; else run_as_root $*; fi ;;
-mrs|--map-rotate-save ) if [[ "$EUID" -eq 0 ]]; then shift; map_rotate_save $*; else run_as_root $*; fi ;;
-mrs|--map-rotate-save ) if [[ "$EUID" -eq 0 ]]; then shift; map_rotate_save $*; else run_as_root $*; fi ;;
-mrl|--map-rotate-load ) if [[ "$EUID" -eq 0 ]]; then shift; map_rotate_load $*; else run_as_root $*; fi ;;
-mrl|--map-rotate-load ) if [[ "$EUID" -eq 0 ]]; then shift; map_rotate_load $*; else run_as_root $*; fi ;;
-bl|--ban-list ) if [[ "$EUID" -eq 0 ]]; then shift; ban_list "-h" ; else run_as_root $*; fi ;;
-bl|--ban-list ) if [[ "$EUID" -eq 0 ]]; then shift; ban_list "-h" ; else run_as_root $*; fi ;;
-bs|--ban-sync ) if [[ "$EUID" -eq 0 ]]; then shift; ban_sync ; else run_as_root $*; fi ;;
-bs|--ban-sync ) if [[ "$EUID" -eq 0 ]]; then shift; ban_sync ; else run_as_root $*; fi ;;
-ba|--ban-add ) if [[ "$EUID" -eq 0 ]]; then shift; ban_add $*; else run_as_root $*; fi ;;
-ba|--ban-add ) if [[ "$EUID" -eq 0 ]]; then shift; ban_add $*; else run_as_root $*; fi ;;
-bd|--ban-del ) if [[ "$EUID" -eq 0 ]]; then shift; ban_del $*; else run_as_root $*; fi ;;
-bd|--ban-del ) if [[ "$EUID" -eq 0 ]]; then shift; ban_del $*; else run_as_root $*; fi ;;
-fp|--fix-permissions ) if [[ "$EUID" -eq 0 ]]; then shift; fix_permissions $*; else run_as_root $*; fi ;;
-as|--admin-sync ) if [[ "$EUID" -eq 0 ]]; then shift; admin_sync ; else run_as_root $*; fi ;;
-pg|--password-game ) if [[ "$EUID" -eq 0 ]]; then shift; Pass="$1"; shift ; password_game "$Pass" $*; else run_as_root $*; fi ;;
-pa|--password-admin ) if [[ "$EUID" -eq 0 ]]; then shift; Pass="$1"; shift ; password_admin "$Pass" $*; else run_as_root $*; fi ;;
* ) echo "Command not recognized: $1"; exit 1 ;;
* ) echo "Command not recognized: $1"; exit 1 ;;
esac
esac