1126 lines
37 KiB
Diff
1126 lines
37 KiB
Diff
From 5b899e58bba86e41281992f8eed8b9a93f5405a6 Mon Sep 17 00:00:00 2001
|
|
From: md_5 <md_5@live.com.au>
|
|
Date: Tue, 2 Jul 2013 13:13:29 +1000
|
|
Subject: [PATCH] mc-dev imports
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/BlockBrewingStand.java b/src/main/java/net/minecraft/server/BlockBrewingStand.java
|
|
new file mode 100644
|
|
index 0000000..270b2cb
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/BlockBrewingStand.java
|
|
@@ -0,0 +1,109 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.util.List;
|
|
+import java.util.Random;
|
|
+
|
|
+public class BlockBrewingStand extends BlockContainer {
|
|
+
|
|
+ private Random a = new Random();
|
|
+
|
|
+ public BlockBrewingStand(int i) {
|
|
+ super(i, Material.ORE);
|
|
+ }
|
|
+
|
|
+ public boolean c() {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ public int d() {
|
|
+ return 25;
|
|
+ }
|
|
+
|
|
+ public TileEntity b(World world) {
|
|
+ return new TileEntityBrewingStand();
|
|
+ }
|
|
+
|
|
+ public boolean b() {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ public void a(World world, int i, int j, int k, AxisAlignedBB axisalignedbb, List list, Entity entity) {
|
|
+ this.a(0.4375F, 0.0F, 0.4375F, 0.5625F, 0.875F, 0.5625F);
|
|
+ super.a(world, i, j, k, axisalignedbb, list, entity);
|
|
+ this.g();
|
|
+ super.a(world, i, j, k, axisalignedbb, list, entity);
|
|
+ }
|
|
+
|
|
+ public void g() {
|
|
+ this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F);
|
|
+ }
|
|
+
|
|
+ public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
|
|
+ if (world.isStatic) {
|
|
+ return true;
|
|
+ } else {
|
|
+ TileEntityBrewingStand tileentitybrewingstand = (TileEntityBrewingStand) world.getTileEntity(i, j, k);
|
|
+
|
|
+ if (tileentitybrewingstand != null) {
|
|
+ entityhuman.openBrewingStand(tileentitybrewingstand);
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void postPlace(World world, int i, int j, int k, EntityLiving entityliving, ItemStack itemstack) {
|
|
+ if (itemstack.hasName()) {
|
|
+ ((TileEntityBrewingStand) world.getTileEntity(i, j, k)).a(itemstack.getName());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void remove(World world, int i, int j, int k, int l, int i1) {
|
|
+ TileEntity tileentity = world.getTileEntity(i, j, k);
|
|
+
|
|
+ if (tileentity instanceof TileEntityBrewingStand) {
|
|
+ TileEntityBrewingStand tileentitybrewingstand = (TileEntityBrewingStand) tileentity;
|
|
+
|
|
+ for (int j1 = 0; j1 < tileentitybrewingstand.getSize(); ++j1) {
|
|
+ ItemStack itemstack = tileentitybrewingstand.getItem(j1);
|
|
+
|
|
+ if (itemstack != null) {
|
|
+ float f = this.a.nextFloat() * 0.8F + 0.1F;
|
|
+ float f1 = this.a.nextFloat() * 0.8F + 0.1F;
|
|
+ float f2 = this.a.nextFloat() * 0.8F + 0.1F;
|
|
+
|
|
+ while (itemstack.count > 0) {
|
|
+ int k1 = this.a.nextInt(21) + 10;
|
|
+
|
|
+ if (k1 > itemstack.count) {
|
|
+ k1 = itemstack.count;
|
|
+ }
|
|
+
|
|
+ itemstack.count -= k1;
|
|
+ EntityItem entityitem = new EntityItem(world, (double) ((float) i + f), (double) ((float) j + f1), (double) ((float) k + f2), new ItemStack(itemstack.id, k1, itemstack.getData()));
|
|
+ float f3 = 0.05F;
|
|
+
|
|
+ entityitem.motX = (double) ((float) this.a.nextGaussian() * f3);
|
|
+ entityitem.motY = (double) ((float) this.a.nextGaussian() * f3 + 0.2F);
|
|
+ entityitem.motZ = (double) ((float) this.a.nextGaussian() * f3);
|
|
+ world.addEntity(entityitem);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ super.remove(world, i, j, k, l, i1);
|
|
+ }
|
|
+
|
|
+ public int getDropType(int i, Random random, int j) {
|
|
+ return Item.BREWING_STAND.id;
|
|
+ }
|
|
+
|
|
+ public boolean q_() {
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ public int b_(World world, int i, int j, int k, int l) {
|
|
+ return Container.b((IInventory) world.getTileEntity(i, j, k));
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/BlockTNT.java b/src/main/java/net/minecraft/server/BlockTNT.java
|
|
new file mode 100644
|
|
index 0000000..9acd4f2
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/BlockTNT.java
|
|
@@ -0,0 +1,80 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.util.Random;
|
|
+
|
|
+public class BlockTNT extends Block {
|
|
+
|
|
+ public BlockTNT(int i) {
|
|
+ super(i, Material.TNT);
|
|
+ this.a(CreativeModeTab.d);
|
|
+ }
|
|
+
|
|
+ public void onPlace(World world, int i, int j, int k) {
|
|
+ super.onPlace(world, i, j, k);
|
|
+ if (world.isBlockIndirectlyPowered(i, j, k)) {
|
|
+ this.postBreak(world, i, j, k, 1);
|
|
+ world.setAir(i, j, k);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void doPhysics(World world, int i, int j, int k, int l) {
|
|
+ if (world.isBlockIndirectlyPowered(i, j, k)) {
|
|
+ this.postBreak(world, i, j, k, 1);
|
|
+ world.setAir(i, j, k);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public int a(Random random) {
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ public void wasExploded(World world, int i, int j, int k, Explosion explosion) {
|
|
+ if (!world.isStatic) {
|
|
+ EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), explosion.c());
|
|
+
|
|
+ entitytntprimed.fuseTicks = world.random.nextInt(entitytntprimed.fuseTicks / 4) + entitytntprimed.fuseTicks / 8;
|
|
+ world.addEntity(entitytntprimed);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void postBreak(World world, int i, int j, int k, int l) {
|
|
+ this.a(world, i, j, k, l, (EntityLiving) null);
|
|
+ }
|
|
+
|
|
+ public void a(World world, int i, int j, int k, int l, EntityLiving entityliving) {
|
|
+ if (!world.isStatic) {
|
|
+ if ((l & 1) == 1) {
|
|
+ EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), entityliving);
|
|
+
|
|
+ world.addEntity(entitytntprimed);
|
|
+ world.makeSound(entitytntprimed, "random.fuse", 1.0F, 1.0F);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
|
|
+ if (entityhuman.by() != null && entityhuman.by().id == Item.FLINT_AND_STEEL.id) {
|
|
+ this.a(world, i, j, k, 1, entityhuman);
|
|
+ world.setAir(i, j, k);
|
|
+ entityhuman.by().damage(1, entityhuman);
|
|
+ return true;
|
|
+ } else {
|
|
+ return super.interact(world, i, j, k, entityhuman, l, f, f1, f2);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void a(World world, int i, int j, int k, Entity entity) {
|
|
+ if (entity instanceof EntityArrow && !world.isStatic) {
|
|
+ EntityArrow entityarrow = (EntityArrow) entity;
|
|
+
|
|
+ if (entityarrow.isBurning()) {
|
|
+ this.a(world, i, j, k, 1, entityarrow.shooter instanceof EntityLiving ? (EntityLiving) entityarrow.shooter : null);
|
|
+ world.setAir(i, j, k);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public boolean a(Explosion explosion) {
|
|
+ return false;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/LocaleLanguage.java b/src/main/java/net/minecraft/server/LocaleLanguage.java
|
|
new file mode 100644
|
|
index 0000000..aa937fb
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/LocaleLanguage.java
|
|
@@ -0,0 +1,73 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import com.google.common.base.Splitter;
|
|
+import com.google.common.collect.Iterables;
|
|
+import com.google.common.collect.Maps;
|
|
+import java.io.IOException;
|
|
+import java.io.InputStream;
|
|
+import java.util.IllegalFormatException;
|
|
+import java.util.Iterator;
|
|
+import java.util.Map;
|
|
+import java.util.regex.Pattern;
|
|
+import org.apache.commons.io.Charsets;
|
|
+import org.apache.commons.io.IOUtils;
|
|
+
|
|
+public class LocaleLanguage {
|
|
+
|
|
+ private static final Pattern a = Pattern.compile("%(\\d+\\$)?[\\d\\.]*[df]");
|
|
+ private static final Splitter b = Splitter.on('=').limit(2);
|
|
+ private static LocaleLanguage c = new LocaleLanguage();
|
|
+ private Map d = Maps.newHashMap();
|
|
+
|
|
+ public LocaleLanguage() {
|
|
+ try {
|
|
+ InputStream inputstream = LocaleLanguage.class.getResourceAsStream("/assets/minecraft/lang/en_US.lang");
|
|
+ Iterator iterator = IOUtils.readLines(inputstream, Charsets.UTF_8).iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ String s = (String) iterator.next();
|
|
+
|
|
+ if (!s.isEmpty() && s.charAt(0) != 35) {
|
|
+ String[] astring = (String[]) Iterables.toArray(b.split(s), String.class);
|
|
+
|
|
+ if (astring != null && astring.length == 2) {
|
|
+ String s1 = astring[0];
|
|
+ String s2 = a.matcher(astring[1]).replaceAll("%$1s");
|
|
+
|
|
+ this.d.put(s1, s2);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ } catch (IOException ioexception) {
|
|
+ ;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ static LocaleLanguage a() {
|
|
+ return c;
|
|
+ }
|
|
+
|
|
+ public synchronized String a(String s) {
|
|
+ return this.c(s);
|
|
+ }
|
|
+
|
|
+ public synchronized String a(String s, Object... aobject) {
|
|
+ String s1 = this.c(s);
|
|
+
|
|
+ try {
|
|
+ return String.format(s1, aobject);
|
|
+ } catch (IllegalFormatException illegalformatexception) {
|
|
+ return "Format error: " + s1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private String c(String s) {
|
|
+ String s1 = (String) this.d.get(s);
|
|
+
|
|
+ return s1 == null ? s : s1;
|
|
+ }
|
|
+
|
|
+ public synchronized boolean b(String s) {
|
|
+ return this.d.containsKey(s);
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/NextTickListEntry.java b/src/main/java/net/minecraft/server/NextTickListEntry.java
|
|
new file mode 100644
|
|
index 0000000..acf8838
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/NextTickListEntry.java
|
|
@@ -0,0 +1,56 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+public class NextTickListEntry implements Comparable {
|
|
+
|
|
+ private static long g;
|
|
+ public int a;
|
|
+ public int b;
|
|
+ public int c;
|
|
+ public int d;
|
|
+ public long e;
|
|
+ public int f;
|
|
+ private long h;
|
|
+
|
|
+ public NextTickListEntry(int i, int j, int k, int l) {
|
|
+ this.h = (long) (g++);
|
|
+ this.a = i;
|
|
+ this.b = j;
|
|
+ this.c = k;
|
|
+ this.d = l;
|
|
+ }
|
|
+
|
|
+ public boolean equals(Object object) {
|
|
+ if (!(object instanceof NextTickListEntry)) {
|
|
+ return false;
|
|
+ } else {
|
|
+ NextTickListEntry nextticklistentry = (NextTickListEntry) object;
|
|
+
|
|
+ return this.a == nextticklistentry.a && this.b == nextticklistentry.b && this.c == nextticklistentry.c && Block.b(this.d, nextticklistentry.d);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public int hashCode() {
|
|
+ return (this.a * 1024 * 1024 + this.c * 1024 + this.b) * 256;
|
|
+ }
|
|
+
|
|
+ public NextTickListEntry a(long i) {
|
|
+ this.e = i;
|
|
+ return this;
|
|
+ }
|
|
+
|
|
+ public void a(int i) {
|
|
+ this.f = i;
|
|
+ }
|
|
+
|
|
+ public int compareTo(NextTickListEntry nextticklistentry) {
|
|
+ return this.e < nextticklistentry.e ? -1 : (this.e > nextticklistentry.e ? 1 : (this.f != nextticklistentry.f ? this.f - nextticklistentry.f : (this.h < nextticklistentry.h ? -1 : (this.h > nextticklistentry.h ? 1 : 0))));
|
|
+ }
|
|
+
|
|
+ public String toString() {
|
|
+ return this.d + ": (" + this.a + ", " + this.b + ", " + this.c + "), " + this.e + ", " + this.f + ", " + this.h;
|
|
+ }
|
|
+
|
|
+ public int compareTo(Object object) {
|
|
+ return this.compareTo((NextTickListEntry) object);
|
|
+ }
|
|
+}
|
|
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 0000000..5d75a54
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/NibbleArray.java
|
|
@@ -0,0 +1,40 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+public class NibbleArray {
|
|
+
|
|
+ public final byte[] a;
|
|
+ private final int b;
|
|
+ private final int c;
|
|
+
|
|
+ public NibbleArray(int i, int j) {
|
|
+ this.a = new byte[i >> 1];
|
|
+ this.b = j;
|
|
+ this.c = j + 4;
|
|
+ }
|
|
+
|
|
+ public NibbleArray(byte[] abyte, int i) {
|
|
+ this.a = abyte;
|
|
+ this.b = i;
|
|
+ this.c = i + 4;
|
|
+ }
|
|
+
|
|
+ public int a(int i, int j, int k) {
|
|
+ int l = j << this.c | k << this.b | i;
|
|
+ int i1 = l >> 1;
|
|
+ int j1 = l & 1;
|
|
+
|
|
+ return j1 == 0 ? this.a[i1] & 15 : this.a[i1] >> 4 & 15;
|
|
+ }
|
|
+
|
|
+ public void a(int i, int j, int k, int l) {
|
|
+ int i1 = j << this.c | k << this.b | i;
|
|
+ int j1 = i1 >> 1;
|
|
+ int k1 = i1 & 1;
|
|
+
|
|
+ if (k1 == 0) {
|
|
+ this.a[j1] = (byte) (this.a[j1] & 240 | l & 15);
|
|
+ } else {
|
|
+ this.a[j1] = (byte) (this.a[j1] & 15 | (l & 15) << 4);
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/OldChunkLoader.java b/src/main/java/net/minecraft/server/OldChunkLoader.java
|
|
new file mode 100644
|
|
index 0000000..53c1cb5
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/OldChunkLoader.java
|
|
@@ -0,0 +1,120 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+public class OldChunkLoader {
|
|
+
|
|
+ public static OldChunk a(NBTTagCompound nbttagcompound) {
|
|
+ int i = nbttagcompound.getInt("xPos");
|
|
+ int j = nbttagcompound.getInt("zPos");
|
|
+ OldChunk oldchunk = new OldChunk(i, j);
|
|
+
|
|
+ oldchunk.g = nbttagcompound.getByteArray("Blocks");
|
|
+ oldchunk.f = new OldNibbleArray(nbttagcompound.getByteArray("Data"), 7);
|
|
+ oldchunk.e = new OldNibbleArray(nbttagcompound.getByteArray("SkyLight"), 7);
|
|
+ oldchunk.d = new OldNibbleArray(nbttagcompound.getByteArray("BlockLight"), 7);
|
|
+ oldchunk.c = nbttagcompound.getByteArray("HeightMap");
|
|
+ oldchunk.b = nbttagcompound.getBoolean("TerrainPopulated");
|
|
+ oldchunk.h = nbttagcompound.getList("Entities");
|
|
+ oldchunk.i = nbttagcompound.getList("TileEntities");
|
|
+ oldchunk.j = nbttagcompound.getList("TileTicks");
|
|
+
|
|
+ try {
|
|
+ oldchunk.a = nbttagcompound.getLong("LastUpdate");
|
|
+ } catch (ClassCastException classcastexception) {
|
|
+ oldchunk.a = (long) nbttagcompound.getInt("LastUpdate");
|
|
+ }
|
|
+
|
|
+ return oldchunk;
|
|
+ }
|
|
+
|
|
+ public static void a(OldChunk oldchunk, NBTTagCompound nbttagcompound, WorldChunkManager worldchunkmanager) {
|
|
+ nbttagcompound.setInt("xPos", oldchunk.k);
|
|
+ nbttagcompound.setInt("zPos", oldchunk.l);
|
|
+ nbttagcompound.setLong("LastUpdate", oldchunk.a);
|
|
+ int[] aint = new int[oldchunk.c.length];
|
|
+
|
|
+ for (int i = 0; i < oldchunk.c.length; ++i) {
|
|
+ aint[i] = oldchunk.c[i];
|
|
+ }
|
|
+
|
|
+ nbttagcompound.setIntArray("HeightMap", aint);
|
|
+ nbttagcompound.setBoolean("TerrainPopulated", oldchunk.b);
|
|
+ NBTTagList nbttaglist = new NBTTagList("Sections");
|
|
+
|
|
+ int j;
|
|
+
|
|
+ for (int k = 0; k < 8; ++k) {
|
|
+ boolean flag = true;
|
|
+
|
|
+ for (j = 0; j < 16 && flag; ++j) {
|
|
+ int l = 0;
|
|
+
|
|
+ while (l < 16 && flag) {
|
|
+ int i1 = 0;
|
|
+
|
|
+ while (true) {
|
|
+ if (i1 < 16) {
|
|
+ int j1 = j << 11 | i1 << 7 | l + (k << 4);
|
|
+ byte b0 = oldchunk.g[j1];
|
|
+
|
|
+ if (b0 == 0) {
|
|
+ ++i1;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ flag = false;
|
|
+ }
|
|
+
|
|
+ ++l;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!flag) {
|
|
+ byte[] abyte = new byte[4096];
|
|
+ NibbleArray nibblearray = new NibbleArray(abyte.length, 4);
|
|
+ NibbleArray nibblearray1 = new NibbleArray(abyte.length, 4);
|
|
+ NibbleArray nibblearray2 = new NibbleArray(abyte.length, 4);
|
|
+
|
|
+ for (int k1 = 0; k1 < 16; ++k1) {
|
|
+ for (int l1 = 0; l1 < 16; ++l1) {
|
|
+ for (int i2 = 0; i2 < 16; ++i2) {
|
|
+ int j2 = k1 << 11 | i2 << 7 | l1 + (k << 4);
|
|
+ byte b1 = oldchunk.g[j2];
|
|
+
|
|
+ abyte[l1 << 8 | i2 << 4 | k1] = (byte) (b1 & 255);
|
|
+ nibblearray.a(k1, l1, i2, oldchunk.f.a(k1, l1 + (k << 4), i2));
|
|
+ nibblearray1.a(k1, l1, i2, oldchunk.e.a(k1, l1 + (k << 4), i2));
|
|
+ nibblearray2.a(k1, l1, i2, oldchunk.d.a(k1, l1 + (k << 4), i2));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ NBTTagCompound nbttagcompound1 = new NBTTagCompound();
|
|
+
|
|
+ nbttagcompound1.setByte("Y", (byte) (k & 255));
|
|
+ nbttagcompound1.setByteArray("Blocks", abyte);
|
|
+ nbttagcompound1.setByteArray("Data", nibblearray.a);
|
|
+ nbttagcompound1.setByteArray("SkyLight", nibblearray1.a);
|
|
+ nbttagcompound1.setByteArray("BlockLight", nibblearray2.a);
|
|
+ nbttaglist.add(nbttagcompound1);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ nbttagcompound.set("Sections", nbttaglist);
|
|
+ byte[] abyte1 = new byte[256];
|
|
+
|
|
+ for (int k2 = 0; k2 < 16; ++k2) {
|
|
+ for (j = 0; j < 16; ++j) {
|
|
+ abyte1[j << 4 | k2] = (byte) (worldchunkmanager.getBiome(oldchunk.k << 4 | k2, oldchunk.l << 4 | j).id & 255);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ nbttagcompound.setByteArray("Biomes", abyte1);
|
|
+ nbttagcompound.set("Entities", oldchunk.h);
|
|
+ nbttagcompound.set("TileEntities", oldchunk.i);
|
|
+ if (oldchunk.j != null) {
|
|
+ nbttagcompound.set("TileTicks", oldchunk.j);
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/Packet254GetInfo.java b/src/main/java/net/minecraft/server/Packet254GetInfo.java
|
|
new file mode 100644
|
|
index 0000000..9afa795
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/Packet254GetInfo.java
|
|
@@ -0,0 +1,53 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.io.DataInput;
|
|
+import java.io.DataOutput;
|
|
+
|
|
+public class Packet254GetInfo extends Packet {
|
|
+
|
|
+ private static final int d = (new Packet250CustomPayload()).n();
|
|
+ public int a;
|
|
+ public String b;
|
|
+ public int c;
|
|
+
|
|
+ public Packet254GetInfo() {}
|
|
+
|
|
+ public void a(DataInput datainput) throws java.io.IOException { // Spigot - throws
|
|
+ try {
|
|
+ datainput.readByte();
|
|
+ datainput.readByte();
|
|
+ a(datainput, 255);
|
|
+ datainput.readShort();
|
|
+ this.a = datainput.readByte();
|
|
+ if (this.a >= 73) {
|
|
+ this.b = a(datainput, 255);
|
|
+ this.c = datainput.readInt();
|
|
+ }
|
|
+ } catch (Throwable throwable) {
|
|
+ this.a = 0;
|
|
+ this.b = "";
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void a(DataOutput dataoutput) throws java.io.IOException { // Spigot - throws
|
|
+ dataoutput.writeByte(1);
|
|
+ dataoutput.writeByte(d);
|
|
+ Packet.a("MC|PingHost", dataoutput);
|
|
+ dataoutput.writeShort(3 + 2 * this.b.length() + 4);
|
|
+ dataoutput.writeByte(this.a);
|
|
+ Packet.a(this.b, dataoutput);
|
|
+ dataoutput.writeInt(this.c);
|
|
+ }
|
|
+
|
|
+ public void handle(Connection connection) {
|
|
+ connection.a(this);
|
|
+ }
|
|
+
|
|
+ public int a() {
|
|
+ return 3 + this.b.length() * 2 + 4;
|
|
+ }
|
|
+
|
|
+ public boolean d() {
|
|
+ return this.a == 0;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/Packet51MapChunk.java b/src/main/java/net/minecraft/server/Packet51MapChunk.java
|
|
new file mode 100644
|
|
index 0000000..4e67e27
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/Packet51MapChunk.java
|
|
@@ -0,0 +1,186 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.io.DataInput;
|
|
+import java.io.DataOutput;
|
|
+import java.io.IOException;
|
|
+import java.util.zip.DataFormatException;
|
|
+import java.util.zip.Deflater;
|
|
+import java.util.zip.Inflater;
|
|
+
|
|
+public class Packet51MapChunk extends Packet {
|
|
+
|
|
+ public int a;
|
|
+ public int b;
|
|
+ public int c;
|
|
+ public int d;
|
|
+ private byte[] buffer;
|
|
+ private byte[] inflatedBuffer;
|
|
+ public boolean e;
|
|
+ private int size;
|
|
+ private static byte[] buildBuffer = new byte[196864];
|
|
+
|
|
+ public Packet51MapChunk() {
|
|
+ this.lowPriority = true;
|
|
+ }
|
|
+
|
|
+ public Packet51MapChunk(Chunk chunk, boolean flag, int i) {
|
|
+ this.lowPriority = true;
|
|
+ this.a = chunk.x;
|
|
+ this.b = chunk.z;
|
|
+ this.e = flag;
|
|
+ ChunkMap chunkmap = a(chunk, flag, i);
|
|
+ Deflater deflater = new Deflater(-1);
|
|
+
|
|
+ this.d = chunkmap.c;
|
|
+ this.c = chunkmap.b;
|
|
+
|
|
+ try {
|
|
+ this.inflatedBuffer = chunkmap.a;
|
|
+ deflater.setInput(chunkmap.a, 0, chunkmap.a.length);
|
|
+ deflater.finish();
|
|
+ this.buffer = new byte[chunkmap.a.length];
|
|
+ this.size = deflater.deflate(this.buffer);
|
|
+ } finally {
|
|
+ deflater.end();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void a(DataInput datainput) throws java.io.IOException { // Spigot - throws
|
|
+ this.a = datainput.readInt();
|
|
+ this.b = datainput.readInt();
|
|
+ this.e = datainput.readBoolean();
|
|
+ this.c = datainput.readShort();
|
|
+ this.d = datainput.readShort();
|
|
+ this.size = datainput.readInt();
|
|
+ if (buildBuffer.length < this.size) {
|
|
+ buildBuffer = new byte[this.size];
|
|
+ }
|
|
+
|
|
+ datainput.readFully(buildBuffer, 0, this.size);
|
|
+ int i = 0;
|
|
+
|
|
+ int j;
|
|
+
|
|
+ for (j = 0; j < 16; ++j) {
|
|
+ i += this.c >> j & 1;
|
|
+ }
|
|
+
|
|
+ j = 12288 * i;
|
|
+ if (this.e) {
|
|
+ j += 256;
|
|
+ }
|
|
+
|
|
+ this.inflatedBuffer = new byte[j];
|
|
+ Inflater inflater = new Inflater();
|
|
+
|
|
+ inflater.setInput(buildBuffer, 0, this.size);
|
|
+
|
|
+ try {
|
|
+ inflater.inflate(this.inflatedBuffer);
|
|
+ } catch (DataFormatException dataformatexception) {
|
|
+ throw new IOException("Bad compressed data format");
|
|
+ } finally {
|
|
+ inflater.end();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void a(DataOutput dataoutput) throws java.io.IOException { // Spigot - throws
|
|
+ dataoutput.writeInt(this.a);
|
|
+ dataoutput.writeInt(this.b);
|
|
+ dataoutput.writeBoolean(this.e);
|
|
+ dataoutput.writeShort((short) (this.c & '\uffff'));
|
|
+ dataoutput.writeShort((short) (this.d & '\uffff'));
|
|
+ dataoutput.writeInt(this.size);
|
|
+ dataoutput.write(this.buffer, 0, this.size);
|
|
+ }
|
|
+
|
|
+ public void handle(Connection connection) {
|
|
+ connection.a(this);
|
|
+ }
|
|
+
|
|
+ public int a() {
|
|
+ return 17 + this.size;
|
|
+ }
|
|
+
|
|
+ public static ChunkMap a(Chunk chunk, boolean flag, int i) {
|
|
+ int j = 0;
|
|
+ ChunkSection[] achunksection = chunk.i();
|
|
+ int k = 0;
|
|
+ ChunkMap chunkmap = new ChunkMap();
|
|
+ byte[] abyte = buildBuffer;
|
|
+
|
|
+ if (flag) {
|
|
+ chunk.seenByPlayer = true;
|
|
+ }
|
|
+
|
|
+ int l;
|
|
+
|
|
+ for (l = 0; l < achunksection.length; ++l) {
|
|
+ if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
|
|
+ chunkmap.b |= 1 << l;
|
|
+ if (achunksection[l].getExtendedIdArray() != null) {
|
|
+ chunkmap.c |= 1 << l;
|
|
+ ++k;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ for (l = 0; l < achunksection.length; ++l) {
|
|
+ if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
|
|
+ byte[] abyte1 = achunksection[l].getIdArray();
|
|
+
|
|
+ System.arraycopy(abyte1, 0, abyte, j, abyte1.length);
|
|
+ j += abyte1.length;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ NibbleArray nibblearray;
|
|
+
|
|
+ for (l = 0; l < achunksection.length; ++l) {
|
|
+ if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
|
|
+ nibblearray = achunksection[l].getDataArray();
|
|
+ System.arraycopy(nibblearray.a, 0, abyte, j, nibblearray.a.length);
|
|
+ j += nibblearray.a.length;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ for (l = 0; l < achunksection.length; ++l) {
|
|
+ if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
|
|
+ nibblearray = achunksection[l].getEmittedLightArray();
|
|
+ System.arraycopy(nibblearray.a, 0, abyte, j, nibblearray.a.length);
|
|
+ j += nibblearray.a.length;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!chunk.world.worldProvider.g) {
|
|
+ for (l = 0; l < achunksection.length; ++l) {
|
|
+ if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
|
|
+ nibblearray = achunksection[l].getSkyLightArray();
|
|
+ System.arraycopy(nibblearray.a, 0, abyte, j, nibblearray.a.length);
|
|
+ j += nibblearray.a.length;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (k > 0) {
|
|
+ for (l = 0; l < achunksection.length; ++l) {
|
|
+ if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && achunksection[l].getExtendedIdArray() != null && (i & 1 << l) != 0) {
|
|
+ nibblearray = achunksection[l].getExtendedIdArray();
|
|
+ System.arraycopy(nibblearray.a, 0, abyte, j, nibblearray.a.length);
|
|
+ j += nibblearray.a.length;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (flag) {
|
|
+ byte[] abyte2 = chunk.m();
|
|
+
|
|
+ System.arraycopy(abyte2, 0, abyte, j, abyte2.length);
|
|
+ j += abyte2.length;
|
|
+ }
|
|
+
|
|
+ chunkmap.a = new byte[j];
|
|
+ System.arraycopy(abyte, 0, chunkmap.a, 0, j);
|
|
+ return chunkmap;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/Packet63WorldParticles.java b/src/main/java/net/minecraft/server/Packet63WorldParticles.java
|
|
new file mode 100644
|
|
index 0000000..f036c53
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/Packet63WorldParticles.java
|
|
@@ -0,0 +1,51 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.io.DataInput;
|
|
+import java.io.DataOutput;
|
|
+
|
|
+public class Packet63WorldParticles extends Packet {
|
|
+
|
|
+ private String a;
|
|
+ private float b;
|
|
+ private float c;
|
|
+ private float d;
|
|
+ private float e;
|
|
+ private float f;
|
|
+ private float g;
|
|
+ private float h;
|
|
+ private int i;
|
|
+
|
|
+ public Packet63WorldParticles() {}
|
|
+
|
|
+ public void a(DataInput datainput) throws java.io.IOException { // Spigot - throws
|
|
+ this.a = a(datainput, 64);
|
|
+ this.b = datainput.readFloat();
|
|
+ this.c = datainput.readFloat();
|
|
+ this.d = datainput.readFloat();
|
|
+ this.e = datainput.readFloat();
|
|
+ this.f = datainput.readFloat();
|
|
+ this.g = datainput.readFloat();
|
|
+ this.h = datainput.readFloat();
|
|
+ this.i = datainput.readInt();
|
|
+ }
|
|
+
|
|
+ public void a(DataOutput dataoutput) throws java.io.IOException { // Spigot - throws
|
|
+ a(this.a, dataoutput);
|
|
+ dataoutput.writeFloat(this.b);
|
|
+ dataoutput.writeFloat(this.c);
|
|
+ dataoutput.writeFloat(this.d);
|
|
+ dataoutput.writeFloat(this.e);
|
|
+ dataoutput.writeFloat(this.f);
|
|
+ dataoutput.writeFloat(this.g);
|
|
+ dataoutput.writeFloat(this.h);
|
|
+ dataoutput.writeInt(this.i);
|
|
+ }
|
|
+
|
|
+ public void handle(Connection connection) {
|
|
+ connection.a(this);
|
|
+ }
|
|
+
|
|
+ public int a() {
|
|
+ return 64;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java
|
|
new file mode 100644
|
|
index 0000000..900ed68
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/RegionFileCache.java
|
|
@@ -0,0 +1,67 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.io.DataInputStream;
|
|
+import java.io.DataOutputStream;
|
|
+import java.io.File;
|
|
+import java.io.IOException;
|
|
+import java.util.HashMap;
|
|
+import java.util.Iterator;
|
|
+import java.util.Map;
|
|
+
|
|
+public class RegionFileCache {
|
|
+
|
|
+ private static final Map a = new HashMap();
|
|
+
|
|
+ public static synchronized RegionFile a(File file1, int i, int j) {
|
|
+ File file2 = new File(file1, "region");
|
|
+ File file3 = new File(file2, "r." + (i >> 5) + "." + (j >> 5) + ".mca");
|
|
+ RegionFile regionfile = (RegionFile) a.get(file3);
|
|
+
|
|
+ if (regionfile != null) {
|
|
+ return regionfile;
|
|
+ } else {
|
|
+ if (!file2.exists()) {
|
|
+ file2.mkdirs();
|
|
+ }
|
|
+
|
|
+ if (a.size() >= 256) {
|
|
+ a();
|
|
+ }
|
|
+
|
|
+ RegionFile regionfile1 = new RegionFile(file3);
|
|
+
|
|
+ a.put(file3, regionfile1);
|
|
+ return regionfile1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static synchronized void a() {
|
|
+ Iterator iterator = a.values().iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ RegionFile regionfile = (RegionFile) iterator.next();
|
|
+
|
|
+ try {
|
|
+ if (regionfile != null) {
|
|
+ regionfile.c();
|
|
+ }
|
|
+ } catch (IOException ioexception) {
|
|
+ ioexception.printStackTrace();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ a.clear();
|
|
+ }
|
|
+
|
|
+ public static DataInputStream c(File file1, int i, int j) {
|
|
+ RegionFile regionfile = a(file1, i, j);
|
|
+
|
|
+ return regionfile.a(i & 31, j & 31);
|
|
+ }
|
|
+
|
|
+ public static DataOutputStream d(File file1, int i, int j) {
|
|
+ RegionFile regionfile = a(file1, i, j);
|
|
+
|
|
+ return regionfile.b(i & 31, j & 31);
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/StructureGenerator.java b/src/main/java/net/minecraft/server/StructureGenerator.java
|
|
new file mode 100644
|
|
index 0000000..ab4dc19
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/minecraft/server/StructureGenerator.java
|
|
@@ -0,0 +1,216 @@
|
|
+package net.minecraft.server;
|
|
+
|
|
+import java.util.HashMap;
|
|
+import java.util.Iterator;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Random;
|
|
+import java.util.concurrent.Callable;
|
|
+
|
|
+public abstract class StructureGenerator extends WorldGenBase {
|
|
+
|
|
+ private WorldGenFeature e;
|
|
+ protected Map d = new HashMap();
|
|
+
|
|
+ public StructureGenerator() {}
|
|
+
|
|
+ public abstract String a();
|
|
+
|
|
+ protected final void a(World world, int i, int j, int k, int l, byte[] abyte) {
|
|
+ this.a(world);
|
|
+ if (!this.d.containsKey(Long.valueOf(ChunkCoordIntPair.a(i, j)))) {
|
|
+ this.b.nextInt();
|
|
+
|
|
+ try {
|
|
+ if (this.a(i, j)) {
|
|
+ StructureStart structurestart = this.b(i, j);
|
|
+
|
|
+ this.d.put(Long.valueOf(ChunkCoordIntPair.a(i, j)), structurestart);
|
|
+ this.a(i, j, structurestart);
|
|
+ }
|
|
+ } catch (Throwable throwable) {
|
|
+ CrashReport crashreport = CrashReport.a(throwable, "Exception preparing structure feature");
|
|
+ CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Feature being prepared");
|
|
+
|
|
+ crashreportsystemdetails.a("Is feature chunk", (Callable) (new CrashReportIsFeatureChunk(this, i, j)));
|
|
+ crashreportsystemdetails.a("Chunk location", String.format("%d,%d", new Object[] { Integer.valueOf(i), Integer.valueOf(j)}));
|
|
+ crashreportsystemdetails.a("Chunk pos hash", (Callable) (new CrashReportChunkPosHash(this, i, j)));
|
|
+ crashreportsystemdetails.a("Structure type", (Callable) (new CrashReportStructureType(this)));
|
|
+ throw new ReportedException(crashreport);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public boolean a(World world, Random random, int i, int j) {
|
|
+ this.a(world);
|
|
+ int k = (i << 4) + 8;
|
|
+ int l = (j << 4) + 8;
|
|
+ boolean flag = false;
|
|
+ Iterator iterator = this.d.values().iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ StructureStart structurestart = (StructureStart) iterator.next();
|
|
+
|
|
+ if (structurestart.d() && structurestart.a().a(k, l, k + 15, l + 15)) {
|
|
+ structurestart.a(world, random, new StructureBoundingBox(k, l, k + 15, l + 15));
|
|
+ flag = true;
|
|
+ this.a(structurestart.e(), structurestart.f(), structurestart);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return flag;
|
|
+ }
|
|
+
|
|
+ public boolean b(int i, int j, int k) {
|
|
+ this.a(this.c);
|
|
+ return this.c(i, j, k) != null;
|
|
+ }
|
|
+
|
|
+ protected StructureStart c(int i, int j, int k) {
|
|
+ Iterator iterator = this.d.values().iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ StructureStart structurestart = (StructureStart) iterator.next();
|
|
+
|
|
+ if (structurestart.d() && structurestart.a().a(i, k, i, k)) {
|
|
+ Iterator iterator1 = structurestart.b().iterator();
|
|
+
|
|
+ while (iterator1.hasNext()) {
|
|
+ StructurePiece structurepiece = (StructurePiece) iterator1.next();
|
|
+
|
|
+ if (structurepiece.c().b(i, j, k)) {
|
|
+ return structurestart;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+ public boolean d(int i, int j, int k) {
|
|
+ this.a(this.c);
|
|
+ Iterator iterator = this.d.values().iterator();
|
|
+
|
|
+ StructureStart structurestart;
|
|
+
|
|
+ do {
|
|
+ if (!iterator.hasNext()) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ structurestart = (StructureStart) iterator.next();
|
|
+ } while (!structurestart.d());
|
|
+
|
|
+ return structurestart.a().a(i, k, i, k);
|
|
+ }
|
|
+
|
|
+ public ChunkPosition getNearestGeneratedFeature(World world, int i, int j, int k) {
|
|
+ this.c = world;
|
|
+ this.a(world);
|
|
+ this.b.setSeed(world.getSeed());
|
|
+ long l = this.b.nextLong();
|
|
+ long i1 = this.b.nextLong();
|
|
+ long j1 = (long) (i >> 4) * l;
|
|
+ long k1 = (long) (k >> 4) * i1;
|
|
+
|
|
+ this.b.setSeed(j1 ^ k1 ^ world.getSeed());
|
|
+ this.a(world, i >> 4, k >> 4, 0, 0, (byte[]) null);
|
|
+ double d0 = Double.MAX_VALUE;
|
|
+ ChunkPosition chunkposition = null;
|
|
+ Iterator iterator = this.d.values().iterator();
|
|
+
|
|
+ ChunkPosition chunkposition1;
|
|
+ int l1;
|
|
+ int i2;
|
|
+ double d1;
|
|
+ int j2;
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ StructureStart structurestart = (StructureStart) iterator.next();
|
|
+
|
|
+ if (structurestart.d()) {
|
|
+ StructurePiece structurepiece = (StructurePiece) structurestart.b().get(0);
|
|
+
|
|
+ chunkposition1 = structurepiece.a();
|
|
+ i2 = chunkposition1.x - i;
|
|
+ l1 = chunkposition1.y - j;
|
|
+ j2 = chunkposition1.z - k;
|
|
+ d1 = (double) (i2 * i2 + l1 * l1 + j2 * j2);
|
|
+ if (d1 < d0) {
|
|
+ d0 = d1;
|
|
+ chunkposition = chunkposition1;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (chunkposition != null) {
|
|
+ return chunkposition;
|
|
+ } else {
|
|
+ List list = this.p_();
|
|
+
|
|
+ if (list != null) {
|
|
+ ChunkPosition chunkposition2 = null;
|
|
+ Iterator iterator1 = list.iterator();
|
|
+
|
|
+ while (iterator1.hasNext()) {
|
|
+ chunkposition1 = (ChunkPosition) iterator1.next();
|
|
+ i2 = chunkposition1.x - i;
|
|
+ l1 = chunkposition1.y - j;
|
|
+ j2 = chunkposition1.z - k;
|
|
+ d1 = (double) (i2 * i2 + l1 * l1 + j2 * j2);
|
|
+ if (d1 < d0) {
|
|
+ d0 = d1;
|
|
+ chunkposition2 = chunkposition1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return chunkposition2;
|
|
+ } else {
|
|
+ return null;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ protected List p_() {
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+ private void a(World world) {
|
|
+ if (this.e == null) {
|
|
+ this.e = (WorldGenFeature) world.a(WorldGenFeature.class, this.a());
|
|
+ if (this.e == null) {
|
|
+ this.e = new WorldGenFeature(this.a());
|
|
+ world.a(this.a(), (WorldMapBase) this.e);
|
|
+ } else {
|
|
+ NBTTagCompound nbttagcompound = this.e.a();
|
|
+ Iterator iterator = nbttagcompound.c().iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ NBTBase nbtbase = (NBTBase) iterator.next();
|
|
+
|
|
+ if (nbtbase.getTypeId() == 10) {
|
|
+ NBTTagCompound nbttagcompound1 = (NBTTagCompound) nbtbase;
|
|
+
|
|
+ if (nbttagcompound1.hasKey("ChunkX") && nbttagcompound1.hasKey("ChunkZ")) {
|
|
+ int i = nbttagcompound1.getInt("ChunkX");
|
|
+ int j = nbttagcompound1.getInt("ChunkZ");
|
|
+ StructureStart structurestart = WorldGenFactory.a(nbttagcompound1, world);
|
|
+
|
|
+ this.d.put(Long.valueOf(ChunkCoordIntPair.a(i, j)), structurestart);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void a(int i, int j, StructureStart structurestart) {
|
|
+ this.e.a(structurestart.a(i, j), i, j);
|
|
+ this.e.c();
|
|
+ }
|
|
+
|
|
+ protected abstract boolean a(int i, int j);
|
|
+
|
|
+ protected abstract StructureStart b(int i, int j);
|
|
+}
|
|
--
|
|
1.8.1.2
|
|
|