Initial commit

This commit is contained in:
NullBite 2023-06-12 21:41:24 -04:00
commit 6532f9c2a2
Signed by: nullbite
GPG Key ID: 6C4D545385D4925A
14 changed files with 432 additions and 0 deletions

4
instance/eula.txt Normal file
View File

@ -0,0 +1,4 @@
#By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula).
#You also agree that tacos are tasty, and the best food in the world.
#Sat Feb 01 21:53:13 EST 2020
eula=TRUE

6
instance/merge.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
shopt -s globstar
shopt -s nullglob
for i in merge/**/*.{yml,yaml} ; do
[[ -e "${i##merge/}" ]] && yq ea -i "select(fileIndex == 0) * select(fileIndex == 1)" "${i##merge/}" "${i}"
done

3
instance/merge/paper.yml Normal file
View File

@ -0,0 +1,3 @@
settings:
unsupported-settings:
allow-piston-duplication: true

View File

@ -0,0 +1,5 @@
climbey:
enabled: true
blockmode: None
crawling:
enabled: true

View File

@ -0,0 +1,8 @@
settings:
restart-on-crash: true
restart-script: start.bat
world-settings:
default:
merge-radius:
exp: -1

47
instance/server.properties Executable file
View File

@ -0,0 +1,47 @@
#Minecraft server properties
#Sat Feb 01 20:30:08 EST 2020
broadcast-rcon-to-ops=true
view-distance=10
max-build-height=256
server-ip=
rcon.port=25575
level-seed=
allow-nether=true
gamemode=survival
enable-command-block=true
server-port=25565
enable-rcon=false
enable-query=false
op-permission-level=4
prevent-proxy-connections=false
generator-settings=
resource-pack=
player-idle-timeout=0
level-name=world
rcon.password=***REMOVED***
motd=owo what's this
query.port=25565
force-gamemode=false
debug=false
hardcore=false
white-list=false
broadcast-console-to-ops=true
pvp=false
spawn-npcs=true
spawn-animals=true
generate-structures=true
snooper-enabled=true
difficulty=normal
function-permission-level=2
network-compression-threshold=256
level-type=default
max-tick-time=60000
spawn-monsters=true
enforce-whitelist=false
max-players=20
use-native-transport=true
spawn-protection=0
resource-pack-sha1=
online-mode=true
allow-flight=true
max-world-size=29999984

4
instance/start.bat Executable file
View File

@ -0,0 +1,4 @@
:;cd "$(dirname "$0")"; exec ./tmux.sh
@echo off
cd /D "%~dp0"
java -Xmx1024M -Xms1024M -jar server.jar nogui

10
instance/start.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/bash
cd "$(dirname "$0")"
if ! [[ -e ./vars ]] ; then
echo 'Please create a "vars" file using "vars.example" as a template'
exit 1
fi
source ./vars
command "$JAVA" $JAVA_PARAMS -jar "$SERVER" nogui
sleep 10

304
instance/update_paper.py Executable file
View File

@ -0,0 +1,304 @@
#!/usr/bin/env python3
import requests
import typing
try:
import colorama
colorama.init()
COLOR_RED=colorama.Fore.RED
COLOR_RESET=colorama.Style.RESET_ALL
except ImportError:
COLOR_RED=''
COLOR_RESET=''
def dbprint(arg: typing.Any) -> typing.Any:
print(f'{COLOR_RED}debug>{COLOR_RESET}', repr(arg))
return arg
class PaperMC:
'''Class for accessing PaperMC API endpoint'''
version = 'v2'
endpoint = f'https://papermc.io/api/{version}'
projects_controller = f'{endpoint}/projects'
url=projects_controller
@staticmethod
def _get(url: str) -> typing.Any:
r=requests.get(url)
return r.json()
@classmethod
def get_projects(cls) -> typing.List:
return [Project(x) \
for x in cls._get(cls.url)["projects"]]
class PaperMC_Async(PaperMC):
@staticmethod
async def _get(url: str) -> typing.Any:
pass
class Project(PaperMC):
'''An object representing a project within PaperMC'''
def __init__(self, project: str):
self.project=str(project)
self.project_controller=f'{self.projects_controller}/{self.project}'
def __repr__(self):
return str(self.project)
def get_project(self):
return Project(self.project)
def get_version_groups(self) -> typing.List:
return [VersionGroup(self.project, x) \
for x in self._get(self.project_controller)["version_groups"]]
def get_versions(self) -> typing.List:
return [Version(self.project, x) \
for x in self._get(self.project_controller)["versions"]]
class _VersionParent(Project):
def __init__(self, project: str, version: str):
super().__init__(project)
self.version=str(version)
# list of builds, info
self.version_controller=\
f'{self.project_controller}/versions/{self.version}'
# info about version family
self.version_family_controller=\
f'{self.project_controller}/version_group/{self.version}'
# builds in version family
self.version_family_builds_controller=\
f'{self.version_family_controller}/builds'
def __repr__(self):
return str(self.version)
def get_version(self):
return Version(self.project, self.version)
def get_version_group(self):
return VersionGroup(self.project, self.version)
class VersionGroup(_VersionParent):
'''
An object representing a group of versions of a PaperMC project
For Paper, this is usually a group of all versions of a full Minecraft release, i.e., every version within 1.18
'''
def get_info(self) -> typing.Any:
return self._get(self.version_family_controller)
def get_versions(self) -> typing.List:
return [Version(self.project, x) \
for x in self._get(self.version_family_controller)["versions"]]
def get_builds(self) -> typing.List:
return [Build(self.project, x["version"], x["build"]) \
for x in self._get(self.version_family_builds_controller)["builds"]]
class Version(_VersionParent):
'''
An object representing a single version of a PaperMC project
For Paper, this is a single Minecraft version; i.e., 1.18.1
'''
def get_builds(self) -> typing.List:
return [Build(self.project, self.version, x) \
for x in self._get(self.version_controller)["builds"]]
class Build(_VersionParent):
'''
An individual build of a single version of a PaperMC project
'''
def __init__(self, project: str, version: str, build: int=None,
build_data: typing.Any=None):
super().__init__(project, version)
if build is not None:
self.build=int(build)
elif build_data is not None:
pass
else:
raise TypeError('either build or build_data should be defined.')
self.version_build_controller=\
f'{self.version_controller}/builds/{self.build}'
def __repr__(self):
return str(self.build)
def get_build(self):
return Build(self.project, self.version, self.build)
def get_info(self):
return self._get(self.version_build_controller)
def get_downloads(self):
info=self.get_info()
return [Download(self.project, self.version, self.build, k, v)
for (k, v) in info["downloads"].items()]
def get_download_by_name(self, name: str):
return next(x for x in self.get_downloads() if x.download_name==name)
class Download(Build):
'''
An artifact from a build of a PaperMC project
'''
def __init__(self, project: str, version: str, build: int, download_name: str, download: dict):
super().__init__(project, version, build)
self.download=download # dictionary including filename and sha256
self.download_name=download_name # name for artifact
self.name=download["name"] # filename for artifact
self.sha256=download["sha256"] # sha256 of file
self.download_controller=\
f'{self.version_build_controller}/downloads/{self.name}' # Download URL
def __repr__(self):
return str(f'{self.download_name}: {self.download_controller}')
def __str__(self):
return str(self.download_controller)
get_projects=PaperMC.get_projects
if __name__ == '__main__':
import argparse
import os
def abort(message: str, status: int=1):
print(message)
exit(status)
def get_best_item(item):
if item != 'auto':
return item
else:
if project is not None:
if version_like is not None:
if build is not None:
return 'downloads'
else:
return 'builds'
else:
return 'version-groups'
else:
return 'projects'
# Initialize Variables
project=None
version=None
version_group=None
version_like=None
build=None
download=None
def list_items(items_to_list: str):
match get_best_item(items_to_list):
case 'projects':
for i in PaperMC.get_projects():
print(i)
case 'versions':
if project is not None:
for i in project.get_versions():
print(i)
case 'version-groups':
if project is not None:
for i in project.get_version_groups():
print(i)
case 'builds':
if version_like is not None:
for i in version_like.get_builds():
info=i.get_info()
print(i, ':', info)
case 'downloads':
if build is not None:
for i in build.get_downloads():
print(repr(i))
p = argparse.ArgumentParser(description=
f"This is a script to download files from PaperMC projects.{os.linesep}Please note that automatic updating is NOT SUPPORTED. This wrapper exists mainly for convenience to avoid manually having to wget the update. Updates should still be manually reviewed to ensure they are stable, and backups should *always* be taken.")
p.add_argument('--project', '-p', nargs='?', default='paper', help='project to act on (default: %(default)s)')
p_version=p.add_mutually_exclusive_group(required=False)
p_version.add_argument('--version', '-v', nargs='?', help='version number or "latest"')
p_version.add_argument('--version-group', '-g', nargs='?', help='version group number or "latest"')
p.add_argument('--build', '-b', nargs='?', help='build number or "latest"; omit to list all builds')
p.add_argument('--download', '-d', nargs='?', help='download name (default: %(default)s)', default='application')
p.add_argument('--list', '-l', nargs='?', const='auto',
choices=['auto', 'projects', 'versions', 'version-groups', 'builds', 'downloads'],
help='list items; no value or \'%(const)s\' lists the most fitting items for the supplied information')
args=p.parse_args()
dbprint(args)
project=Project(args.project)
# Set version object
if args.version is not None:
if str(args.version).lower() == 'latest':
version=project.get_versions()[-1]
else:
# version=next(x for x in project.get_versions() if str(x) == args.version)
version=Version(str(project), args.version)
version_like=version
# Set version group object
if args.version_group is not None:
if str(args.version_group).lower() == 'latest':
version_group=project.get_version_groups()[-1]
else:
version_group=VersionGroup(str(project), args.version_group)
version_like=version_group
# Set build object
if None not in (version_like, args.build):
assert version_like is not None
if str(args.build).lower() == 'latest':
build=version_like.get_builds()[-1]
else:
build=Build(str(project), str(version_like), args.build)
# Set build
if None not in (version_like, build, args.download):
assert build is not None
download=build.get_download_by_name(args.download)
if args.list is not None:
list_items(args.list)
print(project)
print(version_like)
print(build)
print(download)
def debug():
print(PaperMC.endpoint)
print(repr(PaperMC.get_projects()))
p=Project('paper')
vg=p.get_version_groups()
v=p.get_versions()
print(vg)
print(v)
vv=VersionGroup('paper', '1.18').get_versions()[-1].get_builds()
print(vv)
latestbuild=Project('paper').get_version_groups()[-1].get_builds()[-1]
print(latestbuild)
print(latestbuild.get_download_by_name('application'))

8
instance/update_spigot.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/bash
version="${1:-1.16.5}"
wget -O BuildTools.jar https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar
rm -r spigot-build
java -jar BuildTools.jar --rev "${version}" -o spigot-build && \
mv spigot-build/* spigot.jar && \
rm -r spigot-build && \
cp spigot.jar server.jar

4
instance/vars.example Normal file
View File

@ -0,0 +1,4 @@
TMUX_SESSION=mcserver
JAVA_PARAMS="-Dlog4j2.formatMsgNoLookups=true -Xmx1024M -Xms1024M"
JAVA=java
SERVER=server.jar

2
mcserver.service Normal file
View File

@ -0,0 +1,2 @@
[Unit]

6
register.py Executable file
View File

@ -0,0 +1,6 @@
#!/usr/bin/env python3
import os, sys
if __name__ == '__main__':
import argparse
p = argparse.ArgumentParser

21
tmux.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/bash
server="$1"
shift
if ! [[ -e ./vars ]] ; then
echo 'Please create a "vars" file using "vars.example" as a template'
exit 1
fi
source ./vars
cmd="$1"
shift
code_clear=''
code_send=' '
case "$cmd" in
stop) tmux send-keys -t "$TMUX_SESSION" -l "$code_clear" 'stop' "$code_send" ;;
command) tmux send-keys -t "$TMUX_SESSION" -l "$code_clear" "$*" "$code_send" ;;
*) tmux new-window -t $TMUX_SESSION: "./start.sh" || tmux new-session -s $TMUX_SESSION "./start.sh";;
esac