Compare commits

...

1 Commits

Author SHA1 Message Date
b17698b853 Initial commit 2023-12-30 19:43:31 +01:00
5 changed files with 244 additions and 1 deletions

39
Dockerfile Normal file
View File

@ -0,0 +1,39 @@
FROM debian:bookworm-slim
LABEL author="Makaren0" maintainer="Makaffe@hotmail.com"
ENV DEBIAN_FRONTEND=noninteractive
ENV DEBCONF_NOWARNINGS="yes"
RUN apt update; apt upgrade -y\
&& apt install -y libgcc1 lib32stdc++6 unzip curl iproute2 tzdata libgdiplus
RUN apt-get update \
&& apt-get clean \
&& apt-get autoremove
RUN apt --fix-broken install \
&& apt-get update \
&& apt-get upgrade \
&& dpkg --configure -a \
&& apt-get install -f
RUN curl -fsSL https://deb.nodesource.com/setup_14.x | bash - \
&& apt install -y nodejs \
&& mkdir /node_modules
RUN npm install --prefix / ws
RUN apt update; apt upgrade -y\
&& dpkg --add-architecture i386; apt install -y wget file tar bzip2 gzip bsdmainutils python3 util-linux ca-certificates binutils bc jq tmux netcat lib32gcc-s1 lib32z1
RUN useradd -d /home/container -m container
USER container
ENV USER=container HOME=/home/container
WORKDIR /home/container
COPY ./entrypoint.sh /entrypoint.sh
COPY ./wrapper.js /wrapper.js
CMD ["/bin/bash", "/entrypoint.sh"]

View File

@ -1 +1 @@
## Docker images
## Game Rust Facepunch - Docker images

29
entrypoint.sh Normal file
View File

@ -0,0 +1,29 @@
#!/bin/bash
echo -e "╔═════════════════════╗"
echo -e "║ EntryPoint.sh ║"
echo -e "╚═════════════════════╝\n"
cd /home/container
# Fix for Rust not starting
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(pwd)
# Make internal Docker IP address available to processes.
export INTERNAL_IP=`ip route get 1 | awk '{print $NF;exit}'`
# Replace Startup Variables
MODIFIED_STARTUP=`eval echo $(echo ${STARTUP} | sed -e 's/{{/${/g' -e 's/}}/}/g')`
echo ":/home/container$ ${MODIFIED_STARTUP}"
./steamcmd/steamcmd.sh +force_install_dir /home/container +login anonymous +app_update 258550 +quit
if [ -f OXIDE_FLAG ] || [ "${OXIDE}" = 1 ] || [ "${UMOD}" = 1 ]; then
echo "Updating uMod..."
curl -sSL "https://github.com/OxideMod/Oxide.Rust/releases/latest/download/Oxide.Rust-linux.zip" > umod.zip
unzip -o -q umod.zip
rm umod.zip
echo "Done updating uMod!"
fi
# Run the Server
echo -e "INVOKE WRAPPER..."
node /wrapper.js "${MODIFIED_STARTUP}"

View File

@ -0,0 +1,36 @@
#!/bin/bash
# steamcmd Base Installation Script
#
# Server Files: /mnt/server
echo -e "╔═════════════════════╗"
echo -e "║ InstallScript ║"
echo -e "╚═════════════════════╝\n"
SRCDS_APPID=258550
## just in case someone removed the defaults.
if [ "${STEAM_USER}" == "" ]; then
echo -e "steam user is not set.\n"
echo -e "Using anonymous user.\n"
STEAM_USER=anonymous
STEAM_PASS=""
STEAM_AUTH=""
else
echo -e "user set to ${STEAM_USER}"
fi
## download and install steamcmd
cd /tmp
mkdir -p /mnt/server/steamcmd
curl -sSL -o steamcmd.tar.gz https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz
tar -xzvf steamcmd.tar.gz -C /mnt/server/steamcmd
mkdir -p /mnt/server/steamapps # Fix steamcmd disk write error when this folder is missing
cd /mnt/server/steamcmd
# SteamCMD fails otherwise for some reason, even running as root.
# This is changed at the end of the install process anyways.
chown -R root:root /mnt
export HOME=/mnt/server
## install game using steamcmd
./steamcmd.sh +force_install_dir /mnt/server +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} validate +quit

139
wrapper.js Normal file
View File

@ -0,0 +1,139 @@
#!/usr/bin/env node
var startupCmd = "";
const fs = require("fs");
fs.writeFile("latest.log", "", (err) => {
if (err) console.log("Callback error in appendFile:" + err);
});
var args = process.argv.splice(process.execArgv.length + 2);
for (var i = 0; i < args.length; i++) {
if (i === args.length - 1) {
startupCmd += args[i];
} else {
startupCmd += args[i] + " ";
}
}
if (startupCmd.length < 1) {
console.log("Error: Please specify a startup command.");
process.exit();
}
const seenPercentage = {};
function filter(data) {
const str = data.toString();
if (str.startsWith("Loading Prefab Bundle ")) { // Rust seems to spam the same percentage, so filter out any duplicates.
const percentage = str.substr("Loading Prefab Bundle ".length);
if (seenPercentage[percentage]) return;
seenPercentage[percentage] = true;
}
console.log(str);
}
var exec = require("child_process").exec;
console.log("Starting Rust in wrapper.js...");
var exited = false;
const gameProcess = exec(startupCmd);
gameProcess.stdout.on('data', filter);
gameProcess.stderr.on('data', filter);
gameProcess.on('exit', function (code, signal) {
exited = true;
if (code) {
console.log("Main game process exited with code " + code);
// process.exit(code);
}
});
function initialListener(data) {
const command = data.toString().trim();
if (command === 'quit') {
gameProcess.kill('SIGTERM');
} else {
console.log('Unable to run "' + command + '" due to RCON not being connected yet.');
}
}
process.stdin.resume();
process.stdin.setEncoding("utf8");
process.stdin.on('data', initialListener);
process.on('exit', function(code) {
if (exited) return;
console.log("Received request to stop the process, stopping the game...");
gameProcess.kill('SIGTERM');
});
var waiting = true;
var poll = function( ) {
function createPacket(command) {
var packet = {
Identifier: -1,
Message: command,
Name: "WebRcon"
};
return JSON.stringify(packet);
}
var serverHostname = process.env.RCON_IP ? process.env.RCON_IP : "localhost";
var serverPort = process.env.RCON_PORT;
var serverPassword = process.env.RCON_PASS;
var WebSocket = require("ws");
var ws = new WebSocket("ws://" + serverHostname + ":" + serverPort + "/" + serverPassword);
ws.on("open", function open() {
console.log("Connected to RCON. Please wait until the server status switches to \"Running\".");
waiting = false;
// Hack to fix broken console output
ws.send(createPacket('status'));
process.stdin.removeListener('data', initialListener);
gameProcess.stdout.removeListener('data', filter);
gameProcess.stderr.removeListener('data', filter);
process.stdin.on('data', function (text) {
ws.send(createPacket(text));
});
});
ws.on("message", function(data, flags) {
try {
var json = JSON.parse(data);
if (json !== undefined) {
if (json.Message !== undefined && json.Message.length > 0) {
console.log(json.Message);
const fs = require("fs");
fs.appendFile("latest.log", "\n" + json.Message, (err) => {
if (err) console.log("Callback error in appendFile:"+err);
});
}
} else {
console.log("Error: Invalid JSON received");
}
} catch (e) {
if (e) {
console.log(e);
}
}
});
ws.on("error", function(err) {
waiting = true;
console.log("Waiting for RCON to come up...");
setTimeout(poll, 5000);
});
ws.on("close", function() {
if (!waiting) {
console.log("Connection to server closed.");
exited = true;
process.exit();
}
});
}
poll();