Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
lDEVinux
GitHub Repository: lDEVinux/eaglercraft
Path: blob/main/sp-server/src_aux/RegionFile.java
8641 views
1
package net.minecraft.src;
2
3
import java.io.BufferedInputStream;
4
import java.io.ByteArrayInputStream;
5
import java.io.DataInputStream;
6
import java.io.DataOutputStream;
7
import java.io.File;
8
import java.io.IOException;
9
import java.io.RandomAccessFile;
10
import java.util.ArrayList;
11
import java.util.zip.DeflaterOutputStream;
12
import java.util.zip.GZIPInputStream;
13
import java.util.zip.InflaterInputStream;
14
15
public class RegionFile {
16
private static final byte[] emptySector = new byte[4096];
17
private final File fileName;
18
private RandomAccessFile dataFile;
19
private final int[] offsets = new int[1024];
20
private final int[] chunkTimestamps = new int[1024];
21
private ArrayList sectorFree;
22
23
/** McRegion sizeDelta */
24
private int sizeDelta;
25
private long lastModified = 0L;
26
27
public RegionFile(File par1File) {
28
this.fileName = par1File;
29
this.sizeDelta = 0;
30
31
try {
32
if (par1File.exists()) {
33
this.lastModified = par1File.lastModified();
34
}
35
36
this.dataFile = new RandomAccessFile(par1File, "rw");
37
int var2;
38
39
if (this.dataFile.length() < 4096L) {
40
for (var2 = 0; var2 < 1024; ++var2) {
41
this.dataFile.writeInt(0);
42
}
43
44
for (var2 = 0; var2 < 1024; ++var2) {
45
this.dataFile.writeInt(0);
46
}
47
48
this.sizeDelta += 8192;
49
}
50
51
if ((this.dataFile.length() & 4095L) != 0L) {
52
for (var2 = 0; (long) var2 < (this.dataFile.length() & 4095L); ++var2) {
53
this.dataFile.write(0);
54
}
55
}
56
57
var2 = (int) this.dataFile.length() / 4096;
58
this.sectorFree = new ArrayList(var2);
59
int var3;
60
61
for (var3 = 0; var3 < var2; ++var3) {
62
this.sectorFree.add(Boolean.valueOf(true));
63
}
64
65
this.sectorFree.set(0, Boolean.valueOf(false));
66
this.sectorFree.set(1, Boolean.valueOf(false));
67
this.dataFile.seek(0L);
68
int var4;
69
70
for (var3 = 0; var3 < 1024; ++var3) {
71
var4 = this.dataFile.readInt();
72
this.offsets[var3] = var4;
73
74
if (var4 != 0 && (var4 >> 8) + (var4 & 255) <= this.sectorFree.size()) {
75
for (int var5 = 0; var5 < (var4 & 255); ++var5) {
76
this.sectorFree.set((var4 >> 8) + var5, Boolean.valueOf(false));
77
}
78
}
79
}
80
81
for (var3 = 0; var3 < 1024; ++var3) {
82
var4 = this.dataFile.readInt();
83
this.chunkTimestamps[var3] = var4;
84
}
85
} catch (IOException var6) {
86
var6.printStackTrace();
87
}
88
}
89
90
/**
91
* args: x, y - get uncompressed chunk stream from the region file
92
*/
93
public synchronized DataInputStream getChunkDataInputStream(int par1, int par2) {
94
if (this.outOfBounds(par1, par2)) {
95
return null;
96
} else {
97
try {
98
int var3 = this.getOffset(par1, par2);
99
100
if (var3 == 0) {
101
return null;
102
} else {
103
int var4 = var3 >> 8;
104
int var5 = var3 & 255;
105
106
if (var4 + var5 > this.sectorFree.size()) {
107
return null;
108
} else {
109
this.dataFile.seek((long) (var4 * 4096));
110
int var6 = this.dataFile.readInt();
111
112
if (var6 > 4096 * var5) {
113
return null;
114
} else if (var6 <= 0) {
115
return null;
116
} else {
117
byte var7 = this.dataFile.readByte();
118
byte[] var8;
119
120
if (var7 == 1) {
121
var8 = new byte[var6 - 1];
122
this.dataFile.read(var8);
123
return new DataInputStream(
124
new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(var8))));
125
} else if (var7 == 2) {
126
var8 = new byte[var6 - 1];
127
this.dataFile.read(var8);
128
return new DataInputStream(new BufferedInputStream(
129
new InflaterInputStream(new ByteArrayInputStream(var8))));
130
} else {
131
return null;
132
}
133
}
134
}
135
}
136
} catch (IOException var9) {
137
return null;
138
}
139
}
140
}
141
142
/**
143
* args: x, z - get an output stream used to write chunk data, data is on disk
144
* when the returned stream is closed
145
*/
146
public DataOutputStream getChunkDataOutputStream(int par1, int par2) {
147
return this.outOfBounds(par1, par2) ? null
148
: new DataOutputStream(new DeflaterOutputStream(new RegionFileChunkBuffer(this, par1, par2)));
149
}
150
151
/**
152
* args: x, z, data, length - write chunk data at (x, z) to disk
153
*/
154
protected synchronized void write(int par1, int par2, byte[] par3ArrayOfByte, int par4) {
155
try {
156
int var5 = this.getOffset(par1, par2);
157
int var6 = var5 >> 8;
158
int var7 = var5 & 255;
159
int var8 = (par4 + 5) / 4096 + 1;
160
161
if (var8 >= 256) {
162
return;
163
}
164
165
if (var6 != 0 && var7 == var8) {
166
this.write(var6, par3ArrayOfByte, par4);
167
} else {
168
int var9;
169
170
for (var9 = 0; var9 < var7; ++var9) {
171
this.sectorFree.set(var6 + var9, Boolean.valueOf(true));
172
}
173
174
var9 = this.sectorFree.indexOf(Boolean.valueOf(true));
175
int var10 = 0;
176
int var11;
177
178
if (var9 != -1) {
179
for (var11 = var9; var11 < this.sectorFree.size(); ++var11) {
180
if (var10 != 0) {
181
if (((Boolean) this.sectorFree.get(var11)).booleanValue()) {
182
++var10;
183
} else {
184
var10 = 0;
185
}
186
} else if (((Boolean) this.sectorFree.get(var11)).booleanValue()) {
187
var9 = var11;
188
var10 = 1;
189
}
190
191
if (var10 >= var8) {
192
break;
193
}
194
}
195
}
196
197
if (var10 >= var8) {
198
var6 = var9;
199
this.setOffset(par1, par2, var9 << 8 | var8);
200
201
for (var11 = 0; var11 < var8; ++var11) {
202
this.sectorFree.set(var6 + var11, Boolean.valueOf(false));
203
}
204
205
this.write(var6, par3ArrayOfByte, par4);
206
} else {
207
this.dataFile.seek(this.dataFile.length());
208
var6 = this.sectorFree.size();
209
210
for (var11 = 0; var11 < var8; ++var11) {
211
this.dataFile.write(emptySector);
212
this.sectorFree.add(Boolean.valueOf(false));
213
}
214
215
this.sizeDelta += 4096 * var8;
216
this.write(var6, par3ArrayOfByte, par4);
217
this.setOffset(par1, par2, var6 << 8 | var8);
218
}
219
}
220
221
this.setChunkTimestamp(par1, par2, (int) (System.currentTimeMillis() / 1000L));
222
} catch (IOException var12) {
223
var12.printStackTrace();
224
}
225
}
226
227
/**
228
* args: sectorNumber, data, length - write the chunk data to this RegionFile
229
*/
230
private void write(int par1, byte[] par2ArrayOfByte, int par3) throws IOException {
231
this.dataFile.seek((long) (par1 * 4096));
232
this.dataFile.writeInt(par3 + 1);
233
this.dataFile.writeByte(2);
234
this.dataFile.write(par2ArrayOfByte, 0, par3);
235
}
236
237
/**
238
* args: x, z - check region bounds
239
*/
240
private boolean outOfBounds(int par1, int par2) {
241
return par1 < 0 || par1 >= 32 || par2 < 0 || par2 >= 32;
242
}
243
244
/**
245
* args: x, y - get chunk's offset in region file
246
*/
247
private int getOffset(int par1, int par2) {
248
return this.offsets[par1 + par2 * 32];
249
}
250
251
/**
252
* args: x, z, - true if chunk has been saved / converted
253
*/
254
public boolean isChunkSaved(int par1, int par2) {
255
return this.getOffset(par1, par2) != 0;
256
}
257
258
/**
259
* args: x, z, offset - sets the chunk's offset in the region file
260
*/
261
private void setOffset(int par1, int par2, int par3) throws IOException {
262
this.offsets[par1 + par2 * 32] = par3;
263
this.dataFile.seek((long) ((par1 + par2 * 32) * 4));
264
this.dataFile.writeInt(par3);
265
}
266
267
/**
268
* args: x, z, timestamp - sets the chunk's write timestamp
269
*/
270
private void setChunkTimestamp(int par1, int par2, int par3) throws IOException {
271
this.chunkTimestamps[par1 + par2 * 32] = par3;
272
this.dataFile.seek((long) (4096 + (par1 + par2 * 32) * 4));
273
this.dataFile.writeInt(par3);
274
}
275
276
/**
277
* close this RegionFile and prevent further writes
278
*/
279
public void close() throws IOException {
280
if (this.dataFile != null) {
281
this.dataFile.close();
282
}
283
}
284
}
285
286