Merge branch 'singleplayer' of https://github.com/EaglerMods/eaglercraft-sp into singleplayer
This commit is contained in:
commit
254365783e
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,41 @@
|
|||
package net.lax1dude.eaglercraft.sp;
|
||||
|
||||
import org.teavm.classlib.java.util.zip.TChecksum;
|
||||
|
||||
import java.util.zip.Checksum;
|
||||
|
||||
public class CRC32 implements Checksum {
|
||||
private com.jcraft.jzlib.CRC32 impl = new com.jcraft.jzlib.CRC32();
|
||||
long tbytes;
|
||||
|
||||
@Override
|
||||
public long getValue() {
|
||||
return impl.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
impl.reset();
|
||||
tbytes = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(int val) {
|
||||
impl.update(new byte[] { (byte) val }, 0, 1);
|
||||
}
|
||||
|
||||
public void update(byte[] buf) {
|
||||
update(buf, 0, buf.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(byte[] buf, int off, int nbytes) {
|
||||
// avoid int overflow, check null buf
|
||||
if (off <= buf.length && nbytes >= 0 && off >= 0 && buf.length - off >= nbytes) {
|
||||
impl.update(buf, off, nbytes);
|
||||
tbytes += nbytes;
|
||||
} else {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import net.minecraft.src.ChunkCoordIntPair;
|
||||
import org.teavm.jso.JSBody;
|
||||
|
@ -291,7 +290,8 @@ public class IntegratedServer {
|
|||
try {
|
||||
final int[] bytesWritten = new int[1];
|
||||
final int[] lastUpdate = new int[1];
|
||||
String pfx = "worlds/" + pkt.worldName + "/";
|
||||
String shortpfx = pkt.worldName + "/";
|
||||
String pfx = "worlds/" + shortpfx;
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ZipOutputStream c = new ZipOutputStream(baos);
|
||||
c.setComment("contains backup of world '" + pkt.worldName + "'");
|
||||
|
@ -300,19 +300,18 @@ public class IntegratedServer {
|
|||
Map<ChunkCoordIntPair, byte[]> regionsn1 = new HashMap<>();
|
||||
SYS.VFS.iterateFiles(pfx, false, (i) -> {
|
||||
String currPath = i.path.substring(pfx.length());
|
||||
System.out.println(currPath); // 12yee
|
||||
try {
|
||||
byte[] b = i.getAllBytes();
|
||||
if (currPath.startsWith("region/")) {
|
||||
regions.put(VFSChunkLoader.getChunkCoords(currPath.substring(7, -4)), b);
|
||||
} else if (currPath.startsWith("DIM1/region/")) {
|
||||
regions1.put(VFSChunkLoader.getChunkCoords(currPath.substring(12, -4)), b);
|
||||
} else if (currPath.startsWith("DIM-1/region/")) {
|
||||
regionsn1.put(VFSChunkLoader.getChunkCoords(currPath.substring(13, -4)), b);
|
||||
if (currPath.startsWith("level0/")) {
|
||||
regions.put(VFSChunkLoader.getChunkCoords(currPath.substring(7, currPath.length() - 4)), b);
|
||||
} else if (currPath.startsWith("level1/")) {
|
||||
regions1.put(VFSChunkLoader.getChunkCoords(currPath.substring(7, currPath.length() - 4)), b);
|
||||
} else if (currPath.startsWith("level-1/")) {
|
||||
regionsn1.put(VFSChunkLoader.getChunkCoords(currPath.substring(8, currPath.length() - 4)), b);
|
||||
} else {
|
||||
ZipEntry zipEntry = new ZipEntry(currPath);
|
||||
ZipEntry zipEntry = new ZipEntry(shortpfx + currPath);
|
||||
c.putNextEntry(zipEntry);
|
||||
c.write(b); // 12yee
|
||||
c.write(b);
|
||||
c.closeEntry();
|
||||
bytesWritten[0] += b.length;
|
||||
if (bytesWritten[0] - lastUpdate[0] > 10000) {
|
||||
|
@ -328,9 +327,9 @@ public class IntegratedServer {
|
|||
Map<String, byte[]> regionsOut = MCAConverter.convertToMCA(regions);
|
||||
for (String path : regionsOut.keySet()) {
|
||||
byte[] b = regionsOut.get(path);
|
||||
ZipEntry zipEntry = new ZipEntry("region/" + path + ".dat");
|
||||
ZipEntry zipEntry = new ZipEntry(shortpfx + "region/" + path + ".mca");
|
||||
c.putNextEntry(zipEntry);
|
||||
c.write(b); // 12yee
|
||||
c.write(b);
|
||||
c.closeEntry();
|
||||
bytesWritten[0] += b.length;
|
||||
if (bytesWritten[0] - lastUpdate[0] > 10000) {
|
||||
|
@ -341,9 +340,9 @@ public class IntegratedServer {
|
|||
Map<String, byte[]> regions1Out = MCAConverter.convertToMCA(regions1);
|
||||
for (String path : regions1Out.keySet()) {
|
||||
byte[] b = regions1Out.get(path);
|
||||
ZipEntry zipEntry = new ZipEntry("DIM1/region/" + path + ".dat");
|
||||
ZipEntry zipEntry = new ZipEntry(shortpfx + "DIM1/region/" + path + ".mca");
|
||||
c.putNextEntry(zipEntry);
|
||||
c.write(b); // 12yee
|
||||
c.write(b);
|
||||
c.closeEntry();
|
||||
bytesWritten[0] += b.length;
|
||||
if (bytesWritten[0] - lastUpdate[0] > 10000) {
|
||||
|
@ -354,7 +353,7 @@ public class IntegratedServer {
|
|||
Map<String, byte[]> regionsn1Out = MCAConverter.convertToMCA(regionsn1);
|
||||
for (String path : regionsn1Out.keySet()) {
|
||||
byte[] b = regionsn1Out.get(path);
|
||||
ZipEntry zipEntry = new ZipEntry("DIM-1/region/" + path + ".dat");
|
||||
ZipEntry zipEntry = new ZipEntry(shortpfx + "DIM-1/region/" + path + ".mca");
|
||||
c.putNextEntry(zipEntry);
|
||||
c.write(b); // 12yee
|
||||
c.closeEntry();
|
||||
|
|
|
@ -5,12 +5,13 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.jcraft.jzlib.DeflaterOutputStream;
|
||||
import com.jcraft.jzlib.GZIPOutputStream;
|
||||
import net.minecraft.src.ChunkCoordIntPair;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
public class MCAConverter {
|
||||
|
@ -70,6 +71,8 @@ public class MCAConverter {
|
|||
public static Map<String, byte[]> convertToMCA(Map<ChunkCoordIntPair, byte[]> regions) {
|
||||
Map<String, byte[]> regionsOut = new HashMap<>();
|
||||
|
||||
if (regions.size() == 0) return regionsOut;
|
||||
|
||||
try {
|
||||
int timestamp = (int) System.currentTimeMillis();
|
||||
|
||||
|
@ -85,8 +88,8 @@ public class MCAConverter {
|
|||
if (minZ > coords.chunkZPos) minZ = coords.chunkZPos;
|
||||
}
|
||||
|
||||
for (int x = minX - (minX % 32); x <= maxX + (maxX % 32); x += 32) {
|
||||
for (int z = minZ - (minZ % 32); z <= maxZ + (maxZ % 32); z += 32) {
|
||||
for (int x = minX + (minX % 32); x <= maxX + (maxX % 32); x += 32) {
|
||||
for (int z = minZ + (minZ % 32); z <= maxZ + (maxZ % 32); z += 32) {
|
||||
ByteArrayOutputStream offsets = new ByteArrayOutputStream();
|
||||
DataOutputStream offsetsDos = new DataOutputStream(offsets);
|
||||
ByteArrayOutputStream timestamps = new ByteArrayOutputStream();
|
||||
|
|
|
@ -0,0 +1,330 @@
|
|||
package net.lax1dude.eaglercraft.sp;
|
||||
|
||||
import com.jcraft.jzlib.Deflater;
|
||||
import com.jcraft.jzlib.DeflaterOutputStream;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipException;
|
||||
|
||||
import static java.util.zip.Deflater.BEST_COMPRESSION;
|
||||
import static java.util.zip.Deflater.DEFAULT_COMPRESSION;
|
||||
|
||||
public class ZipOutputStream extends DeflaterOutputStream {
|
||||
long LOCSIG = 0x4034b50;
|
||||
long EXTSIG = 0x8074b50;
|
||||
long CENSIG = 0x2014b50;
|
||||
long ENDSIG = 0x6054b50;
|
||||
|
||||
int LOCHDR = 30;
|
||||
int EXTHDR = 16;
|
||||
|
||||
public static final int DEFLATED = 8;
|
||||
public static final int STORED = 0;
|
||||
|
||||
static final int ZIPDataDescriptorFlag = 8;
|
||||
static final int ZIPLocalHeaderVersionNeeded = 20;
|
||||
private String comment;
|
||||
private final List<String> entries = new ArrayList<>();
|
||||
private int compressMethod = DEFLATED;
|
||||
private int compressLevel = -1;
|
||||
private ByteArrayOutputStream cDir = new ByteArrayOutputStream();
|
||||
private ZipEntry currentEntry;
|
||||
private final CRC32 crc = new CRC32();
|
||||
private int offset;
|
||||
private int curOffset;
|
||||
private int nameLength;
|
||||
private byte[] nameBytes;
|
||||
|
||||
public ZipOutputStream(OutputStream p1) throws IOException {
|
||||
super(p1, new Deflater(-1, true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (out != null) {
|
||||
finish();
|
||||
out.close();
|
||||
out = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void closeEntry() throws IOException {
|
||||
if (cDir == null) {
|
||||
throw new IOException();
|
||||
}
|
||||
if (currentEntry == null) {
|
||||
return;
|
||||
}
|
||||
if (currentEntry.getMethod() == DEFLATED) {
|
||||
super.finish();
|
||||
}
|
||||
|
||||
// Verify values for STORED types
|
||||
if (currentEntry.getMethod() == STORED) {
|
||||
if (crc.getValue() != currentEntry.getCrc()) {
|
||||
throw new ZipException();
|
||||
}
|
||||
if (currentEntry.getSize() != crc.tbytes) {
|
||||
throw new ZipException();
|
||||
}
|
||||
}
|
||||
curOffset = LOCHDR;
|
||||
|
||||
// Write the DataDescriptor
|
||||
if (currentEntry.getMethod() != STORED) {
|
||||
curOffset += EXTHDR;
|
||||
writeLong(out, EXTSIG);
|
||||
currentEntry.setCrc(crc.getValue());
|
||||
writeLong(out, currentEntry.getCrc());
|
||||
currentEntry.setCompressedSize(deflater.getTotalOut());
|
||||
writeLong(out, currentEntry.getCompressedSize());
|
||||
currentEntry.setSize(deflater.getTotalIn());
|
||||
writeLong(out, currentEntry.getSize());
|
||||
}
|
||||
// Update the CentralDirectory
|
||||
writeLong(cDir, CENSIG);
|
||||
writeShort(cDir, ZIPLocalHeaderVersionNeeded); // Version created
|
||||
writeShort(cDir, ZIPLocalHeaderVersionNeeded); // Version to extract
|
||||
writeShort(cDir, currentEntry.getMethod() == STORED ? 0 : ZIPDataDescriptorFlag);
|
||||
writeShort(cDir, currentEntry.getMethod());
|
||||
writeShort(cDir, (int) currentEntry.getTime());
|
||||
writeShort(cDir, 0);
|
||||
writeLong(cDir, crc.getValue());
|
||||
if (currentEntry.getMethod() == DEFLATED) {
|
||||
curOffset += writeLong(cDir, deflater.getTotalOut());
|
||||
writeLong(cDir, deflater.getTotalIn());
|
||||
} else {
|
||||
curOffset += writeLong(cDir, crc.tbytes);
|
||||
writeLong(cDir, crc.tbytes);
|
||||
}
|
||||
curOffset += writeShort(cDir, nameLength);
|
||||
if (currentEntry.getExtra() != null) {
|
||||
curOffset += writeShort(cDir, currentEntry.getExtra().length);
|
||||
} else {
|
||||
writeShort(cDir, 0);
|
||||
}
|
||||
String c = currentEntry.getComment();
|
||||
writeShort(cDir, c != null ? c.length() : 0);
|
||||
writeShort(cDir, 0); // Disk Start
|
||||
writeShort(cDir, 0); // Internal File Attributes
|
||||
writeLong(cDir, 0); // External File Attributes
|
||||
writeLong(cDir, offset);
|
||||
cDir.write(nameBytes);
|
||||
nameBytes = null;
|
||||
if (currentEntry.getExtra() != null) {
|
||||
cDir.write(currentEntry.getExtra());
|
||||
}
|
||||
offset += curOffset;
|
||||
if (c != null) {
|
||||
cDir.write(c.getBytes());
|
||||
}
|
||||
currentEntry = null;
|
||||
crc.reset();
|
||||
deflater.end();
|
||||
deflater.init(-1, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() throws IOException {
|
||||
if (out == null) {
|
||||
throw new IOException();
|
||||
}
|
||||
if (cDir == null) {
|
||||
return;
|
||||
}
|
||||
if (entries.size() == 0) {
|
||||
throw new ZipException();
|
||||
}
|
||||
if (currentEntry != null) {
|
||||
closeEntry();
|
||||
}
|
||||
int cdirSize = cDir.size();
|
||||
// Write Central Dir End
|
||||
writeLong(cDir, ENDSIG);
|
||||
writeShort(cDir, 0); // Disk Number
|
||||
writeShort(cDir, 0); // Start Disk
|
||||
writeShort(cDir, entries.size()); // Number of entries
|
||||
writeShort(cDir, entries.size()); // Number of entries
|
||||
writeLong(cDir, cdirSize); // Size of central dir
|
||||
writeLong(cDir, offset); // Offset of central dir
|
||||
if (comment != null) {
|
||||
writeShort(cDir, comment.length());
|
||||
cDir.write(comment.getBytes());
|
||||
} else {
|
||||
writeShort(cDir, 0);
|
||||
}
|
||||
// Write the central dir
|
||||
out.write(cDir.toByteArray());
|
||||
cDir = null;
|
||||
|
||||
}
|
||||
|
||||
public void putNextEntry(ZipEntry ze) throws IOException {
|
||||
if (currentEntry != null) {
|
||||
closeEntry();
|
||||
}
|
||||
if (ze.getMethod() == STORED
|
||||
|| (compressMethod == STORED && ze.getMethod() == -1)) {
|
||||
if (ze.getCrc() == -1) {
|
||||
throw new ZipException("Crc mismatch");
|
||||
}
|
||||
if (ze.getSize() == -1 && ze.getCompressedSize() == -1) {
|
||||
throw new ZipException("Size mismatch");
|
||||
}
|
||||
if (ze.getSize() != ze.getCompressedSize() && ze.getCompressedSize() != -1 && ze.getSize() != -1) {
|
||||
throw new ZipException("Size mismatch");
|
||||
}
|
||||
}
|
||||
if (cDir == null) {
|
||||
throw new IOException("Stream is closed");
|
||||
}
|
||||
if (entries.contains(ze.getName())) {
|
||||
throw new ZipException("Entry already exists: " + ze.getName());
|
||||
}
|
||||
nameLength = utf8Count(ze.getName());
|
||||
if (nameLength > 0xffff) {
|
||||
throw new IllegalArgumentException("Name too long: " + ze.getName());
|
||||
}
|
||||
|
||||
deflater.params(compressLevel, 0);
|
||||
currentEntry = ze;
|
||||
entries.add(currentEntry.getName());
|
||||
if (currentEntry.getMethod() == -1) {
|
||||
currentEntry.setMethod(compressMethod);
|
||||
}
|
||||
writeLong(out, LOCSIG); // Entry header
|
||||
writeShort(out, ZIPLocalHeaderVersionNeeded); // Extraction version
|
||||
writeShort(out, currentEntry.getMethod() == STORED ? 0 : ZIPDataDescriptorFlag);
|
||||
writeShort(out, currentEntry.getMethod());
|
||||
if (currentEntry.getTime() == -1) {
|
||||
currentEntry.setTime(System.currentTimeMillis());
|
||||
}
|
||||
writeShort(out, (int) currentEntry.getTime());
|
||||
writeShort(out, 0);
|
||||
|
||||
if (currentEntry.getMethod() == STORED) {
|
||||
if (currentEntry.getSize() == -1) {
|
||||
currentEntry.setSize(currentEntry.getCompressedSize());
|
||||
} else if (currentEntry.getCompressedSize() == -1) {
|
||||
currentEntry.setCompressedSize(currentEntry.getSize());
|
||||
}
|
||||
writeLong(out, currentEntry.getCrc());
|
||||
writeLong(out, currentEntry.getSize());
|
||||
writeLong(out, currentEntry.getSize());
|
||||
} else {
|
||||
writeLong(out, 0);
|
||||
writeLong(out, 0);
|
||||
writeLong(out, 0);
|
||||
}
|
||||
writeShort(out, nameLength);
|
||||
writeShort(out, currentEntry.getExtra() != null ? currentEntry.getExtra().length : 0);
|
||||
nameBytes = toUTF8Bytes(currentEntry.getName(), nameLength);
|
||||
out.write(nameBytes);
|
||||
if (currentEntry.getExtra() != null) {
|
||||
out.write(currentEntry.getExtra());
|
||||
}
|
||||
}
|
||||
|
||||
public void setComment(String comment) {
|
||||
if (comment.length() > 0xFFFF) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public void setLevel(int level) {
|
||||
if (level < DEFAULT_COMPRESSION || level > BEST_COMPRESSION) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
compressLevel = level;
|
||||
}
|
||||
|
||||
public void setMethod(int method) {
|
||||
if (method != STORED && method != DEFLATED) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
compressMethod = method;
|
||||
|
||||
}
|
||||
|
||||
private long writeLong(OutputStream os, long i) throws IOException {
|
||||
// Write out the long value as an unsigned int
|
||||
os.write((int) (i & 0xFF));
|
||||
os.write((int) (i >> 8) & 0xFF);
|
||||
os.write((int) (i >> 16) & 0xFF);
|
||||
os.write((int) (i >> 24) & 0xFF);
|
||||
return i;
|
||||
}
|
||||
|
||||
private int writeShort(OutputStream os, int i) throws IOException {
|
||||
os.write(i & 0xFF);
|
||||
os.write((i >> 8) & 0xFF);
|
||||
return i;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes data for the current entry to the underlying stream.
|
||||
*
|
||||
* @exception IOException
|
||||
* If an error occurs writing to the stream
|
||||
*/
|
||||
@Override
|
||||
public void write(byte[] buffer, int off, int nbytes)
|
||||
throws IOException {
|
||||
// avoid int overflow, check null buf
|
||||
if ((off < 0 || (nbytes < 0) || off > buffer.length) || (buffer.length - off < nbytes)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
if (currentEntry == null) {
|
||||
throw new ZipException("No active entry");
|
||||
}
|
||||
|
||||
if (currentEntry.getMethod() == STORED) {
|
||||
out.write(buffer, off, nbytes);
|
||||
} else {
|
||||
super.write(buffer, off, nbytes);
|
||||
}
|
||||
crc.update(buffer, off, nbytes);
|
||||
}
|
||||
|
||||
static int utf8Count(String value) {
|
||||
int total = 0;
|
||||
for (int i = value.length(); --i >= 0;) {
|
||||
char ch = value.charAt(i);
|
||||
if (ch < 0x80) {
|
||||
total++;
|
||||
} else if (ch < 0x800) {
|
||||
total += 2;
|
||||
} else {
|
||||
total += 3;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
static byte[] toUTF8Bytes(String value, int length) {
|
||||
byte[] result = new byte[length];
|
||||
int pos = result.length;
|
||||
for (int i = value.length(); --i >= 0;) {
|
||||
char ch = value.charAt(i);
|
||||
if (ch < 0x80) {
|
||||
result[--pos] = (byte) ch;
|
||||
} else if (ch < 0x800) {
|
||||
result[--pos] = (byte) (0x80 | (ch & 0x3f));
|
||||
result[--pos] = (byte) (0xc0 | (ch >> 6));
|
||||
} else {
|
||||
result[--pos] = (byte) (0x80 | (ch & 0x3f));
|
||||
result[--pos] = (byte) (0x80 | ((ch >> 6) & 0x3f));
|
||||
result[--pos] = (byte) (0xe0 | (ch >> 12));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -80,7 +80,7 @@ public class GuiScreenBackupWorld extends GuiScreen {
|
|||
}));
|
||||
}else if(par1GuiButton.id == 4) {
|
||||
IntegratedServer.exportWorld(worldName, IPCPacket05RequestData.REQUEST_LEVEL_MCA);
|
||||
this.mc.displayGuiScreen(new GuiScreenSingleplayerLoading(selectWorld, "selectWorld.progress.exporting.1", () -> {
|
||||
this.mc.displayGuiScreen(new GuiScreenSingleplayerLoading(selectWorld, "selectWorld.progress.exporting.2", () -> {
|
||||
byte[] b = IntegratedServer.getExportResponse();
|
||||
if(b != null) {
|
||||
EaglerAdapter.downloadBytes(worldName + ".zip", b);
|
||||
|
|
|
@ -508,6 +508,7 @@ public class ItemRenderer {
|
|||
* partialTickTime, blockTextureIndex
|
||||
*/
|
||||
private void renderInsideOfBlock(float par1, Icon par2Icon) {
|
||||
if (par2Icon == null) return;
|
||||
Tessellator var3 = Tessellator.instance;
|
||||
float var4 = 0.1F;
|
||||
EaglerAdapter.glColor4f(var4, var4, var4, 0.5F);
|
||||
|
|
Loading…
Reference in New Issue
Block a user