Those with the knowledge to run servers will need no further explanation than the comments in this script
#!/bin/bash
# cwdedsvr v0.13 by haarp
# Released under the GNU General Public License version 3 or later
# Run the Windows Crysis Wars dedicated server (+ mod) with Wine, requiring no X server
# The Crysis Wars server console will be available through ncurses on the controlling terminal
# Requirements: Linux, recent 32bit wine (verified with 1.8.3), screen is also highly recommended
# Howto:
# - Remove the '.wine' directory in your user's home, if it exists already
# - Create the directories '.wine' and '.wine/drive_c' in your user's home
# - Place a working Crysis Wars installation somewhere below drive_c, e.g. 'drive_c/CrysisWars'
# - For MWLL: Make sure the 'MWLL' directory under 'Mods/' is uppercase
# - Put this script into a file, adjust the paths (see PATHS below) and make it executable
# - Think of a short name for the server (avoid spaces!)
# - The server's root dir will be SERVERS_DIR/servername (see PATHS below), create it!
# - Put server.cfg, levelrotation.xml, etc. in it. Logs and stuff will also end up in there
# - You can also put a 'common.cfg' into this dir, which will be executed before server.cfg
# - Run this script without arguments for usage information
# - Useful info for server configuration:
# http://wiki.mechlivinglegends.net/index.php?title=Dedicated_Server
# The following env variables can be set to override those defined below:
# - WINEPREFIX
# - CRYDIR
### PATHS AND SETTINGS (change me! avoid very long paths!) -------------------------------------------------------
CRY_DIR="CrysisWars" # Crysis Wars install dir, relative to Wine's drive_c
SERVERS_DIR="Servers" # Container for root dirs of servers, relative to Wine's drive_c
MOD="MWLL" # The mod, empty quotes for no mod (case-sensitive!)
EXECFILE="" # Optional script to exec between server restarts (e.g. map installs)
# Positional args passed: $1=serverdir | $2=crydir | $3=modname
### RUNTIME PATHS (leave these be!) ------------------------------------------------------------------------------
servername="$1"
serverdir="${WINEPREFIX:-$HOME/.wine}/drive_c/$SERVERS_DIR/$servername" # Full path to root dir of current server
serverdir_win="C:/$SERVERS_DIR/$servername" # Same, in Windows format
##crydir="${WINEPREFIX:-$HOME/.wine}/drive_c/${CRYDIR:-$CRY_DIR}" # Full path to Crysis Wars dir
crydir="${CRYDIR:-$serverdir/crydir}"
pidfile="$serverdir/.wine.pid" # Contains $wine_pid; file exists -> server running
autofile="$serverdir/.automode" # File exists -> Auto-mode enabled
### --------------------------------------------------------------------------------------------------------------
startserver() {
if [[ $MOD = "" ]]; then modarg=""
else modarg="-mod $MOD"
fi
#FIXME: Requires 32bit Wine (https://bugs.winehq.org/show_bug.cgi?id=41000)
export WINEARCH=win32; arch=32
#Background worker that waits until *our* Crysis spawns, then records PID and sets terminal title
#FIXME: This may run indefinitely if it can't find Crysis...
{
until [[ $pid ]]; do
pid=$(pgrep -u $USER -l -f "^$crydir/Bin$arch/CrysisWarsDedicatedServer.exe $modarg -root $serverdir_win " | awk '{print $1}')
sleep 0.1
done
echo "$pid" >"$pidfile"
echo -en "\e]2;cwdedsvr: $servername\007"
} &
echo "Launching Wine..."
if [[ $debug ]]; then
WINEDEBUG="$WINEDEBUG,err-winediag" WINEDLLOVERRIDES="winemenubuilder.exe=,mshtml=,mscoree=" wine "$crydir/Bin$arch/CrysisWarsDedicatedServer.exe" $modarg -root "$serverdir_win" +exec common.cfg +exec server.cfg
else
WINEDEBUG="-all" WINEDLLOVERRIDES="winemenubuilder.exe=,mshtml=,mscoree=" wine wineconsole "$crydir/Bin$arch/CrysisWarsDedicatedServer.exe" $modarg -root "$serverdir_win" +exec common.cfg +exec server.cfg
fi
echo "Wine has quit."
rm "$pidfile" 2>/dev/null
}
checkrun() {
#Path sanity checks
if [[ ! -f "$crydir/Bin$arch/CrysisWarsDedicatedServer.exe" ]]; then
echo -e "$crydir/Bin$arch/CrysisWarsDedicatedServer.exe not found!\nWARS_DIR wrong or bad Crysis install? (see the PATHS section in this script). Aborting!"
exit 1
elif [[ ! "$MOD" = "" && ! -f "$crydir/Mods/$MOD/info.xml" ]]; then
echo "$crydir/Mods/$MOD/info.xml not found (case-sensitive). Aborting!"; exit 1
elif [[ ! -d "$serverdir" || ! -w "$serverdir" ]]; then
echo -e "Server dir $serverdir non-existent!\nDir missing or bad server name? (see the PATHS section in this script). Aborting!"; exit 1
fi
#Abort if server running already, silently remove pidfiles if exists but not running
if [[ -e "$pidfile" ]]; then
if { kill -0 $(< "$pidfile"); } 2>/dev/null; then
echo "Server already running. Aborting!"
exit 1
else rm "$pidfile" 2>/dev/null
fi
fi
#Silently remove $autofile if exists
if [[ -e "$autofile" ]]; then rm "$autofile"; fi
echo "Preliminary checks completed."
echo "Using WINEPREFIX=${WINEPREFIX:-$HOME/.wine}, crydir=$crydir"
sleep 4
}
usage() {
echo "Usage: $(basename "$0") servername {auto|single|restart|stop|status} [debug]"
echo "------"
echo "'auto': Auto-mode; restart the server in the event of a crash/shutdown."
echo "'single': No Auto-mode; terminate when server shuts down. Great for testing!"
echo "'restart': Quit the current server, let auto-mode restart if active."
echo "'stop': Quit the current server, disable auto-mode."
echo "'status': Display the current server status."
echo "'debug': (optional) Display Wine log instead of the server console."
exit
}
status() {
if { kill -0 $(< "$pidfile"); } 2>/dev/null; then
crysis_pid=$(cat "$pidfile")
crysis_mem=$[ $(ps -o rss -p $crysis_pid | tail -n1) /1024 ]
echo "$servername running! RAM usage (MB):"
echo "Crysis: $crysis_mem"
exit 0
else
echo "Not running!"
exit 1
fi
}
finish() {
rm "$autofile" 2>/dev/null
{ kill $(< "$pidfile"); } 2>/dev/null
rm "$pidfile" 2>/dev/null
}
if [[ $# -lt 2 || $# -gt 3 ]]; then usage; fi
if [[ $# = 3 && ! "$3" = "debug" ]]; then usage; fi
if [[ "$3" = "debug" ]]; then debug=1; fi
if [[ $(arch) == "x86_64" ]]; then arch=64
else arch=32
fi
case "$2" in
auto)
checkrun
trap 'finish' EXIT
touch "$autofile"
while [[ -f "$autofile" ]]; do
startserver
[[ -x "$EXECFILE" ]] && "$EXECFILE" "$serverdir" "$crydir" "$MOD"
test -f "$autofile" || break
echo -n "Press Ctrl+C to exit now! Restarting in "
for i in {5..1}; do echo -n "${i}.."; sleep 1; done; echo ""
done
;;
single)
checkrun
trap 'finish' EXIT
startserver
;;
restart)
if [[ -e "$pidfile" ]]; then
echo "Terminating server."
kill $(< "$pidfile")
else echo "Server not running."
fi
;;
stop)
if [[ -e "$autofile" ]]; then
echo "Disabling auto-mode."
rm "$autofile"
fi
if [[ -e "$pidfile" ]]; then
echo "Terminating server."
kill $(< "$pidfile")
else echo "Server not running."
fi
;;
status)
status
;;
*)
usage
;;
esac
exit 0
# ChangeLog:
# 0.13:
# -WARSDIR is CRYDIR now
# 0.12:
# -Thorough overhaul for modern Wine:
# - Xvfb not necessary anymore
# - no more wineserver handling (leak fixed)
# - multilib (bugged)
# - No more .net/mono freezes
# -WARSDIR override through env variable possible
# -Easier paths
# 0.11:
# -Tweaks and fixes for Debian 8/9
# -Now supports 64bit servers (sorta)
# 0.10.2:
# -Better EXECFILE handling
# 0.10.1:
# -Better WINEPREFIX handling
# 0.10.0:
# -Added support for optional common.cfg
# -Now records wineserver_pid to ensure correct memory usage display
# 0.9.3:
# -Disabled Xvfb listening on TCP port (wasn't needed, improves security)
# 0.9.2:
# -Modified script so each server spawns its own Xvfb
# 0.9.1:
# -Added EXECFILE capability
# 0.9:
# -Turned the servername into a commandline argument
# 0.8.4:
# -Small tweaks
# -Reverted port and rcon to reside inside server.cfg again
# 0.8.2:
# -$pidfile now points to the actual CrysisWarsDedicatedServer.exe PID
# 0.8:
# -Can run several servers on one machine now
# 0.7.1:
# -Long command line no longer runs the risk of getting truncated by Wine
# -Requirement for xprop removed again
# 0.7:
# -Major overhaul of documentation comments
# -More checks
# -Defeated the Gecko dialog once and for all
# -Running without mod (vanilla) now possible
# 0.6.2:
# -Minor tweaks
# -Mod selection now possible via variable
# 0.6.1:
# -Script now checks whether Xvfb started correctly and displays its output if not
# -Automatically find free X display starting at :10 instead of hardcoding :90
# -Added 'debug' command line option to show Wine log instead of server console
# 0.6:
# -Crysis server console is now available on the controlling terminal
# -Revised the entire script for increased durability
# -Added a ton of explanations and infos
# -Added and clarified usage (command-line options)
# -Put paths into variables for easier customization
# -Extracted port and RCON settings into variables
# -Removed dependency on xvfb-run and at the same time slightly improved performance
# -Will no longer kill all instances of Xvfb, only the one it spawned itself
# -Will no longer kill all instances of Wine, only CrysisWarsDedicatedServer.exe
# BUG: Resize wineconsole ncurses window with controlling terminal (Wine bug 30193)
# BUG: Server console cursor disappears when running inside screen
# BUG: Using HTTP RCon can sometimes lag or even hang the server. Wine bug?
# LIMIT: Wine truncates very long command lines. I would write the cmd into a file
# and execute it with cmd /c, but that seems to crash the server after mapload (?!)