Skip to content

Instantly share code, notes, and snippets.

@nomisum
Created May 2, 2017 19:15
Show Gist options
  • Save nomisum/d498e3d9fd2d4519983a1df4785455c5 to your computer and use it in GitHub Desktop.
Save nomisum/d498e3d9fd2d4519983a1df4785455c5 to your computer and use it in GitHub Desktop.
server restart snippet
<?php
const SERVER_TEMPLATE_ROOT = '/home/arma3server/arma3/config/templates';
const RESTART_TRIGGER_FILENAME = '/tmp/arma3server-webrestart-command';
const ARMA3_PATH = '/home/arma3server/arma3';
$secretsFile = '/etc/arma3server-webrestart.ini';
$secrets = parse_ini_file($secretsFile);
if (!$secrets) {
echo 'MISSING SECRETS FILE OR SECRETS FILE INVALID. EXAMPLE FOR VALID STRUCTURE: nomisum=s3cr3t';
}
header("Content-Type: text/html;charset=UTF-8");
function send($statuscode, $message = '', $output = '')
{
if (!$message) {
switch ($statuscode) {
case 200:
$message = 'OK';
break;
case 500:
$message = 'Server error';
break;
default:
$message = 'wtf';
}
}
if (!$output) {
$output = $message;
}
header("HTTP/1.1 $statuscode $message");
echo $output;
exit;
}
function triggerRestart($user, $port, $template = '')
{
$date = date('Y-m-d H:i:s');
file_put_contents(
RESTART_TRIGGER_FILENAME,
json_encode([
'date' => $date,
'user' => $user,
'port' => $port,
'template' => $template
]) . "\n",
FILE_APPEND
);
chmod(RESTART_TRIGGER_FILENAME, 0666);
}
function getTemplateNames() {
if (!is_dir(SERVER_TEMPLATE_ROOT)) {
throw new RuntimeException('SERVER_TEMPLATE_ROOT must be a directory');
}
$is_dir = function ($filename) {
return is_dir(SERVER_TEMPLATE_ROOT . '/' . $filename) && !is_link(SERVER_TEMPLATE_ROOT . '/' . $filename);
};
$is_not_dot = function ($dirname) {
return strpos($dirname, '.') !== 0;
};
$is_not_dangerous = function ($dirname) {
return strpos($dirname, '..') === false;
};
$entries = scandir(SERVER_TEMPLATE_ROOT);
$entries = array_filter($entries, $is_dir);
$entries = array_filter($entries, $is_not_dot);
$entries = array_filter($entries, $is_not_dangerous);
return $entries;
}
function getServerPorts() {
$files = scandir(ARMA3_PATH);
$serverPorts = [];
foreach ($files as $file) {
$matches = [];
if (preg_match('/^arma3server-([0-9]{4,5})$/', $file, $matches)) {
$serverPorts[] = intval($matches[1]);
}
}
return $serverPorts;
}
$givenSecret = isset($_REQUEST['secret']) ? trim($_REQUEST['secret']) : '';
$givenPort = isset($_POST['port']) ? intval($_POST['port']) : 0;
$givenTemplate = isset($_POST['template']) ? trim($_POST['template']) : '';
$wantsRestart = isset($_POST['restart']);
$user = '';
if ($givenSecret && in_array($givenSecret, $secrets, true)) {
$user = array_flip($secrets)[$givenSecret];
}
if ($wantsRestart) {
if (!$givenPort) {
echo "invalid port";
exit;
}
if ($givenTemplate && !in_array($givenTemplate, getTemplateNames(), true)) {
echo "invalid template name given";
exit;
}
if (!$user) {
echo "I dont know you.";
exit;
}
$date = date('Y-m-d H:i:s');
syslog(LOG_INFO, "arma3server $givenPort restart triggered at $date by $user");
triggerRestart($user, $givenPort, $givenTemplate);
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Gruppe Adler Server Manager</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
<link rel="stylesheet" type="text/css" href="restart.css"/>
<style>
body {
margin: 1em;
}
</style>
</head>
<body>
<img src="https://www.gruppe-adler.de/wp-content/uploads/160x160_ocker.png" width="80" height="80">
<? if ($wantsRestart) {
$requestNumber = explode("\n", trim(file_get_contents(RESTART_TRIGGER_FILENAME)), 100);
?>
<div class="alert alert-success">
<h1>Neustart für <?= $givenPort ?> ausgelöst (<?= count($requestNumber) ?>)</h1>
</div>
<?
if (count($requestNumber) > 3) {
?>
<div class="alert alert-warning">
Es sind schon einige Neustart-Anweisungen aufgelaufen -- evtl ist hier was kaputt :(
</div>
<?
}
?>
<? } else { ?>
<h1>Server Neustart</h1> <? }
?>
<form name="restart" method="post" action="">
<div class="input-group">
<label>Authentification
<br>
<input type="text" name="secret" value="<?= $givenSecret ?>" required/>
</label>
<input type="hidden" name="restart" value="1"/>
</div>
<div class="input-group">
<label>
Port
<div class="selection">
<select name="port">
<option value="" selected>bitte w&auml;hlen</option>
<?php foreach (getServerPorts() as $serverPort) {?>
<option value="<?= $serverPort ?>"><?= $serverPort?></option>
<?php } ?>
</select>
</div>
</label>
</div>
<div class="input-group">
<label>
Konfiguration
<div class="selection">
<select name="template">
<option value="" selected>nicht &auml;ndern</option>
<?php foreach (getTemplateNames() as $templateName) { ?>
<option value="<?= $templateName ?>"><?= $templateName ?></option>
<?php } ?>
</select>
</div>
</label>
</div>
<div class="btn_container">
<div>
<button class="button" type="submit"><span>KILL</span></button>
</div>
</div>
</form>
<br><br>
<a href="https://arma3-servers.net/server/109969/" style="display: innline-block; margin-top: 20px"><img src="https://arma3-servers.net/server/109969/banners/half-banner-2.png" border="0"></a><a href="https://arma3-servers.net/server/109971/" style="margin-left:20px"><img src="https://arma3-servers.net/server/109971/banners/half-banner-2.png" border="0"></a>
<script>
(function () {
var
$authenticationInput = $('form[name=restart] input[name=secret]'),
auth = localStorage.getItem('adlertools-secret');
$authenticationInput.change(function () {
auth = this.value;
localStorage.setItem('adlertools-secret', auth);
});
$authenticationInput.val(auth);
}());
</script>
</body>
</html>
body {
background: #f0f0f0;
font-family: Arial;
text-align: center;
color: #3A474D;
}
input {
height: 40px;
font-size:26px;
border-radius: 3px;
width: 150px;
}
.input-group {
display: block;
}
label {
color: #767676;
margin-top: 10px;
display: inline-block;
}
.alert-success {
background-color: #6a6;
color: #fff;
border-radius: 3px;
}
#pagegradient {
background-image:
-webkit-gradient(
radial,
50% -50,
300,
50% 0,
0,
from(rgba(230, 237, 241, 0)),
to(rgba(230, 237, 241, 0.8)));
height:100%;
left:0px;
position:absolute;
top:0;
width: 600px;
}
.btn_container {
display:flex;justify-content:center;align-items:center;
}
.button {
border: none;
/*display: inline-block;*/
padding: 0;
margin: 0;
width: 200px;
height: 200px;
margin-top: 30px;
-webkit-border-radius: 100%;
border-radius: 100%;
-webkit-box-shadow:
0px 3px rgba(128,128,128,1), /* gradient effects */
0px 4px rgba(118,118,118,1),
0px 5px rgba(108,108,108,1),
0px 6px rgba(98,98,98,1),
0px 7px rgba(88,88,88,1),
0px 8px rgba(78,78,78,1),
0px 14px 6px -1px rgba(128,128,128,1); /* shadow */
-webkit-transition: -webkit-box-shadow .1s ease-in-out;
-webkit-transition: -webkit-box-shadow .1s ease-in-out;
}
.button span {
width: 200px;
height: 200px;
-webkit-border-radius: 100%;
border-radius: 100%;
line-height: 200px;
background-color: #E8E8E8;
-webkit-box-shadow:
0px -1px #fff, /* top highlight */
0px 1px 1px rgba(255,255,255,0); /* bottom edge */
/*-webkit-background-size: 100%, 100%, 100%, 4px 4px;*/
-webkit-transition: -webkit-transform .1s ease-in-out;
display: inline-block;
color: #3A474D;
text-transform: uppercase;
font-family: 'Arial';
font-weight: 700;
font-size: 26px;
text-shadow: 0px 1px #fff, 0px -1px #262F33;
}
.button:hover {
-webkit-transform: translate(0, -0.5px); /* depth of button press */
-webkit-box-shadow:
0px 4px rgba(128,128,128,1), /* gradient effects */
0px 5px rgba(118,118,118,1),
0px 6px rgba(108,108,108,1),
0px 7px rgba(98,98,98,1),
0px 8px rgba(88,88,88,1),
0px 9px rgba(78,78,78,1),
0px 10px rgba(78,78,78,1),
0px 14px 6px 0px rgba(128,128,128,1); /* shadow */
-webkit-transition: -webkit-transform .1s ease-in-out;
-webkit-transition: -webkit-box-shadow .1s ease-in-out;
}
.button span:hover {
color: #AEBF3B;
text-shadow: 0px -1px #97A63A;
cursor: pointer;
}
.button:active {
-webkit-box-shadow:
0px 0px rgba(128,128,128,1),
0px 1px rgba(118,118,118,1),
0px 2px rgba(108,108,108,1),
0px 3px rgba(98,98,98,1),
0px 4px rgba(88,88,88,1),
0px 5px rgba(78,78,78,1),
0px 10px 2px 0px rgba(128,128,128,.6); /* shadow */
-webkit-transition: -webkit-transform .1s ease-in-out;
-webkit-transition: -webkit-box-shadow .1s ease-in-out;
}
.button:active span{
-webkit-transform: translate(0, 3px); /* depth of button press */
-webkit-transition: -webkit-transform .1s ease-in-out;
}
select {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border:none;
border-radius: 0;
font-size: 1em;
width: 100%
overflow: -moz-hidden-unscrollable;
padding-right: .4em;
background: none;
border: 1px solid transparent;
min-width: 6em;
width: 130%;
min-width: -moz-calc(0em);
width: -moz-calc(100% + 2.4em);
min-width: calc(0em);
width: calc(100% + 2.4em);
width: 100%;
margin: 0;
outline: none;
padding: .6em .8em .5em .8em;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
font-size: 16px;
}
.selection {
width: 100%;
border: 1px solid #bbb;
border-radius: .3em;
box-shadow: 0 1px 0 1px rgba(0,0,0,.04);
background: #f3f3f3;
background: #fff -moz-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
background: #fff -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#e5e5e5));
background: #fff -webkit-linear-gradient(top, #ffffff 0%,#e5e5e5 100%);
background: #fff -o-linear-gradient(top, #ffffff 0%,#e5e5e5 100%);
background: #fff -ms-linear-gradient(top, #ffffff 0%,#e5e5e5 100%);
background: #fff linear-gradient(to bottom, #ffffff 0%,#e5e5e5 100%);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment