Add and setup Waterfall
- Copying config files automatically - Successfully joined servers, though it won't automatically redirect just yet
This commit is contained in:
parent
d584d7540e
commit
ad48a7f528
9 changed files with 341 additions and 15 deletions
7
.docker/bungee/Dockerfile
Normal file
7
.docker/bungee/Dockerfile
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
FROM eclipse-temurin:17-jre-focal
|
||||||
|
|
||||||
|
COPY .docker/bungee/start.sh ./
|
||||||
|
|
||||||
|
WORKDIR /mcserver
|
||||||
|
|
||||||
|
ENTRYPOINT ["bash", "/start.sh"]
|
8
.docker/bungee/start.sh
Normal file
8
.docker/bungee/start.sh
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
trap "echo Received stop signal; pkill java" INT TERM EXIT
|
||||||
|
ls -la
|
||||||
|
file=$(ls waterfall*.jar | tail -1)
|
||||||
|
echo Starting $file
|
||||||
|
mkdir -p proxy
|
||||||
|
cd proxy
|
||||||
|
java -jar ../$file
|
||||||
|
echo Stopped!
|
|
@ -27,6 +27,20 @@ services:
|
||||||
aliases:
|
aliases:
|
||||||
- server2
|
- server2
|
||||||
container_name: mc-server2
|
container_name: mc-server2
|
||||||
|
bungee:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: .docker/bungee/Dockerfile
|
||||||
|
image: bungee
|
||||||
|
container_name: dockermc-bungee
|
||||||
|
networks:
|
||||||
|
dockermc:
|
||||||
|
aliases:
|
||||||
|
- bungee
|
||||||
|
volumes:
|
||||||
|
- dockermc:/mcserver
|
||||||
|
ports:
|
||||||
|
- 25565:25577
|
||||||
volumes:
|
volumes:
|
||||||
dockermc:
|
dockermc:
|
||||||
name: dockermc
|
name: dockermc
|
||||||
|
|
58
.docker/mcserver/configs/server.properties
Normal file
58
.docker/mcserver/configs/server.properties
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#Minecraft server properties
|
||||||
|
#Mon Jul 04 21:41:28 UTC 2022
|
||||||
|
enable-jmx-monitoring=false
|
||||||
|
rcon.port=25575
|
||||||
|
level-seed=
|
||||||
|
gamemode=survival
|
||||||
|
enable-command-block=false
|
||||||
|
enable-query=false
|
||||||
|
generator-settings={}
|
||||||
|
enforce-secure-profile=false
|
||||||
|
level-name=world
|
||||||
|
motd=A Minecraft Server
|
||||||
|
query.port=25565
|
||||||
|
pvp=true
|
||||||
|
generate-structures=true
|
||||||
|
max-chained-neighbor-updates=1000000
|
||||||
|
difficulty=easy
|
||||||
|
network-compression-threshold=256
|
||||||
|
max-tick-time=60000
|
||||||
|
require-resource-pack=false
|
||||||
|
use-native-transport=true
|
||||||
|
max-players=20
|
||||||
|
online-mode=false
|
||||||
|
enable-status=true
|
||||||
|
allow-flight=false
|
||||||
|
broadcast-rcon-to-ops=true
|
||||||
|
view-distance=10
|
||||||
|
server-ip=
|
||||||
|
resource-pack-prompt=
|
||||||
|
allow-nether=true
|
||||||
|
server-port=25565
|
||||||
|
enable-rcon=false
|
||||||
|
sync-chunk-writes=true
|
||||||
|
op-permission-level=4
|
||||||
|
prevent-proxy-connections=false
|
||||||
|
hide-online-players=false
|
||||||
|
resource-pack=
|
||||||
|
entity-broadcast-range-percentage=100
|
||||||
|
simulation-distance=10
|
||||||
|
rcon.password=
|
||||||
|
player-idle-timeout=0
|
||||||
|
debug=false
|
||||||
|
force-gamemode=false
|
||||||
|
rate-limit=0
|
||||||
|
hardcore=false
|
||||||
|
white-list=false
|
||||||
|
broadcast-console-to-ops=true
|
||||||
|
spawn-npcs=true
|
||||||
|
previews-chat=false
|
||||||
|
spawn-animals=true
|
||||||
|
function-permission-level=2
|
||||||
|
level-type=minecraft\:normal
|
||||||
|
text-filtering-config=
|
||||||
|
spawn-monsters=true
|
||||||
|
enforce-whitelist=false
|
||||||
|
spawn-protection=16
|
||||||
|
resource-pack-sha1=
|
||||||
|
max-world-size=29999984
|
170
.docker/mcserver/configs/spigot.yml
Normal file
170
.docker/mcserver/configs/spigot.yml
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
# This is the main configuration file for Spigot.
|
||||||
|
# As you can see, there's tons to configure. Some options may impact gameplay, so use
|
||||||
|
# with caution, and make sure you know what each option does before configuring.
|
||||||
|
# For a reference for any variable inside this file, check out the Spigot wiki at
|
||||||
|
# http://www.spigotmc.org/wiki/spigot-configuration/
|
||||||
|
#
|
||||||
|
# If you need help with the configuration or have any questions related to Spigot,
|
||||||
|
# join us at the Discord or drop by our forums and leave a post.
|
||||||
|
#
|
||||||
|
# Discord: https://www.spigotmc.org/go/discord
|
||||||
|
# Forums: http://www.spigotmc.org/
|
||||||
|
|
||||||
|
settings:
|
||||||
|
debug: false
|
||||||
|
timeout-time: 60
|
||||||
|
restart-on-crash: true
|
||||||
|
restart-script: ./start.sh
|
||||||
|
bungeecord: true
|
||||||
|
sample-count: 12
|
||||||
|
player-shuffle: 0
|
||||||
|
user-cache-size: 1000
|
||||||
|
save-user-cache-on-stop-only: false
|
||||||
|
moved-wrongly-threshold: 0.0625
|
||||||
|
moved-too-quickly-multiplier: 10.0
|
||||||
|
netty-threads: 4
|
||||||
|
attribute:
|
||||||
|
maxHealth:
|
||||||
|
max: 2048.0
|
||||||
|
movementSpeed:
|
||||||
|
max: 2048.0
|
||||||
|
attackDamage:
|
||||||
|
max: 2048.0
|
||||||
|
log-villager-deaths: true
|
||||||
|
log-named-deaths: true
|
||||||
|
messages:
|
||||||
|
whitelist: You are not whitelisted on this server!
|
||||||
|
unknown-command: Unknown command. Type "/help" for help.
|
||||||
|
server-full: The server is full!
|
||||||
|
outdated-client: Outdated client! Please use {0}
|
||||||
|
outdated-server: Outdated server! I'm still on {0}
|
||||||
|
restart: Server is restarting
|
||||||
|
advancements:
|
||||||
|
disable-saving: false
|
||||||
|
disabled:
|
||||||
|
- minecraft:story/disabled
|
||||||
|
commands:
|
||||||
|
spam-exclusions:
|
||||||
|
- /skill
|
||||||
|
silent-commandblock-console: false
|
||||||
|
replace-commands:
|
||||||
|
- setblock
|
||||||
|
- summon
|
||||||
|
- testforblock
|
||||||
|
- tellraw
|
||||||
|
log: true
|
||||||
|
tab-complete: 0
|
||||||
|
send-namespaced: true
|
||||||
|
players:
|
||||||
|
disable-saving: false
|
||||||
|
world-settings:
|
||||||
|
default:
|
||||||
|
below-zero-generation-in-existing-chunks: true
|
||||||
|
merge-radius:
|
||||||
|
item: 2.5
|
||||||
|
exp: 3.0
|
||||||
|
item-despawn-rate: 6000
|
||||||
|
view-distance: default
|
||||||
|
simulation-distance: default
|
||||||
|
thunder-chance: 100000
|
||||||
|
enable-zombie-pigmen-portal-spawns: true
|
||||||
|
wither-spawn-sound-radius: 0
|
||||||
|
hanging-tick-frequency: 100
|
||||||
|
arrow-despawn-rate: 1200
|
||||||
|
trident-despawn-rate: 1200
|
||||||
|
zombie-aggressive-towards-villager: true
|
||||||
|
nerf-spawner-mobs: false
|
||||||
|
mob-spawn-range: 8
|
||||||
|
end-portal-sound-radius: 0
|
||||||
|
growth:
|
||||||
|
cactus-modifier: 100
|
||||||
|
cane-modifier: 100
|
||||||
|
melon-modifier: 100
|
||||||
|
mushroom-modifier: 100
|
||||||
|
pumpkin-modifier: 100
|
||||||
|
sapling-modifier: 100
|
||||||
|
beetroot-modifier: 100
|
||||||
|
carrot-modifier: 100
|
||||||
|
potato-modifier: 100
|
||||||
|
wheat-modifier: 100
|
||||||
|
netherwart-modifier: 100
|
||||||
|
vine-modifier: 100
|
||||||
|
cocoa-modifier: 100
|
||||||
|
bamboo-modifier: 100
|
||||||
|
sweetberry-modifier: 100
|
||||||
|
kelp-modifier: 100
|
||||||
|
twistingvines-modifier: 100
|
||||||
|
weepingvines-modifier: 100
|
||||||
|
cavevines-modifier: 100
|
||||||
|
glowberry-modifier: 100
|
||||||
|
entity-activation-range:
|
||||||
|
animals: 32
|
||||||
|
monsters: 32
|
||||||
|
raiders: 48
|
||||||
|
misc: 16
|
||||||
|
water: 16
|
||||||
|
villagers: 32
|
||||||
|
flying-monsters: 32
|
||||||
|
wake-up-inactive:
|
||||||
|
animals-max-per-tick: 4
|
||||||
|
animals-every: 1200
|
||||||
|
animals-for: 100
|
||||||
|
monsters-max-per-tick: 8
|
||||||
|
monsters-every: 400
|
||||||
|
monsters-for: 100
|
||||||
|
villagers-max-per-tick: 4
|
||||||
|
villagers-every: 600
|
||||||
|
villagers-for: 100
|
||||||
|
flying-monsters-max-per-tick: 8
|
||||||
|
flying-monsters-every: 200
|
||||||
|
flying-monsters-for: 100
|
||||||
|
villagers-work-immunity-after: 100
|
||||||
|
villagers-work-immunity-for: 20
|
||||||
|
villagers-active-for-panic: true
|
||||||
|
tick-inactive-villagers: true
|
||||||
|
ignore-spectators: false
|
||||||
|
entity-tracking-range:
|
||||||
|
players: 48
|
||||||
|
animals: 48
|
||||||
|
monsters: 48
|
||||||
|
misc: 32
|
||||||
|
other: 64
|
||||||
|
ticks-per:
|
||||||
|
hopper-transfer: 8
|
||||||
|
hopper-check: 1
|
||||||
|
hopper-amount: 1
|
||||||
|
hopper-can-load-chunks: false
|
||||||
|
dragon-death-sound-radius: 0
|
||||||
|
seed-village: 10387312
|
||||||
|
seed-desert: 14357617
|
||||||
|
seed-igloo: 14357618
|
||||||
|
seed-jungle: 14357619
|
||||||
|
seed-swamp: 14357620
|
||||||
|
seed-monument: 10387313
|
||||||
|
seed-shipwreck: 165745295
|
||||||
|
seed-ocean: 14357621
|
||||||
|
seed-outpost: 165745296
|
||||||
|
seed-endcity: 10387313
|
||||||
|
seed-slime: 987234911
|
||||||
|
seed-nether: 30084232
|
||||||
|
seed-mansion: 10387319
|
||||||
|
seed-fossil: 14357921
|
||||||
|
seed-portal: 34222645
|
||||||
|
seed-stronghold: default
|
||||||
|
hunger:
|
||||||
|
jump-walk-exhaustion: 0.05
|
||||||
|
jump-sprint-exhaustion: 0.2
|
||||||
|
combat-exhaustion: 0.1
|
||||||
|
regen-exhaustion: 6.0
|
||||||
|
swim-multiplier: 0.01
|
||||||
|
sprint-multiplier: 0.1
|
||||||
|
other-multiplier: 0.0
|
||||||
|
max-tnt-per-tick: 100
|
||||||
|
max-tick-time:
|
||||||
|
tile: 50
|
||||||
|
entity: 50
|
||||||
|
verbose: false
|
||||||
|
config-version: 12
|
||||||
|
stats:
|
||||||
|
disable-saving: false
|
||||||
|
forced-stats: {}
|
57
.docker/mcserver/proxy/config.yml
Normal file
57
.docker/mcserver/proxy/config.yml
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
enforce_secure_profile: false
|
||||||
|
listeners:
|
||||||
|
- query_port: 25577
|
||||||
|
motd: '&bDockerMC proxy'
|
||||||
|
tab_list: GLOBAL_PING
|
||||||
|
query_enabled: false
|
||||||
|
proxy_protocol: false
|
||||||
|
forced_hosts:
|
||||||
|
pvp.md-5.net: pvp
|
||||||
|
ping_passthrough: false
|
||||||
|
priorities:
|
||||||
|
- server1
|
||||||
|
- server2
|
||||||
|
bind_local_address: true
|
||||||
|
host: 0.0.0.0:25577
|
||||||
|
max_players: 1
|
||||||
|
tab_size: 60
|
||||||
|
force_default_server: false
|
||||||
|
remote_ping_cache: -1
|
||||||
|
network_compression_threshold: 256
|
||||||
|
permissions:
|
||||||
|
default:
|
||||||
|
- bungeecord.command.server
|
||||||
|
- bungeecord.command.list
|
||||||
|
admin:
|
||||||
|
- bungeecord.command.alert
|
||||||
|
- bungeecord.command.end
|
||||||
|
- bungeecord.command.ip
|
||||||
|
- bungeecord.command.reload
|
||||||
|
- bungeecord.command.kick
|
||||||
|
log_pings: true
|
||||||
|
connection_throttle_limit: 3
|
||||||
|
server_connect_timeout: 20000
|
||||||
|
timeout: 30000
|
||||||
|
stats: 117e0ead-f30b-4062-9fcc-647f38dfabca
|
||||||
|
player_limit: -1
|
||||||
|
ip_forward: true
|
||||||
|
groups:
|
||||||
|
md_5:
|
||||||
|
- admin
|
||||||
|
remote_ping_timeout: 5000
|
||||||
|
connection_throttle: 4000
|
||||||
|
log_commands: false
|
||||||
|
prevent_proxy_connections: false
|
||||||
|
online_mode: true
|
||||||
|
forge_support: true
|
||||||
|
disabled_commands:
|
||||||
|
- disabledcommandhere
|
||||||
|
servers:
|
||||||
|
server1:
|
||||||
|
motd: '&bDockerMC server 1'
|
||||||
|
address: server1:25565
|
||||||
|
restricted: false
|
||||||
|
server2:
|
||||||
|
motd: '&aDockerMC server 2'
|
||||||
|
address: server2:25565
|
||||||
|
restricted: false
|
|
@ -3,7 +3,7 @@
|
||||||
#done
|
#done
|
||||||
trap "echo Received stop signal; pkill java" INT TERM EXIT
|
trap "echo Received stop signal; pkill java" INT TERM EXIT
|
||||||
ls -la
|
ls -la
|
||||||
file=$(ls *.jar | tail -1)
|
file=$(ls paper*.jar | tail -1)
|
||||||
echo Starting $file
|
echo Starting $file
|
||||||
mkdir -p $MC_SERVER
|
mkdir -p $MC_SERVER
|
||||||
cd $MC_SERVER
|
cd $MC_SERVER
|
||||||
|
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,4 +1,7 @@
|
||||||
/src/dist/
|
/src/dist/
|
||||||
.idea
|
.idea
|
||||||
node_modules
|
node_modules
|
||||||
.docker/mcserver
|
.docker/mcserver/proxy
|
||||||
|
.docker/mcserver/server*
|
||||||
|
.docker/mcserver/*.jar
|
||||||
|
.docker/mcserver/plugins
|
||||||
|
|
35
src/index.ts
35
src/index.ts
|
@ -18,14 +18,27 @@ const running: {
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
console.log("Checking for server updates...", "MC", process.env.MC_VERSION);
|
console.log("Checking for server updates...", "MC", process.env.MC_VERSION);
|
||||||
const res: { builds: Build[] } = await (await fetch(`https://api.papermc.io/v2/projects/paper/versions/${process.env.MC_VERSION}/builds`)).json() as any;
|
await updateServer('paper');
|
||||||
|
await updateServer('waterfall');
|
||||||
|
console.log('Starting server proxy...');
|
||||||
|
exec('docker compose -f /docker-compose.server.yml up -d bungee', loggingCallback);
|
||||||
|
const listener = async (changedPath) => {
|
||||||
|
console.log(`Plugin change detected at ${changedPath}, switching to ${running.prevServerName()}...`);
|
||||||
|
await startNextServer();
|
||||||
|
};
|
||||||
|
running.watch = chokidar.watch(`/mcserver/plugins/*.jar`).on('change', debounce(listener, 500));
|
||||||
|
await startNextServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateServer(project: 'paper' | 'waterfall') {
|
||||||
|
const res: { builds: Build[] } = await (await fetch(`https://api.papermc.io/v2/projects/${project}/versions/${process.env.MC_VERSION}/builds`)).json() as any;
|
||||||
const lastBuild = res.builds[res.builds.length - 1];
|
const lastBuild = res.builds[res.builds.length - 1];
|
||||||
console.log("Latest build is", lastBuild.build, "at", new Date(Date.parse(lastBuild.time)).toLocaleString())
|
console.log(`Latest ${project} build is ${lastBuild.build} at ${new Date(Date.parse(lastBuild.time)).toLocaleString()}`);
|
||||||
try {
|
try {
|
||||||
await promises.access('/mcserver/' + lastBuild.downloads.application.name)
|
await promises.access('/mcserver/' + lastBuild.downloads.application.name)
|
||||||
} catch {
|
} catch {
|
||||||
console.log("Build not found locally, downloading...");
|
console.log("Build not found locally, downloading...");
|
||||||
const newVerRes = await fetch(`https://api.papermc.io/v2/projects/paper/versions/${process.env.MC_VERSION}/builds/${lastBuild.build}/downloads/${lastBuild.downloads.application.name}`);
|
const newVerRes = await fetch(`https://api.papermc.io/v2/projects/${project}/versions/${process.env.MC_VERSION}/builds/${lastBuild.build}/downloads/${lastBuild.downloads.application.name}`);
|
||||||
if (newVerRes.status > 299) {
|
if (newVerRes.status > 299) {
|
||||||
console.log("Error while downloading", await newVerRes.json());
|
console.log("Error while downloading", await newVerRes.json());
|
||||||
throw new Error("Error while downloading");
|
throw new Error("Error while downloading");
|
||||||
|
@ -34,32 +47,28 @@ async function main() {
|
||||||
console.log("Build downloaded", lastBuild.downloads.application.name);
|
console.log("Build downloaded", lastBuild.downloads.application.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const listener = async (changedPath) => {
|
|
||||||
console.log(`Plugin change detected at ${changedPath}, switching to ${running.prevServerName()}`);
|
|
||||||
await startNextServer();
|
|
||||||
};
|
|
||||||
running.watch = chokidar.watch(`/mcserver/plugins/*.jar`).on('change', debounce(listener, 500));
|
|
||||||
await startNextServer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function startNextServer() {
|
async function startNextServer() {
|
||||||
running.server1 = !running.server1;
|
running.server1 = !running.server1;
|
||||||
console.log("Copying plugin files to", running.serverName());
|
console.log(`Copying plugin files to ${running.serverName()}...`);
|
||||||
await promises.cp('/mcserver/plugins', `/mcserver/${running.serverName()}/plugins`, {recursive: true}); // TODO: Don't run servers as root
|
await promises.cp('/mcserver/plugins', `/mcserver/${running.serverName()}/plugins`, {recursive: true}); // TODO: Don't run servers as root
|
||||||
// TODO: Copy config files back to main plugins dir
|
// TODO: Copy config files back to main plugins dir
|
||||||
console.log("Starting server", running.server1 ? 'one' : 'two');
|
console.log('Copying config files...');
|
||||||
|
await promises.cp('/mcserver/configs', `/mcserver/${running.serverName()}`, {recursive: true});
|
||||||
|
console.log("Starting server", running.server1 ? 'one...' : 'two...');
|
||||||
exec('docker compose -f /docker-compose.server.yml up -d ' + running.serverName(), loggingCallback);
|
exec('docker compose -f /docker-compose.server.yml up -d ' + running.serverName(), loggingCallback);
|
||||||
await waitForStartup();
|
await waitForStartup();
|
||||||
await stopPrevServer();
|
await stopPrevServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stopPrevServer() {
|
async function stopPrevServer() {
|
||||||
console.log("Stopping previous server");
|
console.log("Stopping previous server...");
|
||||||
exec('docker compose -f /docker-compose.server.yml stop ' + running.prevServerName(), loggingCallback);
|
exec('docker compose -f /docker-compose.server.yml stop ' + running.prevServerName(), loggingCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function waitForStartup() {
|
function waitForStartup() {
|
||||||
console.log("Waiting for startup");
|
console.log("Waiting for startup...");
|
||||||
return new Promise<void>(function (resolve, reject) {
|
return new Promise<void>(function (resolve, reject) {
|
||||||
exec(`wait-for-it ${running.serverName()}:25565 -t 60`, loggingCallback).on('exit', function (code) {
|
exec(`wait-for-it ${running.serverName()}:25565 -t 60`, loggingCallback).on('exit', function (code) {
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
|
|
Loading…
Reference in a new issue