Skip to content

Instantly share code, notes, and snippets.

@rmmh
Last active January 10, 2019 05:29
Show Gist options
  • Save rmmh/853bc1241c2575712bf77230f16097eb to your computer and use it in GitHub Desktop.
Save rmmh/853bc1241c2575712bf77230f16097eb to your computer and use it in GitHub Desktop.
Source code for the 2011 McRegion Minecraft mod, which was included in Beta 1.3. dn.java and on.java are the integration points.
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
public class dn implements ri {
public boolean a;
private List A;
public List b;
private List B;
private TreeSet C;
private Set D;
public List c;
public List d;
public long e;
private long E;
public int f;
protected int g;
protected int h;
public boolean i;
private long F;
protected int j;
public int k;
public Random l;
public int m;
public int n;
public int o;
public boolean p;
public final qx q;
protected List r;
private bm G;
public File s;
public File t;
public long u;
private jw H;
public long v;
public final String w;
public boolean x;
private ArrayList I;
private int J;
private boolean K;
private boolean L;
static int y = 0;
private Set M;
private int N;
private List O;
public boolean z;
public static jw a(File var0, String var1) {
File var2 = new File(var0, "saves");
File var3 = new File(var2, var1);
if(!var3.exists()) {
return null;
} else {
File var4 = new File(var3, "level.dat");
if(var4.exists()) {
try {
jw var5 = ag.a((InputStream)(new FileInputStream(var4)));
jw var6 = var5.k("Data");
return var6;
} catch (Exception var7) {
var7.printStackTrace();
}
}
return null;
}
}
public static void b(File var0, String var1) {
File var2 = new File(var0, "saves");
File var3 = new File(var2, var1);
if(var3.exists()) {
a((File[])var3.listFiles());
var3.delete();
}
}
private static void a(File[] var0) {
RegionFileCache.clear();
for(int var1 = 0; var1 < var0.length; ++var1) {
if(var0[var1].isDirectory()) {
a((File[])var0[var1].listFiles());
}
var0[var1].delete();
}
}
public ro a() {
return this.q.b;
}
public dn(File var1, String var2) {
this((File)var1, (String)var2, (new Random()).nextLong());
}
public dn(String var1, qx var2, long var3) {
this.a = false;
this.A = new ArrayList();
this.b = new ArrayList();
this.B = new ArrayList();
this.C = new TreeSet();
this.D = new HashSet();
this.c = new ArrayList();
this.d = new ArrayList();
this.e = 0L;
this.E = 16777215L;
this.f = 0;
this.g = (new Random()).nextInt();
this.h = 1013904223;
this.i = false;
this.F = System.currentTimeMillis();
this.j = 40;
this.l = new Random();
this.p = false;
this.r = new ArrayList();
this.u = 0L;
this.v = 0L;
this.I = new ArrayList();
this.J = 0;
this.K = true;
this.L = true;
this.M = new HashSet();
this.N = this.l.nextInt(12000);
this.O = new ArrayList();
this.z = false;
this.w = var1;
this.u = var3;
this.q = var2;
var2.a((dn)this);
this.G = this.a((File)this.t);
this.i();
}
public dn(dn var1, qx var2) {
this.a = false;
this.A = new ArrayList();
this.b = new ArrayList();
this.B = new ArrayList();
this.C = new TreeSet();
this.D = new HashSet();
this.c = new ArrayList();
this.d = new ArrayList();
this.e = 0L;
this.E = 16777215L;
this.f = 0;
this.g = (new Random()).nextInt();
this.h = 1013904223;
this.i = false;
this.F = System.currentTimeMillis();
this.j = 40;
this.l = new Random();
this.p = false;
this.r = new ArrayList();
this.u = 0L;
this.v = 0L;
this.I = new ArrayList();
this.J = 0;
this.K = true;
this.L = true;
this.M = new HashSet();
this.N = this.l.nextInt(12000);
this.O = new ArrayList();
this.z = false;
this.F = var1.F;
this.s = var1.s;
this.t = var1.t;
this.w = var1.w;
this.u = var1.u;
this.e = var1.e;
this.m = var1.m;
this.n = var1.n;
this.o = var1.o;
this.v = var1.v;
this.q = var2;
var2.a((dn)this);
this.G = this.a((File)this.t);
this.i();
}
public dn(File var1, String var2, long var3) {
this(var1, var2, var3, (qx)null);
}
public dn(File var1, String var2, long var3, qx var5) {
this.a = false;
this.A = new ArrayList();
this.b = new ArrayList();
this.B = new ArrayList();
this.C = new TreeSet();
this.D = new HashSet();
this.c = new ArrayList();
this.d = new ArrayList();
this.e = 0L;
this.E = 16777215L;
this.f = 0;
this.g = (new Random()).nextInt();
this.h = 1013904223;
this.i = false;
this.F = System.currentTimeMillis();
this.j = 40;
this.l = new Random();
this.p = false;
this.r = new ArrayList();
this.u = 0L;
this.v = 0L;
this.I = new ArrayList();
this.J = 0;
this.K = true;
this.L = true;
this.M = new HashSet();
this.N = this.l.nextInt(12000);
this.O = new ArrayList();
this.z = false;
this.s = var1;
this.w = var2;
var1.mkdirs();
this.t = new File(var1, var2);
this.t.mkdirs();
try {
File var6 = new File(this.t, "session.lock");
DataOutputStream var7 = new DataOutputStream(new FileOutputStream(var6));
try {
var7.writeLong(this.F);
} finally {
var7.close();
}
} catch (IOException var16) {
var16.printStackTrace();
throw new RuntimeException("Failed to check session lock, aborting");
}
Object var17 = new qx();
File var18 = new File(this.t, "level.dat");
this.p = !var18.exists();
if(var18.exists()) {
try {
jw var8 = ag.a((InputStream)(new FileInputStream(var18)));
jw var9 = var8.k("Data");
this.u = var9.f("RandomSeed");
this.m = var9.e("SpawnX");
this.n = var9.e("SpawnY");
this.o = var9.e("SpawnZ");
this.e = var9.f("Time");
this.v = var9.f("SizeOnDisk");
if(var9.b("Player")) {
this.H = var9.k("Player");
int var10 = this.H.e("Dimension");
if(var10 == -1) {
var17 = new qi();
}
}
} catch (Exception var14) {
var14.printStackTrace();
}
}
if(var5 != null) {
var17 = var5;
}
boolean var19 = false;
if(this.u == 0L) {
this.u = var3;
var19 = true;
}
this.q = (qx)var17;
this.q.a((dn)this);
this.G = this.a((File)this.t);
if(var19) {
this.x = true;
this.m = 0;
this.n = 64;
for(this.o = 0; !this.q.a(this.m, this.o); this.o += this.l.nextInt(64) - this.l.nextInt(64)) {
this.m += this.l.nextInt(64) - this.l.nextInt(64);
}
this.x = false;
}
this.i();
}
protected bm a(File var1) {
return new hr(this, this.q.a((File)var1), this.q.c());
}
public void b() {
if(this.n <= 0) {
this.n = 64;
}
while(this.a(this.m, this.o) == 0) {
this.m += this.l.nextInt(8) - this.l.nextInt(8);
this.o += this.l.nextInt(8) - this.l.nextInt(8);
}
}
public int a(int var1, int var2) {
int var3;
for(var3 = 63; !this.d(var1, var3 + 1, var2); ++var3) {
;
}
return this.a(var1, var3, var2);
}
public void c() {
}
public void a(eu var1) {
try {
if(this.H != null) {
var1.e(this.H);
this.H = null;
}
if(this.G instanceof hr) {
hr var2 = (hr)this.G;
int var3 = gd.d((float)((int)var1.aF)) >> 4;
int var4 = gd.d((float)((int)var1.aH)) >> 4;
var2.c(var3, var4);
}
this.a((nl)var1);
} catch (Exception var5) {
var5.printStackTrace();
}
}
public void a(boolean var1, ru var2) {
if(this.G.b()) {
if(var2 != null) {
var2.b("Saving level");
}
this.r();
if(var2 != null) {
var2.d("Saving chunks");
}
this.G.a(var1, var2);
if (var2 != null) {
RegionFileCache.clear();
}
}
}
private void r() {
this.o();
jw var1 = new jw();
var1.a("RandomSeed", this.u);
var1.a("SpawnX", (int)this.m);
var1.a("SpawnY", (int)this.n);
var1.a("SpawnZ", (int)this.o);
var1.a("Time", this.e);
var1.a("SizeOnDisk", this.v);
var1.a("LastPlayed", System.currentTimeMillis());
eu var2 = null;
if(this.d.size() > 0) {
var2 = (eu)this.d.get(0);
}
jw var3;
if(var2 != null) {
var3 = new jw();
var2.d(var3);
var1.a("Player", (jw)var3);
}
var3 = new jw();
var3.a("Data", (fy)var1);
try {
File var4 = new File(this.t, "level.dat_new");
File var5 = new File(this.t, "level.dat_old");
File var6 = new File(this.t, "level.dat");
ag.a(var3, (OutputStream)(new FileOutputStream(var4)));
if(var5.exists()) {
var5.delete();
}
var6.renameTo(var5);
if(var6.exists()) {
var6.delete();
}
var4.renameTo(var6);
if(var4.exists()) {
var4.delete();
}
} catch (Exception var7) {
var7.printStackTrace();
}
}
public boolean a(int var1) {
if(!this.G.b()) {
return true;
} else {
if(var1 == 0) {
this.r();
}
return this.G.a(false, (ru)null);
}
}
public int a(int var1, int var2, int var3) {
return var1 >= -32000000 && var3 >= -32000000 && var1 < 32000000 && var3 <= 32000000?(var2 < 0?0:(var2 >= 128?0:this.c(var1 >> 4, var3 >> 4).a(var1 & 15, var2, var3 & 15))):0;
}
public boolean d(int var1, int var2, int var3) {
return this.a(var1, var2, var3) == 0;
}
public boolean h(int var1, int var2, int var3) {
return var2 >= 0 && var2 < 128?this.g(var1 >> 4, var3 >> 4):false;
}
public boolean a(int var1, int var2, int var3, int var4) {
return this.a(var1 - var4, var2 - var4, var3 - var4, var1 + var4, var2 + var4, var3 + var4);
}
public boolean a(int var1, int var2, int var3, int var4, int var5, int var6) {
if(var5 >= 0 && var2 < 128) {
var1 >>= 4;
var2 >>= 4;
var3 >>= 4;
var4 >>= 4;
var5 >>= 4;
var6 >>= 4;
for(int var7 = var1; var7 <= var4; ++var7) {
for(int var8 = var3; var8 <= var6; ++var8) {
if(!this.g(var7, var8)) {
return false;
}
}
}
return true;
} else {
return false;
}
}
private boolean g(int var1, int var2) {
return this.G.a(var1, var2);
}
public ib b(int var1, int var2) {
return this.c(var1 >> 4, var2 >> 4);
}
public ib c(int var1, int var2) {
return this.G.b(var1, var2);
}
public boolean a(int var1, int var2, int var3, int var4, int var5) {
if(var1 >= -32000000 && var3 >= -32000000 && var1 < 32000000 && var3 <= 32000000) {
if(var2 < 0) {
return false;
} else if(var2 >= 128) {
return false;
} else {
ib var6 = this.c(var1 >> 4, var3 >> 4);
return var6.a(var1 & 15, var2, var3 & 15, var4, var5);
}
} else {
return false;
}
}
public boolean b(int var1, int var2, int var3, int var4) {
if(var1 >= -32000000 && var3 >= -32000000 && var1 < 32000000 && var3 <= 32000000) {
if(var2 < 0) {
return false;
} else if(var2 >= 128) {
return false;
} else {
ib var5 = this.c(var1 >> 4, var3 >> 4);
return var5.a(var1 & 15, var2, var3 & 15, var4);
}
} else {
return false;
}
}
public ic f(int var1, int var2, int var3) {
int var4 = this.a(var1, var2, var3);
return var4 == 0?ic.a:pj.m[var4].bt;
}
public int e(int var1, int var2, int var3) {
if(var1 >= -32000000 && var3 >= -32000000 && var1 < 32000000 && var3 <= 32000000) {
if(var2 < 0) {
return 0;
} else if(var2 >= 128) {
return 0;
} else {
ib var4 = this.c(var1 >> 4, var3 >> 4);
var1 &= 15;
var3 &= 15;
return var4.b(var1, var2, var3);
}
} else {
return 0;
}
}
public void c(int var1, int var2, int var3, int var4) {
if(this.d(var1, var2, var3, var4)) {
this.f(var1, var2, var3, this.a(var1, var2, var3));
}
}
public boolean d(int var1, int var2, int var3, int var4) {
if(var1 >= -32000000 && var3 >= -32000000 && var1 < 32000000 && var3 <= 32000000) {
if(var2 < 0) {
return false;
} else if(var2 >= 128) {
return false;
} else {
ib var5 = this.c(var1 >> 4, var3 >> 4);
var1 &= 15;
var3 &= 15;
var5.b(var1, var2, var3, var4);
return true;
}
} else {
return false;
}
}
public boolean e(int var1, int var2, int var3, int var4) {
if(this.b(var1, var2, var3, var4)) {
this.f(var1, var2, var3, var4);
return true;
} else {
return false;
}
}
public boolean b(int var1, int var2, int var3, int var4, int var5) {
if(this.a(var1, var2, var3, var4, var5)) {
this.f(var1, var2, var3, var4);
return true;
} else {
return false;
}
}
public void i(int var1, int var2, int var3) {
for(int var4 = 0; var4 < this.r.size(); ++var4) {
((lc)this.r.get(var4)).a(var1, var2, var3);
}
}
protected void f(int var1, int var2, int var3, int var4) {
this.i(var1, var2, var3);
this.h(var1, var2, var3, var4);
}
public void g(int var1, int var2, int var3, int var4) {
if(var3 > var4) {
int var5 = var4;
var4 = var3;
var3 = var5;
}
this.b(var1, var3, var2, var1, var4, var2);
}
public void j(int var1, int var2, int var3) {
for(int var4 = 0; var4 < this.r.size(); ++var4) {
((lc)this.r.get(var4)).b(var1, var2, var3, var1, var2, var3);
}
}
public void b(int var1, int var2, int var3, int var4, int var5, int var6) {
for(int var7 = 0; var7 < this.r.size(); ++var7) {
((lc)this.r.get(var7)).b(var1, var2, var3, var4, var5, var6);
}
}
public void h(int var1, int var2, int var3, int var4) {
this.m(var1 - 1, var2, var3, var4);
this.m(var1 + 1, var2, var3, var4);
this.m(var1, var2 - 1, var3, var4);
this.m(var1, var2 + 1, var3, var4);
this.m(var1, var2, var3 - 1, var4);
this.m(var1, var2, var3 + 1, var4);
}
private void m(int var1, int var2, int var3, int var4) {
if(!this.i && !this.z) {
pj var5 = pj.m[this.a(var1, var2, var3)];
if(var5 != null) {
var5.a((dn)this, var1, var2, var3, var4);
}
}
}
public boolean k(int var1, int var2, int var3) {
return this.c(var1 >> 4, var3 >> 4).c(var1 & 15, var2, var3 & 15);
}
public int l(int var1, int var2, int var3) {
return this.a(var1, var2, var3, true);
}
public int a(int var1, int var2, int var3, boolean var4) {
if(var1 >= -32000000 && var3 >= -32000000 && var1 < 32000000 && var3 <= 32000000) {
int var5;
if(var4) {
var5 = this.a(var1, var2, var3);
if(var5 == pj.ak.bi || var5 == pj.aA.bi) {
int var6 = this.a(var1, var2 + 1, var3, false);
int var7 = this.a(var1 + 1, var2, var3, false);
int var8 = this.a(var1 - 1, var2, var3, false);
int var9 = this.a(var1, var2, var3 + 1, false);
int var10 = this.a(var1, var2, var3 - 1, false);
if(var7 > var6) {
var6 = var7;
}
if(var8 > var6) {
var6 = var8;
}
if(var9 > var6) {
var6 = var9;
}
if(var10 > var6) {
var6 = var10;
}
return var6;
}
}
if(var2 < 0) {
return 0;
} else if(var2 >= 128) {
var5 = 15 - this.f;
if(var5 < 0) {
var5 = 0;
}
return var5;
} else {
ib var11 = this.c(var1 >> 4, var3 >> 4);
var1 &= 15;
var3 &= 15;
return var11.c(var1, var2, var3, this.f);
}
} else {
return 15;
}
}
public boolean m(int var1, int var2, int var3) {
if(var1 >= -32000000 && var3 >= -32000000 && var1 < 32000000 && var3 <= 32000000) {
if(var2 < 0) {
return false;
} else if(var2 >= 128) {
return true;
} else if(!this.g(var1 >> 4, var3 >> 4)) {
return false;
} else {
ib var4 = this.c(var1 >> 4, var3 >> 4);
var1 &= 15;
var3 &= 15;
return var4.c(var1, var2, var3);
}
} else {
return false;
}
}
public int d(int var1, int var2) {
if(var1 >= -32000000 && var2 >= -32000000 && var1 < 32000000 && var2 <= 32000000) {
if(!this.g(var1 >> 4, var2 >> 4)) {
return 0;
} else {
ib var3 = this.c(var1 >> 4, var2 >> 4);
return var3.b(var1 & 15, var2 & 15);
}
} else {
return 0;
}
}
public void a(cs var1, int var2, int var3, int var4, int var5) {
if(!this.q.e || var1 != cs.a) {
if(this.h(var2, var3, var4)) {
if(var1 == cs.a) {
if(this.m(var2, var3, var4)) {
var5 = 15;
}
} else if(var1 == cs.b) {
int var6 = this.a(var2, var3, var4);
if(pj.s[var6] > var5) {
var5 = pj.s[var6];
}
}
if(this.a((cs)var1, var2, var3, var4) != var5) {
this.a(var1, var2, var3, var4, var2, var3, var4);
}
}
}
}
public int a(cs var1, int var2, int var3, int var4) {
if(var3 >= 0 && var3 < 128 && var2 >= -32000000 && var4 >= -32000000 && var2 < 32000000 && var4 <= 32000000) {
int var5 = var2 >> 4;
int var6 = var4 >> 4;
if(!this.g(var5, var6)) {
return 0;
} else {
ib var7 = this.c(var5, var6);
return var7.a(var1, var2 & 15, var3, var4 & 15);
}
} else {
return var1.c;
}
}
public void b(cs var1, int var2, int var3, int var4, int var5) {
if(var2 >= -32000000 && var4 >= -32000000 && var2 < 32000000 && var4 <= 32000000) {
if(var3 >= 0) {
if(var3 < 128) {
if(this.g(var2 >> 4, var4 >> 4)) {
ib var6 = this.c(var2 >> 4, var4 >> 4);
var6.a(var1, var2 & 15, var3, var4 & 15, var5);
for(int var7 = 0; var7 < this.r.size(); ++var7) {
((lc)this.r.get(var7)).a(var2, var3, var4);
}
}
}
}
}
}
public float c(int var1, int var2, int var3) {
return this.q.f[this.l(var1, var2, var3)];
}
public boolean d() {
return this.f < 4;
}
public pr a(ax var1, ax var2) {
return this.a(var1, var2, false);
}
public pr a(ax var1, ax var2, boolean var3) {
if(!Double.isNaN(var1.a) && !Double.isNaN(var1.b) && !Double.isNaN(var1.c)) {
if(!Double.isNaN(var2.a) && !Double.isNaN(var2.b) && !Double.isNaN(var2.c)) {
int var4 = gd.b(var2.a);
int var5 = gd.b(var2.b);
int var6 = gd.b(var2.c);
int var7 = gd.b(var1.a);
int var8 = gd.b(var1.b);
int var9 = gd.b(var1.c);
int var10 = 200;
while(var10-- >= 0) {
if(Double.isNaN(var1.a) || Double.isNaN(var1.b) || Double.isNaN(var1.c)) {
return null;
}
if(var7 == var4 && var8 == var5 && var9 == var6) {
return null;
}
double var11 = 999.0D;
double var13 = 999.0D;
double var15 = 999.0D;
if(var4 > var7) {
var11 = (double)var7 + 1.0D;
}
if(var4 < var7) {
var11 = (double)var7 + 0.0D;
}
if(var5 > var8) {
var13 = (double)var8 + 1.0D;
}
if(var5 < var8) {
var13 = (double)var8 + 0.0D;
}
if(var6 > var9) {
var15 = (double)var9 + 1.0D;
}
if(var6 < var9) {
var15 = (double)var9 + 0.0D;
}
double var17 = 999.0D;
double var19 = 999.0D;
double var21 = 999.0D;
double var23 = var2.a - var1.a;
double var25 = var2.b - var1.b;
double var27 = var2.c - var1.c;
if(var11 != 999.0D) {
var17 = (var11 - var1.a) / var23;
}
if(var13 != 999.0D) {
var19 = (var13 - var1.b) / var25;
}
if(var15 != 999.0D) {
var21 = (var15 - var1.c) / var27;
}
boolean var29 = false;
byte var35;
if(var17 < var19 && var17 < var21) {
if(var4 > var7) {
var35 = 4;
} else {
var35 = 5;
}
var1.a = var11;
var1.b += var25 * var17;
var1.c += var27 * var17;
} else if(var19 < var21) {
if(var5 > var8) {
var35 = 0;
} else {
var35 = 1;
}
var1.a += var23 * var19;
var1.b = var13;
var1.c += var27 * var19;
} else {
if(var6 > var9) {
var35 = 2;
} else {
var35 = 3;
}
var1.a += var23 * var21;
var1.b += var25 * var21;
var1.c = var15;
}
ax var30 = ax.b(var1.a, var1.b, var1.c);
var7 = (int)(var30.a = (double)gd.b(var1.a));
if(var35 == 5) {
--var7;
++var30.a;
}
var8 = (int)(var30.b = (double)gd.b(var1.b));
if(var35 == 1) {
--var8;
++var30.b;
}
var9 = (int)(var30.c = (double)gd.b(var1.c));
if(var35 == 3) {
--var9;
++var30.c;
}
int var31 = this.a(var7, var8, var9);
int var32 = this.e(var7, var8, var9);
pj var33 = pj.m[var31];
if(var31 > 0 && var33.a(var32, var3)) {
pr var34 = var33.a(this, var7, var8, var9, (ax)var1, (ax)var2);
if(var34 != null) {
return var34;
}
}
}
return null;
} else {
return null;
}
} else {
return null;
}
}
public void a(nl var1, String var2, float var3, float var4) {
for(int var5 = 0; var5 < this.r.size(); ++var5) {
((lc)this.r.get(var5)).a(var2, var1.aF, var1.aG - (double)var1.aX, var1.aH, var3, var4);
}
}
public void a(double var1, double var3, double var5, String var7, float var8, float var9) {
for(int var10 = 0; var10 < this.r.size(); ++var10) {
((lc)this.r.get(var10)).a(var7, var1, var3, var5, var8, var9);
}
}
public void a(String var1, int var2, int var3, int var4) {
for(int var5 = 0; var5 < this.r.size(); ++var5) {
((lc)this.r.get(var5)).a(var1, var2, var3, var4);
}
}
public void a(String var1, double var2, double var4, double var6, double var8, double var10, double var12) {
for(int var14 = 0; var14 < this.r.size(); ++var14) {
((lc)this.r.get(var14)).a(var1, var2, var4, var6, var8, var10, var12);
}
}
public boolean a(nl var1) {
int var2 = gd.b(var1.aF / 16.0D);
int var3 = gd.b(var1.aH / 16.0D);
boolean var4 = false;
if(var1 instanceof eu) {
var4 = true;
}
if(!var4 && !this.g(var2, var3)) {
return false;
} else {
if(var1 instanceof eu) {
eu var5 = (eu)var1;
this.d.add(var5);
System.out.println("Player count: " + this.d.size());
}
this.c(var2, var3).a((nl)var1);
this.b.add(var1);
this.b((nl)var1);
return true;
}
}
protected void b(nl var1) {
for(int var2 = 0; var2 < this.r.size(); ++var2) {
((lc)this.r.get(var2)).a(var1);
}
}
protected void c(nl var1) {
for(int var2 = 0; var2 < this.r.size(); ++var2) {
((lc)this.r.get(var2)).b(var1);
}
}
public void d(nl var1) {
if(var1.az != null) {
var1.az.i((nl)null);
}
if(var1.aA != null) {
var1.i((nl)null);
}
var1.F();
if(var1 instanceof eu) {
this.d.remove((eu)var1);
}
}
public void a(lc var1) {
this.r.add(var1);
}
public void b(lc var1) {
this.r.remove(var1);
}
public List a(nl var1, db var2) {
this.I.clear();
int var3 = gd.b(var2.a);
int var4 = gd.b(var2.d + 1.0D);
int var5 = gd.b(var2.b);
int var6 = gd.b(var2.e + 1.0D);
int var7 = gd.b(var2.c);
int var8 = gd.b(var2.f + 1.0D);
for(int var9 = var3; var9 < var4; ++var9) {
for(int var10 = var7; var10 < var8; ++var10) {
if(this.h(var9, 64, var10)) {
for(int var11 = var5 - 1; var11 < var6; ++var11) {
pj var12 = pj.m[this.a(var9, var11, var10)];
if(var12 != null) {
var12.a(this, var9, var11, var10, (db)var2, (ArrayList)this.I);
}
}
}
}
}
double var14 = 0.25D;
List var16 = this.b((nl)var1, (db)var2.b(var14, var14, var14));
for(int var15 = 0; var15 < var16.size(); ++var15) {
db var13 = ((nl)var16.get(var15)).i_();
if(var13 != null && var13.a((db)var2)) {
this.I.add(var13);
}
var13 = var1.a((nl)((nl)var16.get(var15)));
if(var13 != null && var13.a((db)var2)) {
this.I.add(var13);
}
}
return this.I;
}
public int a(float var1) {
float var2 = this.b(var1);
float var3 = 1.0F - (gd.b(var2 * 3.1415927F * 2.0F) * 2.0F + 0.5F);
if(var3 < 0.0F) {
var3 = 0.0F;
}
if(var3 > 1.0F) {
var3 = 1.0F;
}
return (int)(var3 * 11.0F);
}
public ax a(nl var1, float var2) {
float var3 = this.b(var2);
float var4 = gd.b(var3 * 3.1415927F * 2.0F) * 2.0F + 0.5F;
if(var4 < 0.0F) {
var4 = 0.0F;
}
if(var4 > 1.0F) {
var4 = 1.0F;
}
int var5 = gd.b(var1.aF);
int var6 = gd.b(var1.aH);
float var7 = (float)this.a().b(var5, var6);
int var8 = this.a().a(var5, var6).a(var7);
float var9 = (float)(var8 >> 16 & 255) / 255.0F;
float var10 = (float)(var8 >> 8 & 255) / 255.0F;
float var11 = (float)(var8 & 255) / 255.0F;
var9 *= var4;
var10 *= var4;
var11 *= var4;
return ax.b((double)var9, (double)var10, (double)var11);
}
public float b(float var1) {
return this.q.a(this.e, var1);
}
public ax c(float var1) {
float var2 = this.b(var1);
float var3 = gd.b(var2 * 3.1415927F * 2.0F) * 2.0F + 0.5F;
if(var3 < 0.0F) {
var3 = 0.0F;
}
if(var3 > 1.0F) {
var3 = 1.0F;
}
float var4 = (float)(this.E >> 16 & 255L) / 255.0F;
float var5 = (float)(this.E >> 8 & 255L) / 255.0F;
float var6 = (float)(this.E & 255L) / 255.0F;
var4 *= var3 * 0.9F + 0.1F;
var5 *= var3 * 0.9F + 0.1F;
var6 *= var3 * 0.85F + 0.15F;
return ax.b((double)var4, (double)var5, (double)var6);
}
public ax d(float var1) {
float var2 = this.b(var1);
return this.q.a(var2, var1);
}
public int e(int var1, int var2) {
ib var3 = this.b(var1, var2);
int var4;
for(var4 = 127; this.f(var1, var4, var2).c() && var4 > 0; --var4) {
;
}
var1 &= 15;
for(var2 &= 15; var4 > 0; --var4) {
int var5 = var3.a(var1, var4, var2);
if(var5 != 0 && (pj.m[var5].bt.c() || pj.m[var5].bt.d())) {
return var4 + 1;
}
}
return -1;
}
public int f(int var1, int var2) {
return this.b(var1, var2).b(var1 & 15, var2 & 15);
}
public float e(float var1) {
float var2 = this.b(var1);
float var3 = 1.0F - (gd.b(var2 * 3.1415927F * 2.0F) * 2.0F + 0.75F);
if(var3 < 0.0F) {
var3 = 0.0F;
}
if(var3 > 1.0F) {
var3 = 1.0F;
}
return var3 * var3 * 0.5F;
}
public void i(int var1, int var2, int var3, int var4) {
md var5 = new md(var1, var2, var3, var4);
byte var6 = 8;
if(this.a) {
if(this.a(var5.a - var6, var5.b - var6, var5.c - var6, var5.a + var6, var5.b + var6, var5.c + var6)) {
int var7 = this.a(var5.a, var5.b, var5.c);
if(var7 == var5.d && var7 > 0) {
pj.m[var7].a(this, var5.a, var5.b, var5.c, (Random)this.l);
}
}
} else {
if(this.a(var1 - var6, var2 - var6, var3 - var6, var1 + var6, var2 + var6, var3 + var6)) {
if(var4 > 0) {
var5.a((long)pj.m[var4].d() + this.e);
}
if(!this.D.contains(var5)) {
this.D.add(var5);
this.C.add(var5);
}
}
}
}
public void e() {
this.b.removeAll(this.B);
int var1;
nl var2;
int var3;
int var4;
for(var1 = 0; var1 < this.B.size(); ++var1) {
var2 = (nl)this.B.get(var1);
var3 = var2.bz;
var4 = var2.bB;
if(var2.by && this.g(var3, var4)) {
this.c(var3, var4).b(var2);
}
}
for(var1 = 0; var1 < this.B.size(); ++var1) {
this.c((nl)((nl)this.B.get(var1)));
}
this.B.clear();
for(var1 = 0; var1 < this.b.size(); ++var1) {
var2 = (nl)this.b.get(var1);
if(var2.aA != null) {
if(!var2.aA.aW && var2.aA.az == var2) {
continue;
}
var2.aA.az = null;
var2.aA = null;
}
if(!var2.aW) {
this.e(var2);
}
if(var2.aW) {
var3 = var2.bz;
var4 = var2.bB;
if(var2.by && this.g(var3, var4)) {
this.c(var3, var4).b(var2);
}
this.b.remove(var1--);
this.c((nl)var2);
}
}
for(var1 = 0; var1 < this.c.size(); ++var1) {
kp var5 = (kp)this.c.get(var1);
var5.m_();
}
}
public void e(nl var1) {
this.a(var1, true);
}
public void a(nl var1, boolean var2) {
int var3 = gd.b(var1.aF);
int var4 = gd.b(var1.aH);
byte var5 = 32;
if(!var2 || this.a(var3 - var5, 0, var4 - var5, var3 + var5, 128, var4 + var5)) {
var1.be = var1.aF;
var1.bf = var1.aG;
var1.bg = var1.aH;
var1.aN = var1.aL;
var1.aO = var1.aM;
if(var2 && var1.by) {
if(var1.aA != null) {
var1.w();
} else {
var1.q_();
}
}
if(Double.isNaN(var1.aF) || Double.isInfinite(var1.aF)) {
var1.aF = var1.be;
}
if(Double.isNaN(var1.aG) || Double.isInfinite(var1.aG)) {
var1.aG = var1.bf;
}
if(Double.isNaN(var1.aH) || Double.isInfinite(var1.aH)) {
var1.aH = var1.bg;
}
if(Double.isNaN((double)var1.aM) || Double.isInfinite((double)var1.aM)) {
var1.aM = var1.aO;
}
if(Double.isNaN((double)var1.aL) || Double.isInfinite((double)var1.aL)) {
var1.aL = var1.aN;
}
int var6 = gd.b(var1.aF / 16.0D);
int var7 = gd.b(var1.aG / 16.0D);
int var8 = gd.b(var1.aH / 16.0D);
if(!var1.by || var1.bz != var6 || var1.bA != var7 || var1.bB != var8) {
if(var1.by && this.g(var1.bz, var1.bB)) {
this.c(var1.bz, var1.bB).a(var1, var1.bA);
}
if(this.g(var6, var8)) {
var1.by = true;
this.c(var6, var8).a((nl)var1);
} else {
var1.by = false;
}
}
if(var2 && var1.by && var1.az != null) {
if(!var1.az.aW && var1.az.aA == var1) {
this.e(var1.az);
} else {
var1.az.aA = null;
var1.az = null;
}
}
}
}
public boolean a(db var1) {
List var2 = this.b((nl)null, (db)var1);
for(int var3 = 0; var3 < var2.size(); ++var3) {
nl var4 = (nl)var2.get(var3);
if(!var4.aW && var4.ay) {
return false;
}
}
return true;
}
public boolean b(db var1) {
int var2 = gd.b(var1.a);
int var3 = gd.b(var1.d + 1.0D);
int var4 = gd.b(var1.b);
int var5 = gd.b(var1.e + 1.0D);
int var6 = gd.b(var1.c);
int var7 = gd.b(var1.f + 1.0D);
if(var1.a < 0.0D) {
--var2;
}
if(var1.b < 0.0D) {
--var4;
}
if(var1.c < 0.0D) {
--var6;
}
for(int var8 = var2; var8 < var3; ++var8) {
for(int var9 = var4; var9 < var5; ++var9) {
for(int var10 = var6; var10 < var7; ++var10) {
pj var11 = pj.m[this.a(var8, var9, var10)];
if(var11 != null && var11.bt.d()) {
return true;
}
}
}
}
return false;
}
public boolean c(db var1) {
int var2 = gd.b(var1.a);
int var3 = gd.b(var1.d + 1.0D);
int var4 = gd.b(var1.b);
int var5 = gd.b(var1.e + 1.0D);
int var6 = gd.b(var1.c);
int var7 = gd.b(var1.f + 1.0D);
if(this.a(var2, var4, var6, var3, var5, var7)) {
for(int var8 = var2; var8 < var3; ++var8) {
for(int var9 = var4; var9 < var5; ++var9) {
for(int var10 = var6; var10 < var7; ++var10) {
int var11 = this.a(var8, var9, var10);
if(var11 == pj.ar.bi || var11 == pj.C.bi || var11 == pj.D.bi) {
return true;
}
}
}
}
}
return false;
}
public boolean a(db var1, ic var2, nl var3) {
int var4 = gd.b(var1.a);
int var5 = gd.b(var1.d + 1.0D);
int var6 = gd.b(var1.b);
int var7 = gd.b(var1.e + 1.0D);
int var8 = gd.b(var1.c);
int var9 = gd.b(var1.f + 1.0D);
if(!this.a(var4, var6, var8, var5, var7, var9)) {
return false;
} else {
boolean var10 = false;
ax var11 = ax.b(0.0D, 0.0D, 0.0D);
for(int var12 = var4; var12 < var5; ++var12) {
for(int var13 = var6; var13 < var7; ++var13) {
for(int var14 = var8; var14 < var9; ++var14) {
pj var15 = pj.m[this.a(var12, var13, var14)];
if(var15 != null && var15.bt == var2) {
double var16 = (double)((float)(var13 + 1) - mq.c(this.e(var12, var13, var14)));
if((double)var7 >= var16) {
var10 = true;
var15.a(this, var12, var13, var14, (nl)var3, (ax)var11);
}
}
}
}
}
if(var11.c() > 0.0D) {
var11 = var11.b();
double var18 = 0.0040D;
var3.aI += var11.a * var18;
var3.aJ += var11.b * var18;
var3.aK += var11.c * var18;
}
return var10;
}
}
public boolean a(db var1, ic var2) {
int var3 = gd.b(var1.a);
int var4 = gd.b(var1.d + 1.0D);
int var5 = gd.b(var1.b);
int var6 = gd.b(var1.e + 1.0D);
int var7 = gd.b(var1.c);
int var8 = gd.b(var1.f + 1.0D);
for(int var9 = var3; var9 < var4; ++var9) {
for(int var10 = var5; var10 < var6; ++var10) {
for(int var11 = var7; var11 < var8; ++var11) {
pj var12 = pj.m[this.a(var9, var10, var11)];
if(var12 != null && var12.bt == var2) {
return true;
}
}
}
}
return false;
}
public boolean b(db var1, ic var2) {
int var3 = gd.b(var1.a);
int var4 = gd.b(var1.d + 1.0D);
int var5 = gd.b(var1.b);
int var6 = gd.b(var1.e + 1.0D);
int var7 = gd.b(var1.c);
int var8 = gd.b(var1.f + 1.0D);
for(int var9 = var3; var9 < var4; ++var9) {
for(int var10 = var5; var10 < var6; ++var10) {
for(int var11 = var7; var11 < var8; ++var11) {
pj var12 = pj.m[this.a(var9, var10, var11)];
if(var12 != null && var12.bt == var2) {
int var13 = this.e(var9, var10, var11);
double var14 = (double)(var10 + 1);
if(var13 < 8) {
var14 = (double)(var10 + 1) - (double)var13 / 8.0D;
}
if(var14 >= var1.b) {
return true;
}
}
}
}
}
return false;
}
public mc a(nl var1, double var2, double var4, double var6, float var8) {
return this.a(var1, var2, var4, var6, var8, false);
}
public mc a(nl var1, double var2, double var4, double var6, float var8, boolean var9) {
mc var10 = new mc(this, var1, var2, var4, var6, var8);
var10.a = var9;
var10.a();
var10.b();
return var10;
}
public float a(ax var1, db var2) {
double var3 = 1.0D / ((var2.d - var2.a) * 2.0D + 1.0D);
double var5 = 1.0D / ((var2.e - var2.b) * 2.0D + 1.0D);
double var7 = 1.0D / ((var2.f - var2.c) * 2.0D + 1.0D);
int var9 = 0;
int var10 = 0;
for(float var11 = 0.0F; var11 <= 1.0F; var11 = (float)((double)var11 + var3)) {
for(float var12 = 0.0F; var12 <= 1.0F; var12 = (float)((double)var12 + var5)) {
for(float var13 = 0.0F; var13 <= 1.0F; var13 = (float)((double)var13 + var7)) {
double var14 = var2.a + (var2.d - var2.a) * (double)var11;
double var16 = var2.b + (var2.e - var2.b) * (double)var12;
double var18 = var2.c + (var2.f - var2.c) * (double)var13;
if(this.a((ax)ax.b(var14, var16, var18), (ax)var1) == null) {
++var9;
}
++var10;
}
}
}
return (float)var9 / (float)var10;
}
public void j(int var1, int var2, int var3, int var4) {
if(var4 == 0) {
--var2;
}
if(var4 == 1) {
++var2;
}
if(var4 == 2) {
--var3;
}
if(var4 == 3) {
++var3;
}
if(var4 == 4) {
--var1;
}
if(var4 == 5) {
++var1;
}
if(this.a(var1, var2, var3) == pj.ar.bi) {
this.a((double)((float)var1 + 0.5F), (double)((float)var2 + 0.5F), (double)((float)var3 + 0.5F), "random.fizz", 0.5F, 2.6F + (this.l.nextFloat() - this.l.nextFloat()) * 0.8F);
this.e(var1, var2, var3, 0);
}
}
public nl a(Class var1) {
return null;
}
public String f() {
return "All: " + this.b.size();
}
public String g() {
return this.G.c();
}
public kp b(int var1, int var2, int var3) {
ib var4 = this.c(var1 >> 4, var3 >> 4);
return var4 != null?var4.d(var1 & 15, var2, var3 & 15):null;
}
public void a(int var1, int var2, int var3, kp var4) {
ib var5 = this.c(var1 >> 4, var3 >> 4);
if(var5 != null) {
var5.a(var1 & 15, var2, var3 & 15, var4);
}
}
public void n(int var1, int var2, int var3) {
ib var4 = this.c(var1 >> 4, var3 >> 4);
if(var4 != null) {
var4.e(var1 & 15, var2, var3 & 15);
}
}
public boolean g(int var1, int var2, int var3) {
pj var4 = pj.m[this.a(var1, var2, var3)];
return var4 == null?false:var4.a();
}
public void a(ru var1) {
this.a(true, var1);
}
public boolean h() {
if(this.J >= 50) {
return false;
} else {
++this.J;
boolean var2;
try {
int var1 = 500;
while(this.A.size() > 0) {
--var1;
if(var1 <= 0) {
var2 = true;
return var2;
}
((nr)this.A.remove(this.A.size() - 1)).a(this);
}
var2 = false;
} finally {
--this.J;
}
return var2;
}
}
public void a(cs var1, int var2, int var3, int var4, int var5, int var6, int var7) {
this.a(var1, var2, var3, var4, var5, var6, var7, true);
}
public void a(cs var1, int var2, int var3, int var4, int var5, int var6, int var7, boolean var8) {
if(!this.q.e || var1 != cs.a) {
++y;
if(y == 50) {
--y;
} else {
int var9 = (var5 + var2) / 2;
int var10 = (var7 + var4) / 2;
if(!this.h(var9, 64, var10)) {
--y;
} else if(!this.b(var9, var10).h()) {
int var11 = this.A.size();
int var12;
if(var8) {
var12 = 5;
if(var12 > var11) {
var12 = var11;
}
for(int var13 = 0; var13 < var12; ++var13) {
nr var14 = (nr)this.A.get(this.A.size() - var13 - 1);
if(var14.a == var1 && var14.a(var2, var3, var4, var5, var6, var7)) {
--y;
return;
}
}
}
this.A.add(new nr(var1, var2, var3, var4, var5, var6, var7));
var12 = 1000000;
if(this.A.size() > 1000000) {
System.out.println("More than " + var12 + " updates, aborting lighting updates");
this.A.clear();
}
--y;
}
}
}
}
public void i() {
int var1 = this.a(1.0F);
if(var1 != this.f) {
this.f = var1;
}
}
public void a(boolean var1, boolean var2) {
this.K = var1;
this.L = var2;
}
public void j() {
bp.a(this, this.K, this.L);
this.G.a();
int var1 = this.a(1.0F);
if(var1 != this.f) {
this.f = var1;
for(int var2 = 0; var2 < this.r.size(); ++var2) {
((lc)this.r.get(var2)).e();
}
}
++this.e;
if(this.e % (long)this.j == 0L) {
this.a(false, (ru)null);
}
this.a(false);
this.k();
}
protected void k() {
this.M.clear();
int var3;
int var4;
int var6;
int var7;
for(int var1 = 0; var1 < this.d.size(); ++var1) {
eu var2 = (eu)this.d.get(var1);
var3 = gd.b(var2.aF / 16.0D);
var4 = gd.b(var2.aH / 16.0D);
byte var5 = 9;
for(var6 = -var5; var6 <= var5; ++var6) {
for(var7 = -var5; var7 <= var5; ++var7) {
this.M.add(new sn(var6 + var3, var7 + var4));
}
}
}
if(this.N > 0) {
--this.N;
}
Iterator var12 = this.M.iterator();
while(var12.hasNext()) {
sn var13 = (sn)var12.next();
var3 = var13.a * 16;
var4 = var13.b * 16;
ib var14 = this.c(var13.a, var13.b);
int var8;
int var9;
int var10;
if(this.N == 0) {
this.g = this.g * 3 + this.h;
var6 = this.g >> 2;
var7 = var6 & 15;
var8 = var6 >> 8 & 15;
var9 = var6 >> 16 & 127;
var10 = var14.a(var7, var9, var8);
var7 += var3;
var8 += var4;
if(var10 == 0 && this.l(var7, var9, var8) <= this.l.nextInt(8) && this.a((cs)cs.a, var7, var9, var8) <= 0) {
eu var11 = this.a((double)var7 + 0.5D, (double)var9 + 0.5D, (double)var8 + 0.5D, 8.0D);
if(var11 != null && var11.e((double)var7 + 0.5D, (double)var9 + 0.5D, (double)var8 + 0.5D) > 4.0D) {
this.a((double)var7 + 0.5D, (double)var9 + 0.5D, (double)var8 + 0.5D, "ambient.cave.cave", 0.7F, 0.8F + this.l.nextFloat() * 0.2F);
this.N = this.l.nextInt(12000) + 6000;
}
}
}
for(var6 = 0; var6 < 80; ++var6) {
this.g = this.g * 3 + this.h;
var7 = this.g >> 2;
var8 = var7 & 15;
var9 = var7 >> 8 & 15;
var10 = var7 >> 16 & 127;
byte var15 = var14.b[var8 << 11 | var9 << 7 | var10];
if(pj.n[var15]) {
pj.m[var15].a(this, var8 + var3, var10, var9 + var4, (Random)this.l);
}
}
}
}
public boolean a(boolean var1) {
int var2 = this.C.size();
if(var2 != this.D.size()) {
throw new IllegalStateException("TickNextTick list out of synch");
} else {
if(var2 > 1000) {
var2 = 1000;
}
for(int var3 = 0; var3 < var2; ++var3) {
md var4 = (md)this.C.first();
if(!var1 && var4.e > this.e) {
break;
}
this.C.remove(var4);
this.D.remove(var4);
byte var5 = 8;
if(this.a(var4.a - var5, var4.b - var5, var4.c - var5, var4.a + var5, var4.b + var5, var4.c + var5)) {
int var6 = this.a(var4.a, var4.b, var4.c);
if(var6 == var4.d && var6 > 0) {
pj.m[var6].a(this, var4.a, var4.b, var4.c, (Random)this.l);
}
}
}
return this.C.size() != 0;
}
}
public void o(int var1, int var2, int var3) {
byte var4 = 16;
Random var5 = new Random();
for(int var6 = 0; var6 < 1000; ++var6) {
int var7 = var1 + this.l.nextInt(var4) - this.l.nextInt(var4);
int var8 = var2 + this.l.nextInt(var4) - this.l.nextInt(var4);
int var9 = var3 + this.l.nextInt(var4) - this.l.nextInt(var4);
int var10 = this.a(var7, var8, var9);
if(var10 > 0) {
pj.m[var10].b(this, var7, var8, var9, (Random)var5);
}
}
}
public List b(nl var1, db var2) {
this.O.clear();
int var3 = gd.b((var2.a - 2.0D) / 16.0D);
int var4 = gd.b((var2.d + 2.0D) / 16.0D);
int var5 = gd.b((var2.c - 2.0D) / 16.0D);
int var6 = gd.b((var2.f + 2.0D) / 16.0D);
for(int var7 = var3; var7 <= var4; ++var7) {
for(int var8 = var5; var8 <= var6; ++var8) {
if(this.g(var7, var8)) {
this.c(var7, var8).a((nl)var1, var2, this.O);
}
}
}
return this.O;
}
public List a(Class var1, db var2) {
int var3 = gd.b((var2.a - 2.0D) / 16.0D);
int var4 = gd.b((var2.d + 2.0D) / 16.0D);
int var5 = gd.b((var2.c - 2.0D) / 16.0D);
int var6 = gd.b((var2.f + 2.0D) / 16.0D);
ArrayList var7 = new ArrayList();
for(int var8 = var3; var8 <= var4; ++var8) {
for(int var9 = var5; var9 <= var6; ++var9) {
if(this.g(var8, var9)) {
this.c(var8, var9).a((Class)var1, var2, var7);
}
}
}
return var7;
}
public List l() {
return this.b;
}
public void b(int var1, int var2, int var3, kp var4) {
if(this.h(var1, var2, var3)) {
this.b(var1, var3).g();
}
for(int var5 = 0; var5 < this.r.size(); ++var5) {
((lc)this.r.get(var5)).a(var1, var2, var3, var4);
}
}
public int b(Class var1) {
int var2 = 0;
for(int var3 = 0; var3 < this.b.size(); ++var3) {
nl var4 = (nl)this.b.get(var3);
if(var1.isAssignableFrom(var4.getClass())) {
++var2;
}
}
return var2;
}
public void a(List var1) {
this.b.addAll(var1);
for(int var2 = 0; var2 < var1.size(); ++var2) {
this.b((nl)((nl)var1.get(var2)));
}
}
public void b(List var1) {
this.B.addAll(var1);
}
public void m() {
while(this.G.a()) {
;
}
}
public boolean a(int var1, int var2, int var3, int var4, boolean var5) {
int var6 = this.a(var2, var3, var4);
pj var7 = pj.m[var6];
pj var8 = pj.m[var1];
db var9 = var8.d((dn)this, var2, var3, var4);
if(var5) {
var9 = null;
}
return var9 != null && !this.a((db)var9)?false:(var7 != pj.A && var7 != pj.B && var7 != pj.C && var7 != pj.D && var7 != pj.ar && var7 != pj.aS?var1 > 0 && var7 == null && var8.a((dn)this, var2, var3, var4):true);
}
public cc a(nl var1, nl var2, float var3) {
int var4 = gd.b(var1.aF);
int var5 = gd.b(var1.aG);
int var6 = gd.b(var1.aH);
int var7 = (int)(var3 + 16.0F);
int var8 = var4 - var7;
int var9 = var5 - var7;
int var10 = var6 - var7;
int var11 = var4 + var7;
int var12 = var5 + var7;
int var13 = var6 + var7;
dg var14 = new dg(this, var8, var9, var10, var11, var12, var13);
return (new ed(var14)).a(var1, var2, var3);
}
public cc a(nl var1, int var2, int var3, int var4, float var5) {
int var6 = gd.b(var1.aF);
int var7 = gd.b(var1.aG);
int var8 = gd.b(var1.aH);
int var9 = (int)(var5 + 8.0F);
int var10 = var6 - var9;
int var11 = var7 - var9;
int var12 = var8 - var9;
int var13 = var6 + var9;
int var14 = var7 + var9;
int var15 = var8 + var9;
dg var16 = new dg(this, var10, var11, var12, var13, var14, var15);
return (new ed(var16)).a(var1, var2, var3, var4, var5);
}
public boolean k(int var1, int var2, int var3, int var4) {
int var5 = this.a(var1, var2, var3);
return var5 == 0?false:pj.m[var5].c((dn)this, var1, var2, var3, var4);
}
public boolean p(int var1, int var2, int var3) {
return this.k(var1, var2 - 1, var3, 0)?true:(this.k(var1, var2 + 1, var3, 1)?true:(this.k(var1, var2, var3 - 1, 2)?true:(this.k(var1, var2, var3 + 1, 3)?true:(this.k(var1 - 1, var2, var3, 4)?true:this.k(var1 + 1, var2, var3, 5)))));
}
public boolean l(int var1, int var2, int var3, int var4) {
if(this.g(var1, var2, var3)) {
return this.p(var1, var2, var3);
} else {
int var5 = this.a(var1, var2, var3);
return var5 == 0?false:pj.m[var5].c((ri)this, var1, var2, var3, var4);
}
}
public boolean q(int var1, int var2, int var3) {
return this.l(var1, var2 - 1, var3, 0)?true:(this.l(var1, var2 + 1, var3, 1)?true:(this.l(var1, var2, var3 - 1, 2)?true:(this.l(var1, var2, var3 + 1, 3)?true:(this.l(var1 - 1, var2, var3, 4)?true:this.l(var1 + 1, var2, var3, 5)))));
}
public eu a(nl var1, double var2) {
return this.a(var1.aF, var1.aG, var1.aH, var2);
}
public eu a(double var1, double var3, double var5, double var7) {
double var9 = -1.0D;
eu var11 = null;
for(int var12 = 0; var12 < this.d.size(); ++var12) {
eu var13 = (eu)this.d.get(var12);
double var14 = var13.e(var1, var3, var5);
if((var7 < 0.0D || var14 < var7 * var7) && (var9 == -1.0D || var14 < var9)) {
var9 = var14;
var11 = var13;
}
}
return var11;
}
public void a(int var1, int var2, int var3, int var4, int var5, int var6, byte[] var7) {
int var8 = var1 >> 4;
int var9 = var3 >> 4;
int var10 = var1 + var4 - 1 >> 4;
int var11 = var3 + var6 - 1 >> 4;
int var12 = 0;
int var13 = var2;
int var14 = var2 + var5;
if(var2 < 0) {
var13 = 0;
}
if(var14 > 128) {
var14 = 128;
}
for(int var15 = var8; var15 <= var10; ++var15) {
int var16 = var1 - var15 * 16;
int var17 = var1 + var4 - var15 * 16;
if(var16 < 0) {
var16 = 0;
}
if(var17 > 16) {
var17 = 16;
}
for(int var18 = var9; var18 <= var11; ++var18) {
int var19 = var3 - var18 * 16;
int var20 = var3 + var6 - var18 * 16;
if(var19 < 0) {
var19 = 0;
}
if(var20 > 16) {
var20 = 16;
}
var12 = this.c(var15, var18).a(var7, var16, var13, var19, var17, var14, var20, var12);
this.b(var15 * 16 + var16, var13, var18 * 16 + var19, var15 * 16 + var17, var14, var18 * 16 + var20);
}
}
}
public void n() {
}
public void o() {
try {
File var1 = new File(this.t, "session.lock");
DataInputStream var2 = new DataInputStream(new FileInputStream(var1));
try {
if(var2.readLong() != this.F) {
throw new pi("The save is being accessed from another location, aborting");
}
} finally {
var2.close();
}
} catch (IOException var7) {
throw new pi("Failed to check session lock, aborting");
}
}
public void a(long var1) {
this.e = var1;
}
public void f(nl var1) {
int var2 = gd.b(var1.aF / 16.0D);
int var3 = gd.b(var1.aH / 16.0D);
byte var4 = 2;
for(int var5 = var2 - var4; var5 <= var2 + var4; ++var5) {
for(int var6 = var3 - var4; var6 <= var3 + var4; ++var6) {
this.c(var5, var6);
}
}
if(!this.b.contains(var1)) {
this.b.add(var1);
}
}
public boolean a(eu var1, int var2, int var3, int var4) {
return true;
}
public void a(nl var1, byte var2) {
}
public void p() {
this.b.removeAll(this.B);
int var1;
nl var2;
int var3;
int var4;
for(var1 = 0; var1 < this.B.size(); ++var1) {
var2 = (nl)this.B.get(var1);
var3 = var2.bz;
var4 = var2.bB;
if(var2.by && this.g(var3, var4)) {
this.c(var3, var4).b(var2);
}
}
for(var1 = 0; var1 < this.B.size(); ++var1) {
this.c((nl)((nl)this.B.get(var1)));
}
this.B.clear();
for(var1 = 0; var1 < this.b.size(); ++var1) {
var2 = (nl)this.b.get(var1);
if(var2.aA != null) {
if(!var2.aA.aW && var2.aA.az == var2) {
continue;
}
var2.aA.az = null;
var2.aA = null;
}
if(var2.aW) {
var3 = var2.bz;
var4 = var2.bB;
if(var2.by && this.g(var3, var4)) {
this.c(var3, var4).b(var2);
}
this.b.remove(var1--);
this.c((nl)var2);
}
}
}
public bm q() {
return this.G;
}
public void c(int var1, int var2, int var3, int var4, int var5) {
int var6 = this.a(var1, var2, var3);
if(var6 > 0) {
pj.m[var6].a(this, var1, var2, var3, var4, var5);
}
}
}
import java.io.*;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
public class oj implements ao {
private File basePath;
public oj(File basePath, boolean var2) {
this.basePath = basePath;
}
private File getChunkFile(int x, int z) {
String fileName = "c." + Integer.toString(x, 36) + "." + Integer.toString(z, 36) + ".dat";
String dir1 = Integer.toString(x & 63, 36);
String dir2 = Integer.toString(z & 63, 36);
File file = new File(this.basePath, dir1);
file = new File(file, dir2);
file = new File(file, fileName);
return file;
}
public ib a(dn world, int x, int z) {
jw nbt;
DataInputStream regionChunkInputStream = RegionFileCache.getChunkDataInputStream(basePath, x, z);
File chunkFile = this.getChunkFile(x, z);
if (regionChunkInputStream != null) {
nbt = ag.a((DataInput)regionChunkInputStream);
} else if (chunkFile.exists()) {
try {
FileInputStream inputStream = new FileInputStream(chunkFile);
nbt = ag.a(inputStream);
} catch (Exception e) {
e.printStackTrace();
return null;
}
} else {
return null;
}
if(!nbt.b("Level")) {
System.out.println("Chunk file at " + x + "," + z + " is missing level data, skipping");
return null;
}
if(!nbt.k("Level").b("Blocks")) {
System.out.println("Chunk file at " + x + "," + z + " is missing block data, skipping");
return null;
}
ib var7 = a(world, (jw)nbt.k("Level"));
if(!var7.a(x, z)) {
System.out.println("Chunk file at " + x + "," + z + " is in the wrong location; relocating. (Expected " + x + ", " + z + ", got " + var7.j + ", " + var7.k + ")");
nbt.a("xPos", (int) x);
nbt.a("zPos", (int) z);
var7 = a(world, (jw)nbt.k("Level"));
}
try {
if (regionChunkInputStream != null)
regionChunkInputStream.close();
} catch (IOException e) {
;
}
return var7;
}
public void a(dn world, ib chunk) {
world.o();
DataOutputStream output = RegionFileCache.getChunkDataOutputStream(basePath, chunk.j, chunk.k);
jw var6 = new jw();
jw var7 = new jw();
var6.a("Level", (fy)var7);
this.a(chunk, world, var7);
ag.a(var6, (DataOutput)output);
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
world.v += RegionFileCache.getSizeDelta(basePath, chunk.j, chunk.k);
}
public void a(ib var1, dn var2, jw var3) {
var2.o();
var3.a("xPos", (int)var1.j);
var3.a("zPos", (int)var1.k);
var3.a("LastUpdate", var2.e);
var3.a("Blocks", (byte[])var1.b);
var3.a("Data", (byte[])var1.e.a);
var3.a("SkyLight", (byte[])var1.f.a);
var3.a("BlockLight", (byte[])var1.g.a);
var3.a("HeightMap", (byte[])var1.h);
var3.a("TerrainPopulated", var1.n);
var1.q = false;
nn var4 = new nn();
Iterator var6;
jw var8;
for(int var5 = 0; var5 < var1.m.length; ++var5) {
var6 = var1.m[var5].iterator();
while(var6.hasNext()) {
nl var7 = (nl)var6.next();
var1.q = true;
var8 = new jw();
if(var7.c(var8)) {
var4.a((fy)var8);
}
}
}
var3.a("Entities", (fy)var4);
nn var9 = new nn();
var6 = var1.l.values().iterator();
while(var6.hasNext()) {
kp var10 = (kp)var6.next();
var8 = new jw();
var10.b(var8);
var9.a((fy)var8);
}
var3.a("TileEntities", (fy)var9);
}
public static ib a(dn var0, jw var1) {
int var2 = var1.e("xPos");
int var3 = var1.e("zPos");
ib var4 = new ib(var0, var2, var3);
var4.b = var1.j("Blocks");
var4.e = new ql(var1.j("Data"));
var4.f = new ql(var1.j("SkyLight"));
var4.g = new ql(var1.j("BlockLight"));
var4.h = var1.j("HeightMap");
var4.n = var1.m("TerrainPopulated");
if(!var4.e.a()) {
var4.e = new ql(var4.b.length);
}
if(var4.h == null || !var4.f.a()) {
var4.h = new byte[256];
var4.f = new ql(var4.b.length);
var4.c();
}
if(!var4.g.a()) {
var4.g = new ql(var4.b.length);
var4.a();
}
nn var5 = var1.l("Entities");
if(var5 != null) {
for(int var6 = 0; var6 < var5.c(); ++var6) {
jw var7 = (jw)var5.a(var6);
nl var8 = gn.a((jw)var7, var0);
var4.q = true;
if(var8 != null) {
var4.a((nl)var8);
}
}
}
nn var10 = var1.l("TileEntities");
if(var10 != null) {
for(int var11 = 0; var11 < var10.c(); ++var11) {
jw var12 = (jw)var10.a(var11);
kp var9 = kp.c(var12);
if(var9 != null) {
var4.a((kp)var9);
}
}
}
return var4;
}
public void a() {
}
public void b() {
}
public void b(dn var1, ib var2) {
}
}
/*
** 2011 January 5
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**/
// Interfaces with region files on the disk
/*
Region File Format
Concept: The minimum unit of storage on hard drives is 4KB. 90% of Minecraft
chunks are smaller than 4KB. 99% are smaller than 8KB. Write a simple
container to store chunks in single files in runs of 4KB sectors.
Each region file represents a 32x32 group of chunks. The conversion from
chunk number to region number is floor(coord / 32): a chunk at (30, -3)
would be in region (0, -1), and one at (70, -30) would be at (3, -1).
Region files are named "r.x.z.data", where x and z are the region coordinates.
A region file begins with a 4KB header that describes where chunks are stored
in the file. A 4-byte big-endian integer represents sector offsets and sector
counts. The chunk offset for a chunk (x, z) begins at byte 4*(x+z*32) in the
file. The bottom byte of the chunk offset indicates the number of sectors the
chunk takes up, and the top 3 bytes represent the sector number of the chunk.
Given a chunk offset o, the chunk data begins at byte 4096*(o/256) and takes up
at most 4096*(o%256) bytes. A chunk cannot exceed 1MB in size. If a chunk
offset is 0, the corresponding chunk is not stored in the region file.
Chunk data begins with a 4-byte big-endian integer representing the chunk data
length in bytes, not counting the length field. The length must be smaller than
4096 times the number of sectors. The next byte is a version field, to allow
backwards-compatible updates to how chunks are encoded.
A version of 1 represents a gzipped NBT file. The gzipped data is the chunk
length - 1.
A version of 2 represents a deflated (zlib compressed) NBT file. The deflated
data is the chunk length - 1.
*/
import java.io.*;
import java.io.IOException;
import java.lang.*;
import java.util.ArrayList;
import java.util.zip.*;
public class RegionFile {
static final int CHUNK_HEADER_SIZE = 5;
private static final byte emptySector[] = new byte[4096];
private final File fileName;
private RandomAccessFile file;
private final int offsets[];
private ArrayList<Boolean> sectorFree;
private int sizeDelta;
private long lastModified = 0;
public RegionFile(File path) {
offsets = new int[1024];
fileName = path;
debugln("REGION LOAD " + fileName);
sizeDelta = 0;
try {
if (path.exists())
lastModified = path.lastModified();
file = new RandomAccessFile(path, "rw");
if (file.length() < 4096) {
/* we need to write the chunk offset table */
for (int i = 0; i < 1024; ++i)
file.writeInt(0);
/* we need to write the timestamp table */
for (int i = 0; i < 1024; ++i)
file.writeInt(0);
sizeDelta += 4096;
}
if ((file.length() & 0xfff) != 0) {
/* the file size is not a multiple of 4KB, grow it */
for (int i = 0; i < (file.length() & 0xfff); ++i)
file.write((byte)0);
}
/* set up the available sector map */
int nSectors = (int)file.length() / 4096;
sectorFree = new ArrayList<Boolean>(nSectors);
for (int i = 0; i < nSectors; ++i) {
sectorFree.add(true);
}
sectorFree.set(0, false); // chunk offset table
sectorFree.set(1, false); // timestamp table
file.seek(0);
for (int i = 0; i < 1024; ++i) {
int offset = file.readInt();
offsets[i] = offset;
if (offset != 0 && (offset >> 8) + (offset & 0xFF) <= sectorFree.size()) {
for (int sectorNum = 0; sectorNum < (offset & 0xFF); ++sectorNum) {
sectorFree.set((offset >> 8) + sectorNum, false);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/* the modification date of the region file when it was first opened */
public long lastModified() {
return lastModified;
}
/* gets how much the region file has grown since it was last checked */
public synchronized int getSizeDelta() {
int ret = sizeDelta;
sizeDelta = 0;
return ret;
}
// various small debug printing helpers
private void debug(String in) {
//System.out.print(in);
}
private void debugln(String in) {
debug(in + "\n");
}
private void debug(String mode, int x, int z, String in) {
debug("REGION " + mode + " " + fileName.getName() + "[" + x + "," + z + "] = " + in);
}
private void debug(String mode, int x, int z, int count, String in) {
debug("REGION " + mode + " " + fileName.getName() + "[" + x + "," + z + "] " + count + "B = " + in);
}
private void debugln(String mode, int x, int z, String in) {
debug(mode, x, z, in + "\n");
}
/* gets an (uncompressed) stream representing the chunk data
returns null if the chunk is not found or an error occurs */
public synchronized DataInputStream getChunkDataInputStream(int x, int z) {
if (outOfBounds(x, z)) {
debugln("READ", x, z, "out of bounds");
return null;
}
try {
int offset = getOffset(x, z);
if (offset == 0) {
// debugln("READ", x, z, "miss");
return null;
}
int sectorNumber = offset >> 8;
int numSectors = offset & 0xFF;
if (sectorNumber + numSectors > sectorFree.size()) {
debugln("READ", x, z, "invalid sector");
return null;
}
file.seek(sectorNumber * 4096);
int length = file.readInt();
if (length > 4096 * numSectors) {
debugln("READ", x, z, "invalid length: " + length + " > 4096 * " + numSectors);
return null;
}
byte version = file.readByte();
if (version == 1) {
byte[] data = new byte[length - 1];
file.read(data);
DataInputStream ret = new DataInputStream(new GZIPInputStream(
new ByteArrayInputStream(data)
));
// debug("READ", x, z, " = found");
return ret;
} else if (version == 2) {
byte[] data = new byte[length - 1];
file.read(data);
DataInputStream ret = new DataInputStream(new InflaterInputStream(
new ByteArrayInputStream(data)
));
// debug("READ", x, z, " = found");
return ret;
}
debugln("READ", x, z, "unknown version " + version);
return null;
} catch (IOException e) {
debugln("READ", x, z, "exception");
return null;
}
}
public DataOutputStream getChunkDataOutputStream(int x, int z) {
if (outOfBounds(x, z))
return null;
return new DataOutputStream(new DeflaterOutputStream(
new ChunkBuffer(x, z)));
}
/* lets chunk writing be multithreaded by not locking the whole file as a
chunk is serializing -- only writes when serialization is over */
class ChunkBuffer extends ByteArrayOutputStream {
private int x, z;
public ChunkBuffer(int x, int z) {
super(8096); // initialize to 8KB
this.x = x;
this.z = z;
}
public void close() {
RegionFile.this.write(x, z, buf, count);
}
}
/* write a chunk at (x,z) with length bytes of data to disk */
protected synchronized void write(int x, int z, byte[] data, int length) {
try {
int offset = getOffset(x, z);
int sectorNumber = offset >> 8;
int sectorsAllocated = offset & 0xFF;
int sectorsNeeded = (length + CHUNK_HEADER_SIZE) / 4096 + 1;
if (sectorsNeeded >= 256) // maximum chunk size is 1MB
return;
if (sectorNumber != 0 && sectorsAllocated == sectorsNeeded) {
/* we can simply overwrite the old sectors */
debug("SAVE", x, z, length, "rewrite");
write(sectorNumber, data, length);
} else {
/* we need to allocate new sectors */
/* mark the sectors previously used for this chunk as free */
for (int i = 0; i < sectorsAllocated; ++i)
sectorFree.set(sectorNumber + i, true);
/* scan for a free space large enough to store this chunk */
int runStart = sectorFree.indexOf(true);
int runLength = 0;
if (runStart != -1) {
for (int i = runStart; i < sectorFree.size(); ++i) {
if (runLength != 0) {
if (sectorFree.get(i))
runLength++;
else
runLength = 0;
} else if (sectorFree.get(i)) {
runStart = i;
runLength = 1;
}
if (runLength >= sectorsNeeded)
break;
}
}
if (runLength >= sectorsNeeded) {
/* we found a free space large enough */
debug("SAVE", x, z, length, "reuse");
sectorNumber = runStart;
setOffset(x, z, (sectorNumber << 8) | sectorsNeeded);
for (int i = 0; i < sectorsNeeded; ++i)
sectorFree.set(sectorNumber + i, false);
write(sectorNumber, data, length);
} else {
/* no free space large enough found -- we need to grow the file */
debug("SAVE", x, z, length, "grow");
file.seek(file.length());
sectorNumber = sectorFree.size();
for (int i = 0; i < sectorsNeeded; ++i) {
file.write(emptySector);
sectorFree.add(false);
}
sizeDelta += 4096 * sectorsNeeded;
write(sectorNumber, data, length);
setOffset(x, z, (sectorNumber << 8) | sectorsNeeded);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/* write a chunk data to the region file at specified sector number */
private void write(int sectorNumber, byte[] data, int length) throws IOException {
debugln(" " + sectorNumber);
file.seek(sectorNumber * 4096);
file.writeInt(length + 1); // chunk length
file.writeByte(2); // chunk version number
file.write(data, 0, length); // chunk data
}
/* is this an invalid chunk coordinate? */
private boolean outOfBounds(int x, int z) {
return x < 0 || x >= 32 || z < 0 || z >= 32;
}
private int getOffset(int x, int z) throws IOException {
return offsets[x + z * 32];
}
private void setOffset(int x, int z, int offset) throws IOException {
offsets[x + z * 32] = offset;
file.seek((x + z * 32) * 4);
file.writeInt(offset);
}
public void close() throws IOException {
file.close();
}
}
/*
** 2011 January 5
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
*/
// A simple cache and wrapper for efficiently multiple RegionFiles simultaneously.
import java.io.*;
import java.io.IOException;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.util.*;
public class RegionFileCache {
private static final Map<File, Reference<RegionFile>> cache = new HashMap<File, Reference<RegionFile>>();
private RegionFileCache() { }
public static synchronized RegionFile getRegionFile(File basePath, int x, int z) {
File regionDir = new File(basePath, "region");
File file = new File(regionDir, "r." + (x >> 5) + "." + (z >> 5) + ".mcr");
Reference<RegionFile> ref = cache.get(file);
if (ref != null && ref.get() != null)
return ref.get();
if (!regionDir.exists())
regionDir.mkdirs();
RegionFile reg = new RegionFile(file);
cache.put(file, new SoftReference<RegionFile>(reg));
return reg;
}
public static synchronized void clear() {
for (Reference<RegionFile> ref : cache.values()) {
try {
if (ref.get() != null)
ref.get().close();
} catch (IOException e) {
e.printStackTrace();
}
}
cache.clear();
}
public static int getSizeDelta(File basePath, int x, int z) {
RegionFile r = getRegionFile(basePath, x, z);
return r.getSizeDelta();
}
public static DataInputStream getChunkDataInputStream(File basePath, int x, int z) {
RegionFile r = getRegionFile(basePath, x, z);
return r.getChunkDataInputStream(x & 31, z & 31);
}
public static DataOutputStream getChunkDataOutputStream(File basePath, int x, int z) {
RegionFile r = getRegionFile(basePath, x, z);
return r.getChunkDataOutputStream(x & 31, z & 31);
}
}
/*
** 2011 January 5
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**/
// A tool to convert to and from chunk/region files
import java.io.*;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.lang.Integer;
import java.lang.System;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
class RegionTool {
static private boolean isConsole = false;
public static void main(String[] args) {
if (args.length != 2 && args.length != 3)
exitUsage();
if (System.console() != null)
isConsole = true;
int mode = 0;
if (args[0].equalsIgnoreCase("unpack"))
mode = 1;
else if (args[0].equalsIgnoreCase("pack"))
mode = 2;
if (mode == 0)
exitUsage();
File worldDir = new File(args[1]);
if (!worldDir.exists() || !worldDir.isDirectory())
exit("error: " + worldDir.getPath() + " is not a directory");
File targetDir = worldDir;
if (args.length == 3) {
targetDir = new File(args[2]);
if (!targetDir.isDirectory()) {
targetDir.mkdirs();
}
}
if (mode == 1)
unpack(worldDir, targetDir);
else if (mode == 2)
pack(worldDir, targetDir);
}
private static void unpack(File worldDir, File targetDir) {
File regionDir = new File(worldDir, "region");
if (!regionDir.exists())
exit("error: region directory not found");
Set<File> processedFiles = null;
if (worldDir != targetDir)
processedFiles = new HashSet<File>();
Pattern regionFilePattern = Pattern.compile("r\\.(-?[0-9]+)\\.(-?[0-9]+).mcr");
Matcher match;
for (File file : regionDir.listFiles()) {
if (!file.isFile())
continue;
match = regionFilePattern.matcher(file.getName());
if (match.matches()) {
unpackRegionFile(targetDir, file, match);
if (processedFiles != null)
processedFiles.add(file);
}
}
if (processedFiles != null)
copyDir(worldDir, targetDir, processedFiles);
}
private static void pack(File worldDir, File targetDir) {
File regionDir = new File(worldDir, "region");
Set<File> processedFiles = null;
if (worldDir != targetDir)
processedFiles = new HashSet<File>();
Pattern chunkFilePattern = Pattern.compile("c\\.(-?[0-9a-z]+)\\.(-?[0-9a-z]+).dat");
Pattern chunkFolderPattern = Pattern.compile("[0-9a-z]|1[0-9a-r]");
int chunksPacked = 0;
int chunksSkipped = 0;
for (File dir1 : worldDir.listFiles()) {
if (!dir1.isDirectory())
continue;
if (chunkFolderPattern.matcher(dir1.getName()).matches()) {
for (File dir2 : dir1.listFiles()) {
if (!dir2.isDirectory())
continue;
if (chunkFolderPattern.matcher(dir2.getName()).matches()) {
for (File chunkFile : dir2.listFiles()) {
Matcher m = chunkFilePattern.matcher(chunkFile.getName());
boolean packed;
if (m.matches()) {
if (packChunk(targetDir, chunkFile, m))
chunksPacked++;
else
chunksSkipped++;
if (processedFiles != null)
processedFiles.add(chunkFile);
}
if (isConsole)
System.out.print("\rpacked " + chunksPacked + " chunks" +
(chunksSkipped > 0 ? ", skipped " + chunksSkipped + " older ones": ""));
}
}
}
}
}
if (isConsole)
System.out.print("\r");
System.out.println("packed " + chunksPacked + " chunks" +
(chunksSkipped > 0 ? ", skipped " + chunksSkipped + " older ones": ""));
if (processedFiles != null)
copyDir(worldDir, targetDir, processedFiles);
}
private static boolean packChunk(File worldDir, File chunkFile, Matcher m) {
int x = Integer.parseInt(m.group(1), 36);
int z = Integer.parseInt(m.group(2), 36);
RegionFile region = RegionFileCache.getRegionFile(worldDir, x, z);
if (region.lastModified() > chunkFile.lastModified())
return false;
byte buf[] = new byte[4096];
int len = 0;
try {
DataInputStream istream = new DataInputStream(
new GZIPInputStream(new FileInputStream(chunkFile)));
DataOutputStream out = region.getChunkDataOutputStream(x & 31, z & 31);
while (len != -1) {
out.write(buf, 0, len);
len = istream.read(buf);
}
out.close();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
private static void unpackRegionFile(File worldDir, File file, Matcher match) {
long regionModified = file.lastModified();
RegionFile region = new RegionFile(file);
String name = file.getName();
int regionX = Integer.parseInt(match.group(1));
int regionZ = Integer.parseInt(match.group(2));
int nWritten = 0, nSkipped = 0;
for (int x = 0; x < 32; ++x) {
for (int z = 0; z < 32; ++z) {
DataInputStream istream = region.getChunkDataInputStream(x, z);
if (istream == null)
continue;
int chunkX = x + (regionX << 5);
int chunkZ = z + (regionZ << 5);
String chunkName = "c." + Integer.toString(chunkX, 36) + "." + Integer.toString(chunkZ, 36) + ".dat";
File chunkFile = new File(worldDir, Integer.toString(chunkX & 63, 36));
chunkFile = new File(chunkFile, Integer.toString(chunkZ & 63, 36));
if (!chunkFile.exists())
chunkFile.mkdirs();
chunkFile = new File(chunkFile, chunkName);
byte buf[] = new byte[4096];
int len = 0;
if (chunkFile.lastModified() > regionModified) {
nSkipped++;
} else {
try {
DataOutputStream out = new DataOutputStream(
new GZIPOutputStream(new FileOutputStream(chunkFile)));
while (len != -1) {
out.write(buf, 0, len);
len = istream.read(buf);
}
out.close();
nWritten++;
} catch (IOException e) {
e.printStackTrace();
}
}
if (isConsole)
System.out.print("\r" + name + ": unpacked " + nWritten + " chunks" +
(nSkipped > 0 ? ", skipped " + nSkipped + " newer ones": ""));
}
}
if (isConsole)
System.out.print("\r");
System.out.println(name + ": unpacked " + nWritten + " chunks" +
(nSkipped > 0 ? ", skipped " + nSkipped + " newer ones": ""));
}
/* copies all files from one directory to another, except for files in the skip set
does not copy empty directories */
private static void copyDir(File srcDir, File dstDir, Set<File> skip) {
byte buf[] = new byte[4096];
for (File child : srcDir.listFiles()) {
if (child.isDirectory())
copyDir(child, new File(dstDir, child.getName()), skip);
else {
if (!skip.contains(child)) {
try {
File dstfile = new File(dstDir, child.getName());
dstDir.mkdirs();
FileOutputStream out = new FileOutputStream(dstfile);
FileInputStream in = new FileInputStream(child);
int len = 0;
while (len != -1) {
out.write(buf, 0, len);
len = in.read(buf);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
private static void exitUsage() {
exit("regionTool: converts between chunks and regions\n" +
"usage: java -jar RegionTool.jar [un]pack <world directory> [target directory]");
}
private static void exit(String message) {
System.err.println(message);
System.exit(1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment