Removed lombok dependency

This commit is contained in:
themode 2020-11-16 03:10:51 +01:00
parent e3793ed093
commit 3db53a798f
22 changed files with 841 additions and 375 deletions

View File

@ -8,6 +8,10 @@ plugins {
id 'org.jetbrains.kotlin.jvm' version '1.4.10' id 'org.jetbrains.kotlin.jvm' version '1.4.10'
} }
group 'net.minestom.server'
version '1.0'
sourceCompatibility = 1.11
project.ext.lwjglVersion = "3.2.3" project.ext.lwjglVersion = "3.2.3"
switch (OperatingSystem.current()) { switch (OperatingSystem.current()) {
@ -43,11 +47,6 @@ allprojects {
} }
} }
group 'net.minestom.server'
version '1.0'
sourceCompatibility = 1.11
sourceSets { sourceSets {
main { main {
java { java {
@ -126,9 +125,6 @@ dependencies {
api 'com.mojang:authlib:1.5.21' api 'com.mojang:authlib:1.5.21'
api 'org.projectlombok:lombok:1.18.12'
annotationProcessor 'org.projectlombok:lombok:1.18.12'
// Code modification // Code modification
api "org.ow2.asm:asm:${asmVersion}" api "org.ow2.asm:asm:${asmVersion}"
api "org.ow2.asm:asm-tree:${asmVersion}" api "org.ow2.asm:asm-tree:${asmVersion}"

View File

@ -1,23 +1,21 @@
package net.minestom.codegen; package net.minestom.codegen;
import lombok.Getter;
import java.io.File; import java.io.File;
public class PrismarinePaths { public class PrismarinePaths {
@Getter private String blocks; private String blocks;
@Getter private String biomes; private String biomes;
@Getter private String effects; private String effects;
@Getter private String items; private String items;
@Getter private String recipes; private String recipes;
@Getter private String instruments; private String instruments;
@Getter private String materials; private String materials;
@Getter private String entities; private String entities;
@Getter private String protocol; private String protocol;
@Getter private String windows; private String windows;
@Getter private String version; private String version;
@Getter private String language; private String language;
public File getBlockFile() { public File getBlockFile() {
return getFile(blocks, "blocks"); return getFile(blocks, "blocks");
@ -32,6 +30,6 @@ public class PrismarinePaths {
} }
public File getFile(String path, String type) { public File getFile(String path, String type) {
return new File("prismarine-minecraft-data/data/"+path+"/"+type+".json"); return new File("prismarine-minecraft-data/data/" + path + "/" + type + ".json");
} }
} }

View File

@ -1,10 +1,5 @@
package net.minestom.server; package net.minestom.server;
import com.mojang.authlib.AuthenticationService;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import lombok.Getter;
import lombok.Setter;
import net.minestom.server.advancements.AdvancementManager; import net.minestom.server.advancements.AdvancementManager;
import net.minestom.server.benchmark.BenchmarkManager; import net.minestom.server.benchmark.BenchmarkManager;
import net.minestom.server.command.CommandManager; import net.minestom.server.command.CommandManager;
@ -16,7 +11,6 @@ import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.extensions.Extension; import net.minestom.server.extensions.Extension;
import net.minestom.server.extensions.ExtensionManager; import net.minestom.server.extensions.ExtensionManager;
import net.minestom.server.extras.mojangAuth.MojangCrypt;
import net.minestom.server.fluids.Fluid; import net.minestom.server.fluids.Fluid;
import net.minestom.server.gamedata.loottables.LootTableManager; import net.minestom.server.gamedata.loottables.LootTableManager;
import net.minestom.server.gamedata.tags.TagManager; import net.minestom.server.gamedata.tags.TagManager;
@ -60,8 +54,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.net.Proxy;
import java.security.KeyPair;
import java.util.Collection; import java.util.Collection;
/** /**
@ -72,8 +64,7 @@ import java.util.Collection;
*/ */
public final class MinecraftServer { public final class MinecraftServer {
@Getter public final static Logger LOGGER = LoggerFactory.getLogger(MinecraftServer.class);
private final static Logger LOGGER = LoggerFactory.getLogger(MinecraftServer.class);
public static final String VERSION_NAME = "1.16.4"; public static final String VERSION_NAME = "1.16.4";
public static final int PROTOCOL_VERSION = 754; public static final int PROTOCOL_VERSION = 754;
@ -100,15 +91,6 @@ public final class MinecraftServer {
private static final int MS_TO_SEC = 1000; private static final int MS_TO_SEC = 1000;
public static final int TICK_MS = MS_TO_SEC / TICK_PER_SECOND; public static final int TICK_MS = MS_TO_SEC / TICK_PER_SECOND;
@Getter
@Setter
private static boolean hardcoreLook = false;
// Extras
@Getter
@Setter
private static boolean fixLighting = true;
// Network monitoring // Network monitoring
private static int rateLimit = 300; private static int rateLimit = 300;
private static int maxPacketSize = 30_000; private static int maxPacketSize = 30_000;
@ -151,14 +133,6 @@ public final class MinecraftServer {
private static LootTableManager lootTableManager; private static LootTableManager lootTableManager;
private static TagManager tagManager; private static TagManager tagManager;
//Mojang Auth
@Getter
private static final KeyPair keyPair = MojangCrypt.generateKeyPair();
@Getter
private static final AuthenticationService authService = new YggdrasilAuthenticationService(Proxy.NO_PROXY, "");
@Getter
private static final MinecraftSessionService sessionService = authService.createMinecraftSessionService();
public static MinecraftServer init() { public static MinecraftServer init() {
if (minecraftServer != null) // don't init twice if (minecraftServer != null) // don't init twice
return minecraftServer; return minecraftServer;

View File

@ -1,11 +1,11 @@
package net.minestom.server.extensions; package net.minestom.server.extensions;
import com.google.gson.*; import com.google.gson.*;
import lombok.extern.slf4j.Slf4j;
import net.minestom.server.extras.selfmodification.MinestomOverwriteClassLoader; import net.minestom.server.extras.selfmodification.MinestomOverwriteClassLoader;
import net.minestom.server.utils.validate.Check; import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.spongepowered.asm.mixin.Mixins; import org.spongepowered.asm.mixin.Mixins;
@ -19,9 +19,10 @@ import java.net.URLClassLoader;
import java.util.*; import java.util.*;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
@Slf4j
public final class ExtensionManager { public final class ExtensionManager {
public final static Logger LOGGER = LoggerFactory.getLogger(ExtensionManager.class);
private final static String INDEV_CLASSES_FOLDER = "minestom.extension.indevfolder.classes"; private final static String INDEV_CLASSES_FOLDER = "minestom.extension.indevfolder.classes";
private final static String INDEV_RESOURCES_FOLDER = "minestom.extension.indevfolder.resources"; private final static String INDEV_RESOURCES_FOLDER = "minestom.extension.indevfolder.resources";
private final static Gson GSON = new Gson(); private final static Gson GSON = new Gson();
@ -40,7 +41,7 @@ public final class ExtensionManager {
if (!extensionFolder.exists()) { if (!extensionFolder.exists()) {
if (!extensionFolder.mkdirs()) { if (!extensionFolder.mkdirs()) {
log.error("Could not find or create the extension folder, extensions will not be loaded!"); LOGGER.error("Could not find or create the extension folder, extensions will not be loaded!");
return; return;
} }
} }
@ -57,7 +58,7 @@ public final class ExtensionManager {
} }
loader = newClassLoader(urls); loader = newClassLoader(urls);
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
log.error("Failed to get URL.", e); LOGGER.error("Failed to get URL.", e);
continue; continue;
} }
// TODO: Can't we use discoveredExtension.description here? Someone should test that. // TODO: Can't we use discoveredExtension.description here? Someone should test that.
@ -71,7 +72,7 @@ public final class ExtensionManager {
} }
urlsString.append("'").append(url.toString()).append("'"); urlsString.append("'").append(url.toString()).append("'");
} }
log.error("Failed to find extension.json in the urls '{}'.", urlsString); LOGGER.error("Failed to find extension.json in the urls '{}'.", urlsString);
continue; continue;
} }
JsonObject extensionDescriptionJson = JsonParser.parseReader(new InputStreamReader(extensionInputStream)).getAsJsonObject(); JsonObject extensionDescriptionJson = JsonParser.parseReader(new InputStreamReader(extensionInputStream)).getAsJsonObject();
@ -80,8 +81,8 @@ public final class ExtensionManager {
final String extensionName = extensionDescriptionJson.get("name").getAsString(); final String extensionName = extensionDescriptionJson.get("name").getAsString();
// Check the validity of the extension's name. // Check the validity of the extension's name.
if (!extensionName.matches("[A-Za-z]+")) { if (!extensionName.matches("[A-Za-z]+")) {
log.error("Extension '{}' specified an invalid name.", extensionName); LOGGER.error("Extension '{}' specified an invalid name.", extensionName);
log.error("Extension '{}' will not be loaded.", extensionName); LOGGER.error("Extension '{}' will not be loaded.", extensionName);
continue; continue;
} }
@ -90,8 +91,8 @@ public final class ExtensionManager {
{ {
String version; String version;
if (!extensionDescriptionJson.has("version")) { if (!extensionDescriptionJson.has("version")) {
log.warn("Extension '{}' did not specify a version.", extensionName); LOGGER.warn("Extension '{}' did not specify a version.", extensionName);
log.warn("Extension '{}' will continue to load but should specify a plugin version.", extensionName); LOGGER.warn("Extension '{}' will continue to load but should specify a plugin version.", extensionName);
version = "Not Specified"; version = "Not Specified";
} else { } else {
version = extensionDescriptionJson.get("version").getAsString(); version = extensionDescriptionJson.get("version").getAsString();
@ -109,7 +110,7 @@ public final class ExtensionManager {
extensionLoaders.put(extensionName.toLowerCase(), loader); extensionLoaders.put(extensionName.toLowerCase(), loader);
if (extensions.containsKey(extensionName.toLowerCase())) { if (extensions.containsKey(extensionName.toLowerCase())) {
log.error("An extension called '{}' has already been registered.", extensionName); LOGGER.error("An extension called '{}' has already been registered.", extensionName);
continue; continue;
} }
@ -117,7 +118,7 @@ public final class ExtensionManager {
try { try {
jarClass = Class.forName(mainClass, true, loader); jarClass = Class.forName(mainClass, true, loader);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
log.error("Could not find main class '{}' in extension '{}'.", mainClass, extensionName, e); LOGGER.error("Could not find main class '{}' in extension '{}'.", mainClass, extensionName, e);
continue; continue;
} }
@ -125,7 +126,7 @@ public final class ExtensionManager {
try { try {
extensionClass = jarClass.asSubclass(Extension.class); extensionClass = jarClass.asSubclass(Extension.class);
} catch (ClassCastException e) { } catch (ClassCastException e) {
log.error("Main class '{}' in '{}' does not extend the 'Extension' superclass.", mainClass, extensionName, e); LOGGER.error("Main class '{}' in '{}' does not extend the 'Extension' superclass.", mainClass, extensionName, e);
continue; continue;
} }
@ -135,19 +136,19 @@ public final class ExtensionManager {
// Let's just make it accessible, plugin creators don't have to make this public. // Let's just make it accessible, plugin creators don't have to make this public.
constructor.setAccessible(true); constructor.setAccessible(true);
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
log.error("Main class '{}' in '{}' does not define a no-args constructor.", mainClass, extensionName, e); LOGGER.error("Main class '{}' in '{}' does not define a no-args constructor.", mainClass, extensionName, e);
continue; continue;
} }
Extension extension = null; Extension extension = null;
try { try {
extension = constructor.newInstance(); extension = constructor.newInstance();
} catch (InstantiationException e) { } catch (InstantiationException e) {
log.error("Main class '{}' in '{}' cannot be an abstract class.", mainClass, extensionName, e); LOGGER.error("Main class '{}' in '{}' cannot be an abstract class.", mainClass, extensionName, e);
continue; continue;
} catch (IllegalAccessException ignored) { } catch (IllegalAccessException ignored) {
// We made it accessible, should not occur // We made it accessible, should not occur
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
log.error( LOGGER.error(
"While instantiating the main class '{}' in '{}' an exception was thrown.", "While instantiating the main class '{}' in '{}' an exception was thrown.",
mainClass, mainClass,
extensionName, extensionName,
@ -164,7 +165,7 @@ public final class ExtensionManager {
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
// We made it accessible, should not occur // We made it accessible, should not occur
} catch (NoSuchFieldException e) { } catch (NoSuchFieldException e) {
log.error("Main class '{}' in '{}' has no description field.", mainClass, extensionName, e); LOGGER.error("Main class '{}' in '{}' has no description field.", mainClass, extensionName, e);
continue; continue;
} }
@ -178,7 +179,7 @@ public final class ExtensionManager {
e.printStackTrace(); e.printStackTrace();
} catch (NoSuchFieldException e) { } catch (NoSuchFieldException e) {
// This should also not occur (unless someone changed the logger in Extension superclass). // This should also not occur (unless someone changed the logger in Extension superclass).
log.error("Main class '{}' in '{}' has no logger field.", mainClass, extensionName, e); LOGGER.error("Main class '{}' in '{}' has no logger field.", mainClass, extensionName, e);
} }
extensions.put(extensionName.toLowerCase(), extension); extensions.put(extensionName.toLowerCase(), extension);
@ -209,7 +210,7 @@ public final class ExtensionManager {
// this allows developers to have their extension discovered while working on it, without having to build a jar and put in the extension folder // this allows developers to have their extension discovered while working on it, without having to build a jar and put in the extension folder
if (System.getProperty(INDEV_CLASSES_FOLDER) != null && System.getProperty(INDEV_RESOURCES_FOLDER) != null) { if (System.getProperty(INDEV_CLASSES_FOLDER) != null && System.getProperty(INDEV_RESOURCES_FOLDER) != null) {
log.info("Found indev folders for extension. Adding to list of discovered extensions."); LOGGER.info("Found indev folders for extension. Adding to list of discovered extensions.");
final String extensionClasses = System.getProperty(INDEV_CLASSES_FOLDER); final String extensionClasses = System.getProperty(INDEV_CLASSES_FOLDER);
final String extensionResources = System.getProperty(INDEV_RESOURCES_FOLDER); final String extensionResources = System.getProperty(INDEV_RESOURCES_FOLDER);
try (InputStreamReader reader = new InputStreamReader(new FileInputStream(new File(extensionResources, "extension.json")))) { try (InputStreamReader reader = new InputStreamReader(new FileInputStream(new File(extensionResources, "extension.json")))) {
@ -260,11 +261,11 @@ public final class ExtensionManager {
private void setupCodeModifiers(@NotNull List<DiscoveredExtension> extensions) { private void setupCodeModifiers(@NotNull List<DiscoveredExtension> extensions) {
final ClassLoader cl = getClass().getClassLoader(); final ClassLoader cl = getClass().getClassLoader();
if (!(cl instanceof MinestomOverwriteClassLoader)) { if (!(cl instanceof MinestomOverwriteClassLoader)) {
log.warn("Current class loader is not a MinestomOverwriteClassLoader, but " + cl + ". This disables code modifiers (Mixin support is therefore disabled)"); LOGGER.warn("Current class loader is not a MinestomOverwriteClassLoader, but " + cl + ". This disables code modifiers (Mixin support is therefore disabled)");
return; return;
} }
MinestomOverwriteClassLoader modifiableClassLoader = (MinestomOverwriteClassLoader) cl; MinestomOverwriteClassLoader modifiableClassLoader = (MinestomOverwriteClassLoader) cl;
log.info("Start loading code modifiers..."); LOGGER.info("Start loading code modifiers...");
for (DiscoveredExtension extension : extensions) { for (DiscoveredExtension extension : extensions) {
try { try {
if (extension.description.has("codeModifiers")) { if (extension.description.has("codeModifiers")) {
@ -276,14 +277,14 @@ public final class ExtensionManager {
if (extension.description.has("mixinConfig")) { if (extension.description.has("mixinConfig")) {
final String mixinConfigFile = extension.description.get("mixinConfig").getAsString(); final String mixinConfigFile = extension.description.get("mixinConfig").getAsString();
Mixins.addConfiguration(mixinConfigFile); Mixins.addConfiguration(mixinConfigFile);
log.info("Found mixin in extension " + extension.description.get("name").getAsString() + ": " + mixinConfigFile); LOGGER.info("Found mixin in extension " + extension.description.get("name").getAsString() + ": " + mixinConfigFile);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
log.error("Failed to load code modifier for extension in files: " + Arrays.toString(extension.files), e); LOGGER.error("Failed to load code modifier for extension in files: " + Arrays.toString(extension.files), e);
} }
} }
log.info("Done loading code modifiers."); LOGGER.info("Done loading code modifiers.");
} }
private static class DiscoveredExtension { private static class DiscoveredExtension {

View File

@ -1,12 +1,21 @@
package net.minestom.server.extras; package net.minestom.server.extras;
import lombok.Getter; import com.mojang.authlib.AuthenticationService;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.extras.mojangAuth.MojangCrypt;
import java.net.Proxy;
import java.security.KeyPair;
public final class MojangAuth { public final class MojangAuth {
@Getter private static boolean enabled = false;
private static boolean usingMojangAuth = false;
private static final KeyPair keyPair = MojangCrypt.generateKeyPair();
private static final AuthenticationService authService = new YggdrasilAuthenticationService(Proxy.NO_PROXY, "");
private static final MinecraftSessionService sessionService = authService.createMinecraftSessionService();
/** /**
* Enables mojang authentication on the server. * Enables mojang authentication on the server.
@ -15,9 +24,25 @@ public final class MojangAuth {
*/ */
public static void init() { public static void init() {
if (MinecraftServer.getNettyServer().getAddress() == null) { if (MinecraftServer.getNettyServer().getAddress() == null) {
usingMojangAuth = true; enabled = true;
} else { } else {
throw new IllegalStateException("The server has already been started"); throw new IllegalStateException("The server has already been started");
} }
} }
public static boolean isEnabled() {
return enabled;
}
public static KeyPair getKeyPair() {
return keyPair;
}
public static AuthenticationService getAuthService() {
return authService;
}
public static MinecraftSessionService getSessionService() {
return sessionService;
}
} }

View File

@ -1,10 +1,12 @@
package net.minestom.server.extras.selfmodification; package net.minestom.server.extras.selfmodification;
import lombok.extern.slf4j.Slf4j; import net.minestom.server.MinecraftServer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -20,9 +22,10 @@ import java.util.Set;
/** /**
* Class Loader that can modify class bytecode when they are loaded * Class Loader that can modify class bytecode when they are loaded
*/ */
@Slf4j
public class MinestomOverwriteClassLoader extends URLClassLoader { public class MinestomOverwriteClassLoader extends URLClassLoader {
public final static Logger LOGGER = LoggerFactory.getLogger(MinecraftServer.class);
private static MinestomOverwriteClassLoader INSTANCE; private static MinestomOverwriteClassLoader INSTANCE;
/** /**
@ -105,18 +108,18 @@ public class MinestomOverwriteClassLoader extends URLClassLoader {
try { try {
// we do not load system classes by ourselves // we do not load system classes by ourselves
Class<?> systemClass = ClassLoader.getPlatformClassLoader().loadClass(name); Class<?> systemClass = ClassLoader.getPlatformClassLoader().loadClass(name);
log.trace("System class: " + systemClass); LOGGER.trace("System class: " + systemClass);
return systemClass; return systemClass;
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
try { try {
if (isProtected(name)) { if (isProtected(name)) {
log.trace("Protected: " + name); LOGGER.trace("Protected: " + name);
return super.loadClass(name, resolve); return super.loadClass(name, resolve);
} }
return define(name, loadBytes(name, true), resolve); return define(name, loadBytes(name, true), resolve);
} catch (Exception ex) { } catch (Exception ex) {
log.trace("Fail to load class, resorting to parent loader: " + name, ex); LOGGER.trace("Fail to load class, resorting to parent loader: " + name, ex);
// fail to load class, let parent load // fail to load class, let parent load
// this forbids code modification, but at least it will load // this forbids code modification, but at least it will load
return super.loadClass(name, resolve); return super.loadClass(name, resolve);
@ -137,7 +140,7 @@ public class MinestomOverwriteClassLoader extends URLClassLoader {
private Class<?> define(String name, byte[] bytes, boolean resolve) { private Class<?> define(String name, byte[] bytes, boolean resolve) {
Class<?> defined = defineClass(name, bytes, 0, bytes.length); Class<?> defined = defineClass(name, bytes, 0, bytes.length);
log.trace("Loaded with code modifiers: " + name); LOGGER.trace("Loaded with code modifiers: " + name);
if (resolve) { if (resolve) {
resolveClass(defined); resolveClass(defined);
} }
@ -180,7 +183,7 @@ public class MinestomOverwriteClassLoader extends URLClassLoader {
}; };
node.accept(writer); node.accept(writer);
bytes = writer.toByteArray(); bytes = writer.toByteArray();
log.trace("Modified " + name); LOGGER.trace("Modified " + name);
} }
} }
return bytes; return bytes;
@ -208,7 +211,7 @@ public class MinestomOverwriteClassLoader extends URLClassLoader {
if (CodeModifier.class.isAssignableFrom(modifierClass)) { if (CodeModifier.class.isAssignableFrom(modifierClass)) {
CodeModifier modifier = (CodeModifier) modifierClass.getDeclaredConstructor().newInstance(); CodeModifier modifier = (CodeModifier) modifierClass.getDeclaredConstructor().newInstance();
synchronized (modifiers) { synchronized (modifiers) {
log.warn("Added Code modifier: " + modifier); LOGGER.warn("Added Code modifier: " + modifier);
addCodeModifier(modifier); addCodeModifier(modifier);
} }
} }

View File

@ -1,25 +1,29 @@
package net.minestom.server.extras.selfmodification.mixins; package net.minestom.server.extras.selfmodification.mixins;
import lombok.extern.slf4j.Slf4j; import net.minestom.server.MinecraftServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongepowered.asm.service.IMixinAuditTrail; import org.spongepowered.asm.service.IMixinAuditTrail;
/** /**
* Takes care of logging mixin operations * Takes care of logging mixin operations
*/ */
@Slf4j
public class MixinAuditTrailMinestom implements IMixinAuditTrail { public class MixinAuditTrailMinestom implements IMixinAuditTrail {
public final static Logger LOGGER = LoggerFactory.getLogger(MinecraftServer.class);
@Override @Override
public void onApply(String className, String mixinName) { public void onApply(String className, String mixinName) {
log.trace("Applied mixin "+mixinName+" to class "+className); LOGGER.trace("Applied mixin " + mixinName + " to class " + className);
} }
@Override @Override
public void onPostProcess(String className) { public void onPostProcess(String className) {
log.trace("Post processing "+className); LOGGER.trace("Post processing " + className);
} }
@Override @Override
public void onGenerate(String className, String generatorName) { public void onGenerate(String className, String generatorName) {
log.trace("Generating class "+className+" via generator "+generatorName); LOGGER.trace("Generating class " + className + " via generator " + generatorName);
} }
} }

View File

@ -446,8 +446,8 @@ public abstract class Chunk implements Viewable, DataContainer {
// Retrieve & send the buffer to the connection // Retrieve & send the buffer to the connection
playerConnection.sendPacket(getFreshFullDataPacket()); playerConnection.sendPacket(getFreshFullDataPacket());
// TODO do not hardcode // TODO do not hardcode light
if (MinecraftServer.isFixLighting()) { {
UpdateLightPacket updateLightPacket = new UpdateLightPacket(); UpdateLightPacket updateLightPacket = new UpdateLightPacket();
updateLightPacket.chunkX = getChunkX(); updateLightPacket.chunkX = getChunkX();
updateLightPacket.chunkZ = getChunkZ(); updateLightPacket.chunkZ = getChunkZ();

View File

@ -2,7 +2,6 @@ package net.minestom.server.network.netty.channel;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.network.ConnectionManager; import net.minestom.server.network.ConnectionManager;
@ -10,10 +9,13 @@ import net.minestom.server.network.PacketProcessor;
import net.minestom.server.network.netty.packet.InboundPacket; import net.minestom.server.network.netty.packet.InboundPacket;
import net.minestom.server.network.player.PlayerConnection; import net.minestom.server.network.player.PlayerConnection;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Slf4j
public class ClientChannel extends SimpleChannelInboundHandler<InboundPacket> { public class ClientChannel extends SimpleChannelInboundHandler<InboundPacket> {
private final static Logger LOGGER = LoggerFactory.getLogger(ClientChannel.class);
private final ConnectionManager connectionManager = MinecraftServer.getConnectionManager(); private final ConnectionManager connectionManager = MinecraftServer.getConnectionManager();
private final PacketProcessor packetProcessor; private final PacketProcessor packetProcessor;
@ -36,7 +38,7 @@ public class ClientChannel extends SimpleChannelInboundHandler<InboundPacket> {
if (availableBytes > 0) { if (availableBytes > 0) {
final PlayerConnection playerConnection = packetProcessor.getPlayerConnection(ctx); final PlayerConnection playerConnection = packetProcessor.getPlayerConnection(ctx);
log.warn("WARNING: Packet 0x" + Integer.toHexString(packet.packetId) LOGGER.warn("WARNING: Packet 0x" + Integer.toHexString(packet.packetId)
+ " not fully read (" + availableBytes + " bytes left), " + playerConnection); + " not fully read (" + availableBytes + " bytes left), " + playerConnection);
packet.body.skipBytes(availableBytes); packet.body.skipBytes(availableBytes);
@ -61,7 +63,7 @@ public class ClientChannel extends SimpleChannelInboundHandler<InboundPacket> {
@Override @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
log.info(cause.getMessage()); LOGGER.info(cause.getMessage());
cause.printStackTrace(); cause.printStackTrace();
ctx.close(); ctx.close();
} }

View File

@ -4,6 +4,7 @@ import com.mojang.authlib.GameProfile;
import com.mojang.authlib.exceptions.AuthenticationUnavailableException; import com.mojang.authlib.exceptions.AuthenticationUnavailableException;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.data.type.array.ByteArrayData; import net.minestom.server.data.type.array.ByteArrayData;
import net.minestom.server.extras.MojangAuth;
import net.minestom.server.extras.mojangAuth.MojangCrypt; import net.minestom.server.extras.mojangAuth.MojangCrypt;
import net.minestom.server.network.packet.client.ClientPreplayPacket; import net.minestom.server.network.packet.client.ClientPreplayPacket;
import net.minestom.server.network.player.NettyPlayerConnection; import net.minestom.server.network.player.NettyPlayerConnection;
@ -38,25 +39,25 @@ public class EncryptionResponsePacket implements ClientPreplayPacket {
try { try {
final String loginUsername = nettyConnection.getLoginUsername(); final String loginUsername = nettyConnection.getLoginUsername();
if (!Arrays.equals(nettyConnection.getNonce(), getNonce())) { if (!Arrays.equals(nettyConnection.getNonce(), getNonce())) {
MinecraftServer.getLOGGER().error(loginUsername + " tried to login with an invalid nonce!"); MinecraftServer.LOGGER.error(loginUsername + " tried to login with an invalid nonce!");
return; return;
} }
if (!loginUsername.isEmpty()) { if (!loginUsername.isEmpty()) {
final byte[] digestedData = MojangCrypt.digestData("", MinecraftServer.getKeyPair().getPublic(), getSecretKey()); final byte[] digestedData = MojangCrypt.digestData("", MojangAuth.getKeyPair().getPublic(), getSecretKey());
if (digestedData == null) { if (digestedData == null) {
// Incorrect key, probably because of the client // Incorrect key, probably because of the client
MinecraftServer.getLOGGER().error("Connection " + nettyConnection.getRemoteAddress() + " failed initializing encryption."); MinecraftServer.LOGGER.error("Connection " + nettyConnection.getRemoteAddress() + " failed initializing encryption.");
connection.disconnect(); connection.disconnect();
return; return;
} }
final String string3 = new BigInteger(digestedData).toString(16); final String string3 = new BigInteger(digestedData).toString(16);
final GameProfile gameProfile = MinecraftServer.getSessionService().hasJoinedServer(new GameProfile(null, loginUsername), string3); final GameProfile gameProfile = MojangAuth.getSessionService().hasJoinedServer(new GameProfile(null, loginUsername), string3);
nettyConnection.setEncryptionKey(getSecretKey()); nettyConnection.setEncryptionKey(getSecretKey());
MinecraftServer.getLOGGER().info("UUID of player {} is {}", loginUsername, gameProfile.getId()); MinecraftServer.LOGGER.info("UUID of player {} is {}", loginUsername, gameProfile.getId());
CONNECTION_MANAGER.startPlayState(connection, gameProfile.getId(), gameProfile.getName()); CONNECTION_MANAGER.startPlayState(connection, gameProfile.getId(), gameProfile.getName());
} }
} catch (AuthenticationUnavailableException e) { } catch (AuthenticationUnavailableException e) {
@ -73,10 +74,11 @@ public class EncryptionResponsePacket implements ClientPreplayPacket {
} }
public SecretKey getSecretKey() { public SecretKey getSecretKey() {
return MojangCrypt.decryptByteToSecretKey(MinecraftServer.getKeyPair().getPrivate(), sharedSecret); return MojangCrypt.decryptByteToSecretKey(MojangAuth.getKeyPair().getPrivate(), sharedSecret);
} }
public byte[] getNonce() { public byte[] getNonce() {
return MinecraftServer.getKeyPair().getPrivate() == null ? this.verifyToken : MojangCrypt.decryptUsingKey(MinecraftServer.getKeyPair().getPrivate(), this.verifyToken); return MojangAuth.getKeyPair().getPrivate() == null ?
this.verifyToken : MojangCrypt.decryptUsingKey(MojangAuth.getKeyPair().getPrivate(), this.verifyToken);
} }
} }

View File

@ -69,7 +69,7 @@ public class LoginStartPacket implements ClientPreplayPacket {
} }
if (MojangAuth.isUsingMojangAuth() && isNettyClient) { if (MojangAuth.isEnabled() && isNettyClient) {
// Mojang auth // Mojang auth
if (CONNECTION_MANAGER.getPlayer(username) != null) { if (CONNECTION_MANAGER.getPlayer(username) != null) {
connection.sendPacket(new LoginDisconnectPacket(ALREADY_CONNECTED_JSON)); connection.sendPacket(new LoginDisconnectPacket(ALREADY_CONNECTED_JSON));

View File

@ -1,7 +1,7 @@
package net.minestom.server.network.packet.server.login; package net.minestom.server.network.packet.server.login;
import net.minestom.server.MinecraftServer;
import net.minestom.server.data.type.array.ByteArrayData; import net.minestom.server.data.type.array.ByteArrayData;
import net.minestom.server.extras.MojangAuth;
import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.network.player.NettyPlayerConnection; import net.minestom.server.network.player.NettyPlayerConnection;
@ -23,7 +23,7 @@ public class EncryptionRequestPacket implements ServerPacket {
@Override @Override
public void write(@NotNull BinaryWriter writer) { public void write(@NotNull BinaryWriter writer) {
writer.writeSizedString(""); writer.writeSizedString("");
final byte[] publicKey = MinecraftServer.getKeyPair().getPublic().getEncoded(); final byte[] publicKey = MojangAuth.getKeyPair().getPublic().getEncoded();
ByteArrayData.encodeByteArray(writer, publicKey); ByteArrayData.encodeByteArray(writer, publicKey);
ByteArrayData.encodeByteArray(writer, nonce); ByteArrayData.encodeByteArray(writer, nonce);
} }

View File

@ -25,7 +25,7 @@ public class JoinGamePacket implements ServerPacket {
@Override @Override
public void write(@NotNull BinaryWriter writer) { public void write(@NotNull BinaryWriter writer) {
writer.writeInt(entityId); writer.writeInt(entityId);
writer.writeBoolean(MinecraftServer.isHardcoreLook()); writer.writeBoolean(gameMode.isHardcore());
writer.writeByte(gameMode.getId()); writer.writeByte(gameMode.getId());
//Previous Gamemode //Previous Gamemode
writer.writeByte(gameMode.getId()); writer.writeByte(gameMode.getId());

View File

@ -2,8 +2,6 @@ package net.minestom.server.network.player;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.SocketChannel;
import lombok.Getter;
import lombok.Setter;
import net.minestom.server.entity.PlayerSkin; import net.minestom.server.entity.PlayerSkin;
import net.minestom.server.extras.mojangAuth.Decrypter; import net.minestom.server.extras.mojangAuth.Decrypter;
import net.minestom.server.extras.mojangAuth.Encrypter; import net.minestom.server.extras.mojangAuth.Encrypter;
@ -32,14 +30,11 @@ public class NettyPlayerConnection extends PlayerConnection {
private final SocketChannel channel; private final SocketChannel channel;
private SocketAddress remoteAddress; private SocketAddress remoteAddress;
@Getter
private boolean encrypted = false; private boolean encrypted = false;
@Getter
private boolean compressed = false; private boolean compressed = false;
//Could be null. Only used for Mojang Auth //Could be null. Only used for Mojang Auth
@Getter
@Setter
private byte[] nonce = new byte[4]; private byte[] nonce = new byte[4];
// Data from client packets // Data from client packets
@ -232,4 +227,12 @@ public class NettyPlayerConnection extends PlayerConnection {
this.serverAddress = serverAddress; this.serverAddress = serverAddress;
this.serverPort = serverPort; this.serverPort = serverPort;
} }
public byte[] getNonce() {
return nonce;
}
public void setNonce(byte[] nonce) {
this.nonce = nonce;
}
} }

View File

@ -1,6 +1,5 @@
package net.minestom.server.network.player; package net.minestom.server.network.player;
import lombok.Getter;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.chat.ChatColor; import net.minestom.server.chat.ChatColor;
import net.minestom.server.chat.ColoredText; import net.minestom.server.chat.ColoredText;
@ -34,7 +33,6 @@ public abstract class PlayerConnection {
private static final ColoredText rateLimitKickMessage = ColoredText.of(ChatColor.RED + "Too Many Packets"); private static final ColoredText rateLimitKickMessage = ColoredText.of(ChatColor.RED + "Too Many Packets");
//Connection Stats //Connection Stats
@Getter
private final AtomicInteger packetCounter = new AtomicInteger(0); private final AtomicInteger packetCounter = new AtomicInteger(0);
private final AtomicInteger lastPacketCounter = new AtomicInteger(0); private final AtomicInteger lastPacketCounter = new AtomicInteger(0);
private short tickCounter = 0; private short tickCounter = 0;
@ -73,6 +71,10 @@ public abstract class PlayerConnection {
} }
} }
public AtomicInteger getPacketCounter() {
return packetCounter;
}
/** /**
* Returns a printable identifier for this connection, will be the player username * Returns a printable identifier for this connection, will be the player username
* or the connection remote address. * or the connection remote address.

View File

@ -96,11 +96,11 @@ public final class SchedulerManager {
* Shutdowns all normal tasks and call the registered shutdown tasks. * Shutdowns all normal tasks and call the registered shutdown tasks.
*/ */
public void shutdown() { public void shutdown() {
MinecraftServer.getLOGGER().info("Executing all shutdown tasks.."); MinecraftServer.LOGGER.info("Executing all shutdown tasks..");
for (Task task : this.getShutdownTasks()) { for (Task task : this.getShutdownTasks()) {
task.schedule(); task.schedule();
} }
MinecraftServer.getLOGGER().info("Shutting down the scheduled execution service and batches pool."); MinecraftServer.LOGGER.info("Shutting down the scheduled execution service and batches pool.");
this.timerExecutionService.shutdown(); this.timerExecutionService.shutdown();
this.batchesPool.shutdown(); this.batchesPool.shutdown();
try { try {

View File

@ -1,20 +1,15 @@
package net.minestom.server.world; package net.minestom.server.world;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import net.minestom.server.utils.NamespaceID; import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
import org.jglrxavpok.hephaistos.nbt.NBTCompound; import org.jglrxavpok.hephaistos.nbt.NBTCompound;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
/** /**
* https://minecraft.gamepedia.com/Custom_dimension * https://minecraft.gamepedia.com/Custom_dimension
*/ */
@Data
@Builder(builderMethodName = "hiddenBuilder", access = AccessLevel.PUBLIC)
public class DimensionType { public class DimensionType {
private static final AtomicInteger idCounter = new AtomicInteger(0); private static final AtomicInteger idCounter = new AtomicInteger(0);
@ -35,31 +30,47 @@ public class DimensionType {
.build(); .build();
private final int id = idCounter.getAndIncrement(); private final int id = idCounter.getAndIncrement();
@NotNull
private final NamespaceID name; private final NamespaceID name;
private final boolean natural; private final boolean natural;
private final float ambientLight; private final float ambientLight;
private final boolean ceilingEnabled; private final boolean ceilingEnabled;
private final boolean skylightEnabled; private final boolean skylightEnabled;
@Builder.Default private final Optional<Long> fixedTime;
private final Optional<Long> fixedTime = Optional.empty();
private final boolean raidCapable; private final boolean raidCapable;
private final boolean respawnAnchorSafe; private final boolean respawnAnchorSafe;
private final boolean ultrawarm; private final boolean ultrawarm;
@Builder.Default private final boolean bedSafe;
private final boolean bedSafe = true;
private final boolean piglinSafe; private final boolean piglinSafe;
@Builder.Default private final int logicalHeight;
private final int logicalHeight = 256; private final int coordinateScale;
@Builder.Default private final NamespaceID infiniburn;
private final int coordinateScale = 1;
@Builder.Default DimensionType(NamespaceID name, boolean natural, float ambientLight, boolean ceilingEnabled, boolean skylightEnabled, Optional<Long> fixedTime, boolean raidCapable, boolean respawnAnchorSafe, boolean ultrawarm, boolean bedSafe, boolean piglinSafe, int logicalHeight, int coordinateScale, NamespaceID infiniburn) {
private final NamespaceID infiniburn = NamespaceID.from("minecraft:infiniburn_overworld"); this.name = name;
this.natural = natural;
this.ambientLight = ambientLight;
this.ceilingEnabled = ceilingEnabled;
this.skylightEnabled = skylightEnabled;
this.fixedTime = fixedTime;
this.raidCapable = raidCapable;
this.respawnAnchorSafe = respawnAnchorSafe;
this.ultrawarm = ultrawarm;
this.bedSafe = bedSafe;
this.piglinSafe = piglinSafe;
this.logicalHeight = logicalHeight;
this.coordinateScale = coordinateScale;
this.infiniburn = infiniburn;
}
public static DimensionTypeBuilder builder(NamespaceID name) { public static DimensionTypeBuilder builder(NamespaceID name) {
return hiddenBuilder().name(name); return hiddenBuilder().name(name);
} }
public static DimensionTypeBuilder hiddenBuilder() {
return new DimensionTypeBuilder();
}
public NBTCompound toIndexedNBT() { public NBTCompound toIndexedNBT() {
NBTCompound nbt = new NBTCompound(); NBTCompound nbt = new NBTCompound();
NBTCompound element = toNBT(); NBTCompound element = toNBT();
@ -93,7 +104,173 @@ public class DimensionType {
return name.toString(); return name.toString();
} }
public static class DimensionTypeBuilder { public int getId() {
return this.id;
} }
public NamespaceID getName() {
return this.name;
}
public boolean isNatural() {
return this.natural;
}
public float getAmbientLight() {
return this.ambientLight;
}
public boolean isCeilingEnabled() {
return this.ceilingEnabled;
}
public boolean isSkylightEnabled() {
return this.skylightEnabled;
}
public Optional<Long> getFixedTime() {
return this.fixedTime;
}
public boolean isRaidCapable() {
return this.raidCapable;
}
public boolean isRespawnAnchorSafe() {
return this.respawnAnchorSafe;
}
public boolean isUltrawarm() {
return this.ultrawarm;
}
public boolean isBedSafe() {
return this.bedSafe;
}
public boolean isPiglinSafe() {
return this.piglinSafe;
}
public int getLogicalHeight() {
return this.logicalHeight;
}
public int getCoordinateScale() {
return this.coordinateScale;
}
public NamespaceID getInfiniburn() {
return this.infiniburn;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DimensionType that = (DimensionType) o;
return id == that.id &&
Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
public static class DimensionTypeBuilder {
private NamespaceID name;
private boolean natural;
private float ambientLight;
private boolean ceilingEnabled;
private boolean skylightEnabled;
private Optional<Long> fixedTime = Optional.empty();
private boolean raidCapable;
private boolean respawnAnchorSafe;
private boolean ultrawarm;
private boolean bedSafe = true;
private boolean piglinSafe = false;
private int logicalHeight = 256;
private int coordinateScale = 1;
private NamespaceID infiniburn = NamespaceID.from("minecraft:infiniburn_overworld");
DimensionTypeBuilder() {
}
public DimensionType.DimensionTypeBuilder name(NamespaceID name) {
this.name = name;
return this;
}
public DimensionType.DimensionTypeBuilder natural(boolean natural) {
this.natural = natural;
return this;
}
public DimensionType.DimensionTypeBuilder ambientLight(float ambientLight) {
this.ambientLight = ambientLight;
return this;
}
public DimensionType.DimensionTypeBuilder ceilingEnabled(boolean ceilingEnabled) {
this.ceilingEnabled = ceilingEnabled;
return this;
}
public DimensionType.DimensionTypeBuilder skylightEnabled(boolean skylightEnabled) {
this.skylightEnabled = skylightEnabled;
return this;
}
public DimensionType.DimensionTypeBuilder fixedTime(Optional<Long> fixedTime) {
this.fixedTime = fixedTime;
return this;
}
public DimensionType.DimensionTypeBuilder raidCapable(boolean raidCapable) {
this.raidCapable = raidCapable;
return this;
}
public DimensionType.DimensionTypeBuilder respawnAnchorSafe(boolean respawnAnchorSafe) {
this.respawnAnchorSafe = respawnAnchorSafe;
return this;
}
public DimensionType.DimensionTypeBuilder ultrawarm(boolean ultrawarm) {
this.ultrawarm = ultrawarm;
return this;
}
public DimensionType.DimensionTypeBuilder bedSafe(boolean bedSafe) {
this.bedSafe = bedSafe;
return this;
}
public DimensionType.DimensionTypeBuilder piglinSafe(boolean piglinSafe) {
this.piglinSafe = piglinSafe;
return this;
}
public DimensionType.DimensionTypeBuilder logicalHeight(int logicalHeight) {
this.logicalHeight = logicalHeight;
return this;
}
public DimensionType.DimensionTypeBuilder coordinateScale(int coordinateScale) {
this.coordinateScale = coordinateScale;
return this;
}
public DimensionType.DimensionTypeBuilder infiniburn(NamespaceID infiniburn) {
this.infiniburn = infiniburn;
return this;
}
public DimensionType build() {
return new DimensionType(name, natural, ambientLight, ceilingEnabled, skylightEnabled,
fixedTime, raidCapable, respawnAnchorSafe, ultrawarm, bedSafe,
piglinSafe, logicalHeight, coordinateScale, infiniburn);
}
}
} }

View File

@ -1,9 +1,5 @@
package net.minestom.server.world.biomes; package net.minestom.server.world.biomes;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import net.minestom.server.utils.NamespaceID; import net.minestom.server.utils.NamespaceID;
import net.minestom.server.utils.validate.Check; import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -11,19 +7,15 @@ import org.jglrxavpok.hephaistos.nbt.NBTCompound;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@Getter
@Builder
@ToString
@EqualsAndHashCode
public class Biome { public class Biome {
public static final AtomicInteger ID_COUNTER = new AtomicInteger(0); public static final AtomicInteger ID_COUNTER = new AtomicInteger(0);
private static final BiomeEffects DEFAULT_EFFECTS = BiomeEffects.builder() private static final BiomeEffects DEFAULT_EFFECTS = BiomeEffects.builder()
.fog_color(0xC0D8FF) .fogColor(0xC0D8FF)
.sky_color(0x78A7FF) .skyColor(0x78A7FF)
.water_color(0x3F76E4) .waterColor(0x3F76E4)
.water_fog_color(0x50533) .waterFogColor(0x50533)
.build(); .build();
//A plains biome has to be registered or else minecraft will crash //A plains biome has to be registered or else minecraft will crash
@ -40,22 +32,30 @@ public class Biome {
private final int id = ID_COUNTER.getAndIncrement(); private final int id = ID_COUNTER.getAndIncrement();
private final NamespaceID name; private final NamespaceID name;
@Builder.Default private final float depth;
private final float depth = 0.2F; private final float temperature;
@Builder.Default private final float scale;
private final float temperature = 0.25F; private final float downfall;
@Builder.Default private final Category category;
private final float scale = 0.2F; private final BiomeEffects effects;
@Builder.Default private final Precipitation precipitation;
private final float downfall = 0.8F; private final TemperatureModifier temperature_modifier;
@Builder.Default
private final Category category = Category.NONE; Biome(NamespaceID name, float depth, float temperature, float scale, float downfall, Category category, BiomeEffects effects, Precipitation precipitation, TemperatureModifier temperature_modifier) {
@Builder.Default this.name = name;
private final BiomeEffects effects = DEFAULT_EFFECTS; this.depth = depth;
@Builder.Default this.temperature = temperature;
private final Precipitation precipitation = Precipitation.RAIN; this.scale = scale;
@Builder.Default this.downfall = downfall;
private final TemperatureModifier temperature_modifier = TemperatureModifier.NONE; this.category = category;
this.effects = effects;
this.precipitation = precipitation;
this.temperature_modifier = temperature_modifier;
}
public static BiomeBuilder builder() {
return new BiomeBuilder();
}
@NotNull @NotNull
public NBTCompound toNbt() { public NBTCompound toNbt() {
@ -80,15 +80,58 @@ public class Biome {
return nbt; return nbt;
} }
public int getId() {
return this.id;
}
public NamespaceID getName() {
return this.name;
}
public float getDepth() {
return this.depth;
}
public float getTemperature() {
return this.temperature;
}
public float getScale() {
return this.scale;
}
public float getDownfall() {
return this.downfall;
}
public Category getCategory() {
return this.category;
}
public BiomeEffects getEffects() {
return this.effects;
}
public Precipitation getPrecipitation() {
return this.precipitation;
}
public TemperatureModifier getTemperature_modifier() {
return this.temperature_modifier;
}
public enum Precipitation { public enum Precipitation {
RAIN("rain"), NONE("none"), SNOW("snow"); RAIN("rain"), NONE("none"), SNOW("snow");
@Getter
String type; String type;
Precipitation(String type) { Precipitation(String type) {
this.type = type; this.type = type;
} }
public String getType() {
return this.type;
}
} }
public enum Category { public enum Category {
@ -96,23 +139,93 @@ public class Biome {
SAVANNA("savanna"), ICY("icy"), THE_END("the_end"), BEACH("beach"), FOREST("forest"), OCEAN("ocean"), SAVANNA("savanna"), ICY("icy"), THE_END("the_end"), BEACH("beach"), FOREST("forest"), OCEAN("ocean"),
DESERT("desert"), RIVER("river"), SWAMP("swamp"), MUSHROOM("mushroom"), NETHER("nether"); DESERT("desert"), RIVER("river"), SWAMP("swamp"), MUSHROOM("mushroom"), NETHER("nether");
@Getter
String type; String type;
Category(String type) { Category(String type) {
this.type = type; this.type = type;
} }
public String getType() {
return type;
}
} }
public enum TemperatureModifier { public enum TemperatureModifier {
NONE("none"), FROZEN("frozen"); NONE("none"), FROZEN("frozen");
@Getter
String type; String type;
TemperatureModifier(String type) { TemperatureModifier(String type) {
this.type = type; this.type = type;
} }
public String getType() {
return type;
}
} }
public static class BiomeBuilder {
private NamespaceID name;
private float depth = 0.2f;
private float temperature = 0.25f;
private float scale = 0.2f;
private float downfall = 0.8f;
private Category category = Category.NONE;
private BiomeEffects effects = DEFAULT_EFFECTS;
private Precipitation precipitation = Precipitation.RAIN;
private TemperatureModifier temperatureModifier = TemperatureModifier.NONE;
BiomeBuilder() {
}
public Biome.BiomeBuilder name(NamespaceID name) {
this.name = name;
return this;
}
public Biome.BiomeBuilder depth(float depth) {
this.depth = depth;
return this;
}
public Biome.BiomeBuilder temperature(float temperature) {
this.temperature = temperature;
return this;
}
public Biome.BiomeBuilder scale(float scale) {
this.scale = scale;
return this;
}
public Biome.BiomeBuilder downfall(float downfall) {
this.downfall = downfall;
return this;
}
public Biome.BiomeBuilder category(Category category) {
this.category = category;
return this;
}
public Biome.BiomeBuilder effects(BiomeEffects effects) {
this.effects = effects;
return this;
}
public Biome.BiomeBuilder precipitation(Precipitation precipitation) {
this.precipitation = precipitation;
return this;
}
public Biome.BiomeBuilder temperatureModifier(TemperatureModifier temperatureModifier) {
this.temperatureModifier = temperatureModifier;
return this;
}
public Biome build() {
return new Biome(name, depth, temperature, scale, downfall, category, effects, precipitation, temperatureModifier);
}
}
} }

View File

@ -1,127 +1,291 @@
package net.minestom.server.world.biomes; package net.minestom.server.world.biomes;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import net.minestom.server.utils.NamespaceID; import net.minestom.server.utils.NamespaceID;
import org.jglrxavpok.hephaistos.nbt.NBTCompound; import org.jglrxavpok.hephaistos.nbt.NBTCompound;
@Getter
@Builder
@ToString
@EqualsAndHashCode
public class BiomeEffects { public class BiomeEffects {
private final int fog_color; private final int fog_color;
private final int sky_color; private final int sky_color;
private final int water_color; private final int water_color;
private final int water_fog_color; private final int water_fog_color;
@Builder.Default private int foliage_color = -1;
@Builder.Default private int grass_color = -1;
@Builder.Default private GrassColorModifier grass_color_modifier = null;
@Builder.Default private BiomeParticles biomeParticles = null;
@Builder.Default private NamespaceID ambient_sound = null;
@Builder.Default private MoodSound mood_sound = null;
@Builder.Default private AdditionsSound additions_sound = null;
@Builder.Default private Music music = null;
public NBTCompound toNbt() { private final int foliage_color;
NBTCompound nbt = new NBTCompound(); private final int grass_color;
nbt.setInt("fog_color", fog_color); private final GrassColorModifier grass_color_modifier;
if (foliage_color != -1) private final BiomeParticles biomeParticles;
nbt.setInt("foliage_color", foliage_color); private final NamespaceID ambient_sound;
if (grass_color != -1) private final MoodSound mood_sound;
nbt.setInt("grass_color", grass_color); private final AdditionsSound additions_sound;
nbt.setInt("sky_color", sky_color); private final Music music;
nbt.setInt("water_color", water_color);
nbt.setInt("water_fog_color", water_fog_color);
if (grass_color_modifier != null)
nbt.setString("grass_color_modifier", grass_color_modifier.getType());
if (biomeParticles != null)
nbt.set("particle", biomeParticles.toNbt());
if (ambient_sound != null)
nbt.setString("ambient_sound", ambient_sound.toString());
if (mood_sound != null)
nbt.set("mood_sound", mood_sound.toNbt());
if (additions_sound != null)
nbt.set("additions_sound", additions_sound.toNbt());
if (music != null)
nbt.set("music", music.toNbt());
return nbt;
}
public enum GrassColorModifier { BiomeEffects(int fog_color, int sky_color, int water_color, int water_fog_color, int foliage_color, int grass_color, GrassColorModifier grass_color_modifier, BiomeParticles biomeParticles, NamespaceID ambient_sound, MoodSound mood_sound, AdditionsSound additions_sound, Music music) {
NONE("none"), DARK_FOREST("dark_forest"), SWAMP("swamp"); this.fog_color = fog_color;
this.sky_color = sky_color;
this.water_color = water_color;
this.water_fog_color = water_fog_color;
this.foliage_color = foliage_color;
this.grass_color = grass_color;
this.grass_color_modifier = grass_color_modifier;
this.biomeParticles = biomeParticles;
this.ambient_sound = ambient_sound;
this.mood_sound = mood_sound;
this.additions_sound = additions_sound;
this.music = music;
}
@Getter public static BiomeEffectsBuilder builder() {
String type; return new BiomeEffectsBuilder();
}
GrassColorModifier(String type) { public NBTCompound toNbt() {
this.type = type; NBTCompound nbt = new NBTCompound();
} nbt.setInt("fog_color", fog_color);
} if (foliage_color != -1)
nbt.setInt("foliage_color", foliage_color);
if (grass_color != -1)
nbt.setInt("grass_color", grass_color);
nbt.setInt("sky_color", sky_color);
nbt.setInt("water_color", water_color);
nbt.setInt("water_fog_color", water_fog_color);
if (grass_color_modifier != null)
nbt.setString("grass_color_modifier", grass_color_modifier.getType());
if (biomeParticles != null)
nbt.set("particle", biomeParticles.toNbt());
if (ambient_sound != null)
nbt.setString("ambient_sound", ambient_sound.toString());
if (mood_sound != null)
nbt.set("mood_sound", mood_sound.toNbt());
if (additions_sound != null)
nbt.set("additions_sound", additions_sound.toNbt());
if (music != null)
nbt.set("music", music.toNbt());
return nbt;
}
@Getter public int getFog_color() {
@Builder return this.fog_color;
@ToString }
@EqualsAndHashCode
public static class MoodSound {
private final NamespaceID sound; public int getSky_color() {
private final int tick_delay; return this.sky_color;
private final int block_search_extent; }
private final double offset;
public NBTCompound toNbt() { public int getWater_color() {
NBTCompound nbt = new NBTCompound(); return this.water_color;
nbt.setString("sound", sound.toString()); }
nbt.setInt("tick_delay", tick_delay);
nbt.setInt("block_search_extent", block_search_extent);
nbt.setDouble("offset", offset);
return nbt;
}
} public int getWater_fog_color() {
return this.water_fog_color;
}
@Getter public int getFoliage_color() {
@Builder return this.foliage_color;
@ToString }
@EqualsAndHashCode
public static class AdditionsSound {
private final NamespaceID sound; public int getGrass_color() {
private final double tick_chance; return this.grass_color;
}
public NBTCompound toNbt() { public GrassColorModifier getGrass_color_modifier() {
NBTCompound nbt = new NBTCompound(); return this.grass_color_modifier;
nbt.setString("sound", sound.toString()); }
nbt.setDouble("tick_chance", tick_chance);
return nbt;
}
} public BiomeParticles getBiomeParticles() {
return this.biomeParticles;
}
@Getter public NamespaceID getAmbient_sound() {
@Builder return this.ambient_sound;
@ToString }
@EqualsAndHashCode
public static class Music {
private final NamespaceID sound; public MoodSound getMood_sound() {
private final int min_delay; return this.mood_sound;
private final int max_delay; }
private final boolean replace_current_music;
public NBTCompound toNbt() { public AdditionsSound getAdditions_sound() {
NBTCompound nbt = new NBTCompound(); return this.additions_sound;
nbt.setString("sound", sound.toString()); }
nbt.setInt("min_delay", min_delay);
nbt.setInt("max_delay", max_delay);
nbt.setByte("replace_current_music", replace_current_music ? (byte) 1 : (byte) 0);
return nbt;
}
} public Music getMusic() {
return this.music;
}
public String toString() {
return "BiomeEffects(fog_color=" + this.getFog_color() + ", sky_color=" +
this.getSky_color() + ", water_color=" + this.getWater_color() + ", water_fog_color=" +
this.getWater_fog_color() + ", foliage_color=" + this.getFoliage_color() + ", grass_color=" +
this.getGrass_color() + ", grass_color_modifier=" + this.getGrass_color_modifier() + ", biomeParticles=" +
this.getBiomeParticles() + ", ambient_sound=" + this.getAmbient_sound() + ", mood_sound=" +
this.getMood_sound() + ", additions_sound=" + this.getAdditions_sound() + ", music=" + this.getMusic() + ")";
}
public enum GrassColorModifier {
NONE("none"), DARK_FOREST("dark_forest"), SWAMP("swamp");
String type;
GrassColorModifier(String type) {
this.type = type;
}
public String getType() {
return this.type;
}
}
public static class MoodSound {
private final NamespaceID sound;
private final int tickDelay;
private final int blockSearchExtent;
private final double offset;
public MoodSound(NamespaceID sound, int tickDelay, int blockSearchExtent, double offset) {
this.sound = sound;
this.tickDelay = tickDelay;
this.blockSearchExtent = blockSearchExtent;
this.offset = offset;
}
public NBTCompound toNbt() {
NBTCompound nbt = new NBTCompound();
nbt.setString("sound", sound.toString());
nbt.setInt("tick_delay", tickDelay);
nbt.setInt("block_search_extent", blockSearchExtent);
nbt.setDouble("offset", offset);
return nbt;
}
}
public static class AdditionsSound {
private final NamespaceID sound;
private final double tickChance;
public AdditionsSound(NamespaceID sound, double tickChance) {
this.sound = sound;
this.tickChance = tickChance;
}
public NBTCompound toNbt() {
NBTCompound nbt = new NBTCompound();
nbt.setString("sound", sound.toString());
nbt.setDouble("tick_chance", tickChance);
return nbt;
}
}
public static class Music {
private final NamespaceID sound;
private final int minDelay;
private final int maxDelay;
private final boolean replaceCurrentMusic;
public Music(NamespaceID sound, int minDelay, int maxDelay, boolean replaceCurrentMusic) {
this.sound = sound;
this.minDelay = minDelay;
this.maxDelay = maxDelay;
this.replaceCurrentMusic = replaceCurrentMusic;
}
public NBTCompound toNbt() {
NBTCompound nbt = new NBTCompound();
nbt.setString("sound", sound.toString());
nbt.setInt("min_delay", minDelay);
nbt.setInt("max_delay", maxDelay);
nbt.setByte("replace_current_music", replaceCurrentMusic ? (byte) 1 : (byte) 0);
return nbt;
}
}
public static class BiomeEffectsBuilder {
private int fogColor;
private int skyColor;
private int waterColor;
private int waterFogColor;
private int foliageColor = -1;
private int grassColor = -1;
private GrassColorModifier grassColorModifier;
private BiomeParticles biomeParticles;
private NamespaceID ambientSound;
private MoodSound moodSound;
private AdditionsSound additionsSound;
private Music music;
BiomeEffectsBuilder() {
}
public BiomeEffects.BiomeEffectsBuilder fogColor(int fogColor) {
this.fogColor = fogColor;
return this;
}
public BiomeEffects.BiomeEffectsBuilder skyColor(int skyColor) {
this.skyColor = skyColor;
return this;
}
public BiomeEffects.BiomeEffectsBuilder waterColor(int waterColor) {
this.waterColor = waterColor;
return this;
}
public BiomeEffects.BiomeEffectsBuilder waterFogColor(int waterFogColor) {
this.waterFogColor = waterFogColor;
return this;
}
public BiomeEffects.BiomeEffectsBuilder foliageColor(int foliageColor) {
this.foliageColor = foliageColor;
return this;
}
public BiomeEffects.BiomeEffectsBuilder grassColor(int grassColor) {
this.grassColor = grassColor;
return this;
}
public BiomeEffects.BiomeEffectsBuilder grassColorModifier(GrassColorModifier grassColorModifier) {
this.grassColorModifier = grassColorModifier;
return this;
}
public BiomeEffects.BiomeEffectsBuilder biomeParticles(BiomeParticles biomeParticles) {
this.biomeParticles = biomeParticles;
return this;
}
public BiomeEffects.BiomeEffectsBuilder ambientSound(NamespaceID ambientSound) {
this.ambientSound = ambientSound;
return this;
}
public BiomeEffects.BiomeEffectsBuilder moodSound(MoodSound moodSound) {
this.moodSound = moodSound;
return this;
}
public BiomeEffects.BiomeEffectsBuilder additionsSound(AdditionsSound additionsSound) {
this.additionsSound = additionsSound;
return this;
}
public BiomeEffects.BiomeEffectsBuilder music(Music music) {
this.music = music;
return this;
}
public BiomeEffects build() {
return new BiomeEffects(fogColor, skyColor, waterColor, waterFogColor, foliageColor,
grassColor, grassColorModifier, biomeParticles,
ambientSound, moodSound, additionsSound, music);
}
}
} }

View File

@ -1,122 +1,126 @@
package net.minestom.server.world.biomes; package net.minestom.server.world.biomes;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockAlternative; import net.minestom.server.instance.block.BlockAlternative;
import net.minestom.server.item.ItemStack; import net.minestom.server.item.ItemStack;
import net.minestom.server.utils.NamespaceID; import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
import org.jglrxavpok.hephaistos.nbt.NBTCompound; import org.jglrxavpok.hephaistos.nbt.NBTCompound;
import java.util.Map; import java.util.Map;
@Getter
@Builder
@ToString
@EqualsAndHashCode
public class BiomeParticles { public class BiomeParticles {
private final float probability; private final float probability;
private final ParticleOptions options; private final ParticleOptions options;
public NBTCompound toNbt() { public BiomeParticles(float probability, ParticleOptions options) {
NBTCompound nbt = new NBTCompound(); this.probability = probability;
nbt.setFloat("probability", probability); this.options = options;
nbt.set("options", options.toNbt()); }
return nbt;
}
public interface ParticleOptions { public NBTCompound toNbt() {
NBTCompound toNbt(); NBTCompound nbt = new NBTCompound();
} nbt.setFloat("probability", probability);
nbt.set("options", options.toNbt());
return nbt;
}
@Getter public interface ParticleOptions {
@Builder NBTCompound toNbt();
@ToString }
@EqualsAndHashCode
public static class BlockParticle implements ParticleOptions {
//TODO also can be falling_dust public static class BlockParticle implements ParticleOptions {
private static final String type = "block";
private final BlockAlternative block;
@Override //TODO also can be falling_dust
public NBTCompound toNbt() { private static final String type = "block";
NBTCompound nbtCompound = new NBTCompound();
Block block1 = Block.fromStateId(block.getId());
nbtCompound.setString("type", type);
nbtCompound.setString("Name", block1.getName());
Map<String, String> propertiesMap = block.createPropertiesMap();
if (propertiesMap.size() != 0) {
NBTCompound properties = new NBTCompound();
propertiesMap.forEach(properties::setString);
nbtCompound.set("Properties", properties);
}
return nbtCompound;
}
} private final BlockAlternative block;
@Getter public BlockParticle(BlockAlternative block) {
@Builder this.block = block;
@ToString }
@EqualsAndHashCode
public static class DustParticle implements ParticleOptions {
private static final String type = "dust"; @Override
private final float red; public NBTCompound toNbt() {
private final float green; NBTCompound nbtCompound = new NBTCompound();
private final float blue; Block block1 = Block.fromStateId(block.getId());
private final float scale; nbtCompound.setString("type", type);
nbtCompound.setString("Name", block1.getName());
Map<String, String> propertiesMap = block.createPropertiesMap();
if (propertiesMap.size() != 0) {
NBTCompound properties = new NBTCompound();
propertiesMap.forEach(properties::setString);
nbtCompound.set("Properties", properties);
}
return nbtCompound;
}
@Override }
public NBTCompound toNbt() {
NBTCompound nbtCompound = new NBTCompound();
nbtCompound.setString("type", type);
nbtCompound.setFloat("r", red);
nbtCompound.setFloat("g", green);
nbtCompound.setFloat("b", blue);
nbtCompound.setFloat("scale", scale);
return nbtCompound;
}
} public static class DustParticle implements ParticleOptions {
@Getter private static final String type = "dust";
@Builder
@ToString
@EqualsAndHashCode
public static class ItemParticle implements ParticleOptions {
private static final String type = "item"; private final float red;
private final ItemStack item; private final float green;
private final float blue;
private final float scale;
@Override public DustParticle(float red, float green, float blue, float scale) {
public NBTCompound toNbt() { this.red = red;
//todo test count might be wrong type this.green = green;
NBTCompound nbtCompound = item.toNBT(); this.blue = blue;
nbtCompound.setString("type", type); this.scale = scale;
return nbtCompound; }
}
} @Override
public NBTCompound toNbt() {
NBTCompound nbtCompound = new NBTCompound();
nbtCompound.setString("type", type);
nbtCompound.setFloat("r", red);
nbtCompound.setFloat("g", green);
nbtCompound.setFloat("b", blue);
nbtCompound.setFloat("scale", scale);
return nbtCompound;
}
@Getter }
@Builder
@ToString
@EqualsAndHashCode
public static class NormalParticle implements ParticleOptions {
private final NamespaceID type; public static class ItemParticle implements ParticleOptions {
@Override private static final String type = "item";
public NBTCompound toNbt() {
NBTCompound nbtCompound = new NBTCompound();
nbtCompound.setString("type", type.toString());
return nbtCompound;
}
} private final ItemStack item;
public ItemParticle(ItemStack item) {
this.item = item;
}
@Override
public NBTCompound toNbt() {
//todo test count might be wrong type
NBTCompound nbtCompound = item.toNBT();
nbtCompound.setString("type", type);
return nbtCompound;
}
}
public static class NormalParticle implements ParticleOptions {
private final NamespaceID type;
public NormalParticle(@NotNull NamespaceID type) {
this.type = type;
}
@Override
public NBTCompound toNbt() {
NBTCompound nbtCompound = new NBTCompound();
nbtCompound.setString("type", type.toString());
return nbtCompound;
}
}
} }

View File

@ -43,7 +43,7 @@ public class PlayerInit {
NoiseTestGenerator noiseTestGenerator = new NoiseTestGenerator(); NoiseTestGenerator noiseTestGenerator = new NoiseTestGenerator();
instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(DimensionType.OVERWORLD); instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(DimensionType.OVERWORLD);
instanceContainer.enableAutoChunkLoad(true); instanceContainer.enableAutoChunkLoad(true);
instanceContainer.setChunkGenerator(chunkGeneratorDemo); instanceContainer.setChunkGenerator(noiseTestGenerator);
// Load some chunks beforehand // Load some chunks beforehand
final int loopStart = -3; final int loopStart = -3;

View File

@ -1,6 +1,5 @@
package demo.generator; package demo.generator;
import lombok.Data;
import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.batch.ChunkBatch; import net.minestom.server.instance.batch.ChunkBatch;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
@ -9,23 +8,22 @@ import net.minestom.server.utils.BlockPosition;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@Data
public class Structure { public class Structure {
private final Map<BlockPosition, Block> blocks = new HashMap<>(); private final Map<BlockPosition, Block> blocks = new HashMap<>();
public void build(ChunkBatch batch, BlockPosition pos) { public void build(ChunkBatch batch, BlockPosition pos) {
blocks.forEach((bPos, block) -> { blocks.forEach((bPos, block) -> {
if (bPos.getX() + pos.getX() >= Chunk.CHUNK_SIZE_X || bPos.getX() + pos.getX() < 0) if (bPos.getX() + pos.getX() >= Chunk.CHUNK_SIZE_X || bPos.getX() + pos.getX() < 0)
return; return;
if (bPos.getZ() + pos.getZ() >= Chunk.CHUNK_SIZE_Z || bPos.getZ() + pos.getZ() < 0) if (bPos.getZ() + pos.getZ() >= Chunk.CHUNK_SIZE_Z || bPos.getZ() + pos.getZ() < 0)
return; return;
batch.setBlock(bPos.copy().add(pos), block); batch.setBlock(bPos.copy().add(pos), block);
}); });
} }
public void addBlock(Block block, int localX, int localY, int localZ) { public void addBlock(Block block, int localX, int localY, int localZ) {
blocks.put(new BlockPosition(localX, localY, localZ), block); blocks.put(new BlockPosition(localX, localY, localZ), block);
} }
} }