Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
1package net.minecraft.server;
2
3import java.io.*;
4import java.util.ArrayList;
5import java.util.zip.DeflaterOutputStream;
6import java.util.zip.GZIPInputStream;
7import java.util.zip.InflaterInputStream;
8
9public class RegionFile {
10
11 private static final byte[] a = new byte[4096];
12 private final File b;
13 private RandomAccessFile c;
14 private final int[] d = new int[1024];
15 private final int[] e = new int[1024];
16 private ArrayList f;
17 private int g;
18 private long h = 0L;
19
20 public RegionFile(File file1) {
21 this.b = file1;
22 this.b("REGION LOAD " + this.b);
23 this.g = 0;
24
25 try {
26 if (file1.exists()) {
27 this.h = file1.lastModified();
28 }
29
30 this.c = new RandomAccessFile(file1, "rw");
31 int i;
32
33 if (this.c.length() < 4096L) {
34 for (i = 0; i < 1024; ++i) {
35 this.c.writeInt(0);
36 }
37
38 for (i = 0; i < 1024; ++i) {
39 this.c.writeInt(0);
40 }
41
42 this.g += 8192;
43 }
44
45 if ((this.c.length() & 4095L) != 0L) {
46 for (i = 0; (long) i < (this.c.length() & 4095L); ++i) {
47 this.c.write(0);
48 }
49 }
50
51 i = (int) this.c.length() / 4096;
52 this.f = new ArrayList(i);
53
54 int j;
55
56 for (j = 0; j < i; ++j) {
57 this.f.add(Boolean.valueOf(true));
58 }
59
60 this.f.set(0, Boolean.valueOf(false));
61 this.f.set(1, Boolean.valueOf(false));
62 this.c.seek(0L);
63
64 int k;
65
66 for (j = 0; j < 1024; ++j) {
67 k = this.c.readInt();
68 this.d[j] = k;
69 if (k != 0 && (k >> 8) + (k & 255) <= this.f.size()) {
70 for (int l = 0; l < (k & 255); ++l) {
71 this.f.set((k >> 8) + l, Boolean.valueOf(false));
72 }
73 }
74 }
75
76 for (j = 0; j < 1024; ++j) {
77 k = this.c.readInt();
78 this.e[j] = k;
79 }
80 } catch (IOException ioexception) {
81 ioexception.printStackTrace();
82 }
83 }
84
85 public synchronized int a() {
86 int i = this.g;
87
88 this.g = 0;
89 return i;
90 }
91
92 private void a(String s) {
93 }
94
95 private void b(String s) {
96 this.a(s + "\n");
97 }
98
99 private void a(String s, int i, int j, String s1) {
100 this.a("REGION " + s + " " + this.b.getName() + "[" + i + "," + j + "] = " + s1);
101 }
102
103 private void a(String s, int i, int j, int k, String s1) {
104 this.a("REGION " + s + " " + this.b.getName() + "[" + i + "," + j + "] " + k + "B = " + s1);
105 }
106
107 private void b(String s, int i, int j, String s1) {
108 this.a(s, i, j, s1 + "\n");
109 }
110
111 public synchronized DataInputStream a(int i, int j) {
112 if (this.d(i, j)) {
113 this.b("READ", i, j, "out of bounds");
114 return null;
115 } else {
116 try {
117 int k = this.e(i, j);
118
119 if (k == 0) {
120 return null;
121 } else {
122 int l = k >> 8;
123 int i1 = k & 255;
124
125 if (l + i1 > this.f.size()) {
126 this.b("READ", i, j, "invalid sector");
127 return null;
128 } else {
129 this.c.seek((long) (l * 4096));
130 int j1 = this.c.readInt();
131
132 if (j1 > 4096 * i1) {
133 this.b("READ", i, j, "invalid length: " + j1 + " > 4096 * " + i1);
134 return null;
135 } else {
136 byte b0 = this.c.readByte();
137 byte[] abyte;
138 DataInputStream datainputstream;
139
140 if (b0 == 1) {
141 abyte = new byte[j1 - 1];
142 this.c.read(abyte);
143 datainputstream = new DataInputStream(new GZIPInputStream(new ByteArrayInputStream(abyte)));
144 return datainputstream;
145 } else if (b0 == 2) {
146 abyte = new byte[j1 - 1];
147 this.c.read(abyte);
148 datainputstream = new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(abyte)));
149 return datainputstream;
150 } else {
151 this.b("READ", i, j, "unknown version " + b0);
152 return null;
153 }
154 }
155 }
156 }
157 } catch (IOException ioexception) {
158 this.b("READ", i, j, "exception");
159 return null;
160 }
161 }
162 }
163
164 public DataOutputStream b(int i, int j) {
165 return this.d(i, j) ? null : new DataOutputStream(new DeflaterOutputStream(new ChunkBuffer(this, i, j)));
166 }
167
168 protected synchronized void a(int i, int j, byte[] abyte, int k) {
169 try {
170 int l = this.e(i, j);
171 int i1 = l >> 8;
172 int j1 = l & 255;
173 int k1 = (k + 5) / 4096 + 1;
174
175 if (k1 >= 256) {
176 return;
177 }
178
179 if (i1 != 0 && j1 == k1) {
180 this.a("SAVE", i, j, k, "rewrite");
181 this.a(i1, abyte, k);
182 } else {
183 int l1;
184
185 for (l1 = 0; l1 < j1; ++l1) {
186 this.f.set(i1 + l1, Boolean.valueOf(true));
187 }
188
189 l1 = this.f.indexOf(Boolean.valueOf(true));
190 int i2 = 0;
191 int j2;
192
193 if (l1 != -1) {
194 for (j2 = l1; j2 < this.f.size(); ++j2) {
195 if (i2 != 0) {
196 if (((Boolean) this.f.get(j2)).booleanValue()) {
197 ++i2;
198 } else {
199 i2 = 0;
200 }
201 } else if (((Boolean) this.f.get(j2)).booleanValue()) {
202 l1 = j2;
203 i2 = 1;
204 }
205
206 if (i2 >= k1) {
207 break;
208 }
209 }
210 }
211
212 if (i2 >= k1) {
213 this.a("SAVE", i, j, k, "reuse");
214 i1 = l1;
215 this.a(i, j, l1 << 8 | k1);
216
217 for (j2 = 0; j2 < k1; ++j2) {
218 this.f.set(i1 + j2, Boolean.valueOf(false));
219 }
220
221 this.a(i1, abyte, k);
222 } else {
223 this.a("SAVE", i, j, k, "grow");
224 this.c.seek(this.c.length());
225 i1 = this.f.size();
226
227 for (j2 = 0; j2 < k1; ++j2) {
228 this.c.write(a);
229 this.f.add(Boolean.valueOf(false));
230 }
231
232 this.g += 4096 * k1;
233 this.a(i1, abyte, k);
234 this.a(i, j, i1 << 8 | k1);
235 }
236 }
237
238 this.b(i, j, (int) (System.currentTimeMillis() / 1000L));
239 } catch (IOException ioexception) {
240 ioexception.printStackTrace();
241 }
242 }
243
244 private void a(int i, byte[] abyte, int j) throws IOException {
245 this.b(" " + i);
246 this.c.seek((long) (i * 4096));
247 this.c.writeInt(j + 1);
248 this.c.writeByte(2);
249 this.c.write(abyte, 0, j);
250 }
251
252 private boolean d(int i, int j) {
253 return i < 0 || i >= 32 || j < 0 || j >= 32;
254 }
255
256 private int e(int i, int j) {
257 return this.d[i + j * 32];
258 }
259
260 public boolean c(int i, int j) {
261 return this.e(i, j) != 0;
262 }
263
264 private void a(int i, int j, int k) throws IOException {
265 this.d[i + j * 32] = k;
266 this.c.seek((long) ((i + j * 32) * 4));
267 this.c.writeInt(k);
268 }
269
270 private void b(int i, int j, int k) throws IOException {
271 this.e[i + j * 32] = k;
272 this.c.seek((long) (4096 + (i + j * 32) * 4));
273 this.c.writeInt(k);
274 }
275
276 public void b() throws IOException {
277 this.c.close();
278 }
279}