diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8dd9b858e..f419b6ae1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,7 @@ variables: MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository" MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true" -image: maven:3-openjdk-14 +image: maven:3-openjdk-15 cache: paths: @@ -14,4 +14,4 @@ stages: verify: stage: verify script: - - 'mvn $MAVEN_CLI_OPTS verify' \ No newline at end of file + - 'mvn $MAVEN_CLI_OPTS verify' diff --git a/.idea/compiler.xml b/.idea/compiler.xml index b0fb4c5e6..ae693f340 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -10,5 +10,6 @@ + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index b10aa7341..db5b4dc3f 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/ReadMe.md b/ReadMe.md index 45c5fd2f5..375c4e3aa 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -24,8 +24,8 @@ Minosoft is an open source minecraft client, written from scratch in java. It ai - Disk space: Minosoft itself is pretty small (2-3 Mib), the libraries are a bit bigger (up to 100 Mib). You also need to have the "normal" minecraft assets (~ 300 Mib). So a total of 500 Mib is recommended. - GPU: Currently only needed for rendering, no clue yet. - - Java 14 (This is really important, we use specific features that are only available in the latest version. Java 8 is **not** supported). - OpenJDK 14 is (of course) also supported. + - Java 15 (This is really important, we use specific features that are only available in the latest version. Java 8 is **not** supported). + OpenJDK 15 is (of course) also supported. ## Rendering @@ -69,4 +69,13 @@ Many thanks to [Credits](Credits.md). ## Releases and beta We are almost ready to release a beta once !8 is merged. +## Compiling and running +1. Install Maven and java 15 (On Ubuntu based distributions: `sudo apt install maven openjdk-15-jdk`) +2. Clone this repo (`git clone https://gitlab.bixilon.de/bixilon/minosoft.git`) +3. Change directory (`cd minosoft`) +4. Checkout the branch (`git checkout `). Probably `render` +5. Run Minosoft with `mvn javafx:run`. If any errors occur, feel free to open an issue. In this early stage it might be helpful + to delete the app data folder (only of minosoft). + + This readme is work in progress, things may change over time. diff --git a/doc/Modding.md b/doc/Modding.md index 6d7045b99..20a13ea4a 100644 --- a/doc/Modding.md +++ b/doc/Modding.md @@ -12,6 +12,7 @@ In the root folder of your jar file (the mod) must be a file called `mod.json`. "Example dev" ], "name": "Example Mod", + "moddingAPIVersion": 1, "identifier": "example", "mainClass": "de.example.mod.Main", "loading": { @@ -43,7 +44,8 @@ In the root folder of your jar file (the mod) must be a file called `mod.json`. - `uuid` is a unique id for the mod. Generate 1 and keep it in all versions (used for dependencies, etc). **Required** - `versionId` like in android there is a numeric version id. It is used to compare between versions (and as identifier). **Required** - `versionName`, `authors`, `name` is the classic implementation of metadata. Can be anything, will be displayed in the mod list. **Required** -- `identifier` is the prefix of items (for Minecraft it is `minecraft`). Aka the thing before the ``. **Required** +- `moddingAPIVersion` Modding API version of minosoft. Currently `1` **Required** +- `identifier` is the prefix of items (for Minecraft it is `minecraft`). Aka the thing before the `:`. **Required** - `mainClass` the Main class of your mod (self explaining). The main class needs to extent the abstract class `MinosoftMod`. **Required** - `loading` Loading attributes. **Optional** - `priority` should the mod be loaded at the beginning or at the end. Possible values are `LOWEST`, `LOW`, `NORMAL`, `HIGH`, `HIGHEST` **Optional** @@ -52,8 +54,8 @@ In the root folder of your jar file (the mod) must be a file called `mod.json`. - `soft` These mods are **optional** to work. Both use the following format: **Optional** - `uuid` the uuid of the mod to load. **Required** - `version` Specifies the version you need to load. **Optional** - - `minimum` Minimum versionId required. **Maximum, minimum or both** - - `maximum` Maximum versionId required. **Maximum, minimum or both** + - `minimum` Minimum versionId required. **Maximum, minimum, both or none** + - `maximum` Maximum versionId required. **Maximum, minimum, both or none** ## Mod loading (aka Main class) Your main class must extend the following class: `de.bixilon.minosoft.MinosoftMod`. diff --git a/jitpack.yml b/jitpack.yml index e1dfa8381..f1416ce0f 100644 --- a/jitpack.yml +++ b/jitpack.yml @@ -1,4 +1,4 @@ before_install: - wget https://github.com/sormuras/bach/raw/master/install-jdk.sh - - source install-jdk.sh --feature 14 - - jshell --version \ No newline at end of file + - source install-jdk.sh --feature 15 + - jshell --version diff --git a/pom.xml b/pom.xml index abe138652..8f12163c4 100644 --- a/pom.xml +++ b/pom.xml @@ -24,8 +24,9 @@ maven-compiler-plugin 3.8.1 - 14 - 14 + 15 + 15 + --enable-preview @@ -37,9 +38,7 @@ - - org.apache.maven.plugins - + org.apache.maven.plugins maven-assembly-plugin 2.3 @@ -57,8 +56,8 @@ - 14 - 14 + 15 + 15 3.2.3 diff --git a/src/main/java/de/bixilon/minosoft/config/Configuration.java b/src/main/java/de/bixilon/minosoft/config/Configuration.java index 68662e13d..8a42d054e 100644 --- a/src/main/java/de/bixilon/minosoft/config/Configuration.java +++ b/src/main/java/de/bixilon/minosoft/config/Configuration.java @@ -33,19 +33,19 @@ public class Configuration { private final Object lock = new Object(); public Configuration() throws IOException { - File file = new File(StaticConfiguration.homeDir + "config/" + StaticConfiguration.CONFIG_FILENAME); + File file = new File(StaticConfiguration.HOME_DIR + "config/" + StaticConfiguration.CONFIG_FILENAME); if (!file.exists()) { // no configuration file InputStream input = getClass().getResourceAsStream("/config/" + StaticConfiguration.CONFIG_FILENAME); if (input == null) { throw new FileNotFoundException(String.format("[Config] Missing default config: %s!", StaticConfiguration.CONFIG_FILENAME)); } - File folder = new File(StaticConfiguration.homeDir + "config/"); + File folder = new File(StaticConfiguration.HOME_DIR + "config/"); if (!folder.exists() && !folder.mkdirs()) { throw new IOException("[Config] Could not create config folder!"); } Files.copy(input, Paths.get(file.getAbsolutePath())); - file = new File(StaticConfiguration.homeDir + "config/" + StaticConfiguration.CONFIG_FILENAME); + file = new File(StaticConfiguration.HOME_DIR + "config/" + StaticConfiguration.CONFIG_FILENAME); } config = Util.readJsonFromFile(file.getAbsolutePath()); int configVersion = getInt(ConfigurationPaths.CONFIG_VERSION); @@ -67,7 +67,7 @@ public class Configuration { } } // write config to temp file, delete original config, rename temp file to original file to avoid conflicts if minosoft gets closed while saving the config - File tempFile = new File(StaticConfiguration.homeDir + "config/" + StaticConfiguration.CONFIG_FILENAME + ".tmp"); + File tempFile = new File(StaticConfiguration.HOME_DIR + "config/" + StaticConfiguration.CONFIG_FILENAME + ".tmp"); Gson gson = new GsonBuilder().setPrettyPrinting().create(); FileWriter writer; try { diff --git a/src/main/java/de/bixilon/minosoft/config/StaticConfiguration.java b/src/main/java/de/bixilon/minosoft/config/StaticConfiguration.java index 6f13401e1..05c7caf05 100644 --- a/src/main/java/de/bixilon/minosoft/config/StaticConfiguration.java +++ b/src/main/java/de/bixilon/minosoft/config/StaticConfiguration.java @@ -23,10 +23,11 @@ public class StaticConfiguration { public static final boolean COLORED_LOG = true; // the log should be colored with ANSI (does not affect base components) public static final boolean LOG_RELATIVE_TIME = false; // prefix all log messages with the relative start time in milliseconds instead of the formatted time - public static String homeDir; + public static final String HOME_DIR; static { // Sets Config.homeDir to the correct folder per OS + String homeDir; homeDir = System.getProperty("user.home"); if (!homeDir.endsWith(File.separator)) { homeDir += "/"; @@ -42,5 +43,6 @@ public class StaticConfiguration { // failed creating folder throw new RuntimeException(String.format("Could not create home folder (%s)!", homeDir)); } + HOME_DIR = folder.getAbsolutePath() + "/"; } } diff --git a/src/main/java/de/bixilon/minosoft/data/EntityRotation.java b/src/main/java/de/bixilon/minosoft/data/EntityRotation.java index d997d8b21..e874073fa 100644 --- a/src/main/java/de/bixilon/minosoft/data/EntityRotation.java +++ b/src/main/java/de/bixilon/minosoft/data/EntityRotation.java @@ -13,22 +13,7 @@ package de.bixilon.minosoft.data; -public class EntityRotation { - final float yaw; - final float pitch; - final float roll; - - public EntityRotation(float yaw, float pitch, float roll) { - this.yaw = yaw; - this.pitch = pitch; - this.roll = roll; - } - - @Override - public String toString() { - return String.format("%s %s %s", getYaw(), getPitch(), getRoll()); - } - +public record EntityRotation(float yaw, float pitch, float roll) { public float getYaw() { return yaw; } @@ -40,4 +25,9 @@ public class EntityRotation { public float getRoll() { return roll; } + + @Override + public String toString() { + return String.format("%s %s %s", yaw, pitch, roll); + } } diff --git a/src/main/java/de/bixilon/minosoft/data/Player.java b/src/main/java/de/bixilon/minosoft/data/Player.java index 4db1b7a99..b8c14e20a 100644 --- a/src/main/java/de/bixilon/minosoft/data/Player.java +++ b/src/main/java/de/bixilon/minosoft/data/Player.java @@ -33,7 +33,7 @@ public class Player { public final HashMap playerList = new HashMap<>(); final MojangAccount account; final ScoreboardManager scoreboardManager = new ScoreboardManager(); - final World world = new World("world"); + final World world = new World(); final HashMap inventories = new HashMap<>(); float health; int food; diff --git a/src/main/java/de/bixilon/minosoft/data/Vector.java b/src/main/java/de/bixilon/minosoft/data/Vector.java index 12780a83a..5fd097afb 100644 --- a/src/main/java/de/bixilon/minosoft/data/Vector.java +++ b/src/main/java/de/bixilon/minosoft/data/Vector.java @@ -13,26 +13,7 @@ package de.bixilon.minosoft.data; -public class Vector { - final int x; - final int y; - final int z; - - public Vector(int x, int y, int z) { - this.x = x; - this.y = y; - this.z = z; - } - - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; - } - Vector pos = (Vector) obj; - return pos.getX() == getX() && pos.getY() == getY() && pos.getZ() == getZ(); - } - +public record Vector(int x, int y, int z) { public int getX() { return x; } @@ -47,6 +28,6 @@ public class Vector { @Override public String toString() { - return String.format("%s %s %s", getX(), getY(), getZ()); + return String.format("%s %s %s", x, y, z); } } diff --git a/src/main/java/de/bixilon/minosoft/data/assets/AssetsManager.java b/src/main/java/de/bixilon/minosoft/data/assets/AssetsManager.java index 64e958656..18f12a45e 100644 --- a/src/main/java/de/bixilon/minosoft/data/assets/AssetsManager.java +++ b/src/main/java/de/bixilon/minosoft/data/assets/AssetsManager.java @@ -249,6 +249,6 @@ public class AssetsManager { } private static String getAssetDiskPath(String hash) { - return StaticConfiguration.homeDir + String.format("assets/objects/%s/%s.gz", hash.substring(0, 2), hash); + return StaticConfiguration.HOME_DIR + String.format("assets/objects/%s/%s.gz", hash.substring(0, 2), hash); } } diff --git a/src/main/java/de/bixilon/minosoft/data/entities/Location.java b/src/main/java/de/bixilon/minosoft/data/entities/Location.java index a02c87e0b..57e3032cb 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/Location.java +++ b/src/main/java/de/bixilon/minosoft/data/entities/Location.java @@ -13,32 +13,7 @@ package de.bixilon.minosoft.data.entities; -import java.util.Objects; - -public class Location { - final double x; - final double y; - final double z; - - public Location(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; - } - - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; - } - Location that = (Location) obj; - return that.getX() == getX() && that.getY() == getY() && that.getZ() == getZ(); - } - - @Override - public int hashCode() { - return Objects.hash(x, y, z); - } +public record Location(double x, double y, double z) { public double getX() { return x; @@ -54,6 +29,6 @@ public class Location { @Override public String toString() { - return String.format("%s %s %s", getX(), getY(), getZ()); + return String.format("%s %s %s", x, y, z); } } diff --git a/src/main/java/de/bixilon/minosoft/data/entities/RelativeLocation.java b/src/main/java/de/bixilon/minosoft/data/entities/RelativeLocation.java index af7c61cfc..d92fe485a 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/RelativeLocation.java +++ b/src/main/java/de/bixilon/minosoft/data/entities/RelativeLocation.java @@ -13,33 +13,7 @@ package de.bixilon.minosoft.data.entities; -import java.util.Objects; - -public class RelativeLocation { - final double x; - final double y; - final double z; - - public RelativeLocation(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; - } - - @Override - public int hashCode() { - return Objects.hash(x, y, z); - } - - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; - } - RelativeLocation that = (RelativeLocation) obj; - return that.getX() == getX() && that.getY() == getY() && that.getZ() == getZ(); - } - +public record RelativeLocation(double x, double y, double z) { public double getX() { return x; } @@ -54,6 +28,6 @@ public class RelativeLocation { @Override public String toString() { - return String.format("%s %s %s", getX(), getY(), getZ()); + return String.format("%s %s %s", x, y, z); } } diff --git a/src/main/java/de/bixilon/minosoft/data/entities/StatusEffect.java b/src/main/java/de/bixilon/minosoft/data/entities/StatusEffect.java index bc309fe1e..04c9f0ca3 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/StatusEffect.java +++ b/src/main/java/de/bixilon/minosoft/data/entities/StatusEffect.java @@ -15,17 +15,7 @@ package de.bixilon.minosoft.data.entities; import de.bixilon.minosoft.data.mappings.MobEffect; -public class StatusEffect { - final MobEffect effect; - final int amplifier; - final int duration; - - public StatusEffect(MobEffect effect, int amplifier, int duration) { - this.effect = effect; - this.amplifier = amplifier; - this.duration = duration; - } - +public record StatusEffect(MobEffect effect, int amplifier, int duration) { public int getAmplifier() { return amplifier; } diff --git a/src/main/java/de/bixilon/minosoft/data/entities/Velocity.java b/src/main/java/de/bixilon/minosoft/data/entities/Velocity.java index 90b982a60..f26f8c0e5 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/Velocity.java +++ b/src/main/java/de/bixilon/minosoft/data/entities/Velocity.java @@ -13,26 +13,7 @@ package de.bixilon.minosoft.data.entities; -public class Velocity { - final short x; - final short y; - final short z; - - public Velocity(short x, short y, short z) { - this.x = x; - this.y = y; - this.z = z; - } - - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; - } - Velocity that = (Velocity) obj; - return that.getX() == getX() && that.getY() == getY() && that.getZ() == getZ(); - } - +public record Velocity(short x, short y, short z) { public short getX() { return x; } @@ -47,6 +28,6 @@ public class Velocity { @Override public String toString() { - return String.format("%s %s %s", getX(), getY(), getZ()); + return String.format("%s %s %s", x, y, z); } } diff --git a/src/main/java/de/bixilon/minosoft/data/entities/VillagerData.java b/src/main/java/de/bixilon/minosoft/data/entities/VillagerData.java index 554e1d2c2..dd5909893 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/VillagerData.java +++ b/src/main/java/de/bixilon/minosoft/data/entities/VillagerData.java @@ -16,38 +16,9 @@ package de.bixilon.minosoft.data.entities; import de.bixilon.minosoft.data.MapSet; import de.bixilon.minosoft.data.VersionValueMap; -public class VillagerData { - final VillagerTypes type; - final VillagerProfessions profession; - final VillagerLevels level; - +public record VillagerData(VillagerTypes type, VillagerProfessions profession, VillagerLevels level) { public VillagerData(int type, int profession, int level, int versionId) { - this.type = VillagerTypes.byId(type); - this.profession = VillagerProfessions.byId(profession, versionId); - this.level = VillagerLevels.byId(level); - } - - public VillagerData(VillagerTypes type, VillagerProfessions profession, VillagerLevels level) { - this.type = type; - this.profession = profession; - this.level = level; - } - - @Override - public int hashCode() { - return type.hashCode() * profession.hashCode() * level.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; - } - if (hashCode() != obj.hashCode()) { - return false; - } - VillagerData their = (VillagerData) obj; - return getType() == their.getType() && getProfession() == their.getProfession() && getLevel() == their.getLevel(); + this(VillagerTypes.byId(type), VillagerProfessions.byId(profession, versionId), VillagerLevels.byId(level)); } public VillagerTypes getType() { diff --git a/src/main/java/de/bixilon/minosoft/data/entities/block/BedEntityMetaData.java b/src/main/java/de/bixilon/minosoft/data/entities/block/BedEntityMetaData.java index 8cc63894e..1af244946 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/block/BedEntityMetaData.java +++ b/src/main/java/de/bixilon/minosoft/data/entities/block/BedEntityMetaData.java @@ -26,9 +26,9 @@ public class BedEntityMetaData extends BlockEntityMetaData { } public BedEntityMetaData(NBTTag nbt) { - if (nbt instanceof StringTag) { + if (nbt instanceof StringTag stringTag) { // yes, we support bed rgb colors :D - color = new RGBColor(((StringTag) nbt).getValue()); + color = new RGBColor(stringTag.getValue()); return; } color = switch (((IntTag) nbt).getValue()) { diff --git a/src/main/java/de/bixilon/minosoft/data/entities/meta/EntityMetaData.java b/src/main/java/de/bixilon/minosoft/data/entities/meta/EntityMetaData.java index f8e2fc6b5..209d7c9d1 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/meta/EntityMetaData.java +++ b/src/main/java/de/bixilon/minosoft/data/entities/meta/EntityMetaData.java @@ -309,8 +309,8 @@ public class EntityMetaData { public boolean getBoolean(int index, boolean defaultValue) { Object ret = get(index, defaultValue); - if (ret instanceof Byte) { - return (byte) ret == 0x01; + if (ret instanceof Byte b) { + return b == 0x01; } return (boolean) get(index, defaultValue); } diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/BlockId.java b/src/main/java/de/bixilon/minosoft/data/mappings/BlockId.java index f96c8c687..507e5834d 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/BlockId.java +++ b/src/main/java/de/bixilon/minosoft/data/mappings/BlockId.java @@ -13,15 +13,7 @@ package de.bixilon.minosoft.data.mappings; -public class BlockId { - final String mod; - final String identifier; - - public BlockId(String mod, String identifier) { - this.mod = mod; - this.identifier = identifier; - } - +public record BlockId(String mod, String identifier) { public String getMod() { return mod; } @@ -34,21 +26,4 @@ public class BlockId { public String toString() { return String.format("%s:%s", getMod(), getIdentifier()); } - - @Override - public int hashCode() { - return mod.hashCode() * identifier.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; - } - if (hashCode() != obj.hashCode()) { - return false; - } - BlockId their = (BlockId) obj; - return getIdentifier().equals(their.getIdentifier()) && getMod().equals(their.getMod()); - } } diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/Enchantment.java b/src/main/java/de/bixilon/minosoft/data/mappings/Enchantment.java index a16f38e5b..2383bee31 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/Enchantment.java +++ b/src/main/java/de/bixilon/minosoft/data/mappings/Enchantment.java @@ -13,42 +13,17 @@ package de.bixilon.minosoft.data.mappings; -public class Enchantment { - final String mod; - final String identifier; - - public Enchantment(String mod, String identifier) { - this.mod = mod; - this.identifier = identifier; +public record Enchantment(String mod, String identifier) { + public String getMod() { + return mod; } public String getIdentifier() { return identifier; } - public String getMod() { - return mod; - } - @Override public String toString() { - return String.format("%s:%s", getMod(), getIdentifier()); - } - - @Override - public int hashCode() { - return mod.hashCode() * identifier.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; - } - if (hashCode() != obj.hashCode()) { - return false; - } - Enchantment their = (Enchantment) obj; - return getIdentifier().equals(their.getIdentifier()) && getMod().equals(their.getMod()); + return String.format("%s:%s", mod, identifier); } } diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/MobEffect.java b/src/main/java/de/bixilon/minosoft/data/mappings/MobEffect.java index b5be03bb1..8fe1557ea 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/MobEffect.java +++ b/src/main/java/de/bixilon/minosoft/data/mappings/MobEffect.java @@ -13,15 +13,7 @@ package de.bixilon.minosoft.data.mappings; -public class MobEffect { - final String mod; - final String identifier; - - public MobEffect(String mod, String identifier) { - this.mod = mod; - this.identifier = identifier; - } - +public record MobEffect(String mod, String identifier) { public String getMod() { return mod; } @@ -34,21 +26,4 @@ public class MobEffect { public String toString() { return String.format("%s:%s", getMod(), getIdentifier()); } - - @Override - public int hashCode() { - return mod.hashCode() * identifier.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; - } - if (hashCode() != obj.hashCode()) { - return false; - } - MobEffect their = (MobEffect) obj; - return getIdentifier().equals(their.getIdentifier()) && getMod().equals(their.getMod()); - } } diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/Motive.java b/src/main/java/de/bixilon/minosoft/data/mappings/Motive.java index 7e8ae6168..7348103b7 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/Motive.java +++ b/src/main/java/de/bixilon/minosoft/data/mappings/Motive.java @@ -13,15 +13,7 @@ package de.bixilon.minosoft.data.mappings; -public class Motive { - final String mod; - final String identifier; - - public Motive(String mod, String identifier) { - this.mod = mod; - this.identifier = identifier; - } - +public record Motive(String mod, String identifier) { public String getMod() { return mod; } @@ -34,21 +26,4 @@ public class Motive { public String toString() { return String.format("%s:%s", getMod(), getIdentifier()); } - - @Override - public int hashCode() { - return mod.hashCode() * identifier.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; - } - if (hashCode() != obj.hashCode()) { - return false; - } - Motive their = (Motive) obj; - return getIdentifier().equals(their.getIdentifier()) && getMod().equals(their.getMod()); - } } diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/particle/Particle.java b/src/main/java/de/bixilon/minosoft/data/mappings/particle/Particle.java index ef027b725..0e2e034ad 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/particle/Particle.java +++ b/src/main/java/de/bixilon/minosoft/data/mappings/particle/Particle.java @@ -13,15 +13,7 @@ package de.bixilon.minosoft.data.mappings.particle; -public class Particle { - final String mod; - final String identifier; - - public Particle(String mod, String identifier) { - this.mod = mod; - this.identifier = identifier; - } - +public record Particle(String mod, String identifier) { public String getMod() { return mod; } @@ -32,23 +24,6 @@ public class Particle { @Override public String toString() { - return String.format("%s:%s", getMod(), getIdentifier()); - } - - @Override - public int hashCode() { - return mod.hashCode() * identifier.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; - } - if (hashCode() != obj.hashCode()) { - return false; - } - Particle their = (Particle) obj; - return getIdentifier().equals(their.getIdentifier()) && getMod().equals(their.getMod()); + return String.format("%s:%s", mod, identifier); } } diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/recipes/Ingredient.java b/src/main/java/de/bixilon/minosoft/data/mappings/recipes/Ingredient.java index c3886ea25..fbfb3b679 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/recipes/Ingredient.java +++ b/src/main/java/de/bixilon/minosoft/data/mappings/recipes/Ingredient.java @@ -15,14 +15,9 @@ package de.bixilon.minosoft.data.mappings.recipes; import de.bixilon.minosoft.data.inventory.Slot; -public class Ingredient { - final Slot[] slot; - - public Ingredient(Slot[] slot) { - this.slot = slot; - } - +public record Ingredient(Slot[] slot) { public static boolean slotEquals(Slot[] one, Slot[] two) { + // ToDo if (one.length != two.length) { return false; } @@ -43,18 +38,6 @@ public class Ingredient { return false; } - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; - } - if (this.hashCode() != obj.hashCode()) { - return false; - } - Ingredient their = (Ingredient) obj; - return slotEquals(getSlot(), their.getSlot()); - } - public Slot[] getSlot() { return slot; } diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/statistics/Statistic.java b/src/main/java/de/bixilon/minosoft/data/mappings/statistics/Statistic.java index 8d5b500a2..2219cd3fb 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/statistics/Statistic.java +++ b/src/main/java/de/bixilon/minosoft/data/mappings/statistics/Statistic.java @@ -13,15 +13,7 @@ package de.bixilon.minosoft.data.mappings.statistics; -public class Statistic { - final String mod; - final String identifier; - - public Statistic(String mod, String identifier) { - this.mod = mod; - this.identifier = identifier; - } - +public record Statistic(String mod, String identifier) { public String getMod() { return mod; } @@ -32,22 +24,6 @@ public class Statistic { @Override public String toString() { - return String.format("%s:%s", getMod(), getIdentifier()); - } - - @Override - public int hashCode() { - return mod.hashCode() * identifier.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; - } - if (hashCode() != obj.hashCode()) { - return false; - } - return toString().equals(obj.toString()); + return String.format("%s:%s", mod, identifier); } } diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/versions/Versions.java b/src/main/java/de/bixilon/minosoft/data/mappings/versions/Versions.java index 8c668d922..9fd2f28fb 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/versions/Versions.java +++ b/src/main/java/de/bixilon/minosoft/data/mappings/versions/Versions.java @@ -128,7 +128,7 @@ public class Versions { long startTime = System.currentTimeMillis(); // check if mapping folder exist - File mappingFolder = new File(StaticConfiguration.homeDir + "assets/mapping"); + File mappingFolder = new File(StaticConfiguration.HOME_DIR + "assets/mapping"); if (!mappingFolder.exists()) { if (mappingFolder.mkdirs()) { Log.verbose("Created mappings folder."); @@ -138,7 +138,7 @@ public class Versions { } } - String fileName = StaticConfiguration.homeDir + String.format("assets/mapping/%s.tar.gz", version.getVersionName()); + String fileName = StaticConfiguration.HOME_DIR + String.format("assets/mapping/%s.tar.gz", version.getVersionName()); HashMap files; try { files = Util.readJsonTarGzFile(fileName); diff --git a/src/main/java/de/bixilon/minosoft/data/world/BlockPosition.java b/src/main/java/de/bixilon/minosoft/data/world/BlockPosition.java index de8c0cf64..17dad42b2 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/BlockPosition.java +++ b/src/main/java/de/bixilon/minosoft/data/world/BlockPosition.java @@ -16,29 +16,17 @@ package de.bixilon.minosoft.data.world; import de.bixilon.minosoft.render.blockModels.Face.RenderConstants; import de.bixilon.minosoft.render.utility.Vec3; -import java.util.Objects; - -public class BlockPosition { - final int x; - final int y; - final int z; - - public BlockPosition(int x, int y, int z) { - this.x = x; - this.y = y; - this.z = z; +public record BlockPosition(int x, int y, int z) { + public BlockPosition(Vec3 vec3) { + this((int) vec3.x, (int) vec3.y, (int) vec3.z); } - public BlockPosition(Vec3 testPosition) { - x = (int) testPosition.x; - y = (short) testPosition.y; - z = (int) testPosition.z; + public BlockPosition(ChunkLocation chunkLocation, Byte height, InChunkSectionLocation sectionLocation) { + this((chunkLocation.getX() * RenderConstants.SECTION_WIDTH + sectionLocation.getX()), (chunkLocation.getX() * RenderConstants.SECTION_WIDTH + sectionLocation.getX()), (chunkLocation.getZ() * RenderConstants.SECTION_WIDTH + sectionLocation.getZ())); } - public BlockPosition(ChunkLocation chunkLocation, Byte height, ChunkNibbleLocation nibbleLocation) { - this.x = chunkLocation.getX() * RenderConstants.SECTION_WIDTH + nibbleLocation.getX(); - this.y = height * RenderConstants.SECTION_HEIGHT + nibbleLocation.getY(); - this.z = chunkLocation.getZ() * RenderConstants.SECTION_WIDTH + nibbleLocation.getZ(); + public ChunkLocation getChunkLocation() { + return new ChunkLocation(x / 16, z / 16); } public int getX() { @@ -53,48 +41,21 @@ public class BlockPosition { return z; } - @Override - public int hashCode() { - return Objects.hash(x, y, z); - } - - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; + public InChunkLocation getInChunkLocation() { + int x = this.x % RenderConstants.SECTION_WIDTH; + if (x < 0) { + x += RenderConstants.SECTION_WIDTH; } - BlockPosition pos = (BlockPosition) obj; - return pos.getX() == getX() && pos.getY() == getY() && pos.getZ() == getZ(); - } - - public ChunkLocation getChunkLocation() { - int x = getX() / RenderConstants.SECTION_WIDTH; - int z = getZ() / RenderConstants.SECTION_WIDTH; - //ToDo - if (getX() < 0) { - x--; + int z = this.z % RenderConstants.SECTION_WIDTH; + if (z < 0) { + z += RenderConstants.SECTION_WIDTH; } - if (getZ() < 0) { - z--; - } - return new ChunkLocation(x, z); + return new InChunkLocation(x, this.y, z); } @Override public String toString() { - return String.format("%d %d %d", getX(), getY(), getZ()); - } - - public InChunkLocation getInChunkLocation() { - int x = getX() % RenderConstants.SECTION_WIDTH; - if (x < 0) { - x += RenderConstants.SECTION_WIDTH; - } - int z = getZ() % RenderConstants.SECTION_WIDTH; - if (z < 0) { - z += RenderConstants.SECTION_WIDTH; - } - return new InChunkLocation(x, getY(), z); + return String.format("%d %d %d", x, y, z); } public BlockPosition add(int[] ints) { diff --git a/src/main/java/de/bixilon/minosoft/data/world/Chunk.java b/src/main/java/de/bixilon/minosoft/data/world/Chunk.java index c37dfb972..339775b81 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/Chunk.java +++ b/src/main/java/de/bixilon/minosoft/data/world/Chunk.java @@ -21,13 +21,13 @@ import java.util.HashMap; import java.util.concurrent.ConcurrentHashMap; /** - * Collection of 16 chunks nibbles + * Collection of 16 chunks sections */ public class Chunk { - final ConcurrentHashMap nibbles; + final ConcurrentHashMap sections; - public Chunk(ConcurrentHashMap chunks) { - this.nibbles = chunks; + public Chunk(ConcurrentHashMap sections) { + this.sections = sections; } public Block getBlock(InChunkLocation location) { @@ -36,27 +36,27 @@ public class Chunk { public Block getBlock(int x, int y, int z) { byte section = (byte) (y / RenderConstants.SECTION_HEIGHT); - if (!nibbles.containsKey(section)) { + if (!sections.containsKey(section)) { return Blocks.nullBlock; } - return nibbles.get(section).getBlock(x, y % RenderConstants.SECTION_HEIGHT, z); + return sections.get(section).getBlock(x, y % RenderConstants.SECTION_HEIGHT, z); } public void setBlock(int x, int y, int z, Block block) { byte section = (byte) (y / RenderConstants.SECTION_HEIGHT); createSectionIfNotExists(section); - nibbles.get(section).setBlock(x, y % RenderConstants.SECTION_HEIGHT, z, block); + sections.get(section).setBlock(x, y % RenderConstants.SECTION_HEIGHT, z, block); } public void setBlock(InChunkLocation location, Block block) { byte section = (byte) (location.getY() / RenderConstants.SECTION_HEIGHT); createSectionIfNotExists(section); - nibbles.get(section).setBlock(location.getChunkNibbleLocation(), block); + sections.get(section).setBlock(location.getInChunkSectionLocation(), block); } void createSectionIfNotExists(byte section) { - if (nibbles.get(section) == null) { - nibbles.put(section, new ChunkNibble()); + if (sections.get(section) == null) { + sections.put(section, new ChunkSection()); } } @@ -64,7 +64,7 @@ public class Chunk { blocks.forEach(this::setBlock); } - public ConcurrentHashMap getNibbles() { - return nibbles; + public ConcurrentHashMap getSections() { + return sections; } } diff --git a/src/main/java/de/bixilon/minosoft/data/world/ChunkLocation.java b/src/main/java/de/bixilon/minosoft/data/world/ChunkLocation.java index 306ac11f8..47e12ba2d 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/ChunkLocation.java +++ b/src/main/java/de/bixilon/minosoft/data/world/ChunkLocation.java @@ -13,34 +13,10 @@ package de.bixilon.minosoft.data.world; -import java.util.Objects; - /** * Chunk X and Z location (block position / 16, rounded down) */ -public class ChunkLocation { - final int x; - final int z; - - public ChunkLocation(int x, int z) { - this.x = x; - this.z = z; - } - - @Override - public int hashCode() { - return Objects.hash(x, z); - } - - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; - } - ChunkLocation that = (ChunkLocation) obj; - return getX() == that.getX() && getZ() == that.getZ(); - } - +public record ChunkLocation(int x, int z) { public int getX() { return x; } @@ -51,6 +27,6 @@ public class ChunkLocation { @Override public String toString() { - return String.format("%d %d", getX(), getZ()); + return String.format("%d %d", x, z); } } diff --git a/src/main/java/de/bixilon/minosoft/data/world/ChunkNibble.java b/src/main/java/de/bixilon/minosoft/data/world/ChunkSection.java similarity index 73% rename from src/main/java/de/bixilon/minosoft/data/world/ChunkNibble.java rename to src/main/java/de/bixilon/minosoft/data/world/ChunkSection.java index 2d9b42dac..d62259a82 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/ChunkNibble.java +++ b/src/main/java/de/bixilon/minosoft/data/world/ChunkSection.java @@ -21,31 +21,30 @@ import java.util.concurrent.ConcurrentHashMap; /** * Collection of 16x16x16 blocks */ -public class ChunkNibble { - final ConcurrentHashMap blocks; +public class ChunkSection { + final ConcurrentHashMap blocks; - public ChunkNibble(ConcurrentHashMap blocks) { + public ChunkSection(ConcurrentHashMap blocks) { this.blocks = blocks; } - public ChunkNibble() { - // empty + public ChunkSection() { this.blocks = new ConcurrentHashMap<>(); } public Block getBlock(int x, int y, int z) { - return getBlock(new ChunkNibbleLocation(x, y, z)); + return getBlock(new InChunkSectionLocation(x, y, z)); } - public Block getBlock(ChunkNibbleLocation loc) { + public Block getBlock(InChunkSectionLocation loc) { return blocks.get(loc); } public void setBlock(int x, int y, int z, Block block) { - setBlock(new ChunkNibbleLocation(x, y, z), block); + setBlock(new InChunkSectionLocation(x, y, z), block); } - public void setBlock(ChunkNibbleLocation location, Block block) { + public void setBlock(InChunkSectionLocation location, Block block) { if (block == null || block.equals(Blocks.nullBlock)) { blocks.remove(location); return; @@ -53,7 +52,7 @@ public class ChunkNibble { blocks.put(location, block); } - public ConcurrentHashMap getBlocks() { + public ConcurrentHashMap getBlocks() { return blocks; } } diff --git a/src/main/java/de/bixilon/minosoft/data/world/InChunkLocation.java b/src/main/java/de/bixilon/minosoft/data/world/InChunkLocation.java index 7b35bf009..f4d348d51 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/InChunkLocation.java +++ b/src/main/java/de/bixilon/minosoft/data/world/InChunkLocation.java @@ -15,31 +15,14 @@ package de.bixilon.minosoft.data.world; import de.bixilon.minosoft.render.blockModels.Face.RenderConstants; -import java.util.Objects; - -public class InChunkLocation { - final int x; - final int y; - final int z; - - public InChunkLocation(int x, int y, int z) { - this.x = x; - this.y = y; - this.z = z; - } - - @Override - public int hashCode() { - return Objects.hash(x, y, z); - } - - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; +/** + * Chunk X, Y and Z location (max 16x255x16) + */ +public record InChunkLocation(int x, int y, int z) { + public InChunkLocation { + if (x > 15 || y > 255 || z > 15 || x < 0 || y < 0 || z < 0) { + throw new IllegalArgumentException(String.format("Invalid chunk location %s %s %s", x, y, z)); } - InChunkLocation that = (InChunkLocation) obj; - return getX() == that.getX() && getY() == that.getY() && getZ() == that.getZ(); } public int getX() { @@ -50,16 +33,16 @@ public class InChunkLocation { return y; } - public ChunkNibbleLocation getChunkNibbleLocation() { - return new ChunkNibbleLocation(getX(), getY() % RenderConstants.SECTION_HEIGHT, getZ()); + public int getZ() { + return z; + } + + public InChunkSectionLocation getInChunkSectionLocation() { + return new InChunkSectionLocation(x, y % RenderConstants.SECTION_HEIGHT, z); } @Override public String toString() { - return String.format("%d %d %d", getX(), getY(), getZ()); - } - - public int getZ() { - return z; + return String.format("%d %d %d", x, y, z); } } diff --git a/src/main/java/de/bixilon/minosoft/data/world/ChunkNibbleLocation.java b/src/main/java/de/bixilon/minosoft/data/world/InChunkSectionLocation.java similarity index 61% rename from src/main/java/de/bixilon/minosoft/data/world/ChunkNibbleLocation.java rename to src/main/java/de/bixilon/minosoft/data/world/InChunkSectionLocation.java index 0710027b3..fd633722f 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/ChunkNibbleLocation.java +++ b/src/main/java/de/bixilon/minosoft/data/world/InChunkSectionLocation.java @@ -13,36 +13,10 @@ package de.bixilon.minosoft.data.world; -import java.util.Objects; - /** * Chunk X, Y and Z location (max 16x16x16) */ -public class ChunkNibbleLocation { - final int x; - final int y; - final int z; - - public ChunkNibbleLocation(int x, int y, int z) { - this.x = x; - this.y = y; - this.z = z; - } - - @Override - public int hashCode() { - return Objects.hash(x, y, z); - } - - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; - } - ChunkNibbleLocation that = (ChunkNibbleLocation) obj; - return getX() == that.getX() && getY() == that.getY() && getZ() == that.getZ(); - } - +public record InChunkSectionLocation(int x, int y, int z) { public int getX() { return x; } @@ -57,6 +31,6 @@ public class ChunkNibbleLocation { @Override public String toString() { - return String.format("%d %d %d", getX(), getY(), getZ()); + return String.format("%d %d %d", x, y, z); } } diff --git a/src/main/java/de/bixilon/minosoft/data/world/World.java b/src/main/java/de/bixilon/minosoft/data/world/World.java index 9a7c26f54..7d5b90c6e 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/World.java +++ b/src/main/java/de/bixilon/minosoft/data/world/World.java @@ -23,35 +23,22 @@ import java.util.HashMap; import java.util.concurrent.ConcurrentHashMap; /** - * Collection of ChunkColumns + * Collection of chunks */ public class World { final ConcurrentHashMap chunks = new ConcurrentHashMap<>(); final ConcurrentHashMap entities = new ConcurrentHashMap<>(); - final String name; final HashMap blockEntityMeta = new HashMap<>(); boolean hardcore; boolean raining; Dimension dimension; // used for sky color, etc - public World(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public Chunk getChunk(ChunkLocation loc) { - return chunks.get(loc); - } - public ConcurrentHashMap getAllChunks() { return chunks; } public Block getBlock(BlockPosition pos) { - if (pos.y < 1) { + if (pos.getY() < 1) { return Blocks.nullBlock; } ChunkLocation loc = pos.getChunkLocation(); @@ -133,4 +120,8 @@ public class World { public void setBlockEntityData(HashMap blockEntities) { blockEntities.forEach(blockEntityMeta::put); } + + public Chunk getChunk(ChunkLocation chunkLocation) { + return chunks.get(chunkLocation); + } } diff --git a/src/main/java/de/bixilon/minosoft/gui/main/ServerListCell.java b/src/main/java/de/bixilon/minosoft/gui/main/ServerListCell.java index 35882cbad..7cf6a22d3 100644 --- a/src/main/java/de/bixilon/minosoft/gui/main/ServerListCell.java +++ b/src/main/java/de/bixilon/minosoft/gui/main/ServerListCell.java @@ -421,9 +421,8 @@ public class ServerListCell extends ListCell implements Initializable { grid.add(new Label(LocaleManager.translate(Strings.SERVER_INFO_SERVER_MODDED_BRAND) + ":"), 0, ++column); grid.add(moddedBrandLabel, 1, column); - if (lastPing.getServerModInfo() instanceof ForgeModInfo) { - ForgeModInfo modInfo = (ForgeModInfo) lastPing.getServerModInfo(); - Label moddedModsLabel = new Label(modInfo.getModList().toString()); + if (lastPing.getServerModInfo() instanceof ForgeModInfo forgeModInfo) { + Label moddedModsLabel = new Label(forgeModInfo.getModList().toString()); moddedModsLabel.setWrapText(true); grid.add(new Label(LocaleManager.translate(Strings.SERVER_INFO_SERVER_MODDED_MOD_LIST) + ":"), 0, ++column); diff --git a/src/main/java/de/bixilon/minosoft/modding/event/EventMethod.java b/src/main/java/de/bixilon/minosoft/modding/event/EventMethod.java index 645e30bde..42057da3a 100644 --- a/src/main/java/de/bixilon/minosoft/modding/event/EventMethod.java +++ b/src/main/java/de/bixilon/minosoft/modding/event/EventMethod.java @@ -43,7 +43,7 @@ public class EventMethod { if (!method.getParameters()[0].getType().isAssignableFrom(event.getClass())) { return; } - if (!annotation.ignoreCancelled() && event instanceof CancelableEvent && ((CancelableEvent) event).isCancelled()) { + if (!annotation.ignoreCancelled() && event instanceof CancelableEvent cancelableEvent && cancelableEvent.isCancelled()) { return; } try { diff --git a/src/main/java/de/bixilon/minosoft/modding/loading/ModDependency.java b/src/main/java/de/bixilon/minosoft/modding/loading/ModDependency.java new file mode 100644 index 000000000..fae1699cd --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/modding/loading/ModDependency.java @@ -0,0 +1,110 @@ +/* + * Minosoft + * Copyright (C) 2020 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.modding.loading; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import de.bixilon.minosoft.util.Util; + +import java.util.HashSet; +import java.util.UUID; + +public class ModDependency { + + private final UUID uuid; + private Integer versionMinimum; + private Integer versionMaximum; + + public ModDependency(UUID uuid, Integer versionMinimum, Integer versionMaximum) { + this.uuid = uuid; + this.versionMinimum = versionMinimum; + this.versionMaximum = versionMaximum; + } + + public ModDependency(UUID uuid) { + this.uuid = uuid; + } + + public static ModDependency serialize(JsonObject json) { + UUID uuid = Util.getUUIDFromString(json.get("uuid").getAsString()); + Integer versionMinimum = null; + Integer versionMaximum = null; + + if (json.has("version")) { + JsonObject version = json.getAsJsonObject("version"); + if (version.has("minimum")) { + versionMinimum = version.get("minimum").getAsInt(); + } + if (version.has("maximum")) { + versionMaximum = version.get("maximum").getAsInt(); + } + } + return new ModDependency(uuid, versionMinimum, versionMaximum); + } + + public static HashSet serializeDependencyArray(JsonArray json) { + HashSet result = new HashSet<>(); + json.forEach((jsonElement -> result.add(serialize(jsonElement.getAsJsonObject())))); + return result; + } + + public UUID getUUID() { + return uuid; + } + + public Integer getVersionMinimum() { + return versionMinimum; + } + + public Integer getVersionMaximum() { + return versionMaximum; + } + + @Override + public int hashCode() { + int result = uuid.hashCode(); + if (versionMinimum != null && versionMinimum > 0) { + result *= versionMinimum; + } + + if (versionMaximum != null && versionMaximum > 0) { + result *= versionMaximum; + } + return result; + } + + @Override + public boolean equals(Object obj) { + if (super.equals(obj)) { + return true; + } + if (hashCode() != obj.hashCode()) { + return false; + } + ModDependency their = (ModDependency) obj; + return getUUID().equals(their.getUUID()) && getVersionMaximum().equals(their.getVersionMaximum()) && getVersionMinimum().equals(their.getVersionMinimum()); + } + + @Override + public String toString() { + String result = uuid.toString(); + if (versionMinimum != null) { + result += " >" + versionMinimum; + } + if (versionMaximum != null) { + result += " <" + versionMaximum; + } + return result; + } +} diff --git a/src/main/java/de/bixilon/minosoft/modding/loading/ModInfo.java b/src/main/java/de/bixilon/minosoft/modding/loading/ModInfo.java index 33684ad59..142ed5f69 100644 --- a/src/main/java/de/bixilon/minosoft/modding/loading/ModInfo.java +++ b/src/main/java/de/bixilon/minosoft/modding/loading/ModInfo.java @@ -17,6 +17,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonObject; import de.bixilon.minosoft.util.Util; +import java.util.HashSet; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; @@ -26,11 +27,14 @@ public class ModInfo { final String versionName; final String name; final String[] authors; + final int moddingAPIVersion; final String identifier; final String mainClass; + final HashSet hardDependencies = new HashSet<>(); + final HashSet softDependencies = new HashSet<>(); LoadingInfo loadingInfo; - public ModInfo(JsonObject json) { + public ModInfo(JsonObject json) throws ModLoadingException { this.uuid = Util.getUUIDFromString(json.get("uuid").getAsString()); this.versionId = json.get("versionId").getAsInt(); this.versionName = json.get("versionName").getAsString(); @@ -39,6 +43,10 @@ public class ModInfo { this.authors = new String[authors.size()]; AtomicInteger i = new AtomicInteger(); authors.forEach((authorElement) -> this.authors[i.getAndIncrement()] = authorElement.getAsString()); + moddingAPIVersion = json.get("moddingAPIVersion").getAsInt(); + if (moddingAPIVersion > ModLoader.CURRENT_MODDING_API_VERSION) { + throw new ModLoadingException(String.format("Mod was written with for a newer version of minosoft (moddingAPIVersion=%d, expected=%d)", moddingAPIVersion, ModLoader.CURRENT_MODDING_API_VERSION)); + } this.identifier = json.get("identifier").getAsString(); this.mainClass = json.get("mainClass").getAsString(); if (json.has("loading")) { @@ -48,6 +56,15 @@ public class ModInfo { this.loadingInfo.setLoadingPriority(Priorities.valueOf(loading.get("priority").getAsString())); } } + if (json.has("dependencies")) { + JsonObject dependencies = json.getAsJsonObject("dependencies"); + if (dependencies.has("hard")) { + hardDependencies.addAll(ModDependency.serializeDependencyArray(dependencies.getAsJsonArray("hard"))); + } + if (dependencies.has("soft")) { + softDependencies.addAll(ModDependency.serializeDependencyArray(dependencies.getAsJsonArray("soft"))); + } + } } public String[] getAuthors() { diff --git a/src/main/java/de/bixilon/minosoft/modding/loading/ModLoader.java b/src/main/java/de/bixilon/minosoft/modding/loading/ModLoader.java index fc588147d..bcfdac0e8 100644 --- a/src/main/java/de/bixilon/minosoft/modding/loading/ModLoader.java +++ b/src/main/java/de/bixilon/minosoft/modding/loading/ModLoader.java @@ -24,63 +24,78 @@ import org.xeustechnologies.jcl.JclObjectFactory; import java.io.File; import java.io.IOException; -import java.util.HashSet; import java.util.LinkedList; -import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.zip.ZipFile; public class ModLoader { - static final LinkedList mods = new LinkedList<>(); + public static final int CURRENT_MODDING_API_VERSION = 1; + public static final LinkedList mods = new LinkedList<>(); public static void loadMods(CountUpAndDownLatch progress) throws Exception { Log.verbose("Start loading mods..."); + ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), Util.getThreadFactory("ModLoader")); + // load all jars, parse the mod.json // sort the list and prioritize // load all lists and dependencies async - HashSet> callables = new HashSet<>(); - File[] files = new File(StaticConfiguration.homeDir + "mods").listFiles(); + File[] files = new File(StaticConfiguration.HOME_DIR + "mods").listFiles(); if (files == null) { // no mods to load return; } + CountDownLatch latch = new CountDownLatch(files.length); for (File modFile : files) { if (modFile.isDirectory()) { continue; } - callables.add(() -> { + executor.execute(() -> { MinosoftMod mod = loadMod(progress, modFile); if (mod != null) { mods.add(mod); } - return mod; + latch.countDown(); }); } + latch.await(); - Util.executeInThreadPool("ModLoader", callables); + if (mods.size() == 0) { + Log.info("No mods to load."); + return; + } progress.addCount(mods.size() * ModPhases.values().length); // count * mod phases + // sort for priority mods.sort((a, b) -> { if (a == null || b == null) { return 0; } return -(getLoadingPriorityOrDefault(b.getInfo()).ordinal() - getLoadingPriorityOrDefault(a.getInfo()).ordinal()); }); + // ToDo: check dependencies + for (ModPhases phase : ModPhases.values()) { Log.verbose(String.format("Map loading phase changed: %s", phase)); - HashSet> phaseLoaderCallables = new HashSet<>(); - mods.forEach((instance) -> phaseLoaderCallables.add(() -> { - if (!instance.isEnabled()) { - return instance; - } - if (!instance.start(phase)) { - Log.warn(String.format("An error occurred while loading %s", instance.getInfo())); - instance.setEnabled(false); - } - progress.countDown(); - return instance; - })); - Util.executeInThreadPool("ModLoader", phaseLoaderCallables); + CountDownLatch modLatch = new CountDownLatch(mods.size()); + mods.forEach((instance) -> { + executor.execute(() -> { + if (!instance.isEnabled()) { + modLatch.countDown(); + progress.countDown(); + return; + } + if (!instance.start(phase)) { + Log.warn(String.format("An error occurred while loading %s", instance.getInfo())); + instance.setEnabled(false); + } + modLatch.countDown(); + progress.countDown(); + }); + }); + modLatch.await(); } mods.forEach((instance) -> { if (instance.isEnabled()) { @@ -94,6 +109,7 @@ public class ModLoader { } public static MinosoftMod loadMod(CountUpAndDownLatch progress, File file) { + MinosoftMod instance; try { Log.verbose(String.format("[MOD] Loading file %s", file.getAbsolutePath())); progress.countUp(); @@ -107,18 +123,17 @@ public class ModLoader { jcl.add(file.getAbsolutePath()); JclObjectFactory factory = JclObjectFactory.getInstance(); - MinosoftMod instance = (MinosoftMod) factory.create(jcl, modInfo.getMainClass()); + instance = (MinosoftMod) factory.create(jcl, modInfo.getMainClass()); instance.setInfo(modInfo); Log.verbose(String.format("[MOD] Mod file loaded and added to classpath (%s)", modInfo)); zipFile.close(); - progress.countDown(); - return instance; - } catch (IOException e) { + } catch (IOException | ModLoadingException | NullPointerException e) { + instance = null; e.printStackTrace(); Log.warn(String.format("Could not load mod: %s", file.getAbsolutePath())); } progress.countDown(); // failed - return null; + return instance; } private static Priorities getLoadingPriorityOrDefault(ModInfo info) { diff --git a/src/main/java/de/bixilon/minosoft/modding/loading/ModLoadingException.java b/src/main/java/de/bixilon/minosoft/modding/loading/ModLoadingException.java new file mode 100644 index 000000000..81655b8ff --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/modding/loading/ModLoadingException.java @@ -0,0 +1,35 @@ +/* + * Minosoft + * Copyright (C) 2020 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.modding.loading; + +public class ModLoadingException extends Exception { + public ModLoadingException() { + } + + public ModLoadingException(String message) { + super(message); + } + + public ModLoadingException(String message, Throwable cause) { + super(message, cause); + } + + public ModLoadingException(Throwable cause) { + super(cause); + } + + public ModLoadingException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/Connection.java b/src/main/java/de/bixilon/minosoft/protocol/network/Connection.java index 17bfd4455..57966a04a 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/network/Connection.java +++ b/src/main/java/de/bixilon/minosoft/protocol/network/Connection.java @@ -201,8 +201,8 @@ public class Connection { public boolean fireEvent(ConnectionEvent connectionEvent) { Minosoft.eventManagers.forEach((eventManager -> eventManager.getGlobalEventListeners().forEach((method) -> method.invoke(connectionEvent)))); eventListeners.forEach((method -> method.invoke(connectionEvent))); - if (connectionEvent instanceof CancelableEvent) { - return ((CancelableEvent) connectionEvent).isCancelled(); + if (connectionEvent instanceof CancelableEvent cancelableEvent) { + return cancelableEvent.isCancelled(); } return false; } diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/socket/SocketNetwork.java b/src/main/java/de/bixilon/minosoft/protocol/network/socket/SocketNetwork.java index 26b2c90f5..61ce17ae4 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/network/socket/SocketNetwork.java +++ b/src/main/java/de/bixilon/minosoft/protocol/network/socket/SocketNetwork.java @@ -125,10 +125,9 @@ public class SocketNetwork implements Network { outputStream.write(data); outputStream.flush(); - if (packet instanceof PacketEncryptionResponse) { + if (packet instanceof PacketEncryptionResponse packetEncryptionResponse) { // enable encryption - secretKey = ((PacketEncryptionResponse) packet).getSecretKey(); - enableEncryption(secretKey); + enableEncryption(packetEncryptionResponse.getSecretKey()); // wake up other thread socketRThread.interrupt(); } @@ -216,8 +215,8 @@ public class SocketNetwork implements Network { //set special settings to avoid miss timing issues if (packetInstance instanceof PacketLoginSuccess) { connection.setConnectionState(ConnectionStates.PLAY); - } else if (packetInstance instanceof PacketCompressionInterface) { - compressionThreshold = ((PacketCompressionInterface) packetInstance).getThreshold(); + } else if (packetInstance instanceof PacketCompressionInterface compressionPacket) { + compressionThreshold = compressionPacket.getThreshold(); } else if (packetInstance instanceof PacketEncryptionRequest) { // wait until response is ready connection.handle(packetInstance); diff --git a/src/main/java/de/bixilon/minosoft/render/WorldRenderer.java b/src/main/java/de/bixilon/minosoft/render/WorldRenderer.java index 46ebd3c4b..8d3d29ce5 100644 --- a/src/main/java/de/bixilon/minosoft/render/WorldRenderer.java +++ b/src/main/java/de/bixilon/minosoft/render/WorldRenderer.java @@ -55,8 +55,8 @@ public class WorldRenderer { queuedMapData.add(() -> prepareChunk(location, chunk)); } - public void queueChunkNibble(ChunkLocation location, byte sectionHeight, ChunkNibble nibble) { - queuedMapData.add(() -> prepareChunkNibble(location, sectionHeight, nibble)); + public void queueChunkNibble(ChunkLocation location, byte sectionHeight, ChunkSection section) { + queuedMapData.add(() -> prepareChunkNibble(location, sectionHeight, section)); } public void queueBlock(BlockPosition position, Block block) { @@ -69,20 +69,20 @@ public class WorldRenderer { private void prepareChunk(ChunkLocation location, Chunk chunk) { // clear or create current chunk ConcurrentHashMap chunkFaces = new ConcurrentHashMap<>(); - chunk.getNibbles().forEach(((height, chunkNibble) -> chunkFaces.put(height, getFacesForChunkNibble(location, height, chunkNibble)))); + chunk.getSections().forEach(((height, chunkNibble) -> chunkFaces.put(height, getFacesForChunkNibble(location, height, chunkNibble)))); faces.put(location, chunkFaces); } - private void prepareChunkNibble(ChunkLocation chunkLocation, byte sectionHeight, ChunkNibble nibble) { - faces.get(chunkLocation).put(sectionHeight, getFacesForChunkNibble(chunkLocation, sectionHeight, nibble)); + private void prepareChunkNibble(ChunkLocation chunkLocation, byte sectionHeight, ChunkSection section) { + faces.get(chunkLocation).put(sectionHeight, getFacesForChunkNibble(chunkLocation, sectionHeight, section)); } - private ArrayFloatList getFacesForChunkNibble(ChunkLocation chunkLocation, byte sectionHeight, ChunkNibble nibble) { + private ArrayFloatList getFacesForChunkNibble(ChunkLocation chunkLocation, byte sectionHeight, ChunkSection section) { ConcurrentHashMap world = connection.getPlayer().getWorld().getAllChunks(); // clear or create current chunk nibble ArrayFloatList nibbleMap = new ArrayFloatList(); //faces.get(chunkLocation).put(sectionHeight, nibbleMap); - ConcurrentHashMap nibbleBlocks = nibble.getBlocks(); + ConcurrentHashMap nibbleBlocks = section.getBlocks(); nibbleBlocks.forEach((location, block) -> { HashSet facesToDraw = new HashSet<>(); @@ -97,12 +97,12 @@ public class WorldRenderer { } // check if block over us is a full block byte bottomSection = (byte) (sectionHeight - 1); - if (!world.get(chunkLocation).getNibbles().containsKey(bottomSection)) { + if (!world.get(chunkLocation).getSections().containsKey(bottomSection)) { yield null; } - yield world.get(chunkLocation).getNibbles().get(bottomSection).getBlock(location.getX(), RenderConstants.SECTIONS_MAX_Y, location.getZ()); + yield world.get(chunkLocation).getSections().get(bottomSection).getBlock(location.getX(), RenderConstants.SECTIONS_MAX_Y, location.getZ()); } - yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY() - 1, location.getZ())); + yield nibbleBlocks.get(new InChunkSectionLocation(location.getX(), location.getY() - 1, location.getZ())); } case UP -> { if (location.getY() == RenderConstants.SECTIONS_MAX_Y) { @@ -113,48 +113,48 @@ public class WorldRenderer { } // check if block over us is a full block byte upperSection = (byte) (sectionHeight + 1); - if (!world.get(chunkLocation).getNibbles().containsKey(upperSection)) { + if (!world.get(chunkLocation).getSections().containsKey(upperSection)) { yield null; } - yield world.get(chunkLocation).getNibbles().get(upperSection).getBlock(location.getX(), RenderConstants.SECTIONS_MIN_Y, location.getZ()); + yield world.get(chunkLocation).getSections().get(upperSection).getBlock(location.getX(), RenderConstants.SECTIONS_MIN_Y, location.getZ()); } - yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY() + 1, location.getZ())); + yield nibbleBlocks.get(new InChunkSectionLocation(location.getX(), location.getY() + 1, location.getZ())); } case WEST -> { if (location.getX() == RenderConstants.SECTIONS_MIN_X) { - ChunkNibble otherChunkNibble = getChunkNibbleOfWorld(world, new ChunkLocation(chunkLocation.getX() - 1, chunkLocation.getZ()), sectionHeight); + ChunkSection otherChunkNibble = getChunkSectionOfWorld(world, new ChunkLocation(chunkLocation.getX() - 1, chunkLocation.getZ()), sectionHeight); if (otherChunkNibble != null) { yield otherChunkNibble.getBlock(RenderConstants.SECTIONS_MAX_X, location.getY(), location.getZ()); } } - yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX() - 1, location.getY(), location.getZ())); + yield nibbleBlocks.get(new InChunkSectionLocation(location.getX() - 1, location.getY(), location.getZ())); } case EAST -> { if (location.getX() == RenderConstants.SECTIONS_MIN_X) { - ChunkNibble otherChunkNibble = getChunkNibbleOfWorld(world, new ChunkLocation(chunkLocation.getX() + 1, chunkLocation.getZ()), sectionHeight); + ChunkSection otherChunkNibble = getChunkSectionOfWorld(world, new ChunkLocation(chunkLocation.getX() + 1, chunkLocation.getZ()), sectionHeight); if (otherChunkNibble != null) { yield otherChunkNibble.getBlock(RenderConstants.SECTIONS_MAX_X, location.getY(), location.getZ()); } } - yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX() + 1, location.getY(), location.getZ())); + yield nibbleBlocks.get(new InChunkSectionLocation(location.getX() + 1, location.getY(), location.getZ())); } case NORTH -> { if (location.getZ() == RenderConstants.SECTIONS_MIN_Z) { - ChunkNibble otherChunkNibble = getChunkNibbleOfWorld(world, new ChunkLocation(chunkLocation.getX(), chunkLocation.getZ() - 1), sectionHeight); + ChunkSection otherChunkNibble = getChunkSectionOfWorld(world, new ChunkLocation(chunkLocation.getX(), chunkLocation.getZ() - 1), sectionHeight); if (otherChunkNibble != null) { yield otherChunkNibble.getBlock(location.getX(), location.getY(), RenderConstants.SECTIONS_MAX_Z); } } - yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY(), location.getZ() - 1)); + yield nibbleBlocks.get(new InChunkSectionLocation(location.getX(), location.getY(), location.getZ() - 1)); } case SOUTH -> { if (location.getZ() == RenderConstants.SECTIONS_MAX_Z) { - ChunkNibble otherChunkNibble = getChunkNibbleOfWorld(world, new ChunkLocation(chunkLocation.getX(), chunkLocation.getZ() + 1), sectionHeight); + ChunkSection otherChunkNibble = getChunkSectionOfWorld(world, new ChunkLocation(chunkLocation.getX(), chunkLocation.getZ() + 1), sectionHeight); if (otherChunkNibble != null) { yield otherChunkNibble.getBlock(location.getX(), location.getY(), RenderConstants.SECTIONS_MIN_Z); } } - yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY(), location.getZ() + 1)); + yield nibbleBlocks.get(new InChunkSectionLocation(location.getX(), location.getY(), location.getZ() + 1)); } }; if (dependedBlock == null || !BlockModelLoader.getInstance().isFull(dependedBlock, FaceOrientation.inverse(orientation))) { @@ -185,9 +185,9 @@ public class WorldRenderer { glEnd(); } - private ChunkNibble getChunkNibbleOfWorld(ConcurrentHashMap world, ChunkLocation location, byte sectionHeight) { - if (world.containsKey(location) && world.get(location).getNibbles().containsKey(sectionHeight)) { - return world.get(location).getNibbles().get(sectionHeight); + private ChunkSection getChunkSectionOfWorld(ConcurrentHashMap world, ChunkLocation location, byte sectionHeight) { + if (world.containsKey(location) && world.get(location).getSections().containsKey(sectionHeight)) { + return world.get(location).getSections().get(sectionHeight); } return null; } diff --git a/src/main/java/de/bixilon/minosoft/render/texture/TextureLoader.java b/src/main/java/de/bixilon/minosoft/render/texture/TextureLoader.java index eb1d8395b..c92dfb3af 100644 --- a/src/main/java/de/bixilon/minosoft/render/texture/TextureLoader.java +++ b/src/main/java/de/bixilon/minosoft/render/texture/TextureLoader.java @@ -48,7 +48,7 @@ public class TextureLoader { } combineTextures(); try { - PNGDecoder decoder = new PNGDecoder(new FileInputStream(StaticConfiguration.homeDir + "assets/allTextures.png")); + PNGDecoder decoder = new PNGDecoder(new FileInputStream(StaticConfiguration.HOME_DIR + "assets/allTextures.png")); ByteBuffer buf = ByteBuffer.allocateDirect(decoder.getWidth() * decoder.getHeight() * 4); decoder.decode(buf, decoder.getWidth() * 4, PNGDecoder.Format.RGBA); textureID = bindTexture(buf, decoder.getWidth(), decoder.getHeight()); @@ -118,7 +118,7 @@ public class TextureLoader { } try { - File outputFile = new File(StaticConfiguration.homeDir + "assets/allTextures.png"); + File outputFile = new File(StaticConfiguration.HOME_DIR + "assets/allTextures.png"); ImageIO.write(totalImage, "png", outputFile); } catch (IOException e) { e.printStackTrace(); diff --git a/src/main/java/de/bixilon/minosoft/util/ChunkUtil.java b/src/main/java/de/bixilon/minosoft/util/ChunkUtil.java index 1ae34c93b..05511787a 100644 --- a/src/main/java/de/bixilon/minosoft/util/ChunkUtil.java +++ b/src/main/java/de/bixilon/minosoft/util/ChunkUtil.java @@ -16,8 +16,8 @@ package de.bixilon.minosoft.util; import de.bixilon.minosoft.data.mappings.blocks.Block; import de.bixilon.minosoft.data.mappings.blocks.Blocks; import de.bixilon.minosoft.data.world.Chunk; -import de.bixilon.minosoft.data.world.ChunkNibble; -import de.bixilon.minosoft.data.world.ChunkNibbleLocation; +import de.bixilon.minosoft.data.world.ChunkSection; +import de.bixilon.minosoft.data.world.InChunkSectionLocation; import de.bixilon.minosoft.data.world.palette.Palette; import de.bixilon.minosoft.logging.Log; import de.bixilon.minosoft.protocol.protocol.InByteBuffer; @@ -52,11 +52,11 @@ public final class ChunkUtil { //parse data int arrayPos = 0; - ConcurrentHashMap nibbleMap = new ConcurrentHashMap<>(); + ConcurrentHashMap sectionMap = new ConcurrentHashMap<>(); for (byte c = 0; c < RenderConstants.SECTIONS_PER_CHUNK; c++) { // max sections per chunks in chunk column if (BitByte.isBitSet(sectionBitMask, c)) { - ConcurrentHashMap blockMap = new ConcurrentHashMap<>(); + ConcurrentHashMap blockMap = new ConcurrentHashMap<>(); for (int nibbleY = 0; nibbleY < RenderConstants.SECTION_HEIGHT; nibbleY++) { for (int nibbleZ = 0; nibbleZ < RenderConstants.SECTION_WIDTH; nibbleZ++) { @@ -84,15 +84,15 @@ public final class ChunkUtil { arrayPos++; continue; } - blockMap.put(new ChunkNibbleLocation(nibbleX, nibbleY, nibbleZ), block); + blockMap.put(new InChunkSectionLocation(nibbleX, nibbleY, nibbleZ), block); arrayPos++; } } } - nibbleMap.put(c, new ChunkNibble(blockMap)); + sectionMap.put(c, new ChunkSection(blockMap)); } } - return new Chunk(nibbleMap); + return new Chunk(sectionMap); } if (buffer.getVersionId() < 62) { // ToDo: was this really changed in 62? if (sectionBitMask == 0x00 && groundUpContinuous) { @@ -116,12 +116,12 @@ public final class ChunkUtil { } int arrayPos = 0; - ConcurrentHashMap nibbleMap = new ConcurrentHashMap<>(); + ConcurrentHashMap sectionMap = new ConcurrentHashMap<>(); for (byte c = 0; c < RenderConstants.SECTIONS_PER_CHUNK; c++) { // max sections per chunks in chunk column if (!BitByte.isBitSet(sectionBitMask, c)) { continue; } - ConcurrentHashMap blockMap = new ConcurrentHashMap<>(); + ConcurrentHashMap blockMap = new ConcurrentHashMap<>(); for (int nibbleY = 0; nibbleY < RenderConstants.SECTION_HEIGHT; nibbleY++) { for (int nibbleZ = 0; nibbleZ < RenderConstants.SECTION_WIDTH; nibbleZ++) { @@ -132,17 +132,17 @@ public final class ChunkUtil { arrayPos++; continue; } - blockMap.put(new ChunkNibbleLocation(nibbleX, nibbleY, nibbleZ), block); + blockMap.put(new InChunkSectionLocation(nibbleX, nibbleY, nibbleZ), block); arrayPos++; } } } - nibbleMap.put(c, new ChunkNibble(blockMap)); + sectionMap.put(c, new ChunkSection(blockMap)); } - return new Chunk(nibbleMap); + return new Chunk(sectionMap); } // really big thanks to: https://wiki.vg/index.php?title=Chunk_Format&oldid=13712 - ConcurrentHashMap nibbleMap = new ConcurrentHashMap<>(); + ConcurrentHashMap sectionMap = new ConcurrentHashMap<>(); for (byte c = 0; c < RenderConstants.SECTIONS_PER_CHUNK; c++) { // max sections per chunks in chunk column if (!BitByte.isBitSet(sectionBitMask, c)) { continue; @@ -156,7 +156,7 @@ public final class ChunkUtil { long[] data = buffer.readLongArray(buffer.readVarInt()); - ConcurrentHashMap blockMap = new ConcurrentHashMap<>(); + ConcurrentHashMap blockMap = new ConcurrentHashMap<>(); for (int nibbleY = 0; nibbleY < RenderConstants.SECTION_HEIGHT; nibbleY++) { for (int nibbleZ = 0; nibbleZ < RenderConstants.SECTION_WIDTH; nibbleZ++) { for (int nibbleX = 0; nibbleX < RenderConstants.SECTION_WIDTH; nibbleX++) { @@ -188,7 +188,7 @@ public final class ChunkUtil { if (block.equals(Blocks.nullBlock)) { continue; } - blockMap.put(new ChunkNibbleLocation(nibbleX, nibbleY, nibbleZ), block); + blockMap.put(new InChunkSectionLocation(nibbleX, nibbleY, nibbleZ), block); } } } @@ -200,12 +200,12 @@ public final class ChunkUtil { } } - nibbleMap.put(c, new ChunkNibble(blockMap)); + sectionMap.put(c, new ChunkSection(blockMap)); } if (buffer.getVersionId() < 552) { byte[] biomes = buffer.readBytes(RenderConstants.SECTION_WIDTH * RenderConstants.SECTION_WIDTH); } - return new Chunk(nibbleMap); + return new Chunk(sectionMap); } public static void readSkyLightPacket(InByteBuffer buffer, int skyLightMask, int blockLightMask, int emptyBlockLightMask, int emptySkyLightMask) { diff --git a/src/main/java/de/bixilon/minosoft/util/Util.java b/src/main/java/de/bixilon/minosoft/util/Util.java index 2e33a3c1c..82512c82d 100644 --- a/src/main/java/de/bixilon/minosoft/util/Util.java +++ b/src/main/java/de/bixilon/minosoft/util/Util.java @@ -26,10 +26,9 @@ import java.net.URL; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.util.Collection; import java.util.HashMap; import java.util.UUID; -import java.util.concurrent.*; +import java.util.concurrent.ThreadFactory; import java.util.regex.Pattern; import java.util.zip.*; @@ -246,17 +245,6 @@ public final class Util { return new BufferedInputStream(new URL(url).openStream()); } - public static void executeInThreadPool(String name, Collection> callables) throws InterruptedException { - ExecutorService phaseLoader = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), getThreadFactory(name)); - phaseLoader.invokeAll(callables).forEach((tFuture -> { - try { - tFuture.get(); - } catch (ExecutionException | InterruptedException ex) { - ex.getCause().printStackTrace(); - } - })); - } - public static ThreadFactory getThreadFactory(String threadName) { return new ThreadFactoryBuilder().setNameFormat(threadName + "#%d").build(); } diff --git a/src/main/java/de/bixilon/minosoft/util/nbt/tag/CompoundTag.java b/src/main/java/de/bixilon/minosoft/util/nbt/tag/CompoundTag.java index 800d2972d..8a723ffaf 100644 --- a/src/main/java/de/bixilon/minosoft/util/nbt/tag/CompoundTag.java +++ b/src/main/java/de/bixilon/minosoft/util/nbt/tag/CompoundTag.java @@ -80,9 +80,8 @@ public class CompoundTag extends NBTTag { buffer.writeStringNoLength(set.getKey()); // write data - if (set.getValue() instanceof CompoundTag) { + if (set.getValue() instanceof CompoundTag compoundTag) { // that's a subtag! special rule - CompoundTag compoundTag = (CompoundTag) set.getValue(); compoundTag.writeBytesSubTag(buffer); continue; }