Merge branch 'singleplayer' of https://github.com/EaglerMods/eaglercraft-sp into singleplayer

This commit is contained in:
LAX1DUDE 2022-08-02 01:56:40 -07:00
commit 254365783e
10 changed files with 18216 additions and 17880 deletions

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

View File

@ -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();
}
}
}

View File

@ -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();

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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);