mirror of
https://hub.spigotmc.org/stash/scm/spigot/spigot.git
synced 2025-09-18 21:33:01 +00:00
4172 lines
153 KiB
Diff
4172 lines
153 KiB
Diff
From 51c4ef65bc238c7e406e4984629476198dc83e2f Mon Sep 17 00:00:00 2001
|
|
From: md_5 <md_5@live.com.au>
|
|
Date: Sun, 1 Dec 2013 15:10:48 +1100
|
|
Subject: [PATCH] mc-dev imports
|
|
|
|
Imported files which are only modified by Spigot, not upstream. Files here should be completely unmodified aside from trivial changes such as adding throws statements to ensure proper compilation. You may need to add unrelated files in order to ensure a compilable result in the face of synthetic methods.
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/AdvancementDataWorld.java b/src/main/java/net/minecraft/server/AdvancementDataWorld.java
|
|
new file mode 100644
|
|
index 000000000..e2f8a0e01
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/AdvancementDataWorld.java
|
|
@@ -0,0 +1,69 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.google.common.collect.Maps;
|
|
+import com.google.gson.Gson;
|
|
+import com.google.gson.GsonBuilder;
|
|
+import com.google.gson.JsonDeserializationContext;
|
|
+import com.google.gson.JsonElement;
|
|
+import com.google.gson.JsonObject;
|
|
+import com.google.gson.JsonParseException;
|
|
+import java.lang.reflect.Type;
|
|
+import java.util.Collection;
|
|
+import java.util.Iterator;
|
|
+import java.util.Map;
|
|
+import javax.annotation.Nullable;
|
|
+import org.apache.logging.log4j.LogManager;
|
|
+import org.apache.logging.log4j.Logger;
|
|
+
|
|
+public class AdvancementDataWorld extends ResourceDataJson {
|
|
+
|
|
+ private static final Logger LOGGER = LogManager.getLogger();
|
|
+ public static final Gson DESERIALIZER = (new GsonBuilder()).registerTypeHierarchyAdapter(Advancement.SerializedAdvancement.class, (com.google.gson.JsonDeserializer) (jsonelement, type, jsondeserializationcontext) -> {
|
|
+ JsonObject jsonobject = ChatDeserializer.m(jsonelement, "advancement");
|
|
+
|
|
+ return Advancement.SerializedAdvancement.a(jsonobject, jsondeserializationcontext);
|
|
+ }).registerTypeAdapter(AdvancementRewards.class, new AdvancementRewards.b()).registerTypeHierarchyAdapter(IChatBaseComponent.class, new IChatBaseComponent.ChatSerializer()).registerTypeHierarchyAdapter(ChatModifier.class, new ChatModifier.ChatModifierSerializer()).registerTypeAdapterFactory(new ChatTypeAdapterFactory()).create();
|
|
+ public Advancements REGISTRY = new Advancements();
|
|
+
|
|
+ public AdvancementDataWorld() {
|
|
+ super(AdvancementDataWorld.DESERIALIZER, "advancements");
|
|
+ }
|
|
+
|
|
+ protected void a(Map<MinecraftKey, JsonObject> map, IResourceManager iresourcemanager, GameProfilerFiller gameprofilerfiller) {
|
|
+ Map<MinecraftKey, Advancement.SerializedAdvancement> map1 = Maps.newHashMap();
|
|
+
|
|
+ map.forEach((minecraftkey, jsonobject) -> {
|
|
+ try {
|
|
+ Advancement.SerializedAdvancement advancement_serializedadvancement = (Advancement.SerializedAdvancement) AdvancementDataWorld.DESERIALIZER.fromJson(jsonobject, Advancement.SerializedAdvancement.class);
|
|
+
|
|
+ map1.put(minecraftkey, advancement_serializedadvancement);
|
|
+ } catch (IllegalArgumentException | JsonParseException jsonparseexception) {
|
|
+ AdvancementDataWorld.LOGGER.error("Parsing error loading custom advancement {}: {}", minecraftkey, jsonparseexception.getMessage());
|
|
+ }
|
|
+
|
|
+ });
|
|
+ Advancements advancements = new Advancements();
|
|
+
|
|
+ advancements.a((Map) map1);
|
|
+ Iterator iterator = advancements.b().iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ Advancement advancement = (Advancement) iterator.next();
|
|
+
|
|
+ if (advancement.c() != null) {
|
|
+ AdvancementTree.a(advancement);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ this.REGISTRY = advancements;
|
|
+ }
|
|
+
|
|
+ @Nullable
|
|
+ public Advancement a(MinecraftKey minecraftkey) {
|
|
+ return this.REGISTRY.a(minecraftkey);
|
|
+ }
|
|
+
|
|
+ public Collection<Advancement> a() {
|
|
+ return this.REGISTRY.c();
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/ChunkGenerator.java b/src/main/java/net/minecraft/server/ChunkGenerator.java
|
|
new file mode 100644
|
|
index 000000000..b54d5d2b9
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/ChunkGenerator.java
|
|
@@ -0,0 +1,206 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.util.BitSet;
|
|
+import java.util.Iterator;
|
|
+import java.util.List;
|
|
+import java.util.ListIterator;
|
|
+import java.util.Locale;
|
|
+import java.util.Map.Entry;
|
|
+import javax.annotation.Nullable;
|
|
+
|
|
+public abstract class ChunkGenerator<C extends GeneratorSettingsDefault> {
|
|
+
|
|
+ protected final GeneratorAccess a;
|
|
+ protected final long seed;
|
|
+ protected final WorldChunkManager c;
|
|
+ protected final C settings;
|
|
+
|
|
+ public ChunkGenerator(GeneratorAccess generatoraccess, WorldChunkManager worldchunkmanager, C c0) {
|
|
+ this.a = generatoraccess;
|
|
+ this.seed = generatoraccess.getSeed();
|
|
+ this.c = worldchunkmanager;
|
|
+ this.settings = c0;
|
|
+ }
|
|
+
|
|
+ public void createBiomes(IChunkAccess ichunkaccess) {
|
|
+ ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos();
|
|
+ int i = chunkcoordintpair.x;
|
|
+ int j = chunkcoordintpair.z;
|
|
+ BiomeBase[] abiomebase = this.c.getBiomeBlock(i * 16, j * 16, 16, 16);
|
|
+
|
|
+ ichunkaccess.a(abiomebase);
|
|
+ }
|
|
+
|
|
+ protected BiomeBase getCarvingBiome(IChunkAccess ichunkaccess) {
|
|
+ return ichunkaccess.getBiome(BlockPosition.ZERO);
|
|
+ }
|
|
+
|
|
+ protected BiomeBase getDecoratingBiome(RegionLimitedWorldAccess regionlimitedworldaccess, BlockPosition blockposition) {
|
|
+ return this.c.getBiome(blockposition);
|
|
+ }
|
|
+
|
|
+ public void doCarving(IChunkAccess ichunkaccess, WorldGenStage.Features worldgenstage_features) {
|
|
+ SeededRandom seededrandom = new SeededRandom();
|
|
+ boolean flag = true;
|
|
+ ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos();
|
|
+ int i = chunkcoordintpair.x;
|
|
+ int j = chunkcoordintpair.z;
|
|
+ BitSet bitset = ichunkaccess.a(worldgenstage_features);
|
|
+
|
|
+ for (int k = i - 8; k <= i + 8; ++k) {
|
|
+ for (int l = j - 8; l <= j + 8; ++l) {
|
|
+ List<WorldGenCarverWrapper<?>> list = this.getCarvingBiome(ichunkaccess).a(worldgenstage_features);
|
|
+ ListIterator listiterator = list.listIterator();
|
|
+
|
|
+ while (listiterator.hasNext()) {
|
|
+ int i1 = listiterator.nextIndex();
|
|
+ WorldGenCarverWrapper<?> worldgencarverwrapper = (WorldGenCarverWrapper) listiterator.next();
|
|
+
|
|
+ seededrandom.c(this.seed + (long) i1, k, l);
|
|
+ if (worldgencarverwrapper.a(seededrandom, k, l)) {
|
|
+ worldgencarverwrapper.a(ichunkaccess, seededrandom, this.getSeaLevel(), k, l, i, j, bitset);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ @Nullable
|
|
+ public BlockPosition findNearestMapFeature(World world, String s, BlockPosition blockposition, int i, boolean flag) {
|
|
+ StructureGenerator<?> structuregenerator = (StructureGenerator) WorldGenerator.aP.get(s.toLowerCase(Locale.ROOT));
|
|
+
|
|
+ return structuregenerator != null ? structuregenerator.getNearestGeneratedFeature(world, this, blockposition, i, flag) : null;
|
|
+ }
|
|
+
|
|
+ public void addDecorations(RegionLimitedWorldAccess regionlimitedworldaccess) {
|
|
+ int i = regionlimitedworldaccess.a();
|
|
+ int j = regionlimitedworldaccess.b();
|
|
+ int k = i * 16;
|
|
+ int l = j * 16;
|
|
+ BlockPosition blockposition = new BlockPosition(k, 0, l);
|
|
+ BiomeBase biomebase = this.getDecoratingBiome(regionlimitedworldaccess, blockposition.b(8, 8, 8));
|
|
+ SeededRandom seededrandom = new SeededRandom();
|
|
+ long i1 = seededrandom.a(regionlimitedworldaccess.getSeed(), k, l);
|
|
+ WorldGenStage.Decoration[] aworldgenstage_decoration = WorldGenStage.Decoration.values();
|
|
+ int j1 = aworldgenstage_decoration.length;
|
|
+
|
|
+ for (int k1 = 0; k1 < j1; ++k1) {
|
|
+ WorldGenStage.Decoration worldgenstage_decoration = aworldgenstage_decoration[k1];
|
|
+
|
|
+ try {
|
|
+ biomebase.a(worldgenstage_decoration, this, regionlimitedworldaccess, i1, seededrandom, blockposition);
|
|
+ } catch (Exception exception) {
|
|
+ CrashReport crashreport = CrashReport.a(exception, "Biome decoration");
|
|
+
|
|
+ crashreport.a("Generation").a("CenterX", (Object) i).a("CenterZ", (Object) j).a("Step", (Object) worldgenstage_decoration).a("Seed", (Object) i1).a("Biome", (Object) IRegistry.BIOME.getKey(biomebase));
|
|
+ throw new ReportedException(crashreport);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ public abstract void buildBase(IChunkAccess ichunkaccess);
|
|
+
|
|
+ public void addMobs(RegionLimitedWorldAccess regionlimitedworldaccess) {}
|
|
+
|
|
+ public C getSettings() {
|
|
+ return this.settings;
|
|
+ }
|
|
+
|
|
+ public abstract int getSpawnHeight();
|
|
+
|
|
+ public void doMobSpawning(WorldServer worldserver, boolean flag, boolean flag1) {}
|
|
+
|
|
+ public boolean canSpawnStructure(BiomeBase biomebase, StructureGenerator<? extends WorldGenFeatureConfiguration> structuregenerator) {
|
|
+ return biomebase.a(structuregenerator);
|
|
+ }
|
|
+
|
|
+ @Nullable
|
|
+ public <C extends WorldGenFeatureConfiguration> C getFeatureConfiguration(BiomeBase biomebase, StructureGenerator<C> structuregenerator) {
|
|
+ return biomebase.b(structuregenerator);
|
|
+ }
|
|
+
|
|
+ public WorldChunkManager getWorldChunkManager() {
|
|
+ return this.c;
|
|
+ }
|
|
+
|
|
+ public long getSeed() {
|
|
+ return this.seed;
|
|
+ }
|
|
+
|
|
+ public int getGenerationDepth() {
|
|
+ return 256;
|
|
+ }
|
|
+
|
|
+ public List<BiomeBase.BiomeMeta> getMobsFor(EnumCreatureType enumcreaturetype, BlockPosition blockposition) {
|
|
+ return this.a.getBiome(blockposition).getMobs(enumcreaturetype);
|
|
+ }
|
|
+
|
|
+ public void createStructures(IChunkAccess ichunkaccess, ChunkGenerator<?> chunkgenerator, DefinedStructureManager definedstructuremanager) {
|
|
+ Iterator iterator = WorldGenerator.aP.values().iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ StructureGenerator<?> structuregenerator = (StructureGenerator) iterator.next();
|
|
+
|
|
+ if (chunkgenerator.getWorldChunkManager().a(structuregenerator)) {
|
|
+ SeededRandom seededrandom = new SeededRandom();
|
|
+ ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos();
|
|
+ StructureStart structurestart = StructureStart.a;
|
|
+
|
|
+ if (structuregenerator.a(chunkgenerator, seededrandom, chunkcoordintpair.x, chunkcoordintpair.z)) {
|
|
+ BiomeBase biomebase = this.getWorldChunkManager().getBiome(new BlockPosition(chunkcoordintpair.d() + 9, 0, chunkcoordintpair.e() + 9));
|
|
+ StructureStart structurestart1 = structuregenerator.a().create(structuregenerator, chunkcoordintpair.x, chunkcoordintpair.z, biomebase, StructureBoundingBox.a(), 0, chunkgenerator.getSeed());
|
|
+
|
|
+ structurestart1.a(this, definedstructuremanager, chunkcoordintpair.x, chunkcoordintpair.z, biomebase);
|
|
+ structurestart = structurestart1.e() ? structurestart1 : StructureStart.a;
|
|
+ }
|
|
+
|
|
+ ichunkaccess.a(structuregenerator.b(), structurestart);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ public void storeStructures(GeneratorAccess generatoraccess, IChunkAccess ichunkaccess) {
|
|
+ boolean flag = true;
|
|
+ int i = ichunkaccess.getPos().x;
|
|
+ int j = ichunkaccess.getPos().z;
|
|
+ int k = i << 4;
|
|
+ int l = j << 4;
|
|
+
|
|
+ for (int i1 = i - 8; i1 <= i + 8; ++i1) {
|
|
+ for (int j1 = j - 8; j1 <= j + 8; ++j1) {
|
|
+ long k1 = ChunkCoordIntPair.pair(i1, j1);
|
|
+ Iterator iterator = generatoraccess.getChunkAt(i1, j1).h().entrySet().iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ Entry<String, StructureStart> entry = (Entry) iterator.next();
|
|
+ StructureStart structurestart = (StructureStart) entry.getValue();
|
|
+
|
|
+ if (structurestart != StructureStart.a && structurestart.c().a(k, l, k + 15, l + 15)) {
|
|
+ ichunkaccess.a((String) entry.getKey(), k1);
|
|
+ PacketDebug.a(generatoraccess, structurestart);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ public abstract void buildNoise(GeneratorAccess generatoraccess, IChunkAccess ichunkaccess);
|
|
+
|
|
+ public int getSeaLevel() {
|
|
+ return 63;
|
|
+ }
|
|
+
|
|
+ public abstract int getBaseHeight(int i, int j, HeightMap.Type heightmap_type);
|
|
+
|
|
+ public int b(int i, int j, HeightMap.Type heightmap_type) {
|
|
+ return this.getBaseHeight(i, j, heightmap_type);
|
|
+ }
|
|
+
|
|
+ public int c(int i, int j, HeightMap.Type heightmap_type) {
|
|
+ return this.getBaseHeight(i, j, heightmap_type) - 1;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java
|
|
new file mode 100644
|
|
index 000000000..096866b2b
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java
|
|
@@ -0,0 +1,428 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import it.unimi.dsi.fastutil.longs.LongIterator;
|
|
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
|
+import it.unimi.dsi.fastutil.objects.ObjectList;
|
|
+import it.unimi.dsi.fastutil.objects.ObjectListIterator;
|
|
+import java.util.Iterator;
|
|
+import java.util.Random;
|
|
+
|
|
+public abstract class ChunkGeneratorAbstract<T extends GeneratorSettingsDefault> extends ChunkGenerator<T> {
|
|
+
|
|
+ private static final float[] h = (float[]) SystemUtils.a((new float[13824]), (afloat) -> {
|
|
+ for (int i = 0; i < 24; ++i) {
|
|
+ for (int j = 0; j < 24; ++j) {
|
|
+ for (int k = 0; k < 24; ++k) {
|
|
+ afloat[i * 24 * 24 + j * 24 + k] = (float) b(j - 12, k - 12, i - 12);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ });
|
|
+ private static final IBlockData i = Blocks.AIR.getBlockData();
|
|
+ private final int j;
|
|
+ private final int k;
|
|
+ private final int l;
|
|
+ private final int m;
|
|
+ private final int n;
|
|
+ protected final SeededRandom e;
|
|
+ private final NoiseGeneratorOctaves o;
|
|
+ private final NoiseGeneratorOctaves p;
|
|
+ private final NoiseGeneratorOctaves q;
|
|
+ private final NoiseGenerator r;
|
|
+ protected final IBlockData f;
|
|
+ protected final IBlockData g;
|
|
+
|
|
+ public ChunkGeneratorAbstract(GeneratorAccess generatoraccess, WorldChunkManager worldchunkmanager, int i, int j, int k, T t0, boolean flag) {
|
|
+ super(generatoraccess, worldchunkmanager, t0);
|
|
+ this.j = j;
|
|
+ this.k = i;
|
|
+ this.f = t0.r();
|
|
+ this.g = t0.s();
|
|
+ this.l = 16 / this.k;
|
|
+ this.m = k / this.j;
|
|
+ this.n = 16 / this.k;
|
|
+ this.e = new SeededRandom(this.seed);
|
|
+ this.o = new NoiseGeneratorOctaves(this.e, 16);
|
|
+ this.p = new NoiseGeneratorOctaves(this.e, 16);
|
|
+ this.q = new NoiseGeneratorOctaves(this.e, 8);
|
|
+ this.r = (NoiseGenerator) (flag ? new NoiseGenerator3(this.e, 4) : new NoiseGeneratorOctaves(this.e, 4));
|
|
+ }
|
|
+
|
|
+ private double a(int i, int j, int k, double d0, double d1, double d2, double d3) {
|
|
+ double d4 = 0.0D;
|
|
+ double d5 = 0.0D;
|
|
+ double d6 = 0.0D;
|
|
+ double d7 = 1.0D;
|
|
+
|
|
+ for (int l = 0; l < 16; ++l) {
|
|
+ double d8 = NoiseGeneratorOctaves.a((double) i * d0 * d7);
|
|
+ double d9 = NoiseGeneratorOctaves.a((double) j * d1 * d7);
|
|
+ double d10 = NoiseGeneratorOctaves.a((double) k * d0 * d7);
|
|
+ double d11 = d1 * d7;
|
|
+
|
|
+ d4 += this.o.a(l).a(d8, d9, d10, d11, (double) j * d11) / d7;
|
|
+ d5 += this.p.a(l).a(d8, d9, d10, d11, (double) j * d11) / d7;
|
|
+ if (l < 8) {
|
|
+ d6 += this.q.a(l).a(NoiseGeneratorOctaves.a((double) i * d2 * d7), NoiseGeneratorOctaves.a((double) j * d3 * d7), NoiseGeneratorOctaves.a((double) k * d2 * d7), d3 * d7, (double) j * d3 * d7) / d7;
|
|
+ }
|
|
+
|
|
+ d7 /= 2.0D;
|
|
+ }
|
|
+
|
|
+ return MathHelper.b(d4 / 512.0D, d5 / 512.0D, (d6 / 10.0D + 1.0D) / 2.0D);
|
|
+ }
|
|
+
|
|
+ protected double[] b(int i, int j) {
|
|
+ double[] adouble = new double[this.m + 1];
|
|
+
|
|
+ this.a(adouble, i, j);
|
|
+ return adouble;
|
|
+ }
|
|
+
|
|
+ protected void a(double[] adouble, int i, int j, double d0, double d1, double d2, double d3, int k, int l) {
|
|
+ double[] adouble1 = this.a(i, j);
|
|
+ double d4 = adouble1[0];
|
|
+ double d5 = adouble1[1];
|
|
+ double d6 = this.g();
|
|
+ double d7 = this.h();
|
|
+
|
|
+ for (int i1 = 0; i1 < this.i(); ++i1) {
|
|
+ double d8 = this.a(i, i1, j, d0, d1, d2, d3);
|
|
+
|
|
+ d8 -= this.a(d4, d5, i1);
|
|
+ if ((double) i1 > d6) {
|
|
+ d8 = MathHelper.b(d8, (double) l, ((double) i1 - d6) / (double) k);
|
|
+ } else if ((double) i1 < d7) {
|
|
+ d8 = MathHelper.b(d8, -30.0D, (d7 - (double) i1) / (d7 - 1.0D));
|
|
+ }
|
|
+
|
|
+ adouble[i1] = d8;
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ protected abstract double[] a(int i, int j);
|
|
+
|
|
+ protected abstract double a(double d0, double d1, int i);
|
|
+
|
|
+ protected double g() {
|
|
+ return (double) (this.i() - 4);
|
|
+ }
|
|
+
|
|
+ protected double h() {
|
|
+ return 0.0D;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getBaseHeight(int i, int j, HeightMap.Type heightmap_type) {
|
|
+ int k = Math.floorDiv(i, this.k);
|
|
+ int l = Math.floorDiv(j, this.k);
|
|
+ int i1 = Math.floorMod(i, this.k);
|
|
+ int j1 = Math.floorMod(j, this.k);
|
|
+ double d0 = (double) i1 / (double) this.k;
|
|
+ double d1 = (double) j1 / (double) this.k;
|
|
+ double[][] adouble = new double[][]{this.b(k, l), this.b(k, l + 1), this.b(k + 1, l), this.b(k + 1, l + 1)};
|
|
+ int k1 = this.getSeaLevel();
|
|
+
|
|
+ for (int l1 = this.m - 1; l1 >= 0; --l1) {
|
|
+ double d2 = adouble[0][l1];
|
|
+ double d3 = adouble[1][l1];
|
|
+ double d4 = adouble[2][l1];
|
|
+ double d5 = adouble[3][l1];
|
|
+ double d6 = adouble[0][l1 + 1];
|
|
+ double d7 = adouble[1][l1 + 1];
|
|
+ double d8 = adouble[2][l1 + 1];
|
|
+ double d9 = adouble[3][l1 + 1];
|
|
+
|
|
+ for (int i2 = this.j - 1; i2 >= 0; --i2) {
|
|
+ double d10 = (double) i2 / (double) this.j;
|
|
+ double d11 = MathHelper.a(d10, d0, d1, d2, d6, d4, d8, d3, d7, d5, d9);
|
|
+ int j2 = l1 * this.j + i2;
|
|
+
|
|
+ if (d11 > 0.0D || j2 < k1) {
|
|
+ IBlockData iblockdata;
|
|
+
|
|
+ if (d11 > 0.0D) {
|
|
+ iblockdata = this.f;
|
|
+ } else {
|
|
+ iblockdata = this.g;
|
|
+ }
|
|
+
|
|
+ if (heightmap_type.d().test(iblockdata)) {
|
|
+ return j2 + 1;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ protected abstract void a(double[] adouble, int i, int j);
|
|
+
|
|
+ public int i() {
|
|
+ return this.m + 1;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void buildBase(IChunkAccess ichunkaccess) {
|
|
+ ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos();
|
|
+ int i = chunkcoordintpair.x;
|
|
+ int j = chunkcoordintpair.z;
|
|
+ SeededRandom seededrandom = new SeededRandom();
|
|
+
|
|
+ seededrandom.a(i, j);
|
|
+ ChunkCoordIntPair chunkcoordintpair1 = ichunkaccess.getPos();
|
|
+ int k = chunkcoordintpair1.d();
|
|
+ int l = chunkcoordintpair1.e();
|
|
+ double d0 = 0.0625D;
|
|
+ BiomeBase[] abiomebase = ichunkaccess.getBiomeIndex();
|
|
+
|
|
+ for (int i1 = 0; i1 < 16; ++i1) {
|
|
+ for (int j1 = 0; j1 < 16; ++j1) {
|
|
+ int k1 = k + i1;
|
|
+ int l1 = l + j1;
|
|
+ int i2 = ichunkaccess.a(HeightMap.Type.WORLD_SURFACE_WG, i1, j1) + 1;
|
|
+ double d1 = this.r.a((double) k1 * 0.0625D, (double) l1 * 0.0625D, 0.0625D, (double) i1 * 0.0625D);
|
|
+
|
|
+ abiomebase[j1 * 16 + i1].a(seededrandom, ichunkaccess, k1, l1, i2, d1, this.getSettings().r(), this.getSettings().s(), this.getSeaLevel(), this.a.getSeed());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ this.a(ichunkaccess, seededrandom);
|
|
+ }
|
|
+
|
|
+ protected void a(IChunkAccess ichunkaccess, Random random) {
|
|
+ BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
|
|
+ int i = ichunkaccess.getPos().d();
|
|
+ int j = ichunkaccess.getPos().e();
|
|
+ T t0 = this.getSettings();
|
|
+ int k = t0.u();
|
|
+ int l = t0.t();
|
|
+ Iterator iterator = BlockPosition.b(i, 0, j, i + 15, 0, j + 15).iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ BlockPosition blockposition = (BlockPosition) iterator.next();
|
|
+ int i1;
|
|
+
|
|
+ if (l > 0) {
|
|
+ for (i1 = l; i1 >= l - 4; --i1) {
|
|
+ if (i1 >= l - random.nextInt(5)) {
|
|
+ ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (k < 256) {
|
|
+ for (i1 = k + 4; i1 >= k; --i1) {
|
|
+ if (i1 <= k + random.nextInt(5)) {
|
|
+ ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void buildNoise(GeneratorAccess generatoraccess, IChunkAccess ichunkaccess) {
|
|
+ int i = this.getSeaLevel();
|
|
+ ObjectList<WorldGenFeaturePillagerOutpostPoolPiece> objectlist = new ObjectArrayList(10);
|
|
+ ObjectList<WorldGenFeatureDefinedStructureJigsawJunction> objectlist1 = new ObjectArrayList(32);
|
|
+ ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos();
|
|
+ int j = chunkcoordintpair.x;
|
|
+ int k = chunkcoordintpair.z;
|
|
+ int l = j << 4;
|
|
+ int i1 = k << 4;
|
|
+ Iterator iterator = WorldGenerator.aQ.iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ StructureGenerator<?> structuregenerator = (StructureGenerator) iterator.next();
|
|
+ String s = structuregenerator.b();
|
|
+ LongIterator longiterator = ichunkaccess.b(s).iterator();
|
|
+
|
|
+ while (longiterator.hasNext()) {
|
|
+ long j1 = longiterator.nextLong();
|
|
+ ChunkCoordIntPair chunkcoordintpair1 = new ChunkCoordIntPair(j1);
|
|
+ IChunkAccess ichunkaccess1 = generatoraccess.getChunkAt(chunkcoordintpair1.x, chunkcoordintpair1.z);
|
|
+ StructureStart structurestart = ichunkaccess1.a(s);
|
|
+
|
|
+ if (structurestart != null && structurestart.e()) {
|
|
+ Iterator iterator1 = structurestart.d().iterator();
|
|
+
|
|
+ while (iterator1.hasNext()) {
|
|
+ StructurePiece structurepiece = (StructurePiece) iterator1.next();
|
|
+
|
|
+ if (structurepiece.a(chunkcoordintpair, 12) && structurepiece instanceof WorldGenFeaturePillagerOutpostPoolPiece) {
|
|
+ WorldGenFeaturePillagerOutpostPoolPiece worldgenfeaturepillageroutpostpoolpiece = (WorldGenFeaturePillagerOutpostPoolPiece) structurepiece;
|
|
+ WorldGenFeatureDefinedStructurePoolTemplate.Matching worldgenfeaturedefinedstructurepooltemplate_matching = worldgenfeaturepillageroutpostpoolpiece.b().c();
|
|
+
|
|
+ if (worldgenfeaturedefinedstructurepooltemplate_matching == WorldGenFeatureDefinedStructurePoolTemplate.Matching.RIGID) {
|
|
+ objectlist.add(worldgenfeaturepillageroutpostpoolpiece);
|
|
+ }
|
|
+
|
|
+ Iterator iterator2 = worldgenfeaturepillageroutpostpoolpiece.e().iterator();
|
|
+
|
|
+ while (iterator2.hasNext()) {
|
|
+ WorldGenFeatureDefinedStructureJigsawJunction worldgenfeaturedefinedstructurejigsawjunction = (WorldGenFeatureDefinedStructureJigsawJunction) iterator2.next();
|
|
+ int k1 = worldgenfeaturedefinedstructurejigsawjunction.a();
|
|
+ int l1 = worldgenfeaturedefinedstructurejigsawjunction.c();
|
|
+
|
|
+ if (k1 > l - 12 && l1 > i1 - 12 && k1 < l + 15 + 12 && l1 < i1 + 15 + 12) {
|
|
+ objectlist1.add(worldgenfeaturedefinedstructurejigsawjunction);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ double[][][] adouble = new double[2][this.n + 1][this.m + 1];
|
|
+
|
|
+ for (int i2 = 0; i2 < this.n + 1; ++i2) {
|
|
+ adouble[0][i2] = new double[this.m + 1];
|
|
+ this.a(adouble[0][i2], j * this.l, k * this.n + i2);
|
|
+ adouble[1][i2] = new double[this.m + 1];
|
|
+ }
|
|
+
|
|
+ ProtoChunk protochunk = (ProtoChunk) ichunkaccess;
|
|
+ HeightMap heightmap = protochunk.b(HeightMap.Type.OCEAN_FLOOR_WG);
|
|
+ HeightMap heightmap1 = protochunk.b(HeightMap.Type.WORLD_SURFACE_WG);
|
|
+ BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
|
|
+ ObjectListIterator<WorldGenFeaturePillagerOutpostPoolPiece> objectlistiterator = objectlist.iterator();
|
|
+ ObjectListIterator<WorldGenFeatureDefinedStructureJigsawJunction> objectlistiterator1 = objectlist1.iterator();
|
|
+
|
|
+ for (int j2 = 0; j2 < this.l; ++j2) {
|
|
+ int k2;
|
|
+
|
|
+ for (k2 = 0; k2 < this.n + 1; ++k2) {
|
|
+ this.a(adouble[1][k2], j * this.l + j2 + 1, k * this.n + k2);
|
|
+ }
|
|
+
|
|
+ for (k2 = 0; k2 < this.n; ++k2) {
|
|
+ ChunkSection chunksection = protochunk.a(15);
|
|
+
|
|
+ chunksection.a();
|
|
+
|
|
+ for (int l2 = this.m - 1; l2 >= 0; --l2) {
|
|
+ double d0 = adouble[0][k2][l2];
|
|
+ double d1 = adouble[0][k2 + 1][l2];
|
|
+ double d2 = adouble[1][k2][l2];
|
|
+ double d3 = adouble[1][k2 + 1][l2];
|
|
+ double d4 = adouble[0][k2][l2 + 1];
|
|
+ double d5 = adouble[0][k2 + 1][l2 + 1];
|
|
+ double d6 = adouble[1][k2][l2 + 1];
|
|
+ double d7 = adouble[1][k2 + 1][l2 + 1];
|
|
+
|
|
+ for (int i3 = this.j - 1; i3 >= 0; --i3) {
|
|
+ int j3 = l2 * this.j + i3;
|
|
+ int k3 = j3 & 15;
|
|
+ int l3 = j3 >> 4;
|
|
+
|
|
+ if (chunksection.getYPosition() >> 4 != l3) {
|
|
+ chunksection.b();
|
|
+ chunksection = protochunk.a(l3);
|
|
+ chunksection.a();
|
|
+ }
|
|
+
|
|
+ double d8 = (double) i3 / (double) this.j;
|
|
+ double d9 = MathHelper.d(d8, d0, d4);
|
|
+ double d10 = MathHelper.d(d8, d2, d6);
|
|
+ double d11 = MathHelper.d(d8, d1, d5);
|
|
+ double d12 = MathHelper.d(d8, d3, d7);
|
|
+
|
|
+ for (int i4 = 0; i4 < this.k; ++i4) {
|
|
+ int j4 = l + j2 * this.k + i4;
|
|
+ int k4 = j4 & 15;
|
|
+ double d13 = (double) i4 / (double) this.k;
|
|
+ double d14 = MathHelper.d(d13, d9, d10);
|
|
+ double d15 = MathHelper.d(d13, d11, d12);
|
|
+
|
|
+ for (int l4 = 0; l4 < this.k; ++l4) {
|
|
+ int i5 = i1 + k2 * this.k + l4;
|
|
+ int j5 = i5 & 15;
|
|
+ double d16 = (double) l4 / (double) this.k;
|
|
+ double d17 = MathHelper.d(d16, d14, d15);
|
|
+ double d18 = MathHelper.a(d17 / 200.0D, -1.0D, 1.0D);
|
|
+
|
|
+ int k5;
|
|
+ int l5;
|
|
+ int i6;
|
|
+
|
|
+ for (d18 = d18 / 2.0D - d18 * d18 * d18 / 24.0D; objectlistiterator.hasNext(); d18 += a(k5, l5, i6) * 0.8D) {
|
|
+ WorldGenFeaturePillagerOutpostPoolPiece worldgenfeaturepillageroutpostpoolpiece1 = (WorldGenFeaturePillagerOutpostPoolPiece) objectlistiterator.next();
|
|
+ StructureBoundingBox structureboundingbox = worldgenfeaturepillageroutpostpoolpiece1.g();
|
|
+
|
|
+ k5 = Math.max(0, Math.max(structureboundingbox.a - j4, j4 - structureboundingbox.d));
|
|
+ l5 = j3 - (structureboundingbox.b + worldgenfeaturepillageroutpostpoolpiece1.d());
|
|
+ i6 = Math.max(0, Math.max(structureboundingbox.c - i5, i5 - structureboundingbox.f));
|
|
+ }
|
|
+
|
|
+ objectlistiterator.back(objectlist.size());
|
|
+
|
|
+ while (objectlistiterator1.hasNext()) {
|
|
+ WorldGenFeatureDefinedStructureJigsawJunction worldgenfeaturedefinedstructurejigsawjunction1 = (WorldGenFeatureDefinedStructureJigsawJunction) objectlistiterator1.next();
|
|
+ int j6 = j4 - worldgenfeaturedefinedstructurejigsawjunction1.a();
|
|
+
|
|
+ k5 = j3 - worldgenfeaturedefinedstructurejigsawjunction1.b();
|
|
+ l5 = i5 - worldgenfeaturedefinedstructurejigsawjunction1.c();
|
|
+ d18 += a(j6, k5, l5) * 0.4D;
|
|
+ }
|
|
+
|
|
+ objectlistiterator1.back(objectlist1.size());
|
|
+ IBlockData iblockdata;
|
|
+
|
|
+ if (d18 > 0.0D) {
|
|
+ iblockdata = this.f;
|
|
+ } else if (j3 < i) {
|
|
+ iblockdata = this.g;
|
|
+ } else {
|
|
+ iblockdata = ChunkGeneratorAbstract.i;
|
|
+ }
|
|
+
|
|
+ if (iblockdata != ChunkGeneratorAbstract.i) {
|
|
+ if (iblockdata.h() != 0) {
|
|
+ blockposition_mutableblockposition.d(j4, j3, i5);
|
|
+ protochunk.k(blockposition_mutableblockposition);
|
|
+ }
|
|
+
|
|
+ chunksection.setType(k4, k3, j5, iblockdata, false);
|
|
+ heightmap.a(k4, j3, j5, iblockdata);
|
|
+ heightmap1.a(k4, j3, j5, iblockdata);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ chunksection.b();
|
|
+ }
|
|
+
|
|
+ double[][] adouble1 = adouble[0];
|
|
+
|
|
+ adouble[0] = adouble[1];
|
|
+ adouble[1] = adouble1;
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ private static double a(int i, int j, int k) {
|
|
+ int l = i + 12;
|
|
+ int i1 = j + 12;
|
|
+ int j1 = k + 12;
|
|
+
|
|
+ return l >= 0 && l < 24 ? (i1 >= 0 && i1 < 24 ? (j1 >= 0 && j1 < 24 ? (double) ChunkGeneratorAbstract.h[j1 * 24 * 24 + l * 24 + i1] : 0.0D) : 0.0D) : 0.0D;
|
|
+ }
|
|
+
|
|
+ private static double b(int i, int j, int k) {
|
|
+ double d0 = (double) (i * i + k * k);
|
|
+ double d1 = (double) j + 0.5D;
|
|
+ double d2 = d1 * d1;
|
|
+ double d3 = Math.pow(2.718281828459045D, -(d2 / 16.0D + d0 / 16.0D));
|
|
+ double d4 = -d1 * MathHelper.i(d2 / 2.0D + d0 / 2.0D) / 2.0D;
|
|
+
|
|
+ return d4 * d3;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
|
|
new file mode 100644
|
|
index 000000000..93bee851b
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
|
|
@@ -0,0 +1,517 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.google.common.collect.Maps;
|
|
+import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
|
+import it.unimi.dsi.fastutil.longs.LongSet;
|
|
+import it.unimi.dsi.fastutil.shorts.ShortList;
|
|
+import it.unimi.dsi.fastutil.shorts.ShortListIterator;
|
|
+import java.util.Arrays;
|
|
+import java.util.BitSet;
|
|
+import java.util.EnumSet;
|
|
+import java.util.Iterator;
|
|
+import java.util.Map;
|
|
+import java.util.Objects;
|
|
+import java.util.Map.Entry;
|
|
+import java.util.function.Function;
|
|
+import javax.annotation.Nullable;
|
|
+import org.apache.logging.log4j.LogManager;
|
|
+import org.apache.logging.log4j.Logger;
|
|
+
|
|
+public class ChunkRegionLoader {
|
|
+
|
|
+ private static final Logger LOGGER = LogManager.getLogger();
|
|
+
|
|
+ public static ProtoChunk loadChunk(WorldServer worldserver, DefinedStructureManager definedstructuremanager, VillagePlace villageplace, ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) {
|
|
+ ChunkGenerator<?> chunkgenerator = worldserver.getChunkProvider().getChunkGenerator();
|
|
+ WorldChunkManager worldchunkmanager = chunkgenerator.getWorldChunkManager();
|
|
+ NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Level");
|
|
+ ChunkCoordIntPair chunkcoordintpair1 = new ChunkCoordIntPair(nbttagcompound1.getInt("xPos"), nbttagcompound1.getInt("zPos"));
|
|
+
|
|
+ if (!Objects.equals(chunkcoordintpair, chunkcoordintpair1)) {
|
|
+ ChunkRegionLoader.LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", chunkcoordintpair, chunkcoordintpair, chunkcoordintpair1);
|
|
+ }
|
|
+
|
|
+ BiomeBase[] abiomebase = new BiomeBase[256];
|
|
+ BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
|
|
+
|
|
+ if (nbttagcompound1.hasKeyOfType("Biomes", 11)) {
|
|
+ int[] aint = nbttagcompound1.getIntArray("Biomes");
|
|
+
|
|
+ for (int i = 0; i < aint.length; ++i) {
|
|
+ abiomebase[i] = (BiomeBase) IRegistry.BIOME.fromId(aint[i]);
|
|
+ if (abiomebase[i] == null) {
|
|
+ abiomebase[i] = worldchunkmanager.getBiome(blockposition_mutableblockposition.d((i & 15) + chunkcoordintpair.d(), 0, (i >> 4 & 15) + chunkcoordintpair.e()));
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ for (int j = 0; j < abiomebase.length; ++j) {
|
|
+ abiomebase[j] = worldchunkmanager.getBiome(blockposition_mutableblockposition.d((j & 15) + chunkcoordintpair.d(), 0, (j >> 4 & 15) + chunkcoordintpair.e()));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ChunkConverter chunkconverter = nbttagcompound1.hasKeyOfType("UpgradeData", 10) ? new ChunkConverter(nbttagcompound1.getCompound("UpgradeData")) : ChunkConverter.a;
|
|
+ ProtoChunkTickList<Block> protochunkticklist = new ProtoChunkTickList<>((block) -> {
|
|
+ return block == null || block.getBlockData().isAir();
|
|
+ }, chunkcoordintpair, nbttagcompound1.getList("ToBeTicked", 9));
|
|
+ ProtoChunkTickList<FluidType> protochunkticklist1 = new ProtoChunkTickList<>((fluidtype) -> {
|
|
+ return fluidtype == null || fluidtype == FluidTypes.EMPTY;
|
|
+ }, chunkcoordintpair, nbttagcompound1.getList("LiquidsToBeTicked", 9));
|
|
+ boolean flag = nbttagcompound1.getBoolean("isLightOn");
|
|
+ NBTTagList nbttaglist = nbttagcompound1.getList("Sections", 10);
|
|
+ boolean flag1 = true;
|
|
+ ChunkSection[] achunksection = new ChunkSection[16];
|
|
+ boolean flag2 = worldserver.getWorldProvider().g();
|
|
+ ChunkProviderServer chunkproviderserver = worldserver.getChunkProvider();
|
|
+ LightEngine lightengine = chunkproviderserver.getLightEngine();
|
|
+
|
|
+ if (flag) {
|
|
+ lightengine.b(chunkcoordintpair, true);
|
|
+ }
|
|
+
|
|
+ for (int k = 0; k < nbttaglist.size(); ++k) {
|
|
+ NBTTagCompound nbttagcompound2 = nbttaglist.getCompound(k);
|
|
+ byte b0 = nbttagcompound2.getByte("Y");
|
|
+
|
|
+ if (nbttagcompound2.hasKeyOfType("Palette", 9) && nbttagcompound2.hasKeyOfType("BlockStates", 12)) {
|
|
+ ChunkSection chunksection = new ChunkSection(b0 << 4);
|
|
+
|
|
+ chunksection.getBlocks().a(nbttagcompound2.getList("Palette", 10), nbttagcompound2.getLongArray("BlockStates"));
|
|
+ chunksection.recalcBlockCounts();
|
|
+ if (!chunksection.c()) {
|
|
+ achunksection[b0] = chunksection;
|
|
+ }
|
|
+
|
|
+ villageplace.a(chunkcoordintpair, chunksection);
|
|
+ }
|
|
+
|
|
+ if (flag) {
|
|
+ if (nbttagcompound2.hasKeyOfType("BlockLight", 7)) {
|
|
+ lightengine.a(EnumSkyBlock.BLOCK, SectionPosition.a(chunkcoordintpair, b0), new NibbleArray(nbttagcompound2.getByteArray("BlockLight")));
|
|
+ }
|
|
+
|
|
+ if (flag2 && nbttagcompound2.hasKeyOfType("SkyLight", 7)) {
|
|
+ lightengine.a(EnumSkyBlock.SKY, SectionPosition.a(chunkcoordintpair, b0), new NibbleArray(nbttagcompound2.getByteArray("SkyLight")));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ long l = nbttagcompound1.getLong("InhabitedTime");
|
|
+ ChunkStatus.Type chunkstatus_type = a(nbttagcompound);
|
|
+ Object object;
|
|
+
|
|
+ if (chunkstatus_type == ChunkStatus.Type.LEVELCHUNK) {
|
|
+ NBTTagList nbttaglist1;
|
|
+ Function function;
|
|
+ RegistryBlocks registryblocks;
|
|
+ Object object1;
|
|
+
|
|
+ if (nbttagcompound1.hasKeyOfType("TileTicks", 9)) {
|
|
+ nbttaglist1 = nbttagcompound1.getList("TileTicks", 10);
|
|
+ // function = IRegistry.BLOCK::getKey;
|
|
+ registryblocks = IRegistry.BLOCK;
|
|
+ registryblocks.getClass();
|
|
+ object1 = TickListChunk.a(nbttaglist1, IRegistry.BLOCK::getKey, IRegistry.BLOCK::get);
|
|
+ } else {
|
|
+ object1 = protochunkticklist;
|
|
+ }
|
|
+
|
|
+ Object object2;
|
|
+
|
|
+ if (nbttagcompound1.hasKeyOfType("LiquidTicks", 9)) {
|
|
+ nbttaglist1 = nbttagcompound1.getList("LiquidTicks", 10);
|
|
+ // function = IRegistry.FLUID::getKey;
|
|
+ registryblocks = IRegistry.FLUID;
|
|
+ registryblocks.getClass();
|
|
+ object2 = TickListChunk.a(nbttaglist1, IRegistry.FLUID::getKey, IRegistry.FLUID::get);
|
|
+ } else {
|
|
+ object2 = protochunkticklist1;
|
|
+ }
|
|
+
|
|
+ object = new Chunk(worldserver.getMinecraftWorld(), chunkcoordintpair, abiomebase, chunkconverter, (TickList) object1, (TickList) object2, l, achunksection, (chunk) -> {
|
|
+ loadEntities(nbttagcompound1, chunk);
|
|
+ });
|
|
+ } else {
|
|
+ ProtoChunk protochunk = new ProtoChunk(chunkcoordintpair, chunkconverter, achunksection, protochunkticklist, protochunkticklist1);
|
|
+
|
|
+ object = protochunk;
|
|
+ protochunk.a(abiomebase);
|
|
+ protochunk.b(l);
|
|
+ protochunk.a(ChunkStatus.a(nbttagcompound1.getString("Status")));
|
|
+ if (protochunk.getChunkStatus().b(ChunkStatus.FEATURES)) {
|
|
+ protochunk.a(lightengine);
|
|
+ }
|
|
+
|
|
+ if (!flag && protochunk.getChunkStatus().b(ChunkStatus.LIGHT)) {
|
|
+ Iterator iterator = BlockPosition.b(chunkcoordintpair.d(), 0, chunkcoordintpair.e(), chunkcoordintpair.f(), 255, chunkcoordintpair.g()).iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ BlockPosition blockposition = (BlockPosition) iterator.next();
|
|
+
|
|
+ if (((IChunkAccess) object).getType(blockposition).h() != 0) {
|
|
+ protochunk.k(blockposition);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ((IChunkAccess) object).b(flag);
|
|
+ NBTTagCompound nbttagcompound3 = nbttagcompound1.getCompound("Heightmaps");
|
|
+ EnumSet<HeightMap.Type> enumset = EnumSet.noneOf(HeightMap.Type.class);
|
|
+ Iterator iterator1 = ((IChunkAccess) object).getChunkStatus().h().iterator();
|
|
+
|
|
+ while (iterator1.hasNext()) {
|
|
+ HeightMap.Type heightmap_type = (HeightMap.Type) iterator1.next();
|
|
+ String s = heightmap_type.a();
|
|
+
|
|
+ if (nbttagcompound3.hasKeyOfType(s, 12)) {
|
|
+ ((IChunkAccess) object).a(heightmap_type, nbttagcompound3.getLongArray(s));
|
|
+ } else {
|
|
+ enumset.add(heightmap_type);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ HeightMap.a((IChunkAccess) object, enumset);
|
|
+ NBTTagCompound nbttagcompound4 = nbttagcompound1.getCompound("Structures");
|
|
+
|
|
+ ((IChunkAccess) object).a(a(chunkgenerator, definedstructuremanager, worldchunkmanager, nbttagcompound4));
|
|
+ ((IChunkAccess) object).b(b(nbttagcompound4));
|
|
+ if (nbttagcompound1.getBoolean("shouldSave")) {
|
|
+ ((IChunkAccess) object).setNeedsSaving(true);
|
|
+ }
|
|
+
|
|
+ NBTTagList nbttaglist2 = nbttagcompound1.getList("PostProcessing", 9);
|
|
+
|
|
+ NBTTagList nbttaglist3;
|
|
+ int i1;
|
|
+
|
|
+ for (int j1 = 0; j1 < nbttaglist2.size(); ++j1) {
|
|
+ nbttaglist3 = nbttaglist2.b(j1);
|
|
+
|
|
+ for (i1 = 0; i1 < nbttaglist3.size(); ++i1) {
|
|
+ ((IChunkAccess) object).a(nbttaglist3.d(i1), j1);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (chunkstatus_type == ChunkStatus.Type.LEVELCHUNK) {
|
|
+ return new ProtoChunkExtension((Chunk) object);
|
|
+ } else {
|
|
+ ProtoChunk protochunk1 = (ProtoChunk) object;
|
|
+
|
|
+ nbttaglist3 = nbttagcompound1.getList("Entities", 10);
|
|
+
|
|
+ for (i1 = 0; i1 < nbttaglist3.size(); ++i1) {
|
|
+ protochunk1.b(nbttaglist3.getCompound(i1));
|
|
+ }
|
|
+
|
|
+ NBTTagList nbttaglist4 = nbttagcompound1.getList("TileEntities", 10);
|
|
+
|
|
+ NBTTagCompound nbttagcompound5;
|
|
+
|
|
+ for (int k1 = 0; k1 < nbttaglist4.size(); ++k1) {
|
|
+ nbttagcompound5 = nbttaglist4.getCompound(k1);
|
|
+ ((IChunkAccess) object).a(nbttagcompound5);
|
|
+ }
|
|
+
|
|
+ NBTTagList nbttaglist5 = nbttagcompound1.getList("Lights", 9);
|
|
+
|
|
+ for (int l1 = 0; l1 < nbttaglist5.size(); ++l1) {
|
|
+ NBTTagList nbttaglist6 = nbttaglist5.b(l1);
|
|
+
|
|
+ for (int i2 = 0; i2 < nbttaglist6.size(); ++i2) {
|
|
+ protochunk1.b(nbttaglist6.d(i2), l1);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ nbttagcompound5 = nbttagcompound1.getCompound("CarvingMasks");
|
|
+ Iterator iterator2 = nbttagcompound5.getKeys().iterator();
|
|
+
|
|
+ while (iterator2.hasNext()) {
|
|
+ String s1 = (String) iterator2.next();
|
|
+ WorldGenStage.Features worldgenstage_features = WorldGenStage.Features.valueOf(s1);
|
|
+
|
|
+ protochunk1.a(worldgenstage_features, BitSet.valueOf(nbttagcompound5.getByteArray(s1)));
|
|
+ }
|
|
+
|
|
+ return protochunk1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static NBTTagCompound saveChunk(WorldServer worldserver, IChunkAccess ichunkaccess) {
|
|
+ ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos();
|
|
+ NBTTagCompound nbttagcompound = new NBTTagCompound();
|
|
+ NBTTagCompound nbttagcompound1 = new NBTTagCompound();
|
|
+
|
|
+ nbttagcompound.setInt("DataVersion", SharedConstants.a().getWorldVersion());
|
|
+ nbttagcompound.set("Level", nbttagcompound1);
|
|
+ nbttagcompound1.setInt("xPos", chunkcoordintpair.x);
|
|
+ nbttagcompound1.setInt("zPos", chunkcoordintpair.z);
|
|
+ nbttagcompound1.setLong("LastUpdate", worldserver.getTime());
|
|
+ nbttagcompound1.setLong("InhabitedTime", ichunkaccess.q());
|
|
+ nbttagcompound1.setString("Status", ichunkaccess.getChunkStatus().d());
|
|
+ ChunkConverter chunkconverter = ichunkaccess.p();
|
|
+
|
|
+ if (!chunkconverter.a()) {
|
|
+ nbttagcompound1.set("UpgradeData", chunkconverter.b());
|
|
+ }
|
|
+
|
|
+ ChunkSection[] achunksection = ichunkaccess.getSections();
|
|
+ NBTTagList nbttaglist = new NBTTagList();
|
|
+ LightEngineThreaded lightenginethreaded = worldserver.getChunkProvider().getLightEngine();
|
|
+ boolean flag = ichunkaccess.r();
|
|
+
|
|
+ NBTTagCompound nbttagcompound2;
|
|
+
|
|
+ for (int i = -1; i < 17; ++i) {
|
|
+ int finalI = i;
|
|
+ ChunkSection chunksection = (ChunkSection) Arrays.stream(achunksection).filter((chunksection1) -> {
|
|
+ return chunksection1 != null && chunksection1.getYPosition() >> 4 == finalI;
|
|
+ }).findFirst().orElse(Chunk.a);
|
|
+ NibbleArray nibblearray = lightenginethreaded.a(EnumSkyBlock.BLOCK).a(SectionPosition.a(chunkcoordintpair, i));
|
|
+ NibbleArray nibblearray1 = lightenginethreaded.a(EnumSkyBlock.SKY).a(SectionPosition.a(chunkcoordintpair, i));
|
|
+
|
|
+ if (chunksection != Chunk.a || nibblearray != null || nibblearray1 != null) {
|
|
+ nbttagcompound2 = new NBTTagCompound();
|
|
+ nbttagcompound2.setByte("Y", (byte) (i & 255));
|
|
+ if (chunksection != Chunk.a) {
|
|
+ chunksection.getBlocks().a(nbttagcompound2, "Palette", "BlockStates");
|
|
+ }
|
|
+
|
|
+ if (nibblearray != null && !nibblearray.c()) {
|
|
+ nbttagcompound2.setByteArray("BlockLight", nibblearray.asBytes());
|
|
+ }
|
|
+
|
|
+ if (nibblearray1 != null && !nibblearray1.c()) {
|
|
+ nbttagcompound2.setByteArray("SkyLight", nibblearray1.asBytes());
|
|
+ }
|
|
+
|
|
+ nbttaglist.add(nbttagcompound2);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ nbttagcompound1.set("Sections", nbttaglist);
|
|
+ if (flag) {
|
|
+ nbttagcompound1.setBoolean("isLightOn", true);
|
|
+ }
|
|
+
|
|
+ BiomeBase[] abiomebase = ichunkaccess.getBiomeIndex();
|
|
+ int[] aint = abiomebase != null ? new int[abiomebase.length] : new int[0];
|
|
+
|
|
+ if (abiomebase != null) {
|
|
+ for (int j = 0; j < abiomebase.length; ++j) {
|
|
+ aint[j] = IRegistry.BIOME.a(abiomebase[j]);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ nbttagcompound1.setIntArray("Biomes", aint);
|
|
+ NBTTagList nbttaglist1 = new NBTTagList();
|
|
+ Iterator iterator = ichunkaccess.c().iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ BlockPosition blockposition = (BlockPosition) iterator.next();
|
|
+
|
|
+ nbttagcompound2 = ichunkaccess.j(blockposition);
|
|
+ if (nbttagcompound2 != null) {
|
|
+ nbttaglist1.add(nbttagcompound2);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ nbttagcompound1.set("TileEntities", nbttaglist1);
|
|
+ NBTTagList nbttaglist2 = new NBTTagList();
|
|
+
|
|
+ if (ichunkaccess.getChunkStatus().getType() == ChunkStatus.Type.LEVELCHUNK) {
|
|
+ Chunk chunk = (Chunk) ichunkaccess;
|
|
+
|
|
+ chunk.d(false);
|
|
+
|
|
+ for (int k = 0; k < chunk.getEntitySlices().length; ++k) {
|
|
+ Iterator iterator1 = chunk.getEntitySlices()[k].iterator();
|
|
+
|
|
+ while (iterator1.hasNext()) {
|
|
+ Entity entity = (Entity) iterator1.next();
|
|
+ NBTTagCompound nbttagcompound3 = new NBTTagCompound();
|
|
+
|
|
+ if (entity.d(nbttagcompound3)) {
|
|
+ chunk.d(true);
|
|
+ nbttaglist2.add(nbttagcompound3);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ ProtoChunk protochunk = (ProtoChunk) ichunkaccess;
|
|
+
|
|
+ nbttaglist2.addAll(protochunk.y());
|
|
+ nbttagcompound1.set("Lights", a(protochunk.w()));
|
|
+ nbttagcompound2 = new NBTTagCompound();
|
|
+ WorldGenStage.Features[] aworldgenstage_features = WorldGenStage.Features.values();
|
|
+ int l = aworldgenstage_features.length;
|
|
+
|
|
+ for (int i1 = 0; i1 < l; ++i1) {
|
|
+ WorldGenStage.Features worldgenstage_features = aworldgenstage_features[i1];
|
|
+
|
|
+ nbttagcompound2.setByteArray(worldgenstage_features.toString(), ichunkaccess.a(worldgenstage_features).toByteArray());
|
|
+ }
|
|
+
|
|
+ nbttagcompound1.set("CarvingMasks", nbttagcompound2);
|
|
+ }
|
|
+
|
|
+ nbttagcompound1.set("Entities", nbttaglist2);
|
|
+ TickList<Block> ticklist = ichunkaccess.n();
|
|
+
|
|
+ if (ticklist instanceof ProtoChunkTickList) {
|
|
+ nbttagcompound1.set("ToBeTicked", ((ProtoChunkTickList) ticklist).b());
|
|
+ } else if (ticklist instanceof TickListChunk) {
|
|
+ nbttagcompound1.set("TileTicks", ((TickListChunk) ticklist).a(worldserver.getTime()));
|
|
+ } else {
|
|
+ nbttagcompound1.set("TileTicks", worldserver.getBlockTickList().a(chunkcoordintpair));
|
|
+ }
|
|
+
|
|
+ TickList<FluidType> ticklist1 = ichunkaccess.o();
|
|
+
|
|
+ if (ticklist1 instanceof ProtoChunkTickList) {
|
|
+ nbttagcompound1.set("LiquidsToBeTicked", ((ProtoChunkTickList) ticklist1).b());
|
|
+ } else if (ticklist1 instanceof TickListChunk) {
|
|
+ nbttagcompound1.set("LiquidTicks", ((TickListChunk) ticklist1).a(worldserver.getTime()));
|
|
+ } else {
|
|
+ nbttagcompound1.set("LiquidTicks", worldserver.getFluidTickList().a(chunkcoordintpair));
|
|
+ }
|
|
+
|
|
+ nbttagcompound1.set("PostProcessing", a(ichunkaccess.l()));
|
|
+ NBTTagCompound nbttagcompound4 = new NBTTagCompound();
|
|
+ Iterator iterator2 = ichunkaccess.f().iterator();
|
|
+
|
|
+ while (iterator2.hasNext()) {
|
|
+ Entry<HeightMap.Type, HeightMap> entry = (Entry) iterator2.next();
|
|
+
|
|
+ if (ichunkaccess.getChunkStatus().h().contains(entry.getKey())) {
|
|
+ nbttagcompound4.set(((HeightMap.Type) entry.getKey()).a(), new NBTTagLongArray(((HeightMap) entry.getValue()).a()));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ nbttagcompound1.set("Heightmaps", nbttagcompound4);
|
|
+ nbttagcompound1.set("Structures", a(chunkcoordintpair, ichunkaccess.h(), ichunkaccess.v()));
|
|
+ return nbttagcompound;
|
|
+ }
|
|
+
|
|
+ public static ChunkStatus.Type a(@Nullable NBTTagCompound nbttagcompound) {
|
|
+ if (nbttagcompound != null) {
|
|
+ ChunkStatus chunkstatus = ChunkStatus.a(nbttagcompound.getCompound("Level").getString("Status"));
|
|
+
|
|
+ if (chunkstatus != null) {
|
|
+ return chunkstatus.getType();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return ChunkStatus.Type.PROTOCHUNK;
|
|
+ }
|
|
+
|
|
+ private static void loadEntities(NBTTagCompound nbttagcompound, Chunk chunk) {
|
|
+ NBTTagList nbttaglist = nbttagcompound.getList("Entities", 10);
|
|
+ World world = chunk.getWorld();
|
|
+
|
|
+ for (int i = 0; i < nbttaglist.size(); ++i) {
|
|
+ NBTTagCompound nbttagcompound1 = nbttaglist.getCompound(i);
|
|
+
|
|
+ EntityTypes.a(nbttagcompound1, world, (entity) -> {
|
|
+ chunk.a(entity);
|
|
+ return entity;
|
|
+ });
|
|
+ chunk.d(true);
|
|
+ }
|
|
+
|
|
+ NBTTagList nbttaglist1 = nbttagcompound.getList("TileEntities", 10);
|
|
+
|
|
+ for (int j = 0; j < nbttaglist1.size(); ++j) {
|
|
+ NBTTagCompound nbttagcompound2 = nbttaglist1.getCompound(j);
|
|
+ boolean flag = nbttagcompound2.getBoolean("keepPacked");
|
|
+
|
|
+ if (flag) {
|
|
+ chunk.a(nbttagcompound2);
|
|
+ } else {
|
|
+ TileEntity tileentity = TileEntity.create(nbttagcompound2);
|
|
+
|
|
+ if (tileentity != null) {
|
|
+ chunk.a(tileentity);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ private static NBTTagCompound a(ChunkCoordIntPair chunkcoordintpair, Map<String, StructureStart> map, Map<String, LongSet> map1) {
|
|
+ NBTTagCompound nbttagcompound = new NBTTagCompound();
|
|
+ NBTTagCompound nbttagcompound1 = new NBTTagCompound();
|
|
+ Iterator iterator = map.entrySet().iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ Entry<String, StructureStart> entry = (Entry) iterator.next();
|
|
+
|
|
+ nbttagcompound1.set((String) entry.getKey(), ((StructureStart) entry.getValue()).a(chunkcoordintpair.x, chunkcoordintpair.z));
|
|
+ }
|
|
+
|
|
+ nbttagcompound.set("Starts", nbttagcompound1);
|
|
+ NBTTagCompound nbttagcompound2 = new NBTTagCompound();
|
|
+ Iterator iterator1 = map1.entrySet().iterator();
|
|
+
|
|
+ while (iterator1.hasNext()) {
|
|
+ Entry<String, LongSet> entry1 = (Entry) iterator1.next();
|
|
+
|
|
+ nbttagcompound2.set((String) entry1.getKey(), new NBTTagLongArray((LongSet) entry1.getValue()));
|
|
+ }
|
|
+
|
|
+ nbttagcompound.set("References", nbttagcompound2);
|
|
+ return nbttagcompound;
|
|
+ }
|
|
+
|
|
+ private static Map<String, StructureStart> a(ChunkGenerator<?> chunkgenerator, DefinedStructureManager definedstructuremanager, WorldChunkManager worldchunkmanager, NBTTagCompound nbttagcompound) {
|
|
+ Map<String, StructureStart> map = Maps.newHashMap();
|
|
+ NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Starts");
|
|
+ Iterator iterator = nbttagcompound1.getKeys().iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ String s = (String) iterator.next();
|
|
+
|
|
+ map.put(s, WorldGenFactory.a(chunkgenerator, definedstructuremanager, worldchunkmanager, nbttagcompound1.getCompound(s)));
|
|
+ }
|
|
+
|
|
+ return map;
|
|
+ }
|
|
+
|
|
+ private static Map<String, LongSet> b(NBTTagCompound nbttagcompound) {
|
|
+ Map<String, LongSet> map = Maps.newHashMap();
|
|
+ NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("References");
|
|
+ Iterator iterator = nbttagcompound1.getKeys().iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ String s = (String) iterator.next();
|
|
+
|
|
+ map.put(s, new LongOpenHashSet(nbttagcompound1.getLongArray(s)));
|
|
+ }
|
|
+
|
|
+ return map;
|
|
+ }
|
|
+
|
|
+ public static NBTTagList a(ShortList[] ashortlist) {
|
|
+ NBTTagList nbttaglist = new NBTTagList();
|
|
+ ShortList[] ashortlist1 = ashortlist;
|
|
+ int i = ashortlist.length;
|
|
+
|
|
+ for (int j = 0; j < i; ++j) {
|
|
+ ShortList shortlist = ashortlist1[j];
|
|
+ NBTTagList nbttaglist1 = new NBTTagList();
|
|
+
|
|
+ if (shortlist != null) {
|
|
+ ShortListIterator shortlistiterator = shortlist.iterator();
|
|
+
|
|
+ while (shortlistiterator.hasNext()) {
|
|
+ Short oshort = (Short) shortlistiterator.next();
|
|
+
|
|
+ nbttaglist1.add(new NBTTagShort(oshort));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ nbttaglist.add(nbttaglist1);
|
|
+ }
|
|
+
|
|
+ return nbttaglist;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/EntitySquid.java b/src/main/java/net/minecraft/server/EntitySquid.java
|
|
new file mode 100644
|
|
index 000000000..389b32147
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/EntitySquid.java
|
|
@@ -0,0 +1,276 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.util.Random;
|
|
+
|
|
+public class EntitySquid extends EntityWaterAnimal {
|
|
+
|
|
+ public float b;
|
|
+ public float c;
|
|
+ public float d;
|
|
+ public float bz;
|
|
+ public float bA;
|
|
+ public float bB;
|
|
+ public float bC;
|
|
+ public float bD;
|
|
+ private float bE;
|
|
+ private float bF;
|
|
+ private float bG;
|
|
+ private float bH;
|
|
+ private float bI;
|
|
+ private float bJ;
|
|
+
|
|
+ public EntitySquid(EntityTypes<? extends EntitySquid> entitytypes, World world) {
|
|
+ super(entitytypes, world);
|
|
+ this.random.setSeed((long) this.getId());
|
|
+ this.bF = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void initPathfinder() {
|
|
+ this.goalSelector.a(0, new EntitySquid.PathfinderGoalSquid(this));
|
|
+ this.goalSelector.a(1, new EntitySquid.a());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void initAttributes() {
|
|
+ super.initAttributes();
|
|
+ this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(10.0D);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected float b(EntityPose entitypose, EntitySize entitysize) {
|
|
+ return entitysize.height * 0.5F;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected SoundEffect getSoundAmbient() {
|
|
+ return SoundEffects.ENTITY_SQUID_AMBIENT;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected SoundEffect getSoundHurt(DamageSource damagesource) {
|
|
+ return SoundEffects.ENTITY_SQUID_HURT;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected SoundEffect getSoundDeath() {
|
|
+ return SoundEffects.ENTITY_SQUID_DEATH;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected float getSoundVolume() {
|
|
+ return 0.4F;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected boolean playStepSound() {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void movementTick() {
|
|
+ super.movementTick();
|
|
+ this.c = this.b;
|
|
+ this.bz = this.d;
|
|
+ this.bB = this.bA;
|
|
+ this.bD = this.bC;
|
|
+ this.bA += this.bF;
|
|
+ if ((double) this.bA > 6.283185307179586D) {
|
|
+ if (this.world.isClientSide) {
|
|
+ this.bA = 6.2831855F;
|
|
+ } else {
|
|
+ this.bA = (float) ((double) this.bA - 6.283185307179586D);
|
|
+ if (this.random.nextInt(10) == 0) {
|
|
+ this.bF = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F;
|
|
+ }
|
|
+
|
|
+ this.world.broadcastEntityEffect(this, (byte) 19);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (this.av()) {
|
|
+ if (this.bA < 3.1415927F) {
|
|
+ float f = this.bA / 3.1415927F;
|
|
+
|
|
+ this.bC = MathHelper.sin(f * f * 3.1415927F) * 3.1415927F * 0.25F;
|
|
+ if ((double) f > 0.75D) {
|
|
+ this.bE = 1.0F;
|
|
+ this.bG = 1.0F;
|
|
+ } else {
|
|
+ this.bG *= 0.8F;
|
|
+ }
|
|
+ } else {
|
|
+ this.bC = 0.0F;
|
|
+ this.bE *= 0.9F;
|
|
+ this.bG *= 0.99F;
|
|
+ }
|
|
+
|
|
+ if (!this.world.isClientSide) {
|
|
+ this.setMot((double) (this.bH * this.bE), (double) (this.bI * this.bE), (double) (this.bJ * this.bE));
|
|
+ }
|
|
+
|
|
+ Vec3D vec3d = this.getMot();
|
|
+ float f1 = MathHelper.sqrt(b(vec3d));
|
|
+
|
|
+ this.aK += (-((float) MathHelper.d(vec3d.x, vec3d.z)) * 57.295776F - this.aK) * 0.1F;
|
|
+ this.yaw = this.aK;
|
|
+ this.d = (float) ((double) this.d + 3.141592653589793D * (double) this.bG * 1.5D);
|
|
+ this.b += (-((float) MathHelper.d((double) f1, vec3d.y)) * 57.295776F - this.b) * 0.1F;
|
|
+ } else {
|
|
+ this.bC = MathHelper.e(MathHelper.sin(this.bA)) * 3.1415927F * 0.25F;
|
|
+ if (!this.world.isClientSide) {
|
|
+ double d0 = this.getMot().y;
|
|
+
|
|
+ if (this.hasEffect(MobEffects.LEVITATION)) {
|
|
+ d0 = 0.05D * (double) (this.getEffect(MobEffects.LEVITATION).getAmplifier() + 1);
|
|
+ } else if (!this.isNoGravity()) {
|
|
+ d0 -= 0.08D;
|
|
+ }
|
|
+
|
|
+ this.setMot(0.0D, d0 * 0.9800000190734863D, 0.0D);
|
|
+ }
|
|
+
|
|
+ this.b = (float) ((double) this.b + (double) (-90.0F - this.b) * 0.02D);
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean damageEntity(DamageSource damagesource, float f) {
|
|
+ if (super.damageEntity(damagesource, f) && this.getLastDamager() != null) {
|
|
+ this.dV();
|
|
+ return true;
|
|
+ } else {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private Vec3D f(Vec3D vec3d) {
|
|
+ Vec3D vec3d1 = vec3d.a(this.c * 0.017453292F);
|
|
+
|
|
+ vec3d1 = vec3d1.b(-this.aL * 0.017453292F);
|
|
+ return vec3d1;
|
|
+ }
|
|
+
|
|
+ private void dV() {
|
|
+ this.a(SoundEffects.ENTITY_SQUID_SQUIRT, this.getSoundVolume(), this.cV());
|
|
+ Vec3D vec3d = this.f(new Vec3D(0.0D, -1.0D, 0.0D)).add(this.locX, this.locY, this.locZ);
|
|
+
|
|
+ for (int i = 0; i < 30; ++i) {
|
|
+ Vec3D vec3d1 = this.f(new Vec3D((double) this.random.nextFloat() * 0.6D - 0.3D, -1.0D, (double) this.random.nextFloat() * 0.6D - 0.3D));
|
|
+ Vec3D vec3d2 = vec3d1.a(0.3D + (double) (this.random.nextFloat() * 2.0F));
|
|
+
|
|
+ ((WorldServer) this.world).a(Particles.SQUID_INK, vec3d.x, vec3d.y + 0.5D, vec3d.z, 0, vec3d2.x, vec3d2.y, vec3d2.z, 0.10000000149011612D);
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void e(Vec3D vec3d) {
|
|
+ this.move(EnumMoveType.SELF, this.getMot());
|
|
+ }
|
|
+
|
|
+ public static boolean b(EntityTypes<EntitySquid> entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) {
|
|
+ return blockposition.getY() > 45 && blockposition.getY() < generatoraccess.getSeaLevel();
|
|
+ }
|
|
+
|
|
+ public void a(float f, float f1, float f2) {
|
|
+ this.bH = f;
|
|
+ this.bI = f1;
|
|
+ this.bJ = f2;
|
|
+ }
|
|
+
|
|
+ public boolean l() {
|
|
+ return this.bH != 0.0F || this.bI != 0.0F || this.bJ != 0.0F;
|
|
+ }
|
|
+
|
|
+ class a extends PathfinderGoal {
|
|
+
|
|
+ private int b;
|
|
+
|
|
+ private a() {}
|
|
+
|
|
+ @Override
|
|
+ public boolean a() {
|
|
+ EntityLiving entityliving = EntitySquid.this.getLastDamager();
|
|
+
|
|
+ return EntitySquid.this.isInWater() && entityliving != null ? EntitySquid.this.h((Entity) entityliving) < 100.0D : false;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void c() {
|
|
+ this.b = 0;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void e() {
|
|
+ ++this.b;
|
|
+ EntityLiving entityliving = EntitySquid.this.getLastDamager();
|
|
+
|
|
+ if (entityliving != null) {
|
|
+ Vec3D vec3d = new Vec3D(EntitySquid.this.locX - entityliving.locX, EntitySquid.this.locY - entityliving.locY, EntitySquid.this.locZ - entityliving.locZ);
|
|
+ IBlockData iblockdata = EntitySquid.this.world.getType(new BlockPosition(EntitySquid.this.locX + vec3d.x, EntitySquid.this.locY + vec3d.y, EntitySquid.this.locZ + vec3d.z));
|
|
+ Fluid fluid = EntitySquid.this.world.getFluid(new BlockPosition(EntitySquid.this.locX + vec3d.x, EntitySquid.this.locY + vec3d.y, EntitySquid.this.locZ + vec3d.z));
|
|
+
|
|
+ if (fluid.a(TagsFluid.WATER) || iblockdata.isAir()) {
|
|
+ double d0 = vec3d.f();
|
|
+
|
|
+ if (d0 > 0.0D) {
|
|
+ vec3d.d();
|
|
+ float f = 3.0F;
|
|
+
|
|
+ if (d0 > 5.0D) {
|
|
+ f = (float) ((double) f - (d0 - 5.0D) / 5.0D);
|
|
+ }
|
|
+
|
|
+ if (f > 0.0F) {
|
|
+ vec3d = vec3d.a((double) f);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (iblockdata.isAir()) {
|
|
+ vec3d = vec3d.a(0.0D, vec3d.y, 0.0D);
|
|
+ }
|
|
+
|
|
+ EntitySquid.this.a((float) vec3d.x / 20.0F, (float) vec3d.y / 20.0F, (float) vec3d.z / 20.0F);
|
|
+ }
|
|
+
|
|
+ if (this.b % 10 == 5) {
|
|
+ EntitySquid.this.world.addParticle(Particles.BUBBLE, EntitySquid.this.locX, EntitySquid.this.locY, EntitySquid.this.locZ, 0.0D, 0.0D, 0.0D);
|
|
+ }
|
|
+
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ class PathfinderGoalSquid extends PathfinderGoal {
|
|
+
|
|
+ private final EntitySquid b;
|
|
+
|
|
+ public PathfinderGoalSquid(EntitySquid entitysquid) {
|
|
+ this.b = entitysquid;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean a() {
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void e() {
|
|
+ int i = this.b.cw();
|
|
+
|
|
+ if (i > 100) {
|
|
+ this.b.a(0.0F, 0.0F, 0.0F);
|
|
+ } else if (this.b.getRandom().nextInt(50) == 0 || !this.b.inWater || !this.b.l()) {
|
|
+ float f = this.b.getRandom().nextFloat() * 6.2831855F;
|
|
+ float f1 = MathHelper.cos(f) * 0.2F;
|
|
+ float f2 = -0.1F + this.b.getRandom().nextFloat() * 0.2F;
|
|
+ float f3 = MathHelper.sin(f) * 0.2F;
|
|
+
|
|
+ this.b.a(f1, f2, f3);
|
|
+ }
|
|
+
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/GameProfileBanEntry.java b/src/main/java/net/minecraft/server/GameProfileBanEntry.java
|
|
new file mode 100644
|
|
index 000000000..0cc701042
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/GameProfileBanEntry.java
|
|
@@ -0,0 +1,57 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.google.gson.JsonObject;
|
|
+import com.mojang.authlib.GameProfile;
|
|
+import java.util.Date;
|
|
+import java.util.Objects;
|
|
+import java.util.UUID;
|
|
+import javax.annotation.Nullable;
|
|
+
|
|
+public class GameProfileBanEntry extends ExpirableListEntry<GameProfile> {
|
|
+
|
|
+ public GameProfileBanEntry(GameProfile gameprofile) {
|
|
+ this(gameprofile, (Date) null, (String) null, (Date) null, (String) null);
|
|
+ }
|
|
+
|
|
+ public GameProfileBanEntry(GameProfile gameprofile, @Nullable Date date, @Nullable String s, @Nullable Date date1, @Nullable String s1) {
|
|
+ super(gameprofile, date, s, date1, s1);
|
|
+ }
|
|
+
|
|
+ public GameProfileBanEntry(JsonObject jsonobject) {
|
|
+ super(b(jsonobject), jsonobject);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void a(JsonObject jsonobject) {
|
|
+ if (this.getKey() != null) {
|
|
+ jsonobject.addProperty("uuid", ((GameProfile) this.getKey()).getId() == null ? "" : ((GameProfile) this.getKey()).getId().toString());
|
|
+ jsonobject.addProperty("name", ((GameProfile) this.getKey()).getName());
|
|
+ super.a(jsonobject);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public IChatBaseComponent e() {
|
|
+ GameProfile gameprofile = (GameProfile) this.getKey();
|
|
+
|
|
+ return new ChatComponentText(gameprofile.getName() != null ? gameprofile.getName() : Objects.toString(gameprofile.getId(), "(Unknown)"));
|
|
+ }
|
|
+
|
|
+ private static GameProfile b(JsonObject jsonobject) {
|
|
+ if (jsonobject.has("uuid") && jsonobject.has("name")) {
|
|
+ String s = jsonobject.get("uuid").getAsString();
|
|
+
|
|
+ UUID uuid;
|
|
+
|
|
+ try {
|
|
+ uuid = UUID.fromString(s);
|
|
+ } catch (Throwable throwable) {
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+ return new GameProfile(uuid, jsonobject.get("name").getAsString());
|
|
+ } else {
|
|
+ return null;
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/GenericAttributes.java b/src/main/java/net/minecraft/server/GenericAttributes.java
|
|
new file mode 100644
|
|
index 000000000..4ef2ae57e
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/GenericAttributes.java
|
|
@@ -0,0 +1,123 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.util.Collection;
|
|
+import java.util.Iterator;
|
|
+import java.util.UUID;
|
|
+import javax.annotation.Nullable;
|
|
+import org.apache.logging.log4j.LogManager;
|
|
+import org.apache.logging.log4j.Logger;
|
|
+
|
|
+public class GenericAttributes {
|
|
+
|
|
+ private static final Logger LOGGER = LogManager.getLogger();
|
|
+ public static final IAttribute MAX_HEALTH = (new AttributeRanged((IAttribute) null, "generic.maxHealth", 20.0D, 0.0D, 1024.0D)).a("Max Health").a(true);
|
|
+ public static final IAttribute FOLLOW_RANGE = (new AttributeRanged((IAttribute) null, "generic.followRange", 32.0D, 0.0D, 2048.0D)).a("Follow Range");
|
|
+ public static final IAttribute KNOCKBACK_RESISTANCE = (new AttributeRanged((IAttribute) null, "generic.knockbackResistance", 0.0D, 0.0D, 1.0D)).a("Knockback Resistance");
|
|
+ public static final IAttribute MOVEMENT_SPEED = (new AttributeRanged((IAttribute) null, "generic.movementSpeed", 0.699999988079071D, 0.0D, 1024.0D)).a("Movement Speed").a(true);
|
|
+ public static final IAttribute FLYING_SPEED = (new AttributeRanged((IAttribute) null, "generic.flyingSpeed", 0.4000000059604645D, 0.0D, 1024.0D)).a("Flying Speed").a(true);
|
|
+ public static final IAttribute ATTACK_DAMAGE = new AttributeRanged((IAttribute) null, "generic.attackDamage", 2.0D, 0.0D, 2048.0D);
|
|
+ public static final IAttribute ATTACK_KNOCKBACK = new AttributeRanged((IAttribute) null, "generic.attackKnockback", 0.0D, 0.0D, 5.0D);
|
|
+ public static final IAttribute ATTACK_SPEED = (new AttributeRanged((IAttribute) null, "generic.attackSpeed", 4.0D, 0.0D, 1024.0D)).a(true);
|
|
+ public static final IAttribute ARMOR = (new AttributeRanged((IAttribute) null, "generic.armor", 0.0D, 0.0D, 30.0D)).a(true);
|
|
+ public static final IAttribute ARMOR_TOUGHNESS = (new AttributeRanged((IAttribute) null, "generic.armorToughness", 0.0D, 0.0D, 20.0D)).a(true);
|
|
+ public static final IAttribute LUCK = (new AttributeRanged((IAttribute) null, "generic.luck", 0.0D, -1024.0D, 1024.0D)).a(true);
|
|
+
|
|
+ public static NBTTagList a(AttributeMapBase attributemapbase) {
|
|
+ NBTTagList nbttaglist = new NBTTagList();
|
|
+ Iterator iterator = attributemapbase.a().iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ AttributeInstance attributeinstance = (AttributeInstance) iterator.next();
|
|
+
|
|
+ nbttaglist.add(a(attributeinstance));
|
|
+ }
|
|
+
|
|
+ return nbttaglist;
|
|
+ }
|
|
+
|
|
+ private static NBTTagCompound a(AttributeInstance attributeinstance) {
|
|
+ NBTTagCompound nbttagcompound = new NBTTagCompound();
|
|
+ IAttribute iattribute = attributeinstance.getAttribute();
|
|
+
|
|
+ nbttagcompound.setString("Name", iattribute.getName());
|
|
+ nbttagcompound.setDouble("Base", attributeinstance.getBaseValue());
|
|
+ Collection<AttributeModifier> collection = attributeinstance.getModifiers();
|
|
+
|
|
+ if (collection != null && !collection.isEmpty()) {
|
|
+ NBTTagList nbttaglist = new NBTTagList();
|
|
+ Iterator iterator = collection.iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ AttributeModifier attributemodifier = (AttributeModifier) iterator.next();
|
|
+
|
|
+ if (attributemodifier.e()) {
|
|
+ nbttaglist.add(a(attributemodifier));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ nbttagcompound.set("Modifiers", nbttaglist);
|
|
+ }
|
|
+
|
|
+ return nbttagcompound;
|
|
+ }
|
|
+
|
|
+ public static NBTTagCompound a(AttributeModifier attributemodifier) {
|
|
+ NBTTagCompound nbttagcompound = new NBTTagCompound();
|
|
+
|
|
+ nbttagcompound.setString("Name", attributemodifier.getName());
|
|
+ nbttagcompound.setDouble("Amount", attributemodifier.getAmount());
|
|
+ nbttagcompound.setInt("Operation", attributemodifier.getOperation().a());
|
|
+ nbttagcompound.a("UUID", attributemodifier.getUniqueId());
|
|
+ return nbttagcompound;
|
|
+ }
|
|
+
|
|
+ public static void a(AttributeMapBase attributemapbase, NBTTagList nbttaglist) {
|
|
+ for (int i = 0; i < nbttaglist.size(); ++i) {
|
|
+ NBTTagCompound nbttagcompound = nbttaglist.getCompound(i);
|
|
+ AttributeInstance attributeinstance = attributemapbase.a(nbttagcompound.getString("Name"));
|
|
+
|
|
+ if (attributeinstance == null) {
|
|
+ GenericAttributes.LOGGER.warn("Ignoring unknown attribute '{}'", nbttagcompound.getString("Name"));
|
|
+ } else {
|
|
+ a(attributeinstance, nbttagcompound);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ private static void a(AttributeInstance attributeinstance, NBTTagCompound nbttagcompound) {
|
|
+ attributeinstance.setValue(nbttagcompound.getDouble("Base"));
|
|
+ if (nbttagcompound.hasKeyOfType("Modifiers", 9)) {
|
|
+ NBTTagList nbttaglist = nbttagcompound.getList("Modifiers", 10);
|
|
+
|
|
+ for (int i = 0; i < nbttaglist.size(); ++i) {
|
|
+ AttributeModifier attributemodifier = a(nbttaglist.getCompound(i));
|
|
+
|
|
+ if (attributemodifier != null) {
|
|
+ AttributeModifier attributemodifier1 = attributeinstance.a(attributemodifier.getUniqueId());
|
|
+
|
|
+ if (attributemodifier1 != null) {
|
|
+ attributeinstance.removeModifier(attributemodifier1);
|
|
+ }
|
|
+
|
|
+ attributeinstance.addModifier(attributemodifier);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ @Nullable
|
|
+ public static AttributeModifier a(NBTTagCompound nbttagcompound) {
|
|
+ UUID uuid = nbttagcompound.a("UUID");
|
|
+
|
|
+ try {
|
|
+ AttributeModifier.Operation attributemodifier_operation = AttributeModifier.Operation.a(nbttagcompound.getInt("Operation"));
|
|
+
|
|
+ return new AttributeModifier(uuid, nbttagcompound.getString("Name"), nbttagcompound.getDouble("Amount"), attributemodifier_operation);
|
|
+ } catch (Exception exception) {
|
|
+ GenericAttributes.LOGGER.warn("Unable to create attribute: {}", exception.getMessage());
|
|
+ return null;
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/ItemDebugStick.java b/src/main/java/net/minecraft/server/ItemDebugStick.java
|
|
new file mode 100644
|
|
index 000000000..1ea133f67
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/ItemDebugStick.java
|
|
@@ -0,0 +1,85 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.util.Collection;
|
|
+import javax.annotation.Nullable;
|
|
+
|
|
+public class ItemDebugStick extends Item {
|
|
+
|
|
+ public ItemDebugStick(Item.Info item_info) {
|
|
+ super(item_info);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean a(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman) {
|
|
+ if (!world.isClientSide) {
|
|
+ this.a(entityhuman, iblockdata, world, blockposition, false, entityhuman.b(EnumHand.MAIN_HAND));
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public EnumInteractionResult a(ItemActionContext itemactioncontext) {
|
|
+ EntityHuman entityhuman = itemactioncontext.getEntity();
|
|
+ World world = itemactioncontext.getWorld();
|
|
+
|
|
+ if (!world.isClientSide && entityhuman != null) {
|
|
+ BlockPosition blockposition = itemactioncontext.getClickPosition();
|
|
+
|
|
+ this.a(entityhuman, world.getType(blockposition), world, blockposition, true, itemactioncontext.getItemStack());
|
|
+ }
|
|
+
|
|
+ return EnumInteractionResult.SUCCESS;
|
|
+ }
|
|
+
|
|
+ private void a(EntityHuman entityhuman, IBlockData iblockdata, GeneratorAccess generatoraccess, BlockPosition blockposition, boolean flag, ItemStack itemstack) {
|
|
+ if (entityhuman.isCreativeAndOp()) {
|
|
+ Block block = iblockdata.getBlock();
|
|
+ BlockStateList<Block, IBlockData> blockstatelist = block.getStates();
|
|
+ Collection<IBlockState<?>> collection = blockstatelist.d();
|
|
+ String s = IRegistry.BLOCK.getKey(block).toString();
|
|
+
|
|
+ if (collection.isEmpty()) {
|
|
+ a(entityhuman, (IChatBaseComponent) (new ChatMessage(this.getName() + ".empty", new Object[]{s})));
|
|
+ } else {
|
|
+ NBTTagCompound nbttagcompound = itemstack.a("DebugProperty");
|
|
+ String s1 = nbttagcompound.getString(s);
|
|
+ IBlockState<?> iblockstate = blockstatelist.a(s1);
|
|
+
|
|
+ if (flag) {
|
|
+ if (iblockstate == null) {
|
|
+ iblockstate = (IBlockState) collection.iterator().next();
|
|
+ }
|
|
+
|
|
+ IBlockData iblockdata1 = a(iblockdata, iblockstate, entityhuman.isSneaking());
|
|
+
|
|
+ generatoraccess.setTypeAndData(blockposition, iblockdata1, 18);
|
|
+ a(entityhuman, (IChatBaseComponent) (new ChatMessage(this.getName() + ".update", new Object[]{iblockstate.a(), a(iblockdata1, iblockstate)})));
|
|
+ } else {
|
|
+ iblockstate = (IBlockState) a((Iterable) collection, (Object) iblockstate, entityhuman.isSneaking());
|
|
+ String s2 = iblockstate.a();
|
|
+
|
|
+ nbttagcompound.setString(s, s2);
|
|
+ a(entityhuman, (IChatBaseComponent) (new ChatMessage(this.getName() + ".select", new Object[]{s2, a(iblockdata, iblockstate)})));
|
|
+ }
|
|
+
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static <T extends Comparable<T>> IBlockData a(IBlockData iblockdata, IBlockState<T> iblockstate, boolean flag) {
|
|
+ return (IBlockData) iblockdata.set(iblockstate, a(iblockstate.getValues(), iblockdata.get(iblockstate), flag));
|
|
+ }
|
|
+
|
|
+ private static <T> T a(Iterable<T> iterable, @Nullable T t0, boolean flag) {
|
|
+ return flag ? SystemUtils.b(iterable, t0) : SystemUtils.a(iterable, t0);
|
|
+ }
|
|
+
|
|
+ private static void a(EntityHuman entityhuman, IChatBaseComponent ichatbasecomponent) {
|
|
+ ((EntityPlayer) entityhuman).a(ichatbasecomponent, ChatMessageType.GAME_INFO);
|
|
+ }
|
|
+
|
|
+ private static <T extends Comparable<T>> String a(IBlockData iblockdata, IBlockState<T> iblockstate) {
|
|
+ return iblockstate.a(iblockdata.get(iblockstate));
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java b/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java
|
|
new file mode 100644
|
|
index 000000000..ad06a856f
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java
|
|
@@ -0,0 +1,119 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.io.BufferedInputStream;
|
|
+import java.io.BufferedOutputStream;
|
|
+import java.io.DataInput;
|
|
+import java.io.DataInputStream;
|
|
+import java.io.DataOutput;
|
|
+import java.io.DataOutputStream;
|
|
+import java.io.IOException;
|
|
+import java.io.InputStream;
|
|
+import java.io.OutputStream;
|
|
+import java.util.zip.GZIPInputStream;
|
|
+import java.util.zip.GZIPOutputStream;
|
|
+
|
|
+public class NBTCompressedStreamTools {
|
|
+
|
|
+ public static NBTTagCompound a(InputStream inputstream) throws IOException {
|
|
+ DataInputStream datainputstream = new DataInputStream(new BufferedInputStream(new GZIPInputStream(inputstream)));
|
|
+ Throwable throwable = null;
|
|
+
|
|
+ NBTTagCompound nbttagcompound;
|
|
+
|
|
+ try {
|
|
+ nbttagcompound = a((DataInput) datainputstream, NBTReadLimiter.a);
|
|
+ } catch (Throwable throwable1) {
|
|
+ throwable = throwable1;
|
|
+ throw throwable1;
|
|
+ } finally {
|
|
+ if (datainputstream != null) {
|
|
+ if (throwable != null) {
|
|
+ try {
|
|
+ datainputstream.close();
|
|
+ } catch (Throwable throwable2) {
|
|
+ throwable.addSuppressed(throwable2);
|
|
+ }
|
|
+ } else {
|
|
+ datainputstream.close();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ return nbttagcompound;
|
|
+ }
|
|
+
|
|
+ public static void a(NBTTagCompound nbttagcompound, OutputStream outputstream) throws IOException {
|
|
+ DataOutputStream dataoutputstream = new DataOutputStream(new BufferedOutputStream(new GZIPOutputStream(outputstream)));
|
|
+ Throwable throwable = null;
|
|
+
|
|
+ try {
|
|
+ a(nbttagcompound, (DataOutput) dataoutputstream);
|
|
+ } catch (Throwable throwable1) {
|
|
+ throwable = throwable1;
|
|
+ throw throwable1;
|
|
+ } finally {
|
|
+ if (dataoutputstream != null) {
|
|
+ if (throwable != null) {
|
|
+ try {
|
|
+ dataoutputstream.close();
|
|
+ } catch (Throwable throwable2) {
|
|
+ throwable.addSuppressed(throwable2);
|
|
+ }
|
|
+ } else {
|
|
+ dataoutputstream.close();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ public static NBTTagCompound a(DataInputStream datainputstream) throws IOException {
|
|
+ return a((DataInput) datainputstream, NBTReadLimiter.a);
|
|
+ }
|
|
+
|
|
+ public static NBTTagCompound a(DataInput datainput, NBTReadLimiter nbtreadlimiter) throws IOException {
|
|
+ NBTBase nbtbase = a(datainput, 0, nbtreadlimiter);
|
|
+
|
|
+ if (nbtbase instanceof NBTTagCompound) {
|
|
+ return (NBTTagCompound) nbtbase;
|
|
+ } else {
|
|
+ throw new IOException("Root tag must be a named compound tag");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static void a(NBTTagCompound nbttagcompound, DataOutput dataoutput) throws IOException {
|
|
+ a((NBTBase) nbttagcompound, dataoutput);
|
|
+ }
|
|
+
|
|
+ private static void a(NBTBase nbtbase, DataOutput dataoutput) throws IOException {
|
|
+ dataoutput.writeByte(nbtbase.getTypeId());
|
|
+ if (nbtbase.getTypeId() != 0) {
|
|
+ dataoutput.writeUTF("");
|
|
+ nbtbase.write(dataoutput);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static NBTBase a(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException {
|
|
+ byte b0 = datainput.readByte();
|
|
+
|
|
+ if (b0 == 0) {
|
|
+ return new NBTTagEnd();
|
|
+ } else {
|
|
+ datainput.readUTF();
|
|
+ NBTBase nbtbase = NBTBase.createTag(b0);
|
|
+
|
|
+ try {
|
|
+ nbtbase.load(datainput, i, nbtreadlimiter);
|
|
+ return nbtbase;
|
|
+ } catch (IOException ioexception) {
|
|
+ CrashReport crashreport = CrashReport.a(ioexception, "Loading NBT data");
|
|
+ CrashReportSystemDetails crashreportsystemdetails = crashreport.a("NBT Tag");
|
|
+
|
|
+ crashreportsystemdetails.a("Tag type", (Object) b0);
|
|
+ throw new ReportedException(crashreport);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/NBTTagByteArray.java b/src/main/java/net/minecraft/server/NBTTagByteArray.java
|
|
new file mode 100644
|
|
index 000000000..cd5314121
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/NBTTagByteArray.java
|
|
@@ -0,0 +1,160 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.io.DataInput;
|
|
+import java.io.DataOutput;
|
|
+import java.io.IOException;
|
|
+import java.util.Arrays;
|
|
+import java.util.List;
|
|
+import org.apache.commons.lang3.ArrayUtils;
|
|
+
|
|
+public class NBTTagByteArray extends NBTList<NBTTagByte> {
|
|
+
|
|
+ private byte[] data;
|
|
+
|
|
+ NBTTagByteArray() {}
|
|
+
|
|
+ public NBTTagByteArray(byte[] abyte) {
|
|
+ this.data = abyte;
|
|
+ }
|
|
+
|
|
+ public NBTTagByteArray(List<Byte> list) {
|
|
+ this(a(list));
|
|
+ }
|
|
+
|
|
+ private static byte[] a(List<Byte> list) {
|
|
+ byte[] abyte = new byte[list.size()];
|
|
+
|
|
+ for (int i = 0; i < list.size(); ++i) {
|
|
+ Byte obyte = (Byte) list.get(i);
|
|
+
|
|
+ abyte[i] = obyte == null ? 0 : obyte;
|
|
+ }
|
|
+
|
|
+ return abyte;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void write(DataOutput dataoutput) throws IOException {
|
|
+ dataoutput.writeInt(this.data.length);
|
|
+ dataoutput.write(this.data);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException {
|
|
+ nbtreadlimiter.a(192L);
|
|
+ int j = datainput.readInt();
|
|
+
|
|
+ nbtreadlimiter.a((long) (8 * j));
|
|
+ this.data = new byte[j];
|
|
+ datainput.readFully(this.data);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public byte getTypeId() {
|
|
+ return 7;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String toString() {
|
|
+ StringBuilder stringbuilder = new StringBuilder("[B;");
|
|
+
|
|
+ for (int i = 0; i < this.data.length; ++i) {
|
|
+ if (i != 0) {
|
|
+ stringbuilder.append(',');
|
|
+ }
|
|
+
|
|
+ stringbuilder.append(this.data[i]).append('B');
|
|
+ }
|
|
+
|
|
+ return stringbuilder.append(']').toString();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public NBTBase clone() {
|
|
+ byte[] abyte = new byte[this.data.length];
|
|
+
|
|
+ System.arraycopy(this.data, 0, abyte, 0, this.data.length);
|
|
+ return new NBTTagByteArray(abyte);
|
|
+ }
|
|
+
|
|
+ public boolean equals(Object object) {
|
|
+ return this == object ? true : object instanceof NBTTagByteArray && Arrays.equals(this.data, ((NBTTagByteArray) object).data);
|
|
+ }
|
|
+
|
|
+ public int hashCode() {
|
|
+ return Arrays.hashCode(this.data);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public IChatBaseComponent a(String s, int i) {
|
|
+ IChatBaseComponent ichatbasecomponent = (new ChatComponentText("B")).a(NBTTagByteArray.e);
|
|
+ IChatBaseComponent ichatbasecomponent1 = (new ChatComponentText("[")).addSibling(ichatbasecomponent).a(";");
|
|
+
|
|
+ for (int j = 0; j < this.data.length; ++j) {
|
|
+ IChatBaseComponent ichatbasecomponent2 = (new ChatComponentText(String.valueOf(this.data[j]))).a(NBTTagByteArray.d);
|
|
+
|
|
+ ichatbasecomponent1.a(" ").addSibling(ichatbasecomponent2).addSibling(ichatbasecomponent);
|
|
+ if (j != this.data.length - 1) {
|
|
+ ichatbasecomponent1.a(",");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ichatbasecomponent1.a("]");
|
|
+ return ichatbasecomponent1;
|
|
+ }
|
|
+
|
|
+ public byte[] getBytes() {
|
|
+ return this.data;
|
|
+ }
|
|
+
|
|
+ public int size() {
|
|
+ return this.data.length;
|
|
+ }
|
|
+
|
|
+ public NBTTagByte get(int i) {
|
|
+ return new NBTTagByte(this.data[i]);
|
|
+ }
|
|
+
|
|
+ public NBTTagByte set(int i, NBTTagByte nbttagbyte) {
|
|
+ byte b0 = this.data[i];
|
|
+
|
|
+ this.data[i] = nbttagbyte.asByte();
|
|
+ return new NBTTagByte(b0);
|
|
+ }
|
|
+
|
|
+ public void add(int i, NBTTagByte nbttagbyte) {
|
|
+ this.data = ArrayUtils.add(this.data, i, nbttagbyte.asByte());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean a(int i, NBTBase nbtbase) {
|
|
+ if (nbtbase instanceof NBTNumber) {
|
|
+ this.data[i] = ((NBTNumber) nbtbase).asByte();
|
|
+ return true;
|
|
+ } else {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean b(int i, NBTBase nbtbase) {
|
|
+ if (nbtbase instanceof NBTNumber) {
|
|
+ this.data = ArrayUtils.add(this.data, i, ((NBTNumber) nbtbase).asByte());
|
|
+ return true;
|
|
+ } else {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public NBTTagByte remove(int i) {
|
|
+ byte b0 = this.data[i];
|
|
+
|
|
+ this.data = ArrayUtils.remove(this.data, i);
|
|
+ return new NBTTagByte(b0);
|
|
+ }
|
|
+
|
|
+ public void clear() {
|
|
+ this.data = new byte[0];
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/NBTTagIntArray.java b/src/main/java/net/minecraft/server/NBTTagIntArray.java
|
|
new file mode 100644
|
|
index 000000000..36a9edd2e
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/NBTTagIntArray.java
|
|
@@ -0,0 +1,170 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.io.DataInput;
|
|
+import java.io.DataOutput;
|
|
+import java.io.IOException;
|
|
+import java.util.Arrays;
|
|
+import java.util.List;
|
|
+import org.apache.commons.lang3.ArrayUtils;
|
|
+
|
|
+public class NBTTagIntArray extends NBTList<NBTTagInt> {
|
|
+
|
|
+ private int[] data;
|
|
+
|
|
+ NBTTagIntArray() {}
|
|
+
|
|
+ public NBTTagIntArray(int[] aint) {
|
|
+ this.data = aint;
|
|
+ }
|
|
+
|
|
+ public NBTTagIntArray(List<Integer> list) {
|
|
+ this(a(list));
|
|
+ }
|
|
+
|
|
+ private static int[] a(List<Integer> list) {
|
|
+ int[] aint = new int[list.size()];
|
|
+
|
|
+ for (int i = 0; i < list.size(); ++i) {
|
|
+ Integer integer = (Integer) list.get(i);
|
|
+
|
|
+ aint[i] = integer == null ? 0 : integer;
|
|
+ }
|
|
+
|
|
+ return aint;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void write(DataOutput dataoutput) throws IOException {
|
|
+ dataoutput.writeInt(this.data.length);
|
|
+ int[] aint = this.data;
|
|
+ int i = aint.length;
|
|
+
|
|
+ for (int j = 0; j < i; ++j) {
|
|
+ int k = aint[j];
|
|
+
|
|
+ dataoutput.writeInt(k);
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException {
|
|
+ nbtreadlimiter.a(192L);
|
|
+ int j = datainput.readInt();
|
|
+
|
|
+ nbtreadlimiter.a((long) (32 * j));
|
|
+ this.data = new int[j];
|
|
+
|
|
+ for (int k = 0; k < j; ++k) {
|
|
+ this.data[k] = datainput.readInt();
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public byte getTypeId() {
|
|
+ return 11;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String toString() {
|
|
+ StringBuilder stringbuilder = new StringBuilder("[I;");
|
|
+
|
|
+ for (int i = 0; i < this.data.length; ++i) {
|
|
+ if (i != 0) {
|
|
+ stringbuilder.append(',');
|
|
+ }
|
|
+
|
|
+ stringbuilder.append(this.data[i]);
|
|
+ }
|
|
+
|
|
+ return stringbuilder.append(']').toString();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public NBTTagIntArray clone() {
|
|
+ int[] aint = new int[this.data.length];
|
|
+
|
|
+ System.arraycopy(this.data, 0, aint, 0, this.data.length);
|
|
+ return new NBTTagIntArray(aint);
|
|
+ }
|
|
+
|
|
+ public boolean equals(Object object) {
|
|
+ return this == object ? true : object instanceof NBTTagIntArray && Arrays.equals(this.data, ((NBTTagIntArray) object).data);
|
|
+ }
|
|
+
|
|
+ public int hashCode() {
|
|
+ return Arrays.hashCode(this.data);
|
|
+ }
|
|
+
|
|
+ public int[] getInts() {
|
|
+ return this.data;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public IChatBaseComponent a(String s, int i) {
|
|
+ IChatBaseComponent ichatbasecomponent = (new ChatComponentText("I")).a(NBTTagIntArray.e);
|
|
+ IChatBaseComponent ichatbasecomponent1 = (new ChatComponentText("[")).addSibling(ichatbasecomponent).a(";");
|
|
+
|
|
+ for (int j = 0; j < this.data.length; ++j) {
|
|
+ ichatbasecomponent1.a(" ").addSibling((new ChatComponentText(String.valueOf(this.data[j]))).a(NBTTagIntArray.d));
|
|
+ if (j != this.data.length - 1) {
|
|
+ ichatbasecomponent1.a(",");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ichatbasecomponent1.a("]");
|
|
+ return ichatbasecomponent1;
|
|
+ }
|
|
+
|
|
+ public int size() {
|
|
+ return this.data.length;
|
|
+ }
|
|
+
|
|
+ public NBTTagInt get(int i) {
|
|
+ return new NBTTagInt(this.data[i]);
|
|
+ }
|
|
+
|
|
+ public NBTTagInt set(int i, NBTTagInt nbttagint) {
|
|
+ int j = this.data[i];
|
|
+
|
|
+ this.data[i] = nbttagint.asInt();
|
|
+ return new NBTTagInt(j);
|
|
+ }
|
|
+
|
|
+ public void add(int i, NBTTagInt nbttagint) {
|
|
+ this.data = ArrayUtils.add(this.data, i, nbttagint.asInt());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean a(int i, NBTBase nbtbase) {
|
|
+ if (nbtbase instanceof NBTNumber) {
|
|
+ this.data[i] = ((NBTNumber) nbtbase).asInt();
|
|
+ return true;
|
|
+ } else {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean b(int i, NBTBase nbtbase) {
|
|
+ if (nbtbase instanceof NBTNumber) {
|
|
+ this.data = ArrayUtils.add(this.data, i, ((NBTNumber) nbtbase).asInt());
|
|
+ return true;
|
|
+ } else {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public NBTTagInt remove(int i) {
|
|
+ int j = this.data[i];
|
|
+
|
|
+ this.data = ArrayUtils.remove(this.data, i);
|
|
+ return new NBTTagInt(j);
|
|
+ }
|
|
+
|
|
+ public void clear() {
|
|
+ this.data = new int[0];
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/NibbleArray.java b/src/main/java/net/minecraft/server/NibbleArray.java
|
|
new file mode 100644
|
|
index 000000000..89f2beb4b
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/NibbleArray.java
|
|
@@ -0,0 +1,100 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import javax.annotation.Nullable;
|
|
+
|
|
+public class NibbleArray {
|
|
+
|
|
+ @Nullable
|
|
+ protected byte[] a;
|
|
+
|
|
+ public NibbleArray() {}
|
|
+
|
|
+ public NibbleArray(byte[] abyte) {
|
|
+ this.a = abyte;
|
|
+ if (abyte.length != 2048) {
|
|
+ throw new IllegalArgumentException("ChunkNibbleArrays should be 2048 bytes not: " + abyte.length);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ protected NibbleArray(int i) {
|
|
+ this.a = new byte[i];
|
|
+ }
|
|
+
|
|
+ public int a(int i, int j, int k) {
|
|
+ return this.b(this.b(i, j, k));
|
|
+ }
|
|
+
|
|
+ public void a(int i, int j, int k, int l) {
|
|
+ this.a(this.b(i, j, k), l);
|
|
+ }
|
|
+
|
|
+ protected int b(int i, int j, int k) {
|
|
+ return j << 8 | k << 4 | i;
|
|
+ }
|
|
+
|
|
+ private int b(int i) {
|
|
+ if (this.a == null) {
|
|
+ return 0;
|
|
+ } else {
|
|
+ int j = this.d(i);
|
|
+
|
|
+ return this.c(i) ? this.a[j] & 15 : this.a[j] >> 4 & 15;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void a(int i, int j) {
|
|
+ if (this.a == null) {
|
|
+ this.a = new byte[2048];
|
|
+ }
|
|
+
|
|
+ int k = this.d(i);
|
|
+
|
|
+ if (this.c(i)) {
|
|
+ this.a[k] = (byte) (this.a[k] & 240 | j & 15);
|
|
+ } else {
|
|
+ this.a[k] = (byte) (this.a[k] & 15 | (j & 15) << 4);
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ private boolean c(int i) {
|
|
+ return (i & 1) == 0;
|
|
+ }
|
|
+
|
|
+ private int d(int i) {
|
|
+ return i >> 1;
|
|
+ }
|
|
+
|
|
+ public byte[] asBytes() {
|
|
+ if (this.a == null) {
|
|
+ this.a = new byte[2048];
|
|
+ }
|
|
+
|
|
+ return this.a;
|
|
+ }
|
|
+
|
|
+ public NibbleArray b() {
|
|
+ return this.a == null ? new NibbleArray() : new NibbleArray((byte[]) this.a.clone());
|
|
+ }
|
|
+
|
|
+ public String toString() {
|
|
+ StringBuilder stringbuilder = new StringBuilder();
|
|
+
|
|
+ for (int i = 0; i < 4096; ++i) {
|
|
+ stringbuilder.append(Integer.toHexString(this.b(i)));
|
|
+ if ((i & 15) == 15) {
|
|
+ stringbuilder.append("\n");
|
|
+ }
|
|
+
|
|
+ if ((i & 255) == 255) {
|
|
+ stringbuilder.append("\n");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return stringbuilder.toString();
|
|
+ }
|
|
+
|
|
+ public boolean c() {
|
|
+ return this.a == null;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java b/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java
|
|
new file mode 100644
|
|
index 000000000..6aeea22ae
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java
|
|
@@ -0,0 +1,41 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.io.IOException;
|
|
+
|
|
+public class PacketHandshakingInSetProtocol implements Packet<PacketHandshakingInListener> {
|
|
+
|
|
+ private int a;
|
|
+ public String hostname;
|
|
+ public int port;
|
|
+ private EnumProtocol d;
|
|
+
|
|
+ public PacketHandshakingInSetProtocol() {}
|
|
+
|
|
+ @Override
|
|
+ public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
|
+ this.a = packetdataserializer.i();
|
|
+ this.hostname = packetdataserializer.e(255);
|
|
+ this.port = packetdataserializer.readUnsignedShort();
|
|
+ this.d = EnumProtocol.a(packetdataserializer.i());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void b(PacketDataSerializer packetdataserializer) throws IOException {
|
|
+ packetdataserializer.d(this.a);
|
|
+ packetdataserializer.a(this.hostname);
|
|
+ packetdataserializer.writeShort(this.port);
|
|
+ packetdataserializer.d(this.d.a());
|
|
+ }
|
|
+
|
|
+ public void a(PacketHandshakingInListener packethandshakinginlistener) {
|
|
+ packethandshakinginlistener.a(this);
|
|
+ }
|
|
+
|
|
+ public EnumProtocol b() {
|
|
+ return this.d;
|
|
+ }
|
|
+
|
|
+ public int c() {
|
|
+ return this.a;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/PacketPlayInBlockPlace.java b/src/main/java/net/minecraft/server/PacketPlayInBlockPlace.java
|
|
new file mode 100644
|
|
index 000000000..bb88f7c1a
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/PacketPlayInBlockPlace.java
|
|
@@ -0,0 +1,32 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.io.IOException;
|
|
+
|
|
+public class PacketPlayInBlockPlace implements Packet<PacketListenerPlayIn> {
|
|
+
|
|
+ private EnumHand a;
|
|
+
|
|
+ public PacketPlayInBlockPlace() {}
|
|
+
|
|
+ public PacketPlayInBlockPlace(EnumHand enumhand) {
|
|
+ this.a = enumhand;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
|
+ this.a = (EnumHand) packetdataserializer.a(EnumHand.class);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void b(PacketDataSerializer packetdataserializer) throws IOException {
|
|
+ packetdataserializer.a((Enum) this.a);
|
|
+ }
|
|
+
|
|
+ public void a(PacketListenerPlayIn packetlistenerplayin) {
|
|
+ packetlistenerplayin.a(this);
|
|
+ }
|
|
+
|
|
+ public EnumHand b() {
|
|
+ return this.a;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/PacketPlayInChat.java b/src/main/java/net/minecraft/server/PacketPlayInChat.java
|
|
new file mode 100644
|
|
index 000000000..699815b3d
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/PacketPlayInChat.java
|
|
@@ -0,0 +1,36 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.io.IOException;
|
|
+
|
|
+public class PacketPlayInChat implements Packet<PacketListenerPlayIn> {
|
|
+
|
|
+ private String a;
|
|
+
|
|
+ public PacketPlayInChat() {}
|
|
+
|
|
+ public PacketPlayInChat(String s) {
|
|
+ if (s.length() > 256) {
|
|
+ s = s.substring(0, 256);
|
|
+ }
|
|
+
|
|
+ this.a = s;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
|
+ this.a = packetdataserializer.e(256);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void b(PacketDataSerializer packetdataserializer) throws IOException {
|
|
+ packetdataserializer.a(this.a);
|
|
+ }
|
|
+
|
|
+ public void a(PacketListenerPlayIn packetlistenerplayin) {
|
|
+ packetlistenerplayin.a(this);
|
|
+ }
|
|
+
|
|
+ public String b() {
|
|
+ return this.a;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/PacketPlayInUseItem.java b/src/main/java/net/minecraft/server/PacketPlayInUseItem.java
|
|
new file mode 100644
|
|
index 000000000..2f8160ed1
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/PacketPlayInUseItem.java
|
|
@@ -0,0 +1,35 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.io.IOException;
|
|
+
|
|
+public class PacketPlayInUseItem implements Packet<PacketListenerPlayIn> {
|
|
+
|
|
+ private MovingObjectPositionBlock a;
|
|
+ private EnumHand b;
|
|
+
|
|
+ public PacketPlayInUseItem() {}
|
|
+
|
|
+ @Override
|
|
+ public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
|
+ this.b = (EnumHand) packetdataserializer.a(EnumHand.class);
|
|
+ this.a = packetdataserializer.q();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void b(PacketDataSerializer packetdataserializer) throws IOException {
|
|
+ packetdataserializer.a((Enum) this.b);
|
|
+ packetdataserializer.a(this.a);
|
|
+ }
|
|
+
|
|
+ public void a(PacketListenerPlayIn packetlistenerplayin) {
|
|
+ packetlistenerplayin.a(this);
|
|
+ }
|
|
+
|
|
+ public EnumHand b() {
|
|
+ return this.b;
|
|
+ }
|
|
+
|
|
+ public MovingObjectPositionBlock c() {
|
|
+ return this.a;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/PacketPlayOutChat.java b/src/main/java/net/minecraft/server/PacketPlayOutChat.java
|
|
new file mode 100644
|
|
index 000000000..417c26775
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/PacketPlayOutChat.java
|
|
@@ -0,0 +1,49 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.io.IOException;
|
|
+
|
|
+public class PacketPlayOutChat implements Packet<PacketListenerPlayOut> {
|
|
+
|
|
+ private IChatBaseComponent a;
|
|
+ private ChatMessageType b;
|
|
+
|
|
+ public PacketPlayOutChat() {}
|
|
+
|
|
+ public PacketPlayOutChat(IChatBaseComponent ichatbasecomponent) {
|
|
+ this(ichatbasecomponent, ChatMessageType.SYSTEM);
|
|
+ }
|
|
+
|
|
+ public PacketPlayOutChat(IChatBaseComponent ichatbasecomponent, ChatMessageType chatmessagetype) {
|
|
+ this.a = ichatbasecomponent;
|
|
+ this.b = chatmessagetype;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
|
+ this.a = packetdataserializer.h();
|
|
+ this.b = ChatMessageType.a(packetdataserializer.readByte());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void b(PacketDataSerializer packetdataserializer) throws IOException {
|
|
+ packetdataserializer.a(this.a);
|
|
+ packetdataserializer.writeByte(this.b.a());
|
|
+ }
|
|
+
|
|
+ public void a(PacketListenerPlayOut packetlistenerplayout) {
|
|
+ packetlistenerplayout.a(this);
|
|
+ }
|
|
+
|
|
+ public boolean c() {
|
|
+ return this.b == ChatMessageType.SYSTEM || this.b == ChatMessageType.GAME_INFO;
|
|
+ }
|
|
+
|
|
+ public ChatMessageType d() {
|
|
+ return this.b;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean a() {
|
|
+ return true;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java
|
|
new file mode 100644
|
|
index 000000000..abb6fcd0e
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/RegionFile.java
|
|
@@ -0,0 +1,271 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.google.common.collect.Lists;
|
|
+import java.io.BufferedInputStream;
|
|
+import java.io.BufferedOutputStream;
|
|
+import java.io.ByteArrayInputStream;
|
|
+import java.io.ByteArrayOutputStream;
|
|
+import java.io.DataInputStream;
|
|
+import java.io.DataOutputStream;
|
|
+import java.io.File;
|
|
+import java.io.IOException;
|
|
+import java.io.RandomAccessFile;
|
|
+import java.util.List;
|
|
+import java.util.zip.DeflaterOutputStream;
|
|
+import java.util.zip.GZIPInputStream;
|
|
+import java.util.zip.InflaterInputStream;
|
|
+import javax.annotation.Nullable;
|
|
+
|
|
+public class RegionFile implements AutoCloseable {
|
|
+
|
|
+ private static final byte[] a = new byte[4096];
|
|
+ private final RandomAccessFile b;
|
|
+ private final int[] c = new int[1024];
|
|
+ private final int[] d = new int[1024];
|
|
+ private final List<Boolean> e;
|
|
+
|
|
+ public RegionFile(File file) throws IOException {
|
|
+ this.b = new RandomAccessFile(file, "rw");
|
|
+ if (this.b.length() < 4096L) {
|
|
+ this.b.write(RegionFile.a);
|
|
+ this.b.write(RegionFile.a);
|
|
+ }
|
|
+
|
|
+ int i;
|
|
+
|
|
+ if ((this.b.length() & 4095L) != 0L) {
|
|
+ for (i = 0; (long) i < (this.b.length() & 4095L); ++i) {
|
|
+ this.b.write(0);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ i = (int) this.b.length() / 4096;
|
|
+ this.e = Lists.newArrayListWithCapacity(i);
|
|
+
|
|
+ int j;
|
|
+
|
|
+ for (j = 0; j < i; ++j) {
|
|
+ this.e.add(true);
|
|
+ }
|
|
+
|
|
+ this.e.set(0, false);
|
|
+ this.e.set(1, false);
|
|
+ this.b.seek(0L);
|
|
+
|
|
+ int k;
|
|
+
|
|
+ for (j = 0; j < 1024; ++j) {
|
|
+ k = this.b.readInt();
|
|
+ this.c[j] = k;
|
|
+ if (k != 0 && (k >> 8) + (k & 255) <= this.e.size()) {
|
|
+ for (int l = 0; l < (k & 255); ++l) {
|
|
+ this.e.set((k >> 8) + l, false);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ for (j = 0; j < 1024; ++j) {
|
|
+ k = this.b.readInt();
|
|
+ this.d[j] = k;
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ @Nullable
|
|
+ public synchronized DataInputStream a(ChunkCoordIntPair chunkcoordintpair) {
|
|
+ try {
|
|
+ int i = this.getOffset(chunkcoordintpair);
|
|
+
|
|
+ if (i == 0) {
|
|
+ return null;
|
|
+ } else {
|
|
+ int j = i >> 8;
|
|
+ int k = i & 255;
|
|
+
|
|
+ if (j + k > this.e.size()) {
|
|
+ return null;
|
|
+ } else {
|
|
+ this.b.seek((long) (j * 4096));
|
|
+ int l = this.b.readInt();
|
|
+
|
|
+ if (l > 4096 * k) {
|
|
+ return null;
|
|
+ } else if (l <= 0) {
|
|
+ return null;
|
|
+ } else {
|
|
+ byte b0 = this.b.readByte();
|
|
+ byte[] abyte;
|
|
+
|
|
+ if (b0 == 1) {
|
|
+ abyte = new byte[l - 1];
|
|
+ this.b.read(abyte);
|
|
+ return new DataInputStream(new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(abyte))));
|
|
+ } else if (b0 == 2) {
|
|
+ abyte = new byte[l - 1];
|
|
+ this.b.read(abyte);
|
|
+ return new DataInputStream(new BufferedInputStream(new InflaterInputStream(new ByteArrayInputStream(abyte))));
|
|
+ } else {
|
|
+ return null;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ } catch (IOException ioexception) {
|
|
+ return null;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public boolean b(ChunkCoordIntPair chunkcoordintpair) {
|
|
+ int i = this.getOffset(chunkcoordintpair);
|
|
+
|
|
+ if (i == 0) {
|
|
+ return false;
|
|
+ } else {
|
|
+ int j = i >> 8;
|
|
+ int k = i & 255;
|
|
+
|
|
+ if (j + k > this.e.size()) {
|
|
+ return false;
|
|
+ } else {
|
|
+ try {
|
|
+ this.b.seek((long) (j * 4096));
|
|
+ int l = this.b.readInt();
|
|
+
|
|
+ return l > 4096 * k ? false : l > 0;
|
|
+ } catch (IOException ioexception) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public DataOutputStream c(ChunkCoordIntPair chunkcoordintpair) {
|
|
+ return new DataOutputStream(new BufferedOutputStream(new DeflaterOutputStream(new RegionFile.ChunkBuffer(chunkcoordintpair))));
|
|
+ }
|
|
+
|
|
+ protected synchronized void a(ChunkCoordIntPair chunkcoordintpair, byte[] abyte, int i) {
|
|
+ try {
|
|
+ int j = this.getOffset(chunkcoordintpair);
|
|
+ int k = j >> 8;
|
|
+ int l = j & 255;
|
|
+ int i1 = (i + 5) / 4096 + 1;
|
|
+
|
|
+ if (i1 >= 256) {
|
|
+ throw new RuntimeException(String.format("Too big to save, %d > 1048576", i));
|
|
+ }
|
|
+
|
|
+ if (k != 0 && l == i1) {
|
|
+ this.a(k, abyte, i);
|
|
+ } else {
|
|
+ int j1;
|
|
+
|
|
+ for (j1 = 0; j1 < l; ++j1) {
|
|
+ this.e.set(k + j1, true);
|
|
+ }
|
|
+
|
|
+ j1 = this.e.indexOf(true);
|
|
+ int k1 = 0;
|
|
+ int l1;
|
|
+
|
|
+ if (j1 != -1) {
|
|
+ for (l1 = j1; l1 < this.e.size(); ++l1) {
|
|
+ if (k1 != 0) {
|
|
+ if ((Boolean) this.e.get(l1)) {
|
|
+ ++k1;
|
|
+ } else {
|
|
+ k1 = 0;
|
|
+ }
|
|
+ } else if ((Boolean) this.e.get(l1)) {
|
|
+ j1 = l1;
|
|
+ k1 = 1;
|
|
+ }
|
|
+
|
|
+ if (k1 >= i1) {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (k1 >= i1) {
|
|
+ k = j1;
|
|
+ this.a(chunkcoordintpair, j1 << 8 | i1);
|
|
+
|
|
+ for (l1 = 0; l1 < i1; ++l1) {
|
|
+ this.e.set(k + l1, false);
|
|
+ }
|
|
+
|
|
+ this.a(k, abyte, i);
|
|
+ } else {
|
|
+ this.b.seek(this.b.length());
|
|
+ k = this.e.size();
|
|
+
|
|
+ for (l1 = 0; l1 < i1; ++l1) {
|
|
+ this.b.write(RegionFile.a);
|
|
+ this.e.add(false);
|
|
+ }
|
|
+
|
|
+ this.a(k, abyte, i);
|
|
+ this.a(chunkcoordintpair, k << 8 | i1);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ this.b(chunkcoordintpair, (int) (SystemUtils.getTimeMillis() / 1000L));
|
|
+ } catch (IOException ioexception) {
|
|
+ ioexception.printStackTrace();
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ private void a(int i, byte[] abyte, int j) throws IOException {
|
|
+ this.b.seek((long) (i * 4096));
|
|
+ this.b.writeInt(j + 1);
|
|
+ this.b.writeByte(2);
|
|
+ this.b.write(abyte, 0, j);
|
|
+ }
|
|
+
|
|
+ private int getOffset(ChunkCoordIntPair chunkcoordintpair) {
|
|
+ return this.c[this.f(chunkcoordintpair)];
|
|
+ }
|
|
+
|
|
+ public boolean d(ChunkCoordIntPair chunkcoordintpair) {
|
|
+ return this.getOffset(chunkcoordintpair) != 0;
|
|
+ }
|
|
+
|
|
+ private void a(ChunkCoordIntPair chunkcoordintpair, int i) throws IOException {
|
|
+ int j = this.f(chunkcoordintpair);
|
|
+
|
|
+ this.c[j] = i;
|
|
+ this.b.seek((long) (j * 4));
|
|
+ this.b.writeInt(i);
|
|
+ }
|
|
+
|
|
+ private int f(ChunkCoordIntPair chunkcoordintpair) {
|
|
+ return chunkcoordintpair.j() + chunkcoordintpair.k() * 32;
|
|
+ }
|
|
+
|
|
+ private void b(ChunkCoordIntPair chunkcoordintpair, int i) throws IOException {
|
|
+ int j = this.f(chunkcoordintpair);
|
|
+
|
|
+ this.d[j] = i;
|
|
+ this.b.seek((long) (4096 + j * 4));
|
|
+ this.b.writeInt(i);
|
|
+ }
|
|
+
|
|
+ public void close() throws IOException {
|
|
+ this.b.close();
|
|
+ }
|
|
+
|
|
+ class ChunkBuffer extends ByteArrayOutputStream {
|
|
+
|
|
+ private final ChunkCoordIntPair b;
|
|
+
|
|
+ public ChunkBuffer(ChunkCoordIntPair chunkcoordintpair) {
|
|
+ super(8096);
|
|
+ this.b = chunkcoordintpair;
|
|
+ }
|
|
+
|
|
+ public void close() {
|
|
+ RegionFile.this.a(this.b, this.buf, this.count);
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/ServerConnection.java b/src/main/java/net/minecraft/server/ServerConnection.java
|
|
new file mode 100644
|
|
index 000000000..db3485d63
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/ServerConnection.java
|
|
@@ -0,0 +1,143 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.google.common.collect.Lists;
|
|
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
|
+import io.netty.bootstrap.ServerBootstrap;
|
|
+import io.netty.channel.Channel;
|
|
+import io.netty.channel.ChannelException;
|
|
+import io.netty.channel.ChannelFuture;
|
|
+import io.netty.channel.ChannelInitializer;
|
|
+import io.netty.channel.ChannelOption;
|
|
+import io.netty.channel.EventLoopGroup;
|
|
+import io.netty.channel.epoll.Epoll;
|
|
+import io.netty.channel.epoll.EpollEventLoopGroup;
|
|
+import io.netty.channel.epoll.EpollServerSocketChannel;
|
|
+import io.netty.channel.nio.NioEventLoopGroup;
|
|
+import io.netty.channel.socket.ServerSocketChannel;
|
|
+import io.netty.channel.socket.nio.NioServerSocketChannel;
|
|
+import io.netty.handler.timeout.ReadTimeoutHandler;
|
|
+import io.netty.util.concurrent.Future;
|
|
+import java.io.IOException;
|
|
+import java.net.InetAddress;
|
|
+import java.util.Collections;
|
|
+import java.util.Iterator;
|
|
+import java.util.List;
|
|
+import javax.annotation.Nullable;
|
|
+import org.apache.logging.log4j.LogManager;
|
|
+import org.apache.logging.log4j.Logger;
|
|
+
|
|
+public class ServerConnection {
|
|
+
|
|
+ private static final Logger LOGGER = LogManager.getLogger();
|
|
+ public static final LazyInitVar<NioEventLoopGroup> a = new LazyInitVar<>(() -> {
|
|
+ return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Server IO #%d").setDaemon(true).build());
|
|
+ });
|
|
+ public static final LazyInitVar<EpollEventLoopGroup> b = new LazyInitVar<>(() -> {
|
|
+ return new EpollEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Epoll Server IO #%d").setDaemon(true).build());
|
|
+ });
|
|
+ private final MinecraftServer e;
|
|
+ public volatile boolean c;
|
|
+ private final List<ChannelFuture> f = Collections.synchronizedList(Lists.newArrayList());
|
|
+ private final List<NetworkManager> g = Collections.synchronizedList(Lists.newArrayList());
|
|
+
|
|
+ public ServerConnection(MinecraftServer minecraftserver) {
|
|
+ this.e = minecraftserver;
|
|
+ this.c = true;
|
|
+ }
|
|
+
|
|
+ public void a(@Nullable InetAddress inetaddress, int i) throws IOException {
|
|
+ List list = this.f;
|
|
+
|
|
+ synchronized (this.f) {
|
|
+ Class oclass;
|
|
+ LazyInitVar lazyinitvar;
|
|
+
|
|
+ if (Epoll.isAvailable() && this.e.X()) {
|
|
+ oclass = EpollServerSocketChannel.class;
|
|
+ lazyinitvar = ServerConnection.b;
|
|
+ ServerConnection.LOGGER.info("Using epoll channel type");
|
|
+ } else {
|
|
+ oclass = NioServerSocketChannel.class;
|
|
+ lazyinitvar = ServerConnection.a;
|
|
+ ServerConnection.LOGGER.info("Using default channel type");
|
|
+ }
|
|
+
|
|
+ this.f.add(((ServerBootstrap) ((ServerBootstrap) (new ServerBootstrap()).channel(oclass)).childHandler(new ChannelInitializer<Channel>() {
|
|
+ protected void initChannel(Channel channel) throws Exception {
|
|
+ try {
|
|
+ channel.config().setOption(ChannelOption.TCP_NODELAY, true);
|
|
+ } catch (ChannelException channelexception) {
|
|
+ ;
|
|
+ }
|
|
+
|
|
+ channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30)).addLast("legacy_query", new LegacyPingHandler(ServerConnection.this)).addLast("splitter", new PacketSplitter()).addLast("decoder", new PacketDecoder(EnumProtocolDirection.SERVERBOUND)).addLast("prepender", new PacketPrepender()).addLast("encoder", new PacketEncoder(EnumProtocolDirection.CLIENTBOUND));
|
|
+ NetworkManager networkmanager = new NetworkManager(EnumProtocolDirection.SERVERBOUND);
|
|
+
|
|
+ ServerConnection.this.g.add(networkmanager);
|
|
+ channel.pipeline().addLast("packet_handler", networkmanager);
|
|
+ networkmanager.setPacketListener(new HandshakeListener(ServerConnection.this.e, networkmanager));
|
|
+ }
|
|
+ }).group((EventLoopGroup) lazyinitvar.a()).localAddress(inetaddress, i)).bind().syncUninterruptibly());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void b() {
|
|
+ this.c = false;
|
|
+ Iterator iterator = this.f.iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ ChannelFuture channelfuture = (ChannelFuture) iterator.next();
|
|
+
|
|
+ try {
|
|
+ channelfuture.channel().close().sync();
|
|
+ } catch (InterruptedException interruptedexception) {
|
|
+ ServerConnection.LOGGER.error("Interrupted whilst closing channel");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ public void c() {
|
|
+ List list = this.g;
|
|
+
|
|
+ synchronized (this.g) {
|
|
+ Iterator iterator = this.g.iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ NetworkManager networkmanager = (NetworkManager) iterator.next();
|
|
+
|
|
+ if (!networkmanager.h()) {
|
|
+ if (networkmanager.isConnected()) {
|
|
+ try {
|
|
+ networkmanager.a();
|
|
+ } catch (Exception exception) {
|
|
+ if (networkmanager.isLocal()) {
|
|
+ CrashReport crashreport = CrashReport.a(exception, "Ticking memory connection");
|
|
+ CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Ticking connection");
|
|
+
|
|
+ crashreportsystemdetails.a("Connection", networkmanager::toString);
|
|
+ throw new ReportedException(crashreport);
|
|
+ }
|
|
+
|
|
+ ServerConnection.LOGGER.warn("Failed to handle packet for {}", networkmanager.getSocketAddress(), exception);
|
|
+ ChatComponentText chatcomponenttext = new ChatComponentText("Internal server error");
|
|
+
|
|
+ networkmanager.sendPacket(new PacketPlayOutKickDisconnect(chatcomponenttext), (future) -> {
|
|
+ networkmanager.close(chatcomponenttext);
|
|
+ });
|
|
+ networkmanager.stopReading();
|
|
+ }
|
|
+ } else {
|
|
+ iterator.remove();
|
|
+ networkmanager.handleDisconnection();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public MinecraftServer d() {
|
|
+ return this.e;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/ServerStatisticManager.java b/src/main/java/net/minecraft/server/ServerStatisticManager.java
|
|
new file mode 100644
|
|
index 000000000..f59b85ccb
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/ServerStatisticManager.java
|
|
@@ -0,0 +1,234 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.google.common.collect.Maps;
|
|
+import com.google.common.collect.Sets;
|
|
+import com.google.gson.JsonElement;
|
|
+import com.google.gson.JsonObject;
|
|
+import com.google.gson.JsonParseException;
|
|
+import com.google.gson.JsonPrimitive;
|
|
+import com.google.gson.internal.Streams;
|
|
+import com.google.gson.stream.JsonReader;
|
|
+import com.mojang.datafixers.DataFixer;
|
|
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
|
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
|
+import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
|
+import java.io.File;
|
|
+import java.io.IOException;
|
|
+import java.io.StringReader;
|
|
+import java.util.Iterator;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.Set;
|
|
+import java.util.Map.Entry;
|
|
+import org.apache.logging.log4j.LogManager;
|
|
+import org.apache.logging.log4j.Logger;
|
|
+
|
|
+public class ServerStatisticManager extends StatisticManager {
|
|
+
|
|
+ private static final Logger LOGGER = LogManager.getLogger();
|
|
+ private final MinecraftServer c;
|
|
+ private final File d;
|
|
+ private final Set<Statistic<?>> e = Sets.newHashSet();
|
|
+ private int f = -300;
|
|
+
|
|
+ public ServerStatisticManager(MinecraftServer minecraftserver, File file) {
|
|
+ this.c = minecraftserver;
|
|
+ this.d = file;
|
|
+ if (file.isFile()) {
|
|
+ try {
|
|
+ this.a(minecraftserver.aB(), org.apache.commons.io.FileUtils.readFileToString(file));
|
|
+ } catch (IOException ioexception) {
|
|
+ ServerStatisticManager.LOGGER.error("Couldn't read statistics file {}", file, ioexception);
|
|
+ } catch (JsonParseException jsonparseexception) {
|
|
+ ServerStatisticManager.LOGGER.error("Couldn't parse statistics file {}", file, jsonparseexception);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ public void a() {
|
|
+ try {
|
|
+ org.apache.commons.io.FileUtils.writeStringToFile(this.d, this.b());
|
|
+ } catch (IOException ioexception) {
|
|
+ ServerStatisticManager.LOGGER.error("Couldn't save stats", ioexception);
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setStatistic(EntityHuman entityhuman, Statistic<?> statistic, int i) {
|
|
+ super.setStatistic(entityhuman, statistic, i);
|
|
+ this.e.add(statistic);
|
|
+ }
|
|
+
|
|
+ private Set<Statistic<?>> d() {
|
|
+ Set<Statistic<?>> set = Sets.newHashSet(this.e);
|
|
+
|
|
+ this.e.clear();
|
|
+ return set;
|
|
+ }
|
|
+
|
|
+ public void a(DataFixer datafixer, String s) {
|
|
+ try {
|
|
+ JsonReader jsonreader = new JsonReader(new StringReader(s));
|
|
+ Throwable throwable = null;
|
|
+
|
|
+ try {
|
|
+ jsonreader.setLenient(false);
|
|
+ JsonElement jsonelement = Streams.parse(jsonreader);
|
|
+
|
|
+ if (!jsonelement.isJsonNull()) {
|
|
+ NBTTagCompound nbttagcompound = a(jsonelement.getAsJsonObject());
|
|
+
|
|
+ if (!nbttagcompound.hasKeyOfType("DataVersion", 99)) {
|
|
+ nbttagcompound.setInt("DataVersion", 1343);
|
|
+ }
|
|
+
|
|
+ nbttagcompound = GameProfileSerializer.a(datafixer, DataFixTypes.STATS, nbttagcompound, nbttagcompound.getInt("DataVersion"));
|
|
+ if (nbttagcompound.hasKeyOfType("stats", 10)) {
|
|
+ NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("stats");
|
|
+ Iterator iterator = nbttagcompound1.getKeys().iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ String s1 = (String) iterator.next();
|
|
+
|
|
+ if (nbttagcompound1.hasKeyOfType(s1, 10)) {
|
|
+ SystemUtils.a(IRegistry.STATS.getOptional(new MinecraftKey(s1)), (statisticwrapper) -> {
|
|
+ NBTTagCompound nbttagcompound2 = nbttagcompound1.getCompound(s1);
|
|
+ Iterator iterator1 = nbttagcompound2.getKeys().iterator();
|
|
+
|
|
+ while (iterator1.hasNext()) {
|
|
+ String s2 = (String) iterator1.next();
|
|
+
|
|
+ if (nbttagcompound2.hasKeyOfType(s2, 99)) {
|
|
+ SystemUtils.a(this.a(statisticwrapper, s2), (statistic) -> {
|
|
+ this.a.put(statistic, nbttagcompound2.getInt(s2));
|
|
+ }, () -> {
|
|
+ ServerStatisticManager.LOGGER.warn("Invalid statistic in {}: Don't know what {} is", this.d, s2);
|
|
+ });
|
|
+ } else {
|
|
+ ServerStatisticManager.LOGGER.warn("Invalid statistic value in {}: Don't know what {} is for key {}", this.d, nbttagcompound2.get(s2), s2);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }, () -> {
|
|
+ ServerStatisticManager.LOGGER.warn("Invalid statistic type in {}: Don't know what {} is", this.d, s1);
|
|
+ });
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ ServerStatisticManager.LOGGER.error("Unable to parse Stat data from {}", this.d);
|
|
+ } catch (Throwable throwable1) {
|
|
+ throwable = throwable1;
|
|
+ throw throwable1;
|
|
+ } finally {
|
|
+ if (jsonreader != null) {
|
|
+ if (throwable != null) {
|
|
+ try {
|
|
+ jsonreader.close();
|
|
+ } catch (Throwable throwable2) {
|
|
+ throwable.addSuppressed(throwable2);
|
|
+ }
|
|
+ } else {
|
|
+ jsonreader.close();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ } catch (IOException | JsonParseException jsonparseexception) {
|
|
+ ServerStatisticManager.LOGGER.error("Unable to parse Stat data from {}", this.d, jsonparseexception);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private <T> Optional<Statistic<T>> a(StatisticWrapper<T> statisticwrapper, String s) {
|
|
+ Optional<MinecraftKey> optional = Optional.ofNullable(MinecraftKey.a(s));
|
|
+ IRegistry<T> iregistry = statisticwrapper.getRegistry();
|
|
+
|
|
+ iregistry.getClass();
|
|
+ Optional<T> optional2 = optional.flatMap(iregistry::getOptional);
|
|
+ statisticwrapper.getClass();
|
|
+ return optional2.map(statisticwrapper::b);
|
|
+ }
|
|
+
|
|
+ private static NBTTagCompound a(JsonObject jsonobject) {
|
|
+ NBTTagCompound nbttagcompound = new NBTTagCompound();
|
|
+ Iterator iterator = jsonobject.entrySet().iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ Entry<String, JsonElement> entry = (Entry) iterator.next();
|
|
+ JsonElement jsonelement = (JsonElement) entry.getValue();
|
|
+
|
|
+ if (jsonelement.isJsonObject()) {
|
|
+ nbttagcompound.set((String) entry.getKey(), a(jsonelement.getAsJsonObject()));
|
|
+ } else if (jsonelement.isJsonPrimitive()) {
|
|
+ JsonPrimitive jsonprimitive = jsonelement.getAsJsonPrimitive();
|
|
+
|
|
+ if (jsonprimitive.isNumber()) {
|
|
+ nbttagcompound.setInt((String) entry.getKey(), jsonprimitive.getAsInt());
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return nbttagcompound;
|
|
+ }
|
|
+
|
|
+ protected String b() {
|
|
+ Map<StatisticWrapper<?>, JsonObject> map = Maps.newHashMap();
|
|
+ ObjectIterator objectiterator = this.a.object2IntEntrySet().iterator();
|
|
+
|
|
+ while (objectiterator.hasNext()) {
|
|
+ it.unimi.dsi.fastutil.objects.Object2IntMap.Entry<Statistic<?>> it_unimi_dsi_fastutil_objects_object2intmap_entry = (it.unimi.dsi.fastutil.objects.Object2IntMap.Entry) objectiterator.next();
|
|
+ Statistic<?> statistic = (Statistic) it_unimi_dsi_fastutil_objects_object2intmap_entry.getKey();
|
|
+
|
|
+ ((JsonObject) map.computeIfAbsent(statistic.getWrapper(), (statisticwrapper) -> {
|
|
+ return new JsonObject();
|
|
+ })).addProperty(b(statistic).toString(), it_unimi_dsi_fastutil_objects_object2intmap_entry.getIntValue());
|
|
+ }
|
|
+
|
|
+ JsonObject jsonobject = new JsonObject();
|
|
+ Iterator iterator = map.entrySet().iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ Entry<StatisticWrapper<?>, JsonObject> entry = (Entry) iterator.next();
|
|
+
|
|
+ jsonobject.add(IRegistry.STATS.getKey(entry.getKey()).toString(), (JsonElement) entry.getValue());
|
|
+ }
|
|
+
|
|
+ JsonObject jsonobject1 = new JsonObject();
|
|
+
|
|
+ jsonobject1.add("stats", jsonobject);
|
|
+ jsonobject1.addProperty("DataVersion", SharedConstants.a().getWorldVersion());
|
|
+ return jsonobject1.toString();
|
|
+ }
|
|
+
|
|
+ private static <T> MinecraftKey b(Statistic<T> statistic) {
|
|
+ return statistic.getWrapper().getRegistry().getKey(statistic.b());
|
|
+ }
|
|
+
|
|
+ public void c() {
|
|
+ this.e.addAll(this.a.keySet());
|
|
+ }
|
|
+
|
|
+ public void a(EntityPlayer entityplayer) {
|
|
+ int i = this.c.aj();
|
|
+ Object2IntMap<Statistic<?>> object2intmap = new Object2IntOpenHashMap();
|
|
+
|
|
+ if (i - this.f > 300) {
|
|
+ this.f = i;
|
|
+ Iterator iterator = this.d().iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ Statistic<?> statistic = (Statistic) iterator.next();
|
|
+
|
|
+ object2intmap.put(statistic, this.getStatisticValue(statistic));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ entityplayer.playerConnection.sendPacket(new PacketPlayOutStatistic(object2intmap));
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/TileEntitySkull.java b/src/main/java/net/minecraft/server/TileEntitySkull.java
|
|
new file mode 100644
|
|
index 000000000..895a8dfb8
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/TileEntitySkull.java
|
|
@@ -0,0 +1,119 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.google.common.collect.Iterables;
|
|
+import com.mojang.authlib.GameProfile;
|
|
+import com.mojang.authlib.minecraft.MinecraftSessionService;
|
|
+import com.mojang.authlib.properties.Property;
|
|
+import java.util.UUID;
|
|
+import javax.annotation.Nullable;
|
|
+
|
|
+public class TileEntitySkull extends TileEntity implements ITickable {
|
|
+
|
|
+ public GameProfile gameProfile;
|
|
+ private int b;
|
|
+ private boolean c;
|
|
+ private static UserCache userCache;
|
|
+ private static MinecraftSessionService sessionService;
|
|
+
|
|
+ public TileEntitySkull() {
|
|
+ super(TileEntityTypes.SKULL);
|
|
+ }
|
|
+
|
|
+ public static void a(UserCache usercache) {
|
|
+ TileEntitySkull.userCache = usercache;
|
|
+ }
|
|
+
|
|
+ public static void a(MinecraftSessionService minecraftsessionservice) {
|
|
+ TileEntitySkull.sessionService = minecraftsessionservice;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public NBTTagCompound save(NBTTagCompound nbttagcompound) {
|
|
+ super.save(nbttagcompound);
|
|
+ if (this.gameProfile != null) {
|
|
+ NBTTagCompound nbttagcompound1 = new NBTTagCompound();
|
|
+
|
|
+ GameProfileSerializer.serialize(nbttagcompound1, this.gameProfile);
|
|
+ nbttagcompound.set("Owner", nbttagcompound1);
|
|
+ }
|
|
+
|
|
+ return nbttagcompound;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void load(NBTTagCompound nbttagcompound) {
|
|
+ super.load(nbttagcompound);
|
|
+ if (nbttagcompound.hasKeyOfType("Owner", 10)) {
|
|
+ this.setGameProfile(GameProfileSerializer.deserialize(nbttagcompound.getCompound("Owner")));
|
|
+ } else if (nbttagcompound.hasKeyOfType("ExtraType", 8)) {
|
|
+ String s = nbttagcompound.getString("ExtraType");
|
|
+
|
|
+ if (!UtilColor.b(s)) {
|
|
+ this.setGameProfile(new GameProfile((UUID) null, s));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void tick() {
|
|
+ Block block = this.getBlock().getBlock();
|
|
+
|
|
+ if (block == Blocks.DRAGON_HEAD || block == Blocks.DRAGON_WALL_HEAD) {
|
|
+ if (this.world.isBlockIndirectlyPowered(this.position)) {
|
|
+ this.c = true;
|
|
+ ++this.b;
|
|
+ } else {
|
|
+ this.c = false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ @Nullable
|
|
+ @Override
|
|
+ public PacketPlayOutTileEntityData getUpdatePacket() {
|
|
+ return new PacketPlayOutTileEntityData(this.position, 4, this.b());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public NBTTagCompound b() {
|
|
+ return this.save(new NBTTagCompound());
|
|
+ }
|
|
+
|
|
+ public void setGameProfile(@Nullable GameProfile gameprofile) {
|
|
+ this.gameProfile = gameprofile;
|
|
+ this.f();
|
|
+ }
|
|
+
|
|
+ private void f() {
|
|
+ this.gameProfile = b(this.gameProfile);
|
|
+ this.update();
|
|
+ }
|
|
+
|
|
+ public static GameProfile b(GameProfile gameprofile) {
|
|
+ if (gameprofile != null && !UtilColor.b(gameprofile.getName())) {
|
|
+ if (gameprofile.isComplete() && gameprofile.getProperties().containsKey("textures")) {
|
|
+ return gameprofile;
|
|
+ } else if (TileEntitySkull.userCache != null && TileEntitySkull.sessionService != null) {
|
|
+ GameProfile gameprofile1 = TileEntitySkull.userCache.getProfile(gameprofile.getName());
|
|
+
|
|
+ if (gameprofile1 == null) {
|
|
+ return gameprofile;
|
|
+ } else {
|
|
+ Property property = (Property) Iterables.getFirst(gameprofile1.getProperties().get("textures"), (Object) null);
|
|
+
|
|
+ if (property == null) {
|
|
+ gameprofile1 = TileEntitySkull.sessionService.fillProfileProperties(gameprofile1, true);
|
|
+ }
|
|
+
|
|
+ return gameprofile1;
|
|
+ }
|
|
+ } else {
|
|
+ return gameprofile;
|
|
+ }
|
|
+ } else {
|
|
+ return gameprofile;
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureDesertPyramid.java b/src/main/java/net/minecraft/server/WorldGenFeatureDesertPyramid.java
|
|
new file mode 100644
|
|
index 000000000..4f1d57b8a
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/WorldGenFeatureDesertPyramid.java
|
|
@@ -0,0 +1,46 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.mojang.datafixers.Dynamic;
|
|
+import java.util.function.Function;
|
|
+
|
|
+public class WorldGenFeatureDesertPyramid extends WorldGenFeatureRandomScattered<WorldGenFeatureEmptyConfiguration> {
|
|
+
|
|
+ public WorldGenFeatureDesertPyramid(Function<Dynamic<?>, ? extends WorldGenFeatureEmptyConfiguration> function) {
|
|
+ super(function);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String b() {
|
|
+ return "Desert_Pyramid";
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int c() {
|
|
+ return 3;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public StructureGenerator.a a() {
|
|
+ return WorldGenFeatureDesertPyramid.a::new;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected int getSeed() {
|
|
+ return 14357617;
|
|
+ }
|
|
+
|
|
+ public static class a extends StructureStart {
|
|
+
|
|
+ public a(StructureGenerator<?> structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) {
|
|
+ super(structuregenerator, i, j, biomebase, structureboundingbox, k, l);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void a(ChunkGenerator<?> chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) {
|
|
+ WorldGenDesertPyramidPiece worldgendesertpyramidpiece = new WorldGenDesertPyramidPiece(this.d, i * 16, j * 16);
|
|
+
|
|
+ this.b.add(worldgendesertpyramidpiece);
|
|
+ this.b();
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureIgloo.java b/src/main/java/net/minecraft/server/WorldGenFeatureIgloo.java
|
|
new file mode 100644
|
|
index 000000000..0f6ce1526
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/WorldGenFeatureIgloo.java
|
|
@@ -0,0 +1,50 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.mojang.datafixers.Dynamic;
|
|
+import java.util.function.Function;
|
|
+
|
|
+public class WorldGenFeatureIgloo extends WorldGenFeatureRandomScattered<WorldGenFeatureEmptyConfiguration> {
|
|
+
|
|
+ public WorldGenFeatureIgloo(Function<Dynamic<?>, ? extends WorldGenFeatureEmptyConfiguration> function) {
|
|
+ super(function);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String b() {
|
|
+ return "Igloo";
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int c() {
|
|
+ return 3;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public StructureGenerator.a a() {
|
|
+ return WorldGenFeatureIgloo.a::new;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected int getSeed() {
|
|
+ return 14357618;
|
|
+ }
|
|
+
|
|
+ public static class a extends StructureStart {
|
|
+
|
|
+ public a(StructureGenerator<?> structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) {
|
|
+ super(structuregenerator, i, j, biomebase, structureboundingbox, k, l);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void a(ChunkGenerator<?> chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) {
|
|
+ WorldGenFeatureEmptyConfiguration worldgenfeatureemptyconfiguration = (WorldGenFeatureEmptyConfiguration) chunkgenerator.getFeatureConfiguration(biomebase, WorldGenerator.IGLOO);
|
|
+ int k = i * 16;
|
|
+ int l = j * 16;
|
|
+ BlockPosition blockposition = new BlockPosition(k, 90, l);
|
|
+ EnumBlockRotation enumblockrotation = EnumBlockRotation.values()[this.d.nextInt(EnumBlockRotation.values().length)];
|
|
+
|
|
+ WorldGenIglooPiece.a(definedstructuremanager, blockposition, enumblockrotation, this.b, this.d, worldgenfeatureemptyconfiguration);
|
|
+ this.b();
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureJunglePyramid.java b/src/main/java/net/minecraft/server/WorldGenFeatureJunglePyramid.java
|
|
new file mode 100644
|
|
index 000000000..354584258
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/WorldGenFeatureJunglePyramid.java
|
|
@@ -0,0 +1,46 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.mojang.datafixers.Dynamic;
|
|
+import java.util.function.Function;
|
|
+
|
|
+public class WorldGenFeatureJunglePyramid extends WorldGenFeatureRandomScattered<WorldGenFeatureEmptyConfiguration> {
|
|
+
|
|
+ public WorldGenFeatureJunglePyramid(Function<Dynamic<?>, ? extends WorldGenFeatureEmptyConfiguration> function) {
|
|
+ super(function);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String b() {
|
|
+ return "Jungle_Pyramid";
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int c() {
|
|
+ return 3;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public StructureGenerator.a a() {
|
|
+ return WorldGenFeatureJunglePyramid.a::new;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected int getSeed() {
|
|
+ return 14357619;
|
|
+ }
|
|
+
|
|
+ public static class a extends StructureStart {
|
|
+
|
|
+ public a(StructureGenerator<?> structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) {
|
|
+ super(structuregenerator, i, j, biomebase, structureboundingbox, k, l);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void a(ChunkGenerator<?> chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) {
|
|
+ WorldGenJunglePyramidPiece worldgenjunglepyramidpiece = new WorldGenJunglePyramidPiece(this.d, i * 16, j * 16);
|
|
+
|
|
+ this.b.add(worldgenjunglepyramidpiece);
|
|
+ this.b();
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureOceanRuin.java b/src/main/java/net/minecraft/server/WorldGenFeatureOceanRuin.java
|
|
new file mode 100644
|
|
index 000000000..5f847e68f
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/WorldGenFeatureOceanRuin.java
|
|
@@ -0,0 +1,86 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.mojang.datafixers.Dynamic;
|
|
+import java.util.Arrays;
|
|
+import java.util.Map;
|
|
+import java.util.Random;
|
|
+import java.util.function.Function;
|
|
+import java.util.stream.Collectors;
|
|
+
|
|
+public class WorldGenFeatureOceanRuin extends WorldGenFeatureRandomScattered<WorldGenFeatureOceanRuinConfiguration> {
|
|
+
|
|
+ public WorldGenFeatureOceanRuin(Function<Dynamic<?>, ? extends WorldGenFeatureOceanRuinConfiguration> function) {
|
|
+ super(function);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String b() {
|
|
+ return "Ocean_Ruin";
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int c() {
|
|
+ return 3;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected int a(ChunkGenerator<?> chunkgenerator) {
|
|
+ return chunkgenerator.getSettings().l();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected int b(ChunkGenerator<?> chunkgenerator) {
|
|
+ return chunkgenerator.getSettings().m();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public StructureGenerator.a a() {
|
|
+ return WorldGenFeatureOceanRuin.a::new;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected int getSeed() {
|
|
+ return 14357621;
|
|
+ }
|
|
+
|
|
+ public static enum Temperature {
|
|
+
|
|
+ WARM("warm"), COLD("cold");
|
|
+
|
|
+ private static final Map<String, WorldGenFeatureOceanRuin.Temperature> c = (Map) Arrays.stream(values()).collect(Collectors.toMap(WorldGenFeatureOceanRuin.Temperature::a, (worldgenfeatureoceanruin_temperature) -> {
|
|
+ return worldgenfeatureoceanruin_temperature;
|
|
+ }));
|
|
+ private final String d;
|
|
+
|
|
+ private Temperature(String s) {
|
|
+ this.d = s;
|
|
+ }
|
|
+
|
|
+ public String a() {
|
|
+ return this.d;
|
|
+ }
|
|
+
|
|
+ public static WorldGenFeatureOceanRuin.Temperature a(String s) {
|
|
+ return (WorldGenFeatureOceanRuin.Temperature) WorldGenFeatureOceanRuin.Temperature.c.get(s);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static class a extends StructureStart {
|
|
+
|
|
+ public a(StructureGenerator<?> structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) {
|
|
+ super(structuregenerator, i, j, biomebase, structureboundingbox, k, l);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void a(ChunkGenerator<?> chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) {
|
|
+ WorldGenFeatureOceanRuinConfiguration worldgenfeatureoceanruinconfiguration = (WorldGenFeatureOceanRuinConfiguration) chunkgenerator.getFeatureConfiguration(biomebase, WorldGenerator.OCEAN_RUIN);
|
|
+ int k = i * 16;
|
|
+ int l = j * 16;
|
|
+ BlockPosition blockposition = new BlockPosition(k, 90, l);
|
|
+ EnumBlockRotation enumblockrotation = EnumBlockRotation.values()[this.d.nextInt(EnumBlockRotation.values().length)];
|
|
+
|
|
+ WorldGenFeatureOceanRuinPieces.a(definedstructuremanager, blockposition, enumblockrotation, this.b, (Random) this.d, worldgenfeatureoceanruinconfiguration);
|
|
+ this.b();
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/WorldGenFeaturePillagerOutpost.java b/src/main/java/net/minecraft/server/WorldGenFeaturePillagerOutpost.java
|
|
new file mode 100644
|
|
index 000000000..a3c6bac32
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/WorldGenFeaturePillagerOutpost.java
|
|
@@ -0,0 +1,88 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.google.common.collect.Lists;
|
|
+import com.mojang.datafixers.Dynamic;
|
|
+import java.util.List;
|
|
+import java.util.Random;
|
|
+import java.util.function.Function;
|
|
+
|
|
+public class WorldGenFeaturePillagerOutpost extends WorldGenFeatureRandomScattered<WorldGenFeaturePillagerOutpostConfiguration> {
|
|
+
|
|
+ private static final List<BiomeBase.BiomeMeta> a = Lists.newArrayList(new BiomeBase.BiomeMeta[]{new BiomeBase.BiomeMeta(EntityTypes.PILLAGER, 1, 1, 1)});
|
|
+
|
|
+ public WorldGenFeaturePillagerOutpost(Function<Dynamic<?>, ? extends WorldGenFeaturePillagerOutpostConfiguration> function) {
|
|
+ super(function);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String b() {
|
|
+ return "Pillager_Outpost";
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int c() {
|
|
+ return 3;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public List<BiomeBase.BiomeMeta> e() {
|
|
+ return WorldGenFeaturePillagerOutpost.a;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean a(ChunkGenerator<?> chunkgenerator, Random random, int i, int j) {
|
|
+ ChunkCoordIntPair chunkcoordintpair = this.a(chunkgenerator, random, i, j, 0, 0);
|
|
+
|
|
+ if (i == chunkcoordintpair.x && j == chunkcoordintpair.z) {
|
|
+ int k = i >> 4;
|
|
+ int l = j >> 4;
|
|
+
|
|
+ random.setSeed((long) (k ^ l << 4) ^ chunkgenerator.getSeed());
|
|
+ random.nextInt();
|
|
+ if (random.nextInt(5) != 0) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition((i << 4) + 9, 0, (j << 4) + 9));
|
|
+
|
|
+ if (chunkgenerator.canSpawnStructure(biomebase, WorldGenerator.PILLAGER_OUTPOST)) {
|
|
+ for (int i1 = i - 10; i1 <= i + 10; ++i1) {
|
|
+ for (int j1 = j - 10; j1 <= j + 10; ++j1) {
|
|
+ if (WorldGenerator.VILLAGE.a(chunkgenerator, random, i1, j1)) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public StructureGenerator.a a() {
|
|
+ return WorldGenFeaturePillagerOutpost.a::new;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected int getSeed() {
|
|
+ return 165745296;
|
|
+ }
|
|
+
|
|
+ public static class a extends StructureAbstract {
|
|
+
|
|
+ public a(StructureGenerator<?> structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) {
|
|
+ super(structuregenerator, i, j, biomebase, structureboundingbox, k, l);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void a(ChunkGenerator<?> chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) {
|
|
+ BlockPosition blockposition = new BlockPosition(i * 16, 90, j * 16);
|
|
+
|
|
+ WorldGenFeaturePillagerOutpostPieces.a(chunkgenerator, definedstructuremanager, blockposition, this.b, this.d);
|
|
+ this.b();
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureRandomScattered.java b/src/main/java/net/minecraft/server/WorldGenFeatureRandomScattered.java
|
|
new file mode 100644
|
|
index 000000000..ae7973254
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/WorldGenFeatureRandomScattered.java
|
|
@@ -0,0 +1,56 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.mojang.datafixers.Dynamic;
|
|
+import java.util.Random;
|
|
+import java.util.function.Function;
|
|
+
|
|
+public abstract class WorldGenFeatureRandomScattered<C extends WorldGenFeatureConfiguration> extends StructureGenerator<C> {
|
|
+
|
|
+ public WorldGenFeatureRandomScattered(Function<Dynamic<?>, ? extends C> function) {
|
|
+ super(function);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected ChunkCoordIntPair a(ChunkGenerator<?> chunkgenerator, Random random, int i, int j, int k, int l) {
|
|
+ int i1 = this.a(chunkgenerator);
|
|
+ int j1 = this.b(chunkgenerator);
|
|
+ int k1 = i + i1 * k;
|
|
+ int l1 = j + i1 * l;
|
|
+ int i2 = k1 < 0 ? k1 - i1 + 1 : k1;
|
|
+ int j2 = l1 < 0 ? l1 - i1 + 1 : l1;
|
|
+ int k2 = i2 / i1;
|
|
+ int l2 = j2 / i1;
|
|
+
|
|
+ ((SeededRandom) random).a(chunkgenerator.getSeed(), k2, l2, this.getSeed());
|
|
+ k2 *= i1;
|
|
+ l2 *= i1;
|
|
+ k2 += random.nextInt(i1 - j1);
|
|
+ l2 += random.nextInt(i1 - j1);
|
|
+ return new ChunkCoordIntPair(k2, l2);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean a(ChunkGenerator<?> chunkgenerator, Random random, int i, int j) {
|
|
+ ChunkCoordIntPair chunkcoordintpair = this.a(chunkgenerator, random, i, j, 0, 0);
|
|
+
|
|
+ if (i == chunkcoordintpair.x && j == chunkcoordintpair.z) {
|
|
+ BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition(i * 16 + 9, 0, j * 16 + 9));
|
|
+
|
|
+ if (chunkgenerator.canSpawnStructure(biomebase, this)) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ protected int a(ChunkGenerator<?> chunkgenerator) {
|
|
+ return chunkgenerator.getSettings().h();
|
|
+ }
|
|
+
|
|
+ protected int b(ChunkGenerator<?> chunkgenerator) {
|
|
+ return chunkgenerator.getSettings().i();
|
|
+ }
|
|
+
|
|
+ protected abstract int getSeed();
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureShipwreck.java b/src/main/java/net/minecraft/server/WorldGenFeatureShipwreck.java
|
|
new file mode 100644
|
|
index 000000000..e89dbbcb7
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/WorldGenFeatureShipwreck.java
|
|
@@ -0,0 +1,58 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.mojang.datafixers.Dynamic;
|
|
+import java.util.function.Function;
|
|
+
|
|
+public class WorldGenFeatureShipwreck extends WorldGenFeatureRandomScattered<WorldGenFeatureShipwreckConfiguration> {
|
|
+
|
|
+ public WorldGenFeatureShipwreck(Function<Dynamic<?>, ? extends WorldGenFeatureShipwreckConfiguration> function) {
|
|
+ super(function);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String b() {
|
|
+ return "Shipwreck";
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int c() {
|
|
+ return 3;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public StructureGenerator.a a() {
|
|
+ return WorldGenFeatureShipwreck.a::new;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected int getSeed() {
|
|
+ return 165745295;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected int a(ChunkGenerator<?> chunkgenerator) {
|
|
+ return chunkgenerator.getSettings().j();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected int b(ChunkGenerator<?> chunkgenerator) {
|
|
+ return chunkgenerator.getSettings().k();
|
|
+ }
|
|
+
|
|
+ public static class a extends StructureStart {
|
|
+
|
|
+ public a(StructureGenerator<?> structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) {
|
|
+ super(structuregenerator, i, j, biomebase, structureboundingbox, k, l);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void a(ChunkGenerator<?> chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) {
|
|
+ WorldGenFeatureShipwreckConfiguration worldgenfeatureshipwreckconfiguration = (WorldGenFeatureShipwreckConfiguration) chunkgenerator.getFeatureConfiguration(biomebase, WorldGenerator.SHIPWRECK);
|
|
+ EnumBlockRotation enumblockrotation = EnumBlockRotation.values()[this.d.nextInt(EnumBlockRotation.values().length)];
|
|
+ BlockPosition blockposition = new BlockPosition(i * 16, 90, j * 16);
|
|
+
|
|
+ WorldGenShipwreck.a(definedstructuremanager, blockposition, enumblockrotation, this.b, this.d, worldgenfeatureshipwreckconfiguration);
|
|
+ this.b();
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureSwampHut.java b/src/main/java/net/minecraft/server/WorldGenFeatureSwampHut.java
|
|
new file mode 100644
|
|
index 000000000..9c3cbb2b9
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/WorldGenFeatureSwampHut.java
|
|
@@ -0,0 +1,73 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.google.common.collect.Lists;
|
|
+import com.mojang.datafixers.Dynamic;
|
|
+import java.util.List;
|
|
+import java.util.function.Function;
|
|
+
|
|
+public class WorldGenFeatureSwampHut extends WorldGenFeatureRandomScattered<WorldGenFeatureEmptyConfiguration> {
|
|
+
|
|
+ private static final List<BiomeBase.BiomeMeta> a = Lists.newArrayList(new BiomeBase.BiomeMeta[]{new BiomeBase.BiomeMeta(EntityTypes.WITCH, 1, 1, 1)});
|
|
+ private static final List<BiomeBase.BiomeMeta> aS = Lists.newArrayList(new BiomeBase.BiomeMeta[]{new BiomeBase.BiomeMeta(EntityTypes.CAT, 1, 1, 1)});
|
|
+
|
|
+ public WorldGenFeatureSwampHut(Function<Dynamic<?>, ? extends WorldGenFeatureEmptyConfiguration> function) {
|
|
+ super(function);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String b() {
|
|
+ return "Swamp_Hut";
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int c() {
|
|
+ return 3;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public StructureGenerator.a a() {
|
|
+ return WorldGenFeatureSwampHut.a::new;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected int getSeed() {
|
|
+ return 14357620;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public List<BiomeBase.BiomeMeta> e() {
|
|
+ return WorldGenFeatureSwampHut.a;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public List<BiomeBase.BiomeMeta> f() {
|
|
+ return WorldGenFeatureSwampHut.aS;
|
|
+ }
|
|
+
|
|
+ public boolean c(GeneratorAccess generatoraccess, BlockPosition blockposition) {
|
|
+ StructureStart structurestart = this.a(generatoraccess, blockposition, true);
|
|
+
|
|
+ if (structurestart != StructureStart.a && structurestart instanceof WorldGenFeatureSwampHut.a && !structurestart.d().isEmpty()) {
|
|
+ StructurePiece structurepiece = (StructurePiece) structurestart.d().get(0);
|
|
+
|
|
+ return structurepiece instanceof WorldGenWitchHut;
|
|
+ } else {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static class a extends StructureStart {
|
|
+
|
|
+ public a(StructureGenerator<?> structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) {
|
|
+ super(structuregenerator, i, j, biomebase, structureboundingbox, k, l);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void a(ChunkGenerator<?> chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) {
|
|
+ WorldGenWitchHut worldgenwitchhut = new WorldGenWitchHut(this.d, i * 16, j * 16);
|
|
+
|
|
+ this.b.add(worldgenwitchhut);
|
|
+ this.b();
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/WorldGenMonument.java b/src/main/java/net/minecraft/server/WorldGenMonument.java
|
|
new file mode 100644
|
|
index 000000000..29bf219f1
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/WorldGenMonument.java
|
|
@@ -0,0 +1,128 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.google.common.collect.Lists;
|
|
+import com.mojang.datafixers.Dynamic;
|
|
+import java.util.Iterator;
|
|
+import java.util.List;
|
|
+import java.util.Random;
|
|
+import java.util.Set;
|
|
+import java.util.function.Function;
|
|
+
|
|
+public class WorldGenMonument extends StructureGenerator<WorldGenFeatureEmptyConfiguration> {
|
|
+
|
|
+ private static final List<BiomeBase.BiomeMeta> a = Lists.newArrayList(new BiomeBase.BiomeMeta[]{new BiomeBase.BiomeMeta(EntityTypes.GUARDIAN, 1, 2, 4)});
|
|
+
|
|
+ public WorldGenMonument(Function<Dynamic<?>, ? extends WorldGenFeatureEmptyConfiguration> function) {
|
|
+ super(function);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected ChunkCoordIntPair a(ChunkGenerator<?> chunkgenerator, Random random, int i, int j, int k, int l) {
|
|
+ int i1 = chunkgenerator.getSettings().c();
|
|
+ int j1 = chunkgenerator.getSettings().d();
|
|
+ int k1 = i + i1 * k;
|
|
+ int l1 = j + i1 * l;
|
|
+ int i2 = k1 < 0 ? k1 - i1 + 1 : k1;
|
|
+ int j2 = l1 < 0 ? l1 - i1 + 1 : l1;
|
|
+ int k2 = i2 / i1;
|
|
+ int l2 = j2 / i1;
|
|
+
|
|
+ ((SeededRandom) random).a(chunkgenerator.getSeed(), k2, l2, 10387313);
|
|
+ k2 *= i1;
|
|
+ l2 *= i1;
|
|
+ k2 += (random.nextInt(i1 - j1) + random.nextInt(i1 - j1)) / 2;
|
|
+ l2 += (random.nextInt(i1 - j1) + random.nextInt(i1 - j1)) / 2;
|
|
+ return new ChunkCoordIntPair(k2, l2);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean a(ChunkGenerator<?> chunkgenerator, Random random, int i, int j) {
|
|
+ ChunkCoordIntPair chunkcoordintpair = this.a(chunkgenerator, random, i, j, 0, 0);
|
|
+
|
|
+ if (i == chunkcoordintpair.x && j == chunkcoordintpair.z) {
|
|
+ Set<BiomeBase> set = chunkgenerator.getWorldChunkManager().a(i * 16 + 9, j * 16 + 9, 16);
|
|
+ Iterator iterator = set.iterator();
|
|
+
|
|
+ BiomeBase biomebase;
|
|
+
|
|
+ do {
|
|
+ if (!iterator.hasNext()) {
|
|
+ Set<BiomeBase> set1 = chunkgenerator.getWorldChunkManager().a(i * 16 + 9, j * 16 + 9, 29);
|
|
+ Iterator iterator1 = set1.iterator();
|
|
+
|
|
+ BiomeBase biomebase1;
|
|
+
|
|
+ do {
|
|
+ if (!iterator1.hasNext()) {
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ biomebase1 = (BiomeBase) iterator1.next();
|
|
+ } while (biomebase1.o() == BiomeBase.Geography.OCEAN || biomebase1.o() == BiomeBase.Geography.RIVER);
|
|
+
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ biomebase = (BiomeBase) iterator.next();
|
|
+ } while (chunkgenerator.canSpawnStructure(biomebase, WorldGenerator.OCEAN_MONUMENT));
|
|
+
|
|
+ return false;
|
|
+ } else {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public StructureGenerator.a a() {
|
|
+ return WorldGenMonument.a::new;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String b() {
|
|
+ return "Monument";
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int c() {
|
|
+ return 8;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public List<BiomeBase.BiomeMeta> e() {
|
|
+ return WorldGenMonument.a;
|
|
+ }
|
|
+
|
|
+ public static class a extends StructureStart {
|
|
+
|
|
+ private boolean e;
|
|
+
|
|
+ public a(StructureGenerator<?> structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) {
|
|
+ super(structuregenerator, i, j, biomebase, structureboundingbox, k, l);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void a(ChunkGenerator<?> chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) {
|
|
+ this.b(i, j);
|
|
+ }
|
|
+
|
|
+ private void b(int i, int j) {
|
|
+ int k = i * 16 - 29;
|
|
+ int l = j * 16 - 29;
|
|
+ EnumDirection enumdirection = EnumDirection.EnumDirectionLimit.HORIZONTAL.a(this.d);
|
|
+
|
|
+ this.b.add(new WorldGenMonumentPieces.WorldGenMonumentPiece1(this.d, k, l, enumdirection));
|
|
+ this.b();
|
|
+ this.e = true;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) {
|
|
+ if (!this.e) {
|
|
+ this.b.clear();
|
|
+ this.b(this.f(), this.g());
|
|
+ }
|
|
+
|
|
+ super.a(generatoraccess, random, structureboundingbox, chunkcoordintpair);
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/WorldGenVillage.java b/src/main/java/net/minecraft/server/WorldGenVillage.java
|
|
new file mode 100644
|
|
index 000000000..ead451073
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/WorldGenVillage.java
|
|
@@ -0,0 +1,75 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.mojang.datafixers.Dynamic;
|
|
+import java.util.Random;
|
|
+import java.util.function.Function;
|
|
+
|
|
+public class WorldGenVillage extends StructureGenerator<WorldGenFeatureVillageConfiguration> {
|
|
+
|
|
+ public WorldGenVillage(Function<Dynamic<?>, ? extends WorldGenFeatureVillageConfiguration> function) {
|
|
+ super(function);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected ChunkCoordIntPair a(ChunkGenerator<?> chunkgenerator, Random random, int i, int j, int k, int l) {
|
|
+ int i1 = chunkgenerator.getSettings().a();
|
|
+ int j1 = chunkgenerator.getSettings().b();
|
|
+ int k1 = i + i1 * k;
|
|
+ int l1 = j + i1 * l;
|
|
+ int i2 = k1 < 0 ? k1 - i1 + 1 : k1;
|
|
+ int j2 = l1 < 0 ? l1 - i1 + 1 : l1;
|
|
+ int k2 = i2 / i1;
|
|
+ int l2 = j2 / i1;
|
|
+
|
|
+ ((SeededRandom) random).a(chunkgenerator.getSeed(), k2, l2, 10387312);
|
|
+ k2 *= i1;
|
|
+ l2 *= i1;
|
|
+ k2 += random.nextInt(i1 - j1);
|
|
+ l2 += random.nextInt(i1 - j1);
|
|
+ return new ChunkCoordIntPair(k2, l2);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean a(ChunkGenerator<?> chunkgenerator, Random random, int i, int j) {
|
|
+ ChunkCoordIntPair chunkcoordintpair = this.a(chunkgenerator, random, i, j, 0, 0);
|
|
+
|
|
+ if (i == chunkcoordintpair.x && j == chunkcoordintpair.z) {
|
|
+ BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition((i << 4) + 9, 0, (j << 4) + 9));
|
|
+
|
|
+ return chunkgenerator.canSpawnStructure(biomebase, WorldGenerator.VILLAGE);
|
|
+ } else {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public StructureGenerator.a a() {
|
|
+ return WorldGenVillage.a::new;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String b() {
|
|
+ return "Village";
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int c() {
|
|
+ return 8;
|
|
+ }
|
|
+
|
|
+ public static class a extends StructureAbstract {
|
|
+
|
|
+ public a(StructureGenerator<?> structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) {
|
|
+ super(structuregenerator, i, j, biomebase, structureboundingbox, k, l);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void a(ChunkGenerator<?> chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) {
|
|
+ WorldGenFeatureVillageConfiguration worldgenfeaturevillageconfiguration = (WorldGenFeatureVillageConfiguration) chunkgenerator.getFeatureConfiguration(biomebase, WorldGenerator.VILLAGE);
|
|
+ BlockPosition blockposition = new BlockPosition(i * 16, 0, j * 16);
|
|
+
|
|
+ NewVillagePieces.a(chunkgenerator, definedstructuremanager, blockposition, this.b, this.d, worldgenfeaturevillageconfiguration);
|
|
+ this.b();
|
|
+ }
|
|
+ }
|
|
+}
|
|
--
|
|
2.20.1
|
|
|