Install and Admin a Counter Strike: Global Offensive (CS:GO) server on Ubuntu

Csgoscript is a script for installing and Admin a server Counter Strike: Global Offensive (CS:GO) and Sourcemod/Metamod plugins.

version 1061

  1. Download script here (Right click and save as): http://veydunet.com/sc2017/csgoscript

On terminal:

wget -P folder_install http://veydunet.com/sc2017/csgoscript
chmod +x csgoscript
./csgoscript

Change line:
line (18) STEAM_LOGIN="LOGIN"  Create account for this, not use your real steam account!
line (19) STEAM_PASSWORD="PASS"
# Configure the maps of the ‘mapcycle.txt’ and ‘maplist.txt’ files according to the Game Mode, they will be loaded at server startup.
line (70) MAP_CONFIG="0"  # MAP_CONFIG 1 ON / 0 OFF
line (99) IP="192.168.0.1"

# GSLT Is required for running a public server. More info and create http://steamcommunity.com/dev/managegameservers

line (124) GSLT="FBD2Bxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Script CSGOSCRIPT version 1057  (It is better to download the script 1061)
#!/bin/bash
VER_SCR=1057

#*******************************************************************************#
#                                csgoscript.sh                                  #
#                                                                               #
# 	License: MIT License, 2017 Icaza Media                                  #
# 	Purpose: Counter-Strike: Global Offensive | Server Management Script    #
# 	Contributors: http://veydunet.com                                       #
# 	Documentation: https://developer.valvesoftware.com/wiki/Main_Page       #
# 	Website: http://veydunet.com                                            #
#                                                                               #
#*******************************************************************************#

##### CONFIG STEAMCMD ###########################################################
# Create account for this, not use your real steam account!
# =>
STEAM_LOGIN=""
STEAM_PASSWORD=""

##### CONFIG DIRECTORY ##########################################################
#
# -| home/
# -| home/user
# -| home/user/csgoscript            <=== Script csgoscript Here
# -| home/user/steamcmd              <=== (create automatically)
# -| home/user/Steam                 <=== (create automatically)
# -| home/user/csgoserver            <=== If you prefere change this
# -| home/user/csgoserver/csgo       <=== (create automatically)
#
#################################################################################

# csgoserver is the name of the installation directory
NAME_REP_SERVER="csgoserver"               								# <= If you prefere change this
# DIR_CSGO_SERVER is the directory of the server 'csgo' installation
DIR_CSGO_SERVER="$HOME/${NAME_REP_SERVER}" 								# <= No change this!
# steamcmd is directory to install the steamcmd tools
DIR_STEAMCMD="$HOME/steamcmd"              								# <= No change this!
# csgo is directory Counter-Strike: Global Offensive
REP_CSGO="${DIR_CSGO_SERVER}/csgo"         								# <= No change this!
# directory sourcemod configs
DIR_SOURCEMOD="$HOME/${NAME_REP_SERVER}/csgo/addons/sourcemod/configs/" # <= No change this! # Website steamcmd: http://media.steampowered.com URL_STEAMCMD="http://media.steampowered.com/client/steamcmd_linux.tar.gz" FILE_STEAMCMD="steamcmd_linux.tar.gz" 

# MAPS Configuration Game Mode restore ########################################## 
# 
# Configure the maps of the 'mapcycle.txt' and 'maplist.txt' files according to the Game Mode, 
# they will be loaded at server startup. # # Create the files automatically with console => ./csgoscript admin
# Select "Create_Files_Maps_Config" option and configure files.
#
#  Directory backup files => ${DIR_CSGO_SERVER}/csgo/mapsconfig
#
# -| ${DIR_MAP_BCK}/map_casual_cycle		=> ${REP_CSGO}/mapcycle.txt -| Classic Casual Mode
# -| ${DIR_MAP_BCK}/map_competitive_cycle	=> ${REP_CSGO}/mapcycle.txt -| Classic Competitive Mode
# -| ${DIR_MAP_BCK}/map_race_cycle			=> ${REP_CSGO}/mapcycle.txt -| Arm Race Mode
# -| ${DIR_MAP_BCK}/map_demolition_cycle	=> ${REP_CSGO}/mapcycle.txt -| Demolition Mode
# -| ${DIR_MAP_BCK}/map_deathmatch_cycle	=> ${REP_CSGO}/mapcycle.txt -| Deathmatch Mode
#
# -| ${DIR_MAP_BCK}/map_casual_list			=> ${REP_CSGO}/maplist.txt  -| Classic Casual Mode
# -| ${DIR_MAP_BCK}/map_competitive_list	=> ${REP_CSGO}/maplist.txt  -| Classic Competitive Mode 
# -| ${DIR_MAP_BCK}/map_race_list			=> ${REP_CSGO}/maplist.txt  -| Arm Race Mode
# -| ${DIR_MAP_BCK}/map_demolition_list		=> ${REP_CSGO}/maplist.txt  -| Demolition Mode
# -| ${DIR_MAP_BCK}/map_deathmatch_list		=> ${REP_CSGO}/maplist.txt  -| Deathmatch Mode
#
# =>
MAP_CONFIG="0"	# MAP_CONFIG 1 ON / 0 OFF
# directory file backup config mapcycle.txt and maplist.txt Game Mode
DIR_MAP_BCK="${DIR_CSGO_SERVER}/csgo/mapsconfig" 		# <= If you prefere change this (mapsconfig) 

##### Plugin [Metamod - Sourcemod] current version ############################### 
# 
# sourcemod => sourcemod-1.8.0-git6002
# metamod   => mmsource-1.10.7-git957
#
# Website sourcemod: https://www.sourcemod.net
# Website metamod:   https://www.sourcemm.net
#
#################################################################################
# =>
# URL download sourcemod
URL_SOURCEMOD="https://sm.alliedmods.net/smdrop/1.8/sourcemod-1.8.0-git6002-linux.tar.gz" 	# <= Change for Update
# sourcemod file download
FILE_SOURCEMOD="sourcemod-1.8.0-git6002-linux.tar.gz" 									  	# <= Change for Update
# URL download metamod
URL_METAMOD="https://mms.alliedmods.net/mmsdrop/1.10/mmsource-1.10.7-git957-linux.tar.gz" 	# <= Change for Update
# metamod file download
FILE_METAMOD="mmsource-1.10.7-git957-linux.tar.gz" 											# <= Change for Update
# URL download csgoscript update
URL_CSGOSCRIPT="http://veydunet.com/sc2017/csgoscriptupdt"              					# <= No change this!
# csgoscript file download
FILE_CSGOSCRIPT="csgoscriptupdt"                                        					# <= No change this! 

##### CONFIG SERVER ############################################################# 
# =>
IP="192.168.0.1"
PORT="27015"
CLIENTPORT="27005"
SOURCETVPORT="27020"
TICKRATE="64"
SERVERCFG="server.cfg"
MAXPLAYERS="16"

##### CONFIG GAME TYPE +mapgroup/+map ###########################################
# =>
MGRP_CLASSIC="mg_bomb_se"           	# +mapgroup # => Classic
DEFMAP_CLASSIC="de_dust"            	# +map      #
MGRP_COMPET="mg_bomb_se"            	# +mapgroup # => Competitive
DEFMAP_COMPET="de_dust2"            	# +map      #
MGRP_ARM="mg_armsrace"              	# +mapgroup # => Arm Race
DEFMAP_ARM="ar_shoots"              	# +map      #
MGRP_DEMOLI="mg_demolition"         	# +mapgroup # => Demolition
DEFMAP_DEMOLI="de_lake"             	# +map      #
MGRP_DEATH="mg_deathmatch"          	# +mapgroup # => Deathmatch
DEFMAP_DEATH="aim_deagle_artur_v02" 	# +map      #

# GSLT ##########################################################################
#      Is required for running a public server
#      More info and create: http://steamcommunity.com/dev/managegameservers
# =>
GSLT="FBD2Bxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# Editor ########################################################################
# csgo script use Nano for edit files if you use other editor change this
# =>
EDIT_FILES="nano"

##### INSTALL DEDICATED SERVER ##################################################
# =>
INSTALL_FUNCT(){

if [ ! -d "$DIR_STEAMCMD" ] ; then
	echo -e "===========> Create directory steamcmd \n"
		mkdir ${DIR_STEAMCMD}
fi
	echo -e "===========> Download ${FILE_STEAMCMD} .... \n"
		wget -P ${DIR_STEAMCMD} ${URL_STEAMCMD}

	echo -e "===========> Unzip ${FILE_STEAMCMD} \n"
		cd ${DIR_STEAMCMD} && tar xvf ${FILE_STEAMCMD}

	echo -e "===========> Remove ${FILE_STEAMCMD} \n"
		rm ${DIR_STEAMCMD}/${FILE_STEAMCMD}

	echo -e "===========> chmod steamcmd.sh \n"
		chmod +x steamcmd.sh

	echo -e "===========> Start Install Server Counter-Strike: Global Offensive \n"
		cd ${DIR_STEAMCMD}
		./steamcmd.sh +login ${STEAM_LOGIN} ${STEAM_PASSWORD} +force_install_dir ${DIR_CSGO_SERVER} +app_update 740 validate +quit

}

##### UPDATE DEDICATED SERVER ###################################################
# =>
UPDT_FUNCT(){

	echo -e "\n===========> Save motd.txt before update \n"
	if [ -f "${REP_CSGO}/motd.txt" ] ; then
		 cp "${REP_CSGO}/motd.txt" "${REP_CSGO}/motd.txt.bck"
	fi

	echo -e "===========> Save mapcycle.txt before update \n"
	if [ -f "${REP_CSGO}/mapcycle.txt" ] ; then
		 cp "${REP_CSGO}/mapcycle.txt" "${REP_CSGO}/mapcycle.txt.bck"
	fi

	echo -e "===========> Save maplist.txt before update \n"
	if [ -f "${REP_CSGO}/maplist.txt" ] ; then
		 cp "${REP_CSGO}/maplist.txt" "${REP_CSGO}/maplist.txt.bck"
	fi

	if [ -f "${DIR_STEAMCMD}/steamcmd.sh" ] ; then
	echo -e "===========> Start Update Server Counter-Strike: Global Offensive \n"
		cd ${DIR_STEAMCMD}
		./steamcmd.sh +login ${STEAM_LOGIN} ${STEAM_PASSWORD} +force_install_dir ${DIR_CSGO_SERVER} +app_update 740 validate +quit
	else
		INSTALL_FUNCT
	fi

	echo -e "\n"
	if [ -f "${REP_CSGO}/motd.txt.bck" ] ; then
		echo -e "===========> Restore motd.txt \n"
		mv "${REP_CSGO}/motd.txt.bck" "${REP_CSGO}/motd.txt"
	fi

	if [ -f "${REP_CSGO}/mapcycle.txt.bck" ] ; then
		echo -e "===========> Restore mapcycle.txt \n"
		mv "${REP_CSGO}/mapcycle.txt.bck" "${REP_CSGO}/mapcycle.txt"
	fi

	if [ -f "${REP_CSGO}/maplist.txt.bck" ] ; then
 		echo -e "===========> Restore maplist.txt \n"
		mv "${REP_CSGO}/maplist.txt.bck" "${REP_CSGO}/maplist.txt"
	fi

}

##### START DEDICATED SERVER ####################################################
# =>
START_FUNCT(){

	echo -e "===========> Start Server \n"

PS3='?: '

echo -e "Select Server Mode \n"

select choix in "Classic_Casual" "Classic_Competitive" "Arms_Race" "Demolition" "Deathmatch"
do
if [ "$choix" = Classic_Casual ] ; then
	M_FILE_CYCLE="map_casual_cycle"
	M_FILE_LIST="map_casual_list"
	MAPSCNF_FUNCT
	echo -e "===========> Start Classic Casual Mode \n"
	GAMETYPE="0"
	GAMEMODE="0"
	MAPGROUP=${MGRP_CLASSIC}
	DEFAULTMAP=${DEFMAP_CLASSIC}
 	PARAM_START
exit 0
fi

if [ "$choix" = Classic_Competitive ] ; then
	M_FILE_CYCLE="map_competitive_cycle"
	M_FILE_LIST="map_competitive_list"
	MAPSCNF_FUNCT
	echo -e "===========> Start Classic Competitive Mode \n"
	GAMETYPE="0"
	GAMEMODE="1"
	MAPGROUP=${MGRP_COMPET}
	DEFAULTMAP=${DEFMAP_COMPET}
 	PARAM_START
exit 0
fi

if [ "$choix" = Arms_Race ] ; then	
	M_FILE_CYCLE="map_race_cycle"
	M_FILE_LIST="map_race_list"
	MAPSCNF_FUNCT	
	echo -e "===========> Start Arm Race Mode \n"
	GAMETYPE="1"
	GAMEMODE="0"
	MAPGROUP=${MGRP_ARM}
	DEFAULTMAP=${DEFMAP_ARM}
 	PARAM_START
exit 0
fi

if [ "$choix" = Demolition ] ; then
	M_FILE_CYCLE="map_demolition_cycle"
	M_FILE_LIST="map_demolition_list"
	MAPSCNF_FUNCT	
	echo -e "===========> Start Demolition Mode \n"
	GAMETYPE="1"
	GAMEMODE="1"
	MAPGROUP=${MGRP_DEMOLI}
	DEFAULTMAP=${DEFMAP_DEMOLI}
 	PARAM_START
exit 0
fi

if [ "$choix" = Deathmatch ] ; then
	M_FILE_CYCLE="map_deathmatch_cycle"
	M_FILE_LIST="map_deathmatch_list"
	MAPSCNF_FUNCT	
	echo -e "===========> Start Deathmatch Mode \n"	
	GAMETYPE="1"
	GAMEMODE="2"
	MAPGROUP=${MGRP_DEATH}
	DEFAULTMAP=${DEFMAP_DEATH}
	PARAM_START
exit 0
fi

done
 
}

PARAM_START(){

cd ${DIR_CSGO_SERVER}

./srcds_run -game csgo -usercon -strictportbind -ip ${IP} -port ${PORT} +clientport ${CLIENTPORT} +tv_port ${SOURCETVPORT} +sv_setsteamaccount ${GSLT} -tickrate ${TICKRATE} +map ${DEFAULTMAP} +servercfgfile ${SERVERCFG} -maxplayers_override ${MAXPLAYERS} +mapgroup ${MAPGROUP} +game_mode ${GAMEMODE} +game_type ${GAMETYPE}

}

##### RESTORE MAP CONFIG GAME MODE ##############################################
# =>
MAPSCNF_FUNCT(){

	if [ $MAP_CONFIG = "1" ] ; then

	if [ -f "${DIR_MAP_BCK}/${M_FILE_CYCLE}" ] ; then
		 echo -e "===========> Restore mapcycle.txt Game Mode config \n"
		 mv "${DIR_MAP_BCK}/${M_FILE_CYCLE}" "${REP_CSGO}/mapcycle.txt"
	fi
	if [ -f "${DIR_MAP_BCK}/${M_FILE_LIST}" ] ; then
		 echo -e "===========> Restore maplist.txt Game Mode config \n"
		 mv "${DIR_MAP_BCK}/${M_FILE_LIST}" "${REP_CSGO}/maplist.txt"
	fi

	fi

}

##### CREATE BACKUP FILES #######################################################
#
# =>
MAPSBCKCREATE_FUNCT(){

	if [ ! -d "${DIR_MAP_BCK}" ] ; then
		echo -e "===========> Create directory ${DIR_MAP_BCK} \n"
		mkdir ${DIR_MAP_BCK}
	fi

echo -e "===========> Create backup file mapcycle.txt and maplist.txt config Game Mode \n"

	if [ -f "${REP_CSGO}/mapcycle.txt" ] ; then
		 echo -e "=> Create file mapcycle.txt for Classic Casual Mode file name: map_casual_cycle \n"
		 cp "${REP_CSGO}/mapcycle.txt" "${DIR_MAP_BCK}/map_casual_cycle"
		 echo -e "=> Create file mapcycle.txt for Classic Competitive Mode file name: map_competitive_cycle \n"
		 cp "${REP_CSGO}/mapcycle.txt" "${DIR_MAP_BCK}/map_competitive_cycle"
		 echo -e "=> Create file mapcycle.txt for Arm Race Mode file name: map_race_cycle \n"
		 cp "${REP_CSGO}/mapcycle.txt" "${DIR_MAP_BCK}/map_race_cycle"
		 echo -e "=> Create file mapcycle.txt for Demolition Mode file name: map_demolition_cycle \n"
		 cp "${REP_CSGO}/mapcycle.txt" "${DIR_MAP_BCK}/map_demolition_cycle \n"
		 echo -e "=> Create file mapcycle.txt for Deathmatch Mode file name: map_deathmatch_cycle \n"
		 cp "${REP_CSGO}/mapcycle.txt" "${DIR_MAP_BCK}/map_deathmatch_cycle \n"
	fi

	if [ -f "${REP_CSGO}/maplist.txt" ] ; then
		 echo -e "=> Create file maplist.txt for Classic Casual Mode file name: map_casual_list \n"
		 cp "${REP_CSGO}/maplist.txt" "${DIR_MAP_BCK}/map_casual_list"
		 echo -e "=> Create file maplist.txt for Classic Competitive Mode file name: map_competitive_list \n"
		 cp "${REP_CSGO}/maplist.txt" "${DIR_MAP_BCK}/map_competitive_list"
		 echo -e "=> Create file maplist.txt for Arm Race Mode file name: map_race_list \n"
		 cp "${REP_CSGO}/maplist.txt" "${DIR_MAP_BCK}/map_race_list"
		 echo -e "=> Create file maplist.txt for Demolition Mode file name: map_demolition_list \n"
		 cp "${REP_CSGO}/maplist.txt" "${DIR_MAP_BCK}/map_demolition_list"
		 echo -e "=> Create file maplist.txt for Deathmatch Mode file name: map_deathmatch_list \n"
		 cp "${REP_CSGO}/maplist.txt" "${DIR_MAP_BCK}/map_deathmatch_list"
	fi

}

##### INSTALL PLUGIN ############################################################
# =>
PLUGIN_FUNCT(){

	echo -e "===========> Start Install plugins \n"

	if [ -f "${DIR_SOURCEMOD}/admins_simple.ini" ] ; then
		 echo -e "===========> Save admins_simple.ini before update \n"
		 cp "${DIR_SOURCEMOD}/admins_simple.ini" "${DIR_SOURCEMOD}/admins_simple.ini.bck"
	fi

	if [ -f "${DIR_SOURCEMOD}/adminmenu_maplist.ini" ] ; then
		 echo -e "===========> Save adminmenu_maplist.ini before update \n"
		 cp "${DIR_SOURCEMOD}/adminmenu_maplist.ini" "${DIR_SOURCEMOD}/adminmenu_maplist.ini.bck"
	fi

	echo -e "===========> Download SOURCEMOD plugin .... \n"
		wget -P ${REP_CSGO} ${URL_SOURCEMOD}

	echo -e "===========> Download METAMOD plugin .... \n"
		wget -P ${REP_CSGO} ${URL_METAMOD}

	echo -e "===========> Install Plugins \n"
		cd ${REP_CSGO} && tar xvf ${FILE_SOURCEMOD} && tar xvf ${FILE_METAMOD}

	echo -e "\n===========> Remove tar download \n"
		rm ${FILE_SOURCEMOD} && rm ${FILE_METAMOD}

	if [ -f "${DIR_SOURCEMOD}/admins_simple.ini.bck" ] ; then
		echo -e "===========> Restore admins_simple.ini \n"
		mv "${DIR_SOURCEMOD}/admins_simple.ini.bck" "${DIR_SOURCEMOD}/admins_simple.ini"
	fi

	if [ -f "${DIR_SOURCEMOD}/adminmenu_maplist.ini.bck" ] ; then
		echo -e "===========> Restore adminmenu_maplist.ini \n"
		mv "${DIR_SOURCEMOD}/adminmenu_maplist.ini.bck" "${DIR_SOURCEMOD}/adminmenu_maplist.ini"
	fi

}

##### Admin #####################################################################
# =>
ADMIN_FUNCT(){

	echo -e "===========> Admin \n"

PS3='?: '

	echo -e "===========> Select \n"

select choix in "Edit_csgoscript" "Update_csgoscript" "Edit_SERVERcfg" "Create_Files_Maps_Config"
do
if [ "$choix" = Edit_csgoscript ] ; then
	ADMIN_E_FUNCT
exit 0
fi

if [ "$choix" = Update_csgoscript ] ; then
	ADMIN_U_FUNCT
exit 0
fi

if [ "$choix" = Edit_SERVERcfg ] ; then
	ADMIN_S_FUNCT
exit 0
fi

if [ "$choix" = Create_Files_Maps_Config ] ; then
	ADMIN_M_FUNCT
exit 0
fi

done

}

ADMIN_E_FUNCT(){
    ${EDIT_FILES} csgoscript
}

ADMIN_U_FUNCT(){
	echo -e "===========> Download last update csgoscript \n"
	wget -P $HOME/ ${URL_CSGOSCRIPT}
	echo -e "\n===========> Install last update csgoscript \n"
	mv "${FILE_CSGOSCRIPT}" "csgoscript"
	chmod +x csgoscript
	echo -e "===========> csgoscript is up to date \n"
}

ADMIN_S_FUNCT(){
if [ -f "${REP_CSGO}/cfg/server.cfg" ] ; then
		${EDIT_FILES} ${REP_CSGO}/cfg/server.cfg
	else
		echo "[ FAIL ] server.cfg file no exist! Create file in => ${REP_CSGO}/cfg/server.cfg"	
fi
}

ADMIN_M_FUNCT(){
	MAPSBCKCREATE_FUNCT
}

##### Help csgoscript ###########################################################
# =>
HELP_FUNCT(){

	echo -e "\n  Use : [./csgoscript] [OPTION]"
	echo -e "  Counter-Strike: Global Offensive | Server Management Script \n"

	echo "	install             Install Counter-Strike: Global Offensive"
	echo "	update              Update Counter-Strike: Global Offensive"
	echo "	start               Start Counter-Strike: Global Offensive"
	echo "	plugin              Download and Install plugin Sourcemod & Metamod"
	echo "	admin               Admin csgoscript Edit/Update/..."
	echo "	-e            		Admin csgoscript Edit"	
	echo "	-u            		Admin csgoscript Update"
	echo "	-s            		Admin csgoscript edit server.cfg file"
	echo "	-m            		Admin csgoscript create file Maps backup config"		
	echo -e "	vers                Version csgoscript \n"

}

##### PREVENT FROM RUNNING THIS SCRIPT AS ROOT ##################################
# =>
if [ "$(whoami)" = "root" ] ; then

		echo "[ FAIL ] Do NOT run this script as root!"
		exit 1
fi

if [ $# -eq 0 ] ; then

##### START CHOICE ##############################################################
# =>
PS3='?: '

select choix in "INSTALL" "UPDATE" "START" "INSTALL_PLUGIN" "ADMIN"
do
if [ "$choix" = INSTALL ] ; then
	INSTALL_FUNCT
exit 0
fi

if [ "$choix" = UPDATE ] ; then
	UPDT_FUNCT
exit 0
fi

if [ "$choix" = START ] ; then
	START_FUNCT
exit 0
fi

if [ "$choix" = INSTALL_PLUGIN ] ; then
	PLUGIN_FUNCT
exit 0

fi
if [ "$choix" = ADMIN ] ; then
	ADMIN_FUNCT
exit 0
fi

done

exit 0;

fi

##### ARGUMENTS #################################################################
# =>
if [ $1 = "install" ] ; then
	INSTALL_FUNCT
fi

if [ $1 = "update" ] ; then
	UPDT_FUNCT
fi

if [ $1 = "start" ] ; then
	START_FUNCT
fi

if [ $1 = "plugin" ] ; then
	PLUGIN_FUNCT
fi

if [ $1 = "admin" ] ; then
	ADMIN_FUNCT
fi

if [ $1 = "--help" ] ; then
	HELP_FUNCT
fi

if [ $1 = "vers" ] ; then
	echo -e "CSGOSCRIPT version: ${VER_SCR}"
fi

if [ $1 = "-e" ] ; then
	ADMIN_E_FUNCT
fi

if [ $1 = "-u" ] ; then
	ADMIN_U_FUNCT
fi

if [ $1 = "-s" ] ; then
	ADMIN_S_FUNCT
fi

if [ $1 = "-m" ] ; then
	ADMIN_M_FUNCT
fi

#  .▄▄ ·       ▄• ▄▌▄ •▄  ▄▄▄·  ▐ ▄  ▄▄▄· ▄▄▄▄· ▪  .▄▄ ·
#  ▐█ ▀. ▪     █▪██▌█▌▄▌▪▐█ ▀█ •█▌▐█▐█ ▀█ ▐█ ▀█▪██ ▐█ ▀.
#  ▄▀▀▀█▄ ▄█▀▄ █▌▐█▌▐▀▀▄·▄█▀▀█ ▐█▐▐▌▄█▀▀█ ▐█▀▀█▄▐█·▄▀▀▀█▄
#  ▐█▄▪▐█▐█▌.▐▌▐█▄█▌▐█.█▌▐█ ▪▐▌██▐█▌▐█ ▪▐▌██▄▪▐█▐█▌▐█▄▪▐█
#   ▀▀▀▀  ▀█▄▀▪ ▀▀▀ ·▀  ▀ ▀  ▀ ▀▀ █▪ ▀  ▀ ·▀▀▀▀ ▀▀▀ ▀▀▀▀  script