mirror of
https://ceregatti.org/git/daniel/dayzdockerserver.git
synced 2025-06-23 20:41:18 +00:00
Lots of layout changes.
Add placeholders for future functions. Add buttons for install, update, update mods, etc. Add bootstrap icons CDN. Remove old CSS in favor of Bootstrap classes. Add favico. Update docs.
This commit is contained in:
parent
8a8dc7f25a
commit
052304f450
6 changed files with 170 additions and 70 deletions
|
@ -18,6 +18,10 @@ This volume can get quite large. It will require at least 2G of disk space for t
|
||||||
Some map mods are as large as 10G. Make sure you have that much disk space in the location where docker stores its
|
Some map mods are as large as 10G. Make sure you have that much disk space in the location where docker stores its
|
||||||
volumes, usually `/var/lib/docker/volumes`.
|
volumes, usually `/var/lib/docker/volumes`.
|
||||||
|
|
||||||
|
## Goals
|
||||||
|
|
||||||
|
* Provide a turnkey DayZ server with mod support.
|
||||||
|
|
||||||
## Configure and Build
|
## Configure and Build
|
||||||
|
|
||||||
Ensure [Docker](https://docs.docker.com/engine/install/) and [Docker compose](https://docs.docker.com/compose/install/)
|
Ensure [Docker](https://docs.docker.com/engine/install/) and [Docker compose](https://docs.docker.com/compose/install/)
|
||||||
|
@ -152,7 +156,7 @@ docker compose exec main dayzserver force
|
||||||
When the server exits cleanly, i.e. exit code 0, the container also stops. Otherwise, a crash is presumed, and the server will be restarted.
|
When the server exits cleanly, i.e. exit code 0, the container also stops. Otherwise, a crash is presumed, and the server will be restarted.
|
||||||
|
|
||||||
NOTE: As DayZ Experimental 1.19, the server is known to not exit upon SIGINT when mods are installed. This makes force stopping the server
|
NOTE: As DayZ Experimental 1.19, the server is known to not exit upon SIGINT when mods are installed. This makes force stopping the server
|
||||||
required. This is not a clean exit, and will cause the server to restart. Manually take the server [down](#down) to stop the container.
|
required. This is not a clean exit, and will cause the server to restart. Manually take the server [down](#stop) to stop the container.
|
||||||
|
|
||||||
### Workshop - Add / List / Remove / Update mods
|
### Workshop - Add / List / Remove / Update mods
|
||||||
|
|
||||||
|
|
BIN
web/root/favicon.png
Normal file
BIN
web/root/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 81 KiB |
|
@ -1,23 +1,15 @@
|
||||||
body {
|
body {
|
||||||
padding-top: 10px;
|
padding: 10px;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
}
|
}
|
||||||
.green {
|
|
||||||
color: green;
|
button {
|
||||||
font-weight: bolder;
|
padding: 5px;
|
||||||
}
|
margin: 10px;
|
||||||
.yellow {
|
|
||||||
color: yellow;
|
|
||||||
font-weight: bolder;
|
|
||||||
}
|
|
||||||
.darkgrey {
|
|
||||||
background-color: darkgray;
|
|
||||||
font-weight: bolder;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.modInfo {
|
th, td {
|
||||||
background-color: aliceblue;
|
padding-right: 10px
|
||||||
}
|
}
|
||||||
|
|
||||||
.result {
|
.result {
|
||||||
|
@ -32,7 +24,3 @@ body {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-underline: blue;
|
text-underline: blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
th, td {
|
|
||||||
padding-right: 10px
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>DayZ Docker Server</title>
|
<title>DayZ Docker Server</title>
|
||||||
|
<link rel="icon" type="image/x-icon" href="/favicon.png">
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
||||||
<link rel="stylesheet" href="/index.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.3.0/font/bootstrap-icons.css"> <link rel="stylesheet" href="/index.css">
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
|
||||||
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
|
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
|
||||||
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
|
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
|
||||||
|
|
|
@ -1,31 +1,48 @@
|
||||||
const template = `
|
const template = `
|
||||||
<div class="container-fluid">
|
<div class="container-fluid bg-light">
|
||||||
<div class="row jumbotron darkgrey">
|
<div class="d-flex justify-content-between">
|
||||||
<div class="col-7">
|
<div class="text-center">
|
||||||
<h1>DayZ Docker Server</h1>
|
<h1>DayZ Docker Server</h1>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex">
|
||||||
|
<div class="text-center">
|
||||||
|
<button
|
||||||
|
@click="install"
|
||||||
|
:class="'btn ' + (installed ? 'btn-danger' : 'btn-success')"
|
||||||
|
>
|
||||||
|
Install Server Files
|
||||||
|
</button>
|
||||||
|
<button @click="updatebase" class="btn btn-warning">Update Base</button>
|
||||||
|
<button @click="updatemods" class="btn btn-warning">Update Mods</button>
|
||||||
|
</div>
|
||||||
|
<div class="text-center">
|
||||||
|
<button @click="server" class="btn btn-primary">Server</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3 form-control-lg">
|
<div class="form-control-lg">
|
||||||
<form @submit="handleSubmit">
|
<form @submit="handleSubmit">
|
||||||
<input name="search" placeholder="Search mods..." autofocus>
|
<input name="search" placeholder="Search mods..." autofocus>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-2">
|
<div>
|
||||||
<div>
|
<div class="justify-right">
|
||||||
Server files installed: {{ installed }}
|
Server files installed:
|
||||||
|
<span class="bi bi-check h2 text-success" v-if="installed"></span>
|
||||||
|
<span class="bi bi-x h2 danger text-danger" v-else></span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div v-if="version != ''">
|
||||||
Version: {{ version }}
|
Version: <span class="text-success font-weight-bold">{{ version }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="fetchError != ''"
|
v-if="fetchError != ''"
|
||||||
class="row jumbotron text-center alert alert-danger"
|
class="text-center alert alert-danger"
|
||||||
>
|
>
|
||||||
{{ fetchError }}
|
{{ fetchError }}
|
||||||
</div>
|
</div>
|
||||||
<div class="row jumbotron darkgrey">
|
<div class="d-flex">
|
||||||
<div class="col-3">
|
<div>
|
||||||
<h2 class="text-center">Mods</h2>
|
<h2 class="text-center">Mods</h2>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -39,7 +56,7 @@ const template = `
|
||||||
<td>
|
<td>
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
:href="'https://steamcommunity.com/sharedfiles/filedetails/?id=' + mod.id"
|
:href="steamURL + mod.id"
|
||||||
>
|
>
|
||||||
{{ mod.id }}
|
{{ mod.id }}
|
||||||
</a>
|
</a>
|
||||||
|
@ -51,7 +68,40 @@ const template = `
|
||||||
</template>
|
</template>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-9 modInfo" v-if="searchResults != ''">
|
<div v-if="modInfo != ''">
|
||||||
|
<div>
|
||||||
|
<h3>{{ modInfo.name }}</h3>
|
||||||
|
<div class="d-flex">
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
ID: {{ modInfo.id }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Size: {{ modInfo.size.toLocaleString("en-US") }}
|
||||||
|
</div>
|
||||||
|
<div v-if="modInfo.customXML.length > 0">
|
||||||
|
Custom XML files:
|
||||||
|
<ul>
|
||||||
|
<li v-for="info in modInfo.customXML">
|
||||||
|
<a
|
||||||
|
:class="'simulink xmlfile ' + info.name"
|
||||||
|
@click="getXMLInfo(modInfo.id,info.name)"
|
||||||
|
>
|
||||||
|
{{ info.name }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div v-if="XMLInfo != ''">
|
||||||
|
<textarea cols="120" rows="15" v-if="this.XMLInfo != ''">{{ this.XMLInfo }}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="searchResults != ''">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Steam Link</th>
|
<th>Steam Link</th>
|
||||||
|
@ -65,9 +115,9 @@ const template = `
|
||||||
<td>
|
<td>
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
:href="'https://steamcommunity.com/sharedfiles/filedetails/?id=' + result.publishedfileid"
|
:href="steamURL + result.publishedfileid"
|
||||||
>
|
>
|
||||||
<img data-bs-toggle="tooltip" data-bs-placement="left" :title="result.short_description" width="160" height="90" :src="result.preview_url">
|
<img :alt="result.short_description" data-bs-toggle="tooltip" data-bs-placement="left" :title="result.short_description" width="160" height="90" :src="result.preview_url">
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ result.title }}</td>
|
<td>{{ result.title }}</td>
|
||||||
|
@ -81,37 +131,6 @@ const template = `
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-9 modInfo" v-if="modInfo != ''">
|
|
||||||
<div class="text-center col-12">
|
|
||||||
<h2>{{ modInfo.name }} mod info:</h2>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-2">
|
|
||||||
<div>
|
|
||||||
ID: {{ modInfo.id }}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Size: {{ modInfo.size.toLocaleString("en-US") }}
|
|
||||||
</div>
|
|
||||||
<div v-if="modInfo.customXML.length > 0">
|
|
||||||
Custom XML files:
|
|
||||||
<ul>
|
|
||||||
<li v-for="info in modInfo.customXML">
|
|
||||||
<a
|
|
||||||
:class="'simulink xmlfile ' + info.name"
|
|
||||||
@click="getXMLInfo(modInfo.id,info.name)"
|
|
||||||
>
|
|
||||||
{{ info.name }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-10">
|
|
||||||
<textarea cols="120" rows="15" v-if="this.XMLInfo != ''">{{ this.XMLInfo }}</textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
@ -126,6 +145,7 @@ export default {
|
||||||
mods: [],
|
mods: [],
|
||||||
modInfo: "",
|
modInfo: "",
|
||||||
searchResults: [],
|
searchResults: [],
|
||||||
|
steamURL: 'https://steamcommunity.com/sharedfiles/filedetails/?id=',
|
||||||
version: "Unknown",
|
version: "Unknown",
|
||||||
XMLFile: "",
|
XMLFile: "",
|
||||||
XMLInfo: "",
|
XMLInfo: "",
|
||||||
|
@ -196,6 +216,17 @@ export default {
|
||||||
this.fetchError = error.message
|
this.fetchError = error.message
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
removeMod(modId) {
|
||||||
|
fetch('/remove/' + modId)
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(response => {
|
||||||
|
console.log(response)
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(error)
|
||||||
|
this.fetchError = error.message
|
||||||
|
})
|
||||||
|
},
|
||||||
BKMG(val) {
|
BKMG(val) {
|
||||||
const units = ['bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
|
const units = ['bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
|
||||||
let l = 0, n = parseInt(val, 10) || 0
|
let l = 0, n = parseInt(val, 10) || 0
|
||||||
|
|
78
web/web.js
78
web/web.js
|
@ -1,3 +1,11 @@
|
||||||
|
/*
|
||||||
|
A DayZ Linux server provisioning system.
|
||||||
|
|
||||||
|
This is the web UI for provisioning a DayZ server running under Linux.
|
||||||
|
It manages the main container that installs and maintains the base DayZ server files
|
||||||
|
along with all mod base files. The goal being to keep all of these centralized and consistent,
|
||||||
|
but to also make them available for the creation of server containers.
|
||||||
|
*/
|
||||||
import express from 'express'
|
import express from 'express'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
|
@ -45,6 +53,49 @@ const configFiles = [
|
||||||
'types.xml',
|
'types.xml',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// From https://helpthedeadreturn.wordpress.com/2019/07/17/dayz-sa-mission-file
|
||||||
|
const allConfigFiles = {
|
||||||
|
"db": [ // global server config and core loot economy files
|
||||||
|
"events.xml", // dynamic events
|
||||||
|
"globals.xml", // global settings
|
||||||
|
"messages.xml", // server broadcast messages and shutdown
|
||||||
|
"types.xml" // loot table
|
||||||
|
],
|
||||||
|
"env": [ // coordinates, static and dynamic spawns for each entity
|
||||||
|
"cattle_territories.xml",
|
||||||
|
"domestic_animals_territories.xml",
|
||||||
|
"hare_territories.xml",
|
||||||
|
"hen_territories.xml",
|
||||||
|
"pig_territories.xml",
|
||||||
|
"red_deer_territories.xml",
|
||||||
|
"roe_deer_territories.xml",
|
||||||
|
"sheep_goat_territories.xml",
|
||||||
|
"wild_boar_territories.xml",
|
||||||
|
"wolf_territories.xml",
|
||||||
|
"zombie_territories.xml"
|
||||||
|
],
|
||||||
|
"root": [
|
||||||
|
"cfgeconomycore.xml", // loot economy core settings and extensions
|
||||||
|
"cfgeffectarea.json", // static contaminated area coordinates and other properties
|
||||||
|
"cfgenvironment.xml", // includes env\* files and parameters
|
||||||
|
"cfgeventgroups.xml", // definitions of groups of objects that spawn together in a dynamic event
|
||||||
|
"cfgeventspawns.xml", // coordinates where events may occur
|
||||||
|
"cfggameplay.json", // gameplay configuration settings.
|
||||||
|
"cfgIgnoreList.xml", // list of items that won’t be loaded from the storage
|
||||||
|
"cfglimitsdefinition.xml", // list of valid categories, tags, usageflags and valueflags
|
||||||
|
"cfglimitsdefinitionuser.xml", // shortcut groups of usageflags and valueflags
|
||||||
|
"cfgplayerspawnpoints.xml", // new character spawn points
|
||||||
|
"cfgrandompresets.xml", // collection of groups of items
|
||||||
|
"cfgspawnabletypes.xml", // loot categorization (ie hoarder) as well as set of items that spawn as cargo or as attachment on weapons, vehicles or infected.
|
||||||
|
"cfgundergroundtriggers.json", // used for triggering light and sounds in the Livonia bunker, not used for Chernarus
|
||||||
|
"cfgweather.xml", // weather configuration
|
||||||
|
"init.c", // mission startup file (PC only)
|
||||||
|
"map*.xml",
|
||||||
|
"mapgroupproto.xml", // structures, tags, maxloot and lootpoints
|
||||||
|
"mapgrouppos.xml" // all valid lootpoints
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
installFile: serverFiles + "/DayZServer",
|
installFile: serverFiles + "/DayZServer",
|
||||||
modDir: modDir + "/" + client_appid,
|
modDir: modDir + "/" + client_appid,
|
||||||
|
@ -52,6 +103,13 @@ const config = {
|
||||||
steamAPIKey: process.env["STEAMAPIKEY"]
|
steamAPIKey: process.env["STEAMAPIKEY"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getVersion = (installed) => {
|
||||||
|
if(installed) {
|
||||||
|
return "1.20.bogus"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
const getDirSize = (dirPath) => {
|
const getDirSize = (dirPath) => {
|
||||||
let size = 0
|
let size = 0
|
||||||
const files = fs.readdirSync(dirPath)
|
const files = fs.readdirSync(dirPath)
|
||||||
|
@ -144,6 +202,23 @@ app.get(('/install/:modId'), (req, res) => {
|
||||||
res.send(modId + " was installed")
|
res.send(modId + " was installed")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Remove a mod
|
||||||
|
app.get(('/remove/:modId'), (req, res) => {
|
||||||
|
const modId = req.params["modId"]
|
||||||
|
// Shell out to steamcmd, monitor the process, and display the output as it runs
|
||||||
|
res.send(modId + " was removed")
|
||||||
|
})
|
||||||
|
|
||||||
|
// Update base files
|
||||||
|
app.get('/updatebase', (req, res) => {
|
||||||
|
res.send("Base files were updates")
|
||||||
|
})
|
||||||
|
|
||||||
|
// Update mods
|
||||||
|
app.get('/updatemods', (req, res) => {
|
||||||
|
res.send("Mod files were updates")
|
||||||
|
})
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get the status of things:
|
Get the status of things:
|
||||||
If the base files are installed, the version of the server, a list of mods, etc.
|
If the base files are installed, the version of the server, a list of mods, etc.
|
||||||
|
@ -152,9 +227,10 @@ app.get('/status', (req, res) => {
|
||||||
// FIXME Async/await this stuff...
|
// FIXME Async/await this stuff...
|
||||||
const installed = fs.existsSync(config.installFile)
|
const installed = fs.existsSync(config.installFile)
|
||||||
const mods = getMods()
|
const mods = getMods()
|
||||||
|
const version = getVersion(installed)
|
||||||
const ret = {
|
const ret = {
|
||||||
"installed": installed,
|
"installed": installed,
|
||||||
"version": "1.20.bogus",
|
"version": version,
|
||||||
"mods": mods
|
"mods": mods
|
||||||
}
|
}
|
||||||
res.send(ret)
|
res.send(ret)
|
||||||
|
|
Loading…
Add table
Reference in a new issue