add basic subservers

This commit is contained in:
Sen 2025-06-10 19:37:49 +02:00
parent 21b18d9809
commit 21820720db
Signed by: sen
GPG key ID: 3AC50A6F47D1B722
14 changed files with 764 additions and 84 deletions

View file

@ -86,6 +86,7 @@ import proxy.util.User;
import proxy.util.ViaProxyProcess;
import proxy.util.Log;
import proxy.util.Option;
import proxy.util.SpigotProcess;
public class Proxy {
public static final String NAME = "VProxy";
@ -113,6 +114,7 @@ public class Proxy {
private final Map<String, User> users = Maps.newTreeMap();
private final Map<String, ProxyHandler> players = Maps.newTreeMap();
private final Map<String, Command> commands = Maps.newTreeMap();
private final Map<String, SpigotProcess> servers = Maps.newTreeMap();
private final Thread serverThread;
private final ServerInfo status = new ServerInfo(NAME + " 1.8.9", 47);
private final ViaProxyProcess viaProxy = new ViaProxyProcess(this);
@ -132,12 +134,14 @@ public class Proxy {
@Config
private String forwardHost = "127.0.0.1";
@Config
private String viaProxyJar = "ViaProxy.jar";
@Config
private String viaProxyJavaPath = "";
@Config
private int viaProxyMaxMem = 1024;
@Config
private String spigotJavaPath = "";
@Config
private int spigotMaxMem = 1024;
@Config
private int forwardPort = 25563;
@Config
private String bindHost = "";
@ -162,6 +166,102 @@ public class Proxy {
@Config
private String[] info = new String[0];
@Config
private boolean commandBlocks = false;
@Config
private int viewDistance = 8;
@Config
private int difficulty = 3;
@Config
private int timeSyncInterval = 100;
@Config
private int autosaveInterval = 6000;
@Config
private int chunkGcInterval = 600;
@Config
private int animalSpawnInterval = 400;
@Config
private int monsterSpawnInterval = 1;
@Config
private boolean animalSpawns = true;
@Config
private boolean monsterSpawns = true;
@Config
private boolean npcSpawns = true;
@Config
private int animalLimit = 20;
@Config
private int monsterLimit = 70;
@Config
private int waterMobLimit = 5;
@Config
private int ambientMobLimit = 15;
@Config
private int watchdog = 120;
@Config
private int itemDespawn = 6000;
@Config
private int arrowDespawn = 1200;
@Config
private int tntPerTick = 100;
@Config
private int cactusHeight = 3;
@Config
private int reedHeight = 4;
@Config
private boolean noMoodSounds = false;
@Config
private boolean noIceSnow = false;
@Config
private boolean noThunder = false;
@Config
private int historySize = 50;
@Config
private int historyExpiry = 10;
@Config
private int wandItem = 271;
@Config
private boolean superPickaxeDrops = false;
@Config
private int polyPoints = 24;
@Config
private int superPickaxeSize = 15;
@Config
private int brushRadius = 50;
@Config
private String worldType = "DEFAULT";
@Config
private String generatorSettings = "";
@Config
private String seed = "";
@Config
private boolean generateStructures = true;
@Config
private boolean useRavines = true;
@Config
private boolean useCaves = true;
@Config
private boolean useDungeons = true;
@Config
private boolean useFortresses = true;
@Config
private boolean useMineshafts = true;
@Config
private boolean useStrongholds = true;
@Config
private boolean useTemples = true;
@Config
private boolean useVillages = true;
@Config
private boolean bedrockFlat = false;
@Config
private boolean allowNether = true;
@Config
private boolean allowEnd = true;
private long lastPingSync;
private static String getIcon(File file) {
@ -306,6 +406,15 @@ public class Proxy {
public void run(long time) {
this.loadConfig();
new File("jars").mkdirs();
for(String name : new String[] {"ViaProxy", "PandaSpigot", "WorldEdit"}) {
File file = new File(new File("jars"), name.toLowerCase(Locale.US) + ".jar");
if(!file.exists()) {
Log.error("The file %s could not be found in the jars directory. Please download the correct version of %s and place it at %s.",
file.getName(), name, file.getAbsolutePath());
return;
}
}
this.loadUsers();
Log.info("Hosting proxy on localhost:%d", this.proxyPort);
try {
@ -315,10 +424,22 @@ public class Proxy {
Log.error(e, "Could not bind to port");
return;
}
new File("schematics").mkdirs();
if(!this.viaProxy.start()) {
this.terminateEndpoints();
return;
}
this.servers.put("server", new SpigotProcess(this, "server", this.forwardPort));
for(SpigotProcess server : this.servers.values()) {
if(!server.start()) {
this.endProxy();
return;
}
}
for(User user : this.users.values()) {
if(user.isAdmin())
this.sendServerCommand("op", user.getUsername());
}
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
Proxy.this.endProxy();
@ -382,6 +503,9 @@ public class Proxy {
private void endProxy() {
this.viaProxy.shutdown();
for(SpigotProcess server : this.servers.values()) {
server.shutdown();
}
this.terminateEndpoints();
this.saveData();
}
@ -528,10 +652,6 @@ public class Proxy {
return this.proxyPort;
}
public String getViaProxyJar() {
return this.viaProxyJar;
}
public String getViaProxyJavaPath() {
return this.viaProxyJavaPath;
}
@ -540,6 +660,14 @@ public class Proxy {
return this.viaProxyMaxMem;
}
public String getSpigotJavaPath() {
return this.spigotJavaPath;
}
public int getSpigotMaxMem() {
return this.spigotMaxMem;
}
public int getForwardPort() {
return this.forwardPort;
}
@ -605,6 +733,13 @@ public class Proxy {
}
}
public void sendServerCommand(String ... command) {
String cmd = Formatter.joinSpace(0, command);
for(SpigotProcess server : this.servers.values()) {
server.runCommand(cmd);
}
}
private void addPlayer(ProxyHandler handler) {
handler.sendToClient(new S38PacketPlayerListItem(this.players.values(), false));
this.sendPacket(new S38PacketPlayerListItem(handler, Action.ADD_PLAYER), handler);
@ -677,7 +812,7 @@ public class Proxy {
this.register(new CommandTell());
this.register(new CommandTellraw());
for(String cmd : new String[] {"?", "about", "ban", "ban-ip", "banlist", "icanhasbukkit", "me", "pardon", "pardon-ip", "pl", "plugins", "restart", "rl", "say", "scoreboard", "stop", "timings", "title", "toggledownfall", "trigger", "ver", "version", "whitelist", "clone", "debug", "fill", "testfor", "testforblock", "testforblocks", "setidletimeout", "stats", "save-off", "save-on", "save-all", "spreadplayers"}) {
for(String cmd : new String[] {"?", "about", "ban", "ban-ip", "banlist", "icanhasbukkit", "me", "pardon", "pardon-ip", "pl", "plugins", "restart", "rl", "say", "scoreboard", "stop", "timings", "title", "toggledownfall", "trigger", "ver", "version", "whitelist", "clone", "debug", "fill", "testfor", "testforblock", "testforblocks", "setidletimeout", "stats", "save-off", "save-on", "save-all", "spreadplayers", "difficulty", "defaultgamemode"}) {
this.register(new CommandDummy(cmd));
}
@ -685,11 +820,12 @@ public class Proxy {
this.register(new CommandSeed());
this.register(new CommandPass("achievement", "<give|take> <stat_name|*> [player]", "Gives takes achievements to players or takes them"));
this.register(new CommandPass("deop", "<player>", "Removes a player from the operator list"));
this.register(new CommandPass("op", "<player>", "Adds a player to the operator list"));
this.register(new CommandPass("blockdata", "<x> <y> <z> <dataTag>", "Sets data of a tile entity"));
this.register(new CommandPass("clear", "[player] [item] [data] [maxCount] [dataTag]", "Clears items in the inventory of a player"));
this.register(new CommandPass("defaultgamemode", "<mode>", "Sets the default game mode of the server"));
this.register(new CommandPass("deop", "<player>", "Removes a player from the operator list"));
this.register(new CommandPass("difficulty", "<new difficulty>", "Sets the difficulty of the server"));
this.register(new CommandPass("effect", "<player> <effect> [seconds] [amplifier] [hideParticles] OR /effect <player> clear", "Gives entities status effects or removes them"));
this.register(new CommandPass("enchant", "<player> <enchantment ID> [level]", "Enchants the item in the hand of a player"));
this.register(new CommandPass("entitydata", "<entity> <dataTag>", "Sets data of an entity"));
@ -698,7 +834,6 @@ public class Proxy {
this.register(new CommandPass("gamerule", "<rule name> [value]", "Sets a gamerule of the server"));
this.register(new CommandPass("give", "<player> <item> [amount] [data] [dataTag]", "Gives an item to a player"));
this.register(new CommandPass("kill", "[player|entity]", "Kills entities"));
this.register(new CommandPass("op", "<player>", "Adds a player to the operator list"));
this.register(new CommandPass("particle", "<name> <x> <y> <z> <xd> <yd> <zd> <speed> [count] [mode]", "Displays particle effects to players"));
this.register(new CommandPass("playsound", "<sound> <player> [x] [y] [z] [volume] [pitch] [minimumVolume]", "Plays sound effects to players"));
this.register(new CommandPass("replaceitem", "<entity|block> ...", "Replaces an item in the inventory of an entity"));
@ -719,6 +854,14 @@ public class Proxy {
return this.commands;
}
public Map<String, String> getOptions() {
Map<String, String> map = Maps.newHashMap();
for(Entry<String, Option> entry : this.options.entrySet()) {
map.put(entry.getKey(), entry.getValue().toString());
}
return map;
}
public Collection<ProxyHandler> getPlayers() {
return this.players.values();
}

View file

@ -42,6 +42,7 @@ public class CommandAdmin extends Command {
if(user.isAdmin())
throw new RunException("%s is already an admin", user.getUsername());
user.setAdmin(true);
proxy.sendServerCommand("op", user.getUsername());
if(user.isOnline())
((ProxyHandler)user).sendMessage(Formatter.GOLD + "You were given proxy admin privileges");
sendInfo(player, "%s is now an admin", user.getUsername());

View file

@ -33,6 +33,7 @@ public class CommandRevoke extends Command {
if(!user.isAdmin())
throw new RunException("%s is not an admin", user.getUsername());
user.setAdmin(false);
proxy.sendServerCommand("deop", user.getUsername());
if(user.isOnline())
((ProxyHandler)user).sendMessage(Formatter.RED + "Your admin privileges were revoked");
sendInfo(player, "%s is no longer an admin", user.getUsername());

View file

@ -29,9 +29,13 @@ public class Log {
private static final boolean COLORS = !System.getProperty("os.name").toLowerCase(Locale.US).contains("win") && System.getProperty("log.nocolor") == null;
private static final DateFormat FORMAT = new SimpleDateFormat("HH:mm:ss");
private static void log(LogLevel level, String name, String msg) {
System.err.printf(COLORS ? "\u001b[34m[%s]\u001b[m \u001b[" + level.color + "m[%s/%s]\u001b[m \u001b[36m(%s)\u001b[m \u001b[0m%s\n" : "[%s] [%s/%s] (%s) %s\n",
FORMAT.format(new Date()), Thread.currentThread().getName(), level.name, name, msg);
}
private static void log(LogLevel level, String msg) {
System.err.printf(COLORS ? "\u001b[34m[%s]\u001b[m \u001b[" + level.color + "m[%s/%s]\u001b[m \u001b[36m(" + Proxy.NAME + ")\u001b[m \u001b[0m%s\n" : "[%s] [%s/%s] (" + Proxy.NAME + ") %s\n",
FORMAT.format(new Date()), Thread.currentThread().getName(), level.name, msg);
log(level, Proxy.NAME, msg);
}
public static void error(String msg) {
@ -68,6 +72,10 @@ public class Log {
log(LogLevel.WARN, String.format(fmt, args));
}
public static void infoAs(String name, String msg) {
log(LogLevel.INFO, name, msg);
}
public static void info(String msg) {
log(LogLevel.INFO, msg);
}

View file

@ -17,6 +17,17 @@ public class Option {
this.object = object;
}
public String toString() {
if(this.field.getType() == String[].class)
return "[]";
try {
return String.valueOf(this.field.get(this.object));
}
catch(IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public JsonElement get() {
Object obj;
try {

View file

@ -0,0 +1,104 @@
package proxy.util;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.ProcessBuilder.Redirect;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.base.Charsets;
import com.google.common.io.Resources;
import proxy.Proxy;
public class SpigotProcess extends SubProcess {
private final int port;
public SpigotProcess(Proxy proxy, String name, int port) {
super(proxy, name);
this.port = port;
}
protected Process createProcess() throws IOException {
final Process process = new ProcessBuilder(
this.proxy.getSpigotJavaPath().isEmpty() ? getJavaDir() : this.proxy.getSpigotJavaPath(),
"-Xmx" + this.proxy.getSpigotMaxMem() + "m",
"-jar", "pandaspigot.jar"
).directory(this.dir).redirectOutput(Redirect.PIPE).redirectErrorStream(true).redirectInput(Redirect.PIPE).start();
Thread con = new Thread(new Runnable() {
private final BufferedReader reader = new BufferedReader(new InputStreamReader(new BufferedInputStream(process.getInputStream())));
public void run() {
while(true) {
String line;
try {
line = this.reader.readLine();
}
catch(IOException e) {
line = null;
}
if(line == null)
break;
Log.infoAs("Server " + SpigotProcess.this.name, line);
}
}
}, this.name + " console");
con.setDaemon(true);
con.start();
return process;
}
private Map<String, String> getVarMap() {
Map<String, String> map = this.proxy.getOptions();
map.put("port", "" + this.port);
map.put("schematicsDir", new File("schematics").getAbsolutePath());
return map;
}
private void copyFile(String template, String dest) {
String content;
try {
content = Resources.toString(Resources.getResource(template), Charsets.UTF_8);
}
catch(IOException e) {
Log.error(e, "Could not read %s", template);
return;
}
for(Entry<String, String> entry : this.getVarMap().entrySet()) {
content = content.replace("[#" + entry.getKey() + "]", entry.getValue());
}
createFile(dest, content);
}
protected String getStopCommand() {
return "stop";
}
protected void setup() {
this.copyJar("pandaspigot.jar", "pandaspigot.jar");
this.copyJar("worldedit.jar", "plugins/worldedit.jar");
this.copyFile("server.tmp", "server.properties");
this.copyFile("bukkit.tmp", "bukkit.yml");
this.copyFile("spigot.tmp", "spigot.yml");
this.copyFile("paper.tmp", "paper.yml");
this.copyFile("panda.tmp", "pandaspigot.yml");
this.copyFile("worldedit.tmp", "plugins/WorldEdit/config.yml");
this.createFile("eula.txt", "eula=true");
this.createFile("help.yml", "");
this.createFile("permissions.yml", "");
this.createFile("ops.json", "[]");
this.createFile("whitelist.json", "[]");
this.createFile("usercache.json", "[]");
this.createFile("banned-players.json", "[]");
this.createFile("banned-ips.json", "[]");
this.createFile("commands.yml", "command-block-overrides: []\naliases:\n icanhasbukkit:\n - version $1-");
this.createFile("wepif.yml", "ignore-nijiperms-bridges: true\nresolvers:\n enabled:\n - DinnerPermsResolver\n disabled:\n - PluginPermissionsResolver\n - PermissionsExResolver\n - bPermissionsResolver\n - GroupManagerResolver\n - NijiPermissionsResolver\n - FlatFilePermissionsResolver\npermissions:\n groups:\n default:\n permissions: []\n admins:\n permissions:\n - '*'\n users: []");
this.createFile("plugins/bStats/config.yml", "enabled: false\nserverUuid: 11111111-1111-1111-1111-111111111111\nlogFailedRequests: false\nlogSentData: false\nlogResponseStatusText: false");
}
}

View file

@ -0,0 +1,106 @@
package proxy.util;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Locale;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import proxy.Proxy;
public abstract class SubProcess {
protected final Proxy proxy;
protected final File dir;
protected final String name;
protected Process process;
protected PrintWriter writer;
public SubProcess(Proxy proxy, String name) {
this.proxy = proxy;
this.name = name;
this.dir = new File(name);
}
protected static String getJavaDir() {
String separator = System.getProperty("file.separator");
String path = System.getProperty("java.home") + separator + "bin" + separator;
return System.getProperty("os.name").toLowerCase(Locale.US).contains("win") && (new File(path + "javaw.exe")).isFile() ? path + "javaw.exe" : path + "java";
}
protected void copyJar(String jar, String dest) {
File src = new File(new File("jars"), jar);
File dst = new File(this.dir, dest);
dst.getParentFile().mkdirs();
try {
Files.copy(src, dst);
}
catch(IOException e) {
Log.error(e, "Could not copy %s to %s", src, dst);
}
}
protected void createFile(String dest, String content) {
File dst = new File(this.dir, dest);
dst.getParentFile().mkdirs();
try {
Files.write(content, dst, Charsets.UTF_8);
}
catch(IOException e) {
Log.error(e, "Could not write %s", dst);
}
}
public boolean start() {
this.dir.mkdirs();
this.setup();
try {
this.process = this.createProcess();
}
catch(IOException e) {
Log.error(e, "Could not start process for %s", this.name);
return false;
}
this.writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new BufferedOutputStream(this.process.getOutputStream()))), true);
return true;
}
protected abstract Process createProcess() throws IOException;
protected abstract void setup();
protected abstract String getStopCommand();
public void shutdown() {
if(this.writer != null) {
try {
this.writer.println(this.getStopCommand());
}
catch(Exception e) {
}
}
if(this.process != null) {
try {
this.process.waitFor();
}
catch(InterruptedException e) {
Log.error(e, "Interrupted while waiting for process of %s to terminate", this.name);
}
}
}
public void runCommand(String cmd) {
if(this.writer != null) {
try {
this.writer.println(cmd);
}
catch(Exception e) {
}
}
}
}

View file

@ -1,43 +1,19 @@
package proxy.util;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.ProcessBuilder.Redirect;
import java.util.Locale;
import proxy.Proxy;
public class ViaProxyProcess {
private final Proxy proxy;
private Process process;
private PrintWriter writer;
public class ViaProxyProcess extends SubProcess {
public ViaProxyProcess(Proxy proxy) {
this.proxy = proxy;
super(proxy, "viaproxy");
}
private static String getJavaDir() {
String separator = System.getProperty("file.separator");
String path = System.getProperty("java.home") + separator + "bin" + separator;
return System.getProperty("os.name").toLowerCase(Locale.US).contains("win") && (new File(path + "javaw.exe")).isFile() ? path + "javaw.exe" : path + "java";
}
public boolean start() {
if(!new File(this.proxy.getViaProxyJar()).exists()) {
Log.error("The file %s could not be found in the current directory. Please download the lastest Version of ViaProxy and place it at %s.",
this.proxy.getViaProxyJar(), new File(this.proxy.getViaProxyJar()).getAbsolutePath());
return false;
}
try {
this.process = new ProcessBuilder(
protected Process createProcess() throws IOException {
return new ProcessBuilder(
this.proxy.getViaProxyJavaPath().isEmpty() ? getJavaDir() : this.proxy.getViaProxyJavaPath(),
"-Xmx" + this.proxy.getViaProxyMaxMem() + "m",
"-jar", this.proxy.getViaProxyJar(),
"-jar", "viaproxy.jar",
"cli",
"--proxy-online-mode", "false",
"--chat-signing", "false",
@ -45,41 +21,14 @@ public class ViaProxyProcess {
"--compression-threshold", "" + this.proxy.getCompression(),
"--target-address", "127.0.0.1:" + this.proxy.getProxyPort(),
"--bind-address", (this.proxy.getBindHost().isEmpty() ? "0.0.0.0" : this.proxy.getBindHost()) + ":" + this.proxy.getBindPort()
).redirectOutput(Redirect.INHERIT).redirectError(Redirect.INHERIT).redirectInput(Redirect.PIPE).start();
}
catch(IOException e) {
Log.error(e, "Could not start ViaProxy process");
return false;
}
this.writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new BufferedOutputStream(this.process.getOutputStream()))), true);
return true;
).directory(this.dir).redirectOutput(Redirect.INHERIT).redirectError(Redirect.INHERIT).redirectInput(Redirect.PIPE).start();
}
public void shutdown() {
if(this.writer != null) {
try {
this.writer.println("exit");
}
catch(Exception e) {
}
}
if(this.process != null) {
try {
this.process.waitFor();
}
catch(InterruptedException e) {
Log.error(e, "Interrupted while waiting for ViaProxy to terminate");
}
}
protected String getStopCommand() {
return "exit";
}
public void runCommand(String cmd) {
if(this.writer != null) {
try {
this.writer.println(cmd);
}
catch(Exception e) {
}
}
protected void setup() {
this.copyJar("viaproxy.jar", "viaproxy.jar");
}
}

View file

@ -0,0 +1,29 @@
settings:
allow-end: [#allowEnd]
warn-on-overload: true
permissions-file: permissions.yml
update-folder: update
plugin-profiling: false
connection-throttle: 1
query-plugins: false
deprecated-verbose: default
shutdown-message: Server closed
spawn-limits:
monsters: [#monsterLimit]
animals: [#animalLimit]
water-animals: [#waterMobLimit]
ambient: [#ambientMobLimit]
chunk-gc:
period-in-ticks: [#chunkGcInterval]
load-threshold: 0
ticks-per:
animal-spawns: [#animalSpawnInterval]
monster-spawns: [#monsterSpawnInterval]
autosave: [#autosaveInterval]
aliases: now-in-commands.yml
database:
username: nulluser
isolation: SERIALIZABLE
driver: org.sqlite.JDBC
password: nullpass
url: jdbc:sqlite:null.db

View file

@ -0,0 +1,30 @@
trackPluginScoreboards: false
proxyOnlineMode: false
maxBookPageSize: 2560
maxBookTotalSizeMultiplier: 0.98
packetLimiter:
kickMessage: "&cSent too many packets."
limits:
all:
interval: 7.0
maxPacketRate: 500.0
logPlayerIpAddresses: false
worlds:
default:
timeUpdateFrequency: [#timeSyncInterval]
smoothTeleportation: false
disablePlayerData: false
disableChunkSaving: false
disableEntityAi: false
randomArrowTrajectory: true
knockback:
friction: 2.0
horizontal: 0.4
vertical: 0.4
verticalLimit: 0.4000000059604645
extraHorizontal: 0.5
extraVertical: 0.1
optimizeTntMovement: false
optimizeLiquidExplosions: true
optimizeArmorStandMovement: false
randomArrowDamage: true

View file

@ -0,0 +1,88 @@
config-version: 9
settings:
baby-zombie-movement-speed: 0.5
limit-player-interactions: true
data-value-allowed-items: []
stackable-buckets:
lava: false
water: false
milk: false
effect-modifiers:
strength: 1.3
weakness: -0.5
warnWhenSettingExcessiveVelocity: true
world-settings:
default:
verbose: false
keep-spawn-loaded: false
allow-block-location-tab-completion: true
disable-thunder: [#noThunder]
disable-ice-and-snow: [#noIceSnow]
tick-next-tick-list-cap: 10000
tick-next-tick-list-cap-ignores-redstone: false
generator-settings:
canyon: [#useRavines]
caves: [#useCaves]
dungeon: [#useDungeons]
fortress: [#useFortresses]
mineshaft: [#useMineshafts]
monument: false
stronghold: [#useStrongholds]
temple: [#useTemples]
village: [#useVillages]
flat-bedrock: [#bedrockFlat]
falling-blocks-collide-with-signs: false
disable-mood-sounds: [#noMoodSounds]
use-async-lighting: false
portal-search-radius: 128
despawn-ranges:
soft: 32
hard: 128
disable-teleportation-suffocation-check: false
tnt-explosion-volume: 4.0
nether-ceiling-void-damage: false
squid-spawn-height:
minimum: 45.0
maximum: 63.0
mob-spawner-tick-rate: 1
player-blocking-damage-multiplier: 0.5
fishing-time-range:
MinimumTicks: 100
MaximumTicks: 900
max-growth-height:
cactus: [#cactusHeight]
reeds: [#reedHeight]
cache-chunk-maps: false
remove-unloaded:
enderpearls: true
tnt-entities: true
falling-blocks: true
remove-invalid-mob-spawner-tile-entities: true
player-exhaustion:
block-break: 0.02500000037252903
swimming: 0.014999999664723873
fast-drain:
lava: false
water: false
lava-flow-speed:
normal: 30
nether: 10
load-chunks:
enderpearls: false
tnt-entities: false
falling-blocks: false
game-mechanics:
boats-drop-boats: false
disable-player-crits: false
disable-chest-cat-detection: true
disable-end-credits: true
optimize-explosions: false
falling-block-height-nerf: 0
disable-explosion-knockback: false
water-over-lava-flow-speed: 5
fix-cannons: false
tnt-entity-height-nerf: 0
use-hopper-check: false
all-chunks-are-slime-chunks: false
allow-undead-horse-leashing: false
container-update-tick-rate: 1

View file

@ -0,0 +1,38 @@
spawn-protection=0
generator-settings=[#generatorSettings]
force-gamemode=true
allow-nether=[#allowNether]
gamemode=0
broadcast-console-to-ops=false
enable-query=false
player-idle-timeout=0
difficulty=[#difficulty]
spawn-monsters=[#monsterSpawns]
op-permission-level=4
resource-pack-hash=
announce-player-achievements=false
pvp=true
snooper-enabled=false
level-type=[#worldType]
hardcore=false
enable-command-block=[#commandBlocks]
max-players=100000
network-compression-threshold=-1
max-world-size=29999984
server-port=[#port]
debug=false
server-ip=127.0.0.1
spawn-npcs=[#npcSpawns]
allow-flight=false
level-name=world
view-distance=[#viewDistance]
resource-pack=
spawn-animals=[#animalSpawns]
white-list=false
generate-structures=[#generateStructures]
online-mode=false
max-build-height=256
level-seed=[#seed]
use-native-transport=[#epoll]
motd=proxy sub server
enable-rcon=false

View file

@ -0,0 +1,115 @@
config-version: 8
settings:
save-user-cache-on-stop-only: true
bungeecord: false
late-bind: false
sample-count: 0
player-shuffle: 0
filter-creative-items: true
user-cache-size: 0
int-cache-limit: 1024
moved-wrongly-threshold: 0.0625
moved-too-quickly-threshold: 100.0
timeout-time: [#watchdog]
restart-on-crash: false
restart-script: ./null.sh
netty-threads: 4
attribute:
maxHealth:
max: 2048.0
movementSpeed:
max: 2048.0
attackDamage:
max: 2048.0
debug: false
timings:
enabled: false
verbose: false
server-name-privacy: false
hidden-config-entries:
- database
- settings.bungeecord-addresses
history-interval: 300
history-length: 3600
commands:
tab-complete: 0
log: false
spam-exclusions:
- /skill
silent-commandblock-console: true
replace-commands:
- setblock
- summon
- testforblock
- tellraw
messages:
whitelist: np
unknown-command: "\u00a74Unknown command. Type \"/help\" for help."
server-full: np
outdated-client: np
outdated-server: np
restart: np
stats:
disable-saving: true
forced-stats:
achievement.openInventory: 1
world-settings:
default:
verbose: false
chunks-per-tick: 650
clear-tick-list: false
merge-radius:
exp: -1
item: -1
nerf-spawner-mobs: false
entity-activation-range:
animals: 32
monsters: 32
misc: 16
entity-tracking-range:
players: 48
animals: 48
monsters: 48
misc: 32
other: 64
ticks-per:
hopper-transfer: 8
hopper-check: 8
hopper-amount: 1
random-light-updates: false
save-structure-info: true
anti-xray:
enabled: false
engine-mode: 1
hide-blocks:
- 14
replace-blocks:
- 1
mob-spawn-range: 4
growth:
cactus-modifier: 100
cane-modifier: 100
melon-modifier: 100
mushroom-modifier: 100
pumpkin-modifier: 100
sapling-modifier: 100
wheat-modifier: 100
netherwart-modifier: 100
max-bulk-chunks: 10
max-entity-collisions: 8
dragon-death-sound-radius: 0
seed-village: 10387312
seed-feature: 14357617
hunger:
walk-exhaustion: 0.2
sprint-exhaustion: 0.8
combat-exhaustion: 0.3
regen-exhaustion: 3.0
max-tnt-per-tick: [#tntPerTick]
item-despawn-rate: [#itemDespawn]
arrow-despawn-rate: [#arrowDespawn]
enable-zombie-pigmen-portal-spawns: false
wither-spawn-sound-radius: 0
view-distance: [#viewDistance]
hanging-tick-frequency: 100
zombie-aggressive-towards-villager: true

View file

@ -0,0 +1,57 @@
limits:
allow-extra-data-values: false
max-blocks-changed:
default: -1
maximum: -1
max-polygonal-points:
default: -1
maximum: [#polyPoints]
max-radius: -1
max-super-pickaxe-size: [#superPickaxeSize]
max-brush-radius: [#brushRadius]
butcher-radius:
default: -1
maximum: -1
disallowed-blocks: []
use-inventory:
enable: false
allow-override: false
creative-mode-overrides: false
logging:
log-commands: false
file: nullfile
format: "none"
super-pickaxe:
drop-items: true
many-drop-items: [#superPickaxeDrops]
snapshots:
directory:
navigation-wand:
item: -1
max-distance: 1
scripting:
timeout: 1
dir: nullscripts
saving:
dir: [#schematicsDir]
files:
allow-symbolic-links: false
history:
size: [#historySize]
expiration: [#historyExpiry]
wand-item: [#wandItem]
shell-save-type:
no-double-slash: false
no-op-permissions: false
debug: false
show-help-on-first-use: false