Clean up client source

This commit is contained in:
catfoolyou 2025-03-22 14:52:41 -04:00
parent 1d659d2493
commit f29a2ff38a
53 changed files with 36188 additions and 52732 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

@ -18,11 +18,11 @@ public class WorldConverterEPK {
while((f = dc.readFile()) != null) {
byte[] b = f.data;
if(!hasReadType) {
if(f.type.equals("HEAD") && f.name.equals("file-type") && EPKDecompiler.readASCII(f.data).equals("epk/world152")) {
if(f.type.equals("HEAD") && f.name.equals("file-type") && EPKDecompiler.readASCII(f.data).equals("epk/world164")) {
hasReadType = true;
continue;
}else {
throw new IOException("file does not contain a singleplayer 1.5.2 world!");
throw new IOException("file does not contain a singleplayer 1.6.4 world!");
}
}
if(f.type.equals("FILE")) {
@ -64,7 +64,7 @@ public class WorldConverterEPK {
final int[] bytesWritten = new int[1];
final int[] lastUpdate = new int[1];
String pfx = "worlds/" + realWorldName + "/";
EPK2Compiler c = new EPK2Compiler(realWorldName, worldOwner, "epk/world152");
EPK2Compiler c = new EPK2Compiler(realWorldName, worldOwner, "epk/world164");
SYS.VFS.iterateFiles(pfx, false, (i) -> {
byte[] b = i.getAllBytes();
c.append(i.path.substring(pfx.length()), b);

View File

@ -565,7 +565,7 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
* Returns the server's Minecraft version as string.
*/
public String getMinecraftVersion() {
return "1.5.2";
return "1.6.4";
}
/**

View File

@ -1,18 +0,0 @@
package net.lax1dude.eaglercraft.sp;
public class BooleanResult {
public static final BooleanResult TRUE = new BooleanResult(true);
public static final BooleanResult FALSE = new BooleanResult(false);
public final boolean bool;
private BooleanResult(boolean b) {
bool = b;
}
public static BooleanResult _new(boolean b) {
return b ? TRUE : FALSE;
}
}

View File

@ -1,39 +0,0 @@
package net.lax1dude.eaglercraft.sp;
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

@ -1,45 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.minecraft.src.ILogAgent;
public class EAGLogAgent implements ILogAgent {
private final Logger logger = Logger.getLogger("IntegratedServer");
public Logger getServerLogger() {
return this.logger;
}
public void logInfo(String par1Str) {
this.logger.log(Level.INFO, par1Str);
}
public void logWarning(String par1Str) {
this.logger.log(Level.WARNING, par1Str);
}
public void logWarningFormatted(String par1Str, Object... par2ArrayOfObj) {
this.logger.log(Level.WARNING, par1Str, par2ArrayOfObj);
}
public void logWarningException(String par1Str, Throwable par2Throwable) {
this.logger.log(Level.WARNING, par1Str, par2Throwable);
}
public void logSevere(String par1Str) {
this.logger.log(Level.SEVERE, par1Str);
}
public void logSevereException(String par1Str, Throwable par2Throwable) {
this.logger.log(Level.SEVERE, par1Str, par2Throwable);
}
@Override
public void logFine(String var1) {
this.logger.log(Level.FINE, var1);
}
}

View File

@ -1,158 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.io.IOException;
import net.lax1dude.eaglercraft.sp.ipc.IPCPacket14StringList;
import net.minecraft.server.MinecraftServer;
import net.minecraft.src.EnumGameType;
import net.minecraft.src.ILogAgent;
import net.minecraft.src.WorldSettings;
public class EAGMinecraftServer extends MinecraftServer {
protected int difficulty;
protected EnumGameType gamemode;
protected long lastTick;
protected WorkerListenThread listenThreadImpl;
protected WorldSettings newWorldSettings;
protected boolean paused;
private int tpsCounter = 0;
private int tpsMeasure = 0;
private long tpsTimer = 0l;
public EAGMinecraftServer(String world, String owner, WorldSettings currentWorldSettings) {
super(world);
this.setServerOwner(owner);
System.out.println("server owner: " + owner);
this.setConfigurationManager(new EAGPlayerList(this));
this.listenThreadImpl = new WorkerListenThread(this);
this.newWorldSettings = currentWorldSettings;
this.paused = false;
}
public void setBaseServerProperties(int difficulty, EnumGameType gamemode) {
this.difficulty = difficulty;
this.gamemode = gamemode;
this.setCanSpawnAnimals(true);
this.setCanSpawnNPCs(true);
this.setAllowPvp(true);
this.setAllowFlight(true);
}
public void mainLoop() {
long ctm = SysUtil.steadyTimeMillis();
long elapsed = ctm - tpsTimer;
if(elapsed >= 1000l) {
tpsTimer = ctm;
tpsMeasure = tpsCounter;
IntegratedServer.sendIPCPacket(new IPCPacket14StringList(IPCPacket14StringList.SERVER_TPS, getTPSAndChunkBuffer(tpsMeasure)));
tpsCounter = 0;
}
if(paused && this.playersOnline.size() <= 1) {
lastTick = ctm;
return;
}
long delta = ctm - lastTick;
if (delta > 2000L && ctm - this.timeOfLastWarning >= 15000L) {
this.getLogAgent().logWarning("Can\'t keep up! Did the system time change, or is the server overloaded? Skipping " + ((delta - 2000l) / 50l) + " ticks");
delta = 2000L;
this.timeOfLastWarning = ctm;
}
if (delta < 0L) {
this.getLogAgent().logWarning("Time ran backwards! Did the fucking system time change?");
delta = 0L;
}
if (this.worldServers[0].areAllPlayersAsleep()) {
this.tick();
++tpsCounter;
lastTick = SysUtil.steadyTimeMillis();
} else {
if (delta > 50l) {
delta -= 50L;
lastTick += 50l;
this.tick();
++tpsCounter;
}
}
}
public void setPaused(boolean p) {
paused = p;
if(!p) {
lastTick = SysUtil.steadyTimeMillis();
}
}
public boolean getPaused() {
return paused;
}
@Override
protected boolean startServer() throws IOException {
SkinsPlugin.reset();
//VoiceChatPlugin.reset();
this.loadAllWorlds(folderName, 0l, newWorldSettings);
this.lastTick = SysUtil.steadyTimeMillis();
return true;
}
@Override
public void stopServer() {
super.stopServer();
SkinsPlugin.reset();
//VoiceChatPlugin.reset();
}
@Override
public boolean canStructuresSpawn() {
return false;
}
@Override
public EnumGameType getGameType() {
return gamemode;
}
@Override
public int getDifficulty() {
return difficulty;
}
@Override
public boolean isHardcore() {
return false;
}
@Override
public boolean isDedicatedServer() {
return false;
}
@Override
public boolean isCommandBlockEnabled() {
return true;
}
@Override
public WorkerListenThread getNetworkThread() {
return listenThreadImpl;
}
@Override
public String shareToLAN(EnumGameType var1, boolean var2) {
return null;
}
@Override
public ILogAgent getLogAgent() {
return IntegratedServer.logger;
}
}

View File

@ -1,28 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import net.minecraft.server.MinecraftServer;
import net.minecraft.src.EntityPlayerMP;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.ServerConfigurationManager;
public class EAGPlayerList extends ServerConfigurationManager {
private NBTTagCompound hostPlayerNBT = null;
public EAGPlayerList(MinecraftServer par1MinecraftServer) {
super(par1MinecraftServer);
this.viewDistance = 4;
}
protected void writePlayerData(EntityPlayerMP par1EntityPlayerMP) {
if (par1EntityPlayerMP.getCommandSenderName().equals(this.getServerInstance().getServerOwner())) {
this.hostPlayerNBT = new NBTTagCompound();
par1EntityPlayerMP.writeToNBT(hostPlayerNBT);
}
super.writePlayerData(par1EntityPlayerMP);
}
public NBTTagCompound getHostPlayerData() {
return this.hostPlayerNBT;
}
}

View File

@ -1,151 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.jcraft.jzlib.CRC32;
public class EPK2Compiler {
private final ByteArrayOutputStream os;
private final CRC32 checkSum = new CRC32();
private int lengthIntegerOffset = 0;
private int totalFileCount = 0;
public EPK2Compiler(String name, String owner, String type) {
os = new ByteArrayOutputStream(0x200000);
try {
os.write(new byte[]{(byte)69,(byte)65,(byte)71,(byte)80,(byte)75,(byte)71,(byte)36,(byte)36}); // EAGPKG$$
os.write(new byte[]{(byte)6,(byte)118,(byte)101,(byte)114,(byte)50,(byte)46,(byte)48}); // 6 + ver2.0
Date d = new Date();
byte[] filename = (name + ".epk").getBytes(StandardCharsets.UTF_8);
os.write(filename.length);
os.write(filename);
byte[] comment = ("\n\n # Eagler EPK v2.0 (c) " + (new SimpleDateFormat("yyyy")).format(d) + " " +
owner + "\n # export: on " + (new SimpleDateFormat("MM/dd/yyyy")).format(d) + " at " +
(new SimpleDateFormat("hh:mm:ss aa")).format(d) + "\n\n # world name: " + name + "\n\n")
.getBytes(StandardCharsets.UTF_8);
os.write((comment.length >> 8) & 255);
os.write(comment.length & 255);
os.write(comment);
writeLong(d.getTime(), os);
lengthIntegerOffset = os.size();
os.write(new byte[]{(byte)255,(byte)255,(byte)255,(byte)255}); // this will be replaced with the file count
os.write('0'); // compression type: none
os.write(new byte[]{(byte)72,(byte)69,(byte)65,(byte)68}); // HEAD
os.write(new byte[]{(byte)9,(byte)102,(byte)105,(byte)108,(byte)101,(byte)45,(byte)116,(byte)121,
(byte)112,(byte)101}); // 9 + file-type
byte[] typeBytes = type.getBytes(StandardCharsets.UTF_8);
writeInt(typeBytes.length, os);
os.write(typeBytes); // write type
os.write('>');
++totalFileCount;
os.write(new byte[]{(byte)72,(byte)69,(byte)65,(byte)68}); // HEAD
os.write(new byte[]{(byte)10,(byte)119,(byte)111,(byte)114,(byte)108,(byte)100,(byte)45,(byte)110,
(byte)97,(byte)109,(byte)101}); // 10 + world-name
byte[] nameBytes = name.getBytes(StandardCharsets.UTF_8);
writeInt(nameBytes.length, os);
os.write(nameBytes); // write name
os.write('>');
++totalFileCount;
os.write(new byte[]{(byte)72,(byte)69,(byte)65,(byte)68}); // HEAD
os.write(new byte[]{(byte)11,(byte)119,(byte)111,(byte)114,(byte)108,(byte)100,(byte)45,(byte)111,
(byte)119,(byte)110,(byte)101,(byte)114}); // 11 + world-owner
byte[] ownerBytes = owner.getBytes(StandardCharsets.UTF_8);
writeInt(ownerBytes.length, os);
os.write(ownerBytes); // write owner
os.write('>');
++totalFileCount;
}catch(IOException ex) {
throw new RuntimeException("This happened somehow", ex);
}
}
public void append(String name, byte[] dat) {
try {
checkSum.reset();
checkSum.update(dat, 0, dat.length);
long sum = checkSum.getValue();
os.write(new byte[]{(byte)70,(byte)73,(byte)76,(byte)69}); // FILE
byte[] nameBytes = name.getBytes(StandardCharsets.UTF_8);
os.write(nameBytes.length);
os.write(nameBytes);
writeInt(dat.length + 5, os);
writeInt((int)sum, os);
os.write(dat);
os.write(':');
os.write('>');
++totalFileCount;
}catch(IOException ex) {
throw new RuntimeException("This happened somehow", ex);
}
}
public byte[] complete() {
try {
os.write(new byte[]{(byte)69,(byte)78,(byte)68,(byte)36}); // END$
os.write(new byte[]{(byte)58,(byte)58,(byte)58,(byte)89,(byte)69,(byte)69,(byte)58,(byte)62}); // :::YEE:>
byte[] ret = os.toByteArray();
ret[lengthIntegerOffset] = (byte)((totalFileCount >> 24) & 0xFF);
ret[lengthIntegerOffset + 1] = (byte)((totalFileCount >> 16) & 0xFF);
ret[lengthIntegerOffset + 2] = (byte)((totalFileCount >> 8) & 0xFF);
ret[lengthIntegerOffset + 3] = (byte)(totalFileCount & 0xFF);
return ret;
}catch(IOException ex) {
throw new RuntimeException("This happened somehow", ex);
}
}
public static void writeInt(int i, OutputStream os) throws IOException {
os.write((i >> 24) & 0xFF);
os.write((i >> 16) & 0xFF);
os.write((i >> 8) & 0xFF);
os.write(i & 0xFF);
}
public static void writeLong(long i, OutputStream os) throws IOException {
os.write((int)((i >> 56) & 0xFF));
os.write((int)((i >> 48) & 0xFF));
os.write((int)((i >> 40) & 0xFF));
os.write((int)((i >> 32) & 0xFF));
os.write((int)((i >> 24) & 0xFF));
os.write((int)((i >> 16) & 0xFF));
os.write((int)((i >> 8) & 0xFF));
os.write((int)(i & 0xFF));
}
}

View File

@ -1,217 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import com.jcraft.jzlib.CRC32;
import com.jcraft.jzlib.GZIPInputStream;
import com.jcraft.jzlib.InflaterInputStream;
public class EPKDecompiler {
public static class FileEntry {
public final String type;
public final String name;
public final byte[] data;
protected FileEntry(String type, String name, byte[] data) {
this.type = type;
this.name = name;
this.data = data;
}
}
private ByteArrayInputStream in2;
private DataInputStream in;
private InputStream zis;
private SHA1Digest dg;
private CRC32 crc32;
private int numFiles;
private boolean isFinished = false;
private boolean isOldFormat = false;
public EPKDecompiler(byte[] data) throws IOException {
in2 = new ByteArrayInputStream(data);
byte[] header = new byte[8];
in2.read(header);
if(Arrays.equals(header, new byte[]{(byte)69,(byte)65,(byte)71,(byte)80,(byte)75,(byte)71,(byte)36,(byte)36})) {
byte[] endCode = new byte[] { (byte)':', (byte)':', (byte)':', (byte)'Y',
(byte)'E', (byte)'E', (byte)':', (byte)'>' };
for(int i = 0; i < 8; ++i) {
if(data[data.length - 8 + i] != endCode[i]) {
throw new IOException("EPK file is missing EOF code (:::YEE:>)");
}
}
in2 = new ByteArrayInputStream(data, 8, data.length - 16);
initNew();
}else if(Arrays.equals(header, new byte[]{(byte)69,(byte)65,(byte)71,(byte)80,(byte)75,(byte)71,(byte)33,(byte)33})) {
initOld();
}
}
public boolean isOld() {
return isOldFormat;
}
public FileEntry readFile() throws IOException {
if(!isOldFormat) {
return readFileNew();
}else {
return readFileOld();
}
}
private void initNew() throws IOException {
InputStream is = in2;
String vers = readASCII(is);
if(!vers.startsWith("ver2.")) {
throw new IOException("Unknown or invalid EPK version: " + vers);
}
is.skip(is.read()); // skip filename
is.skip(loadShort(is)); // skip comment
is.skip(8); // skip millis date
numFiles = loadInt(is);
char compressionType = (char)is.read();
switch(compressionType) {
case 'G':
zis = new GZIPInputStream(is);
break;
case 'Z':
zis = new InflaterInputStream(is);
break;
case '0':
zis = is;
break;
default:
throw new IOException("Invalid or unsupported EPK compression: " + compressionType);
}
crc32 = new CRC32();
}
private FileEntry readFileNew() throws IOException {
if(isFinished) {
return null;
}
byte[] typeBytes = new byte[4];
zis.read(typeBytes);
String type = readASCII(typeBytes);
if(numFiles == 0) {
if(!"END$".equals(type)) {
throw new IOException("EPK file is missing END code (END$)");
}
isFinished = true;
return null;
}else {
if("END$".equals(type)) {
throw new IOException("Unexpected END when there are still " + numFiles + " files remaining");
}else {
String name = readASCII(zis);
int len = loadInt(zis);
byte[] data;
if("FILE".equals(type)) {
if(len < 5) {
throw new IOException("File '" + name + "' is incomplete (no crc)");
}
int loadedCrc = loadInt(zis);
data = new byte[len - 5];
zis.read(data);
crc32.reset();
crc32.update(data, 0, data.length);
if((int)crc32.getValue() != loadedCrc) {
throw new IOException("File '" + name + "' has an invalid checksum");
}
if(zis.read() != ':') {
throw new IOException("File '" + name + "' is incomplete");
}
}else {
data = new byte[len];
zis.read(data);
}
if(zis.read() != '>') {
throw new IOException("Object '" + name + "' is incomplete");
}
--numFiles;
return new FileEntry(type, name, data);
}
}
}
private static final int loadShort(InputStream is) throws IOException {
return (is.read() << 8) | is.read();
}
private static final int loadInt(InputStream is) throws IOException {
return (is.read() << 24) | (is.read() << 16) | (is.read() << 8) | is.read();
}
public static final String readASCII(byte[] bytesIn) throws IOException {
char[] charIn = new char[bytesIn.length];
for(int i = 0; i < bytesIn.length; ++i) {
charIn[i] = (char)((int)bytesIn[i] & 0xFF);
}
return new String(charIn);
}
private static final String readASCII(InputStream bytesIn) throws IOException {
int len = bytesIn.read();
char[] charIn = new char[len];
for(int i = 0; i < len; ++i) {
charIn[i] = (char)(bytesIn.read() & 0xFF);
}
return new String(charIn);
}
private void initOld() throws IOException {
isOldFormat = true;
dg = new SHA1Digest();
in = new DataInputStream(in2);
in.readUTF();
in = new DataInputStream(new InflaterInputStream(in2));
}
private FileEntry readFileOld() throws IOException {
if(isFinished) {
return null;
}
String s = in.readUTF();
if(s.equals(" end")) {
isFinished = true;
return null;
}else if(!s.equals("<file>")) {
throw new IOException("invalid epk file");
}
String path = in.readUTF();
byte[] digest = new byte[20];
byte[] digest2 = new byte[20];
in.read(digest);
int len = in.readInt();
byte[] file = new byte[len];
in.read(file);
dg.update(file, 0, len); dg.doFinal(digest2, 0);
if(!Arrays.equals(digest, digest2)) throw new IOException("invalid file hash for "+path);
if(!"</file>".equals(in.readUTF())) throw new IOException("invalid epk file");
return new FileEntry("FILE", path, file);
}
}

View File

@ -1,189 +0,0 @@
package net.lax1dude.eaglercraft.sp;
public class EaglerUUID {
private final long mostSigBits;
private final long leastSigBits;
private EaglerUUID(byte[] data) {
long msb = 0;
long lsb = 0;
assert data.length == 16 : "data must be 16 bytes in length";
for (int i=0; i<8; i++)
msb = (msb << 8) | (data[i] & 0xff);
for (int i=8; i<16; i++)
lsb = (lsb << 8) | (data[i] & 0xff);
this.mostSigBits = msb;
this.leastSigBits = lsb;
}
public EaglerUUID(long mostSigBits, long leastSigBits) {
this.mostSigBits = mostSigBits;
this.leastSigBits = leastSigBits;
}
private static final EaglercraftRandom random = new EaglercraftRandom();
public static EaglerUUID randomUUID() {
byte[] randomBytes = new byte[16];
random.nextBytes(randomBytes);
randomBytes[6] &= 0x0f; /* clear version */
randomBytes[6] |= 0x40; /* set to version 4 */
randomBytes[8] &= 0x3f; /* clear variant */
randomBytes[8] |= 0x80; /* set to IETF variant */
return new EaglerUUID(randomBytes);
}
private static final MD5Digest yee = new MD5Digest();
public static EaglerUUID nameUUIDFromBytes(byte[] name) {
yee.update(name, 0, name.length);
byte[] md5Bytes = new byte[16];
yee.doFinal(md5Bytes, 0);
md5Bytes[6] &= 0x0f; /* clear version */
md5Bytes[6] |= 0x30; /* set to version 3 */
md5Bytes[8] &= 0x3f; /* clear variant */
md5Bytes[8] |= 0x80; /* set to IETF variant */
return new EaglerUUID(md5Bytes);
}
public static EaglerUUID fromString(String name) {
String[] components = name.split("-");
if (components.length != 5)
throw new IllegalArgumentException("Invalid UUID string: "+name);
for (int i=0; i<5; i++)
components[i] = "0x"+components[i];
long mostSigBits = Long.decode(components[0]).longValue();
mostSigBits <<= 16;
mostSigBits |= Long.decode(components[1]).longValue();
mostSigBits <<= 16;
mostSigBits |= Long.decode(components[2]).longValue();
long leastSigBits = Long.decode(components[3]).longValue();
leastSigBits <<= 48;
leastSigBits |= Long.decode(components[4]).longValue();
return new EaglerUUID(mostSigBits, leastSigBits);
}
public long getLeastSignificantBits() {
return leastSigBits;
}
public long getMostSignificantBits() {
return mostSigBits;
}
/**
* The version number associated with this {@code UUID}. The version
* number describes how this {@code UUID} was generated.
*
* The version number has the following meaning:
* <ul>
* <li>1 Time-based UUID
* <li>2 DCE security UUID
* <li>3 Name-based UUID
* <li>4 Randomly generated UUID
* </ul>
*
* @return The version number of this {@code UUID}
*/
public int version() {
// Version is bits masked by 0x000000000000F000 in MS long
return (int)((mostSigBits >> 12) & 0x0f);
}
/**
* The variant number associated with this {@code UUID}. The variant
* number describes the layout of the {@code UUID}.
*
* The variant number has the following meaning:
* <ul>
* <li>0 Reserved for NCS backward compatibility
* <li>2 <a href="http://www.ietf.org/rfc/rfc4122.txt">IETF&nbsp;RFC&nbsp;4122</a>
* (Leach-Salz), used by this class
* <li>6 Reserved, Microsoft Corporation backward compatibility
* <li>7 Reserved for future definition
* </ul>
*
* @return The variant number of this {@code UUID}
*/
public int variant() {
// This field is composed of a varying number of bits.
// 0 - - Reserved for NCS backward compatibility
// 1 0 - The IETF aka Leach-Salz variant (used by this class)
// 1 1 0 Reserved, Microsoft backward compatibility
// 1 1 1 Reserved for future definition.
return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62)))
& (leastSigBits >> 63));
}
public long timestamp() {
if (version() != 1) {
throw new UnsupportedOperationException("Not a time-based UUID");
}
return (mostSigBits & 0x0FFFL) << 48
| ((mostSigBits >> 16) & 0x0FFFFL) << 32
| mostSigBits >>> 32;
}
/**
* The clock sequence value associated with this UUID.
*
* <p> The 14 bit clock sequence value is constructed from the clock
* sequence field of this UUID. The clock sequence field is used to
* guarantee temporal uniqueness in a time-based UUID.
*
* <p> The {@code clockSequence} value is only meaningful in a time-based
* UUID, which has version type 1. If this UUID is not a time-based UUID
* then this method throws UnsupportedOperationException.
*
* @return The clock sequence of this {@code UUID}
*
* @throws UnsupportedOperationException
* If this UUID is not a version 1 UUID
*/
public int clockSequence() {
if (version() != 1) {
throw new UnsupportedOperationException("Not a time-based UUID");
}
return (int)((leastSigBits & 0x3FFF000000000000L) >>> 48);
}
public String toString() {
return (digits(mostSigBits >> 32, 8) + "-" +
digits(mostSigBits >> 16, 4) + "-" +
digits(mostSigBits, 4) + "-" +
digits(leastSigBits >> 48, 4) + "-" +
digits(leastSigBits, 12));
}
private static String digits(long val, int digits) {
long hi = 1L << (digits * 4);
return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}
public int hashCode() {
long hilo = mostSigBits ^ leastSigBits;
return ((int)(hilo >> 32)) ^ (int) hilo;
}
public boolean equals(Object obj) {
if ((null == obj) || !(obj instanceof EaglerUUID))
return false;
EaglerUUID id = (EaglerUUID)obj;
return (mostSigBits == id.mostSigBits &&
leastSigBits == id.leastSigBits);
}
public int compareTo(EaglerUUID val) {
return (this.mostSigBits < val.mostSigBits ? -1 :
(this.mostSigBits > val.mostSigBits ? 1 :
(this.leastSigBits < val.leastSigBits ? -1 :
(this.leastSigBits > val.leastSigBits ? 1 :
0))));
}
}

View File

@ -1,84 +0,0 @@
package net.lax1dude.eaglercraft.sp;
public class EaglercraftRandom {
private static final long multiplier = 0x5DEECE66DL;
private static final long addend = 0xBL;
private static final long mask = (1L << 48) - 1;
private static final double DOUBLE_UNIT = 0x1.0p-53;
private long seed = 69;
public EaglercraftRandom() {
this(System.nanoTime());
}
public EaglercraftRandom(long seed) {
setSeed(seed);
}
public void setSeed(long yeed) {
seed = yeed;
}
protected int next(int bits) {
seed = (seed * multiplier + addend) & mask;
return (int)(seed >>> (48 - bits));
}
public void nextBytes(byte[] bytes) {
for (int i = 0, len = bytes.length; i < len; )
for (int rnd = nextInt(),
n = Math.min(len - i, Integer.SIZE/Byte.SIZE);
n-- > 0; rnd >>= Byte.SIZE)
bytes[i++] = (byte)rnd;
}
public int nextInt() {
return next(32);
}
public int nextInt(int bound) {
int r = next(31);
int m = bound - 1;
if ((bound & m) == 0) // i.e., bound is a power of 2
r = (int)((bound * (long)r) >> 31);
else {
for (int u = r;
u - (r = u % bound) + m < 0;
u = next(31))
;
}
return r;
}
public long nextLong() {
return ((long)(next(32)) << 32) + next(32);
}
public boolean nextBoolean() {
return next(1) != 0;
}
public float nextFloat() {
return next(24) / ((float)(1 << 24));
}
public double nextDouble() {
return (((long)(next(26)) << 27) + next(27)) * DOUBLE_UNIT;
}
private double nextNextGaussian;
private boolean haveNextNextGaussian = false;
public double nextGaussian() {
// See Knuth, ACP, Section 3.4.1 Algorithm C.
if (haveNextNextGaussian) {
haveNextNextGaussian = false;
return nextNextGaussian;
} else {
double v1, v2, s;
do {
v1 = 2 * nextDouble() - 1; // between -1 and 1
v2 = 2 * nextDouble() - 1; // between -1 and 1
s = v1 * v1 + v2 * v2;
} while (s >= 1 || s == 0);
double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
nextNextGaussian = v2 * multiplier;
haveNextNextGaussian = true;
return v1 * multiplier;
}
}
}

View File

@ -1,74 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
// note that there's a few things not implemented, but I don't care.
public class ExpiringSet<T> extends HashSet<T> {
private final long expiration;
private final ExpiringEvent<T> event;
private final Map<T, Long> timestamps = new HashMap<>();
public ExpiringSet(long expiration) {
this.expiration = expiration;
this.event = null;
}
public ExpiringSet(long expiration, ExpiringEvent<T> event) {
this.expiration = expiration;
this.event = event;
}
public interface ExpiringEvent<T> {
void onExpiration(T item);
}
public void checkForExpirations() {
Iterator<T> iterator = this.timestamps.keySet().iterator();
long now = SysUtil.steadyTimeMillis();
while (iterator.hasNext()) {
T element = iterator.next();
if (super.contains(element)) {
if (this.timestamps.get(element) + this.expiration < now) {
if (this.event != null)
this.event.onExpiration(element);
iterator.remove();
super.remove(element);
}
} else {
iterator.remove();
super.remove(element);
}
}
}
public boolean add(T o) {
checkForExpirations();
boolean success = super.add(o);
if (success)
timestamps.put(o, SysUtil.steadyTimeMillis());
return success;
}
public boolean remove(Object o) {
checkForExpirations();
boolean success = super.remove(o);
if (success)
timestamps.remove(o);
return success;
}
public void clear() {
this.timestamps.clear();
super.clear();
}
public boolean contains(Object o) {
checkForExpirations();
return super.contains(o);
}
}

View File

@ -1,124 +0,0 @@
package net.lax1dude.eaglercraft.sp;
/**
* base implementation of MD4 family style digest as outlined in
* "Handbook of Applied Cryptography", pages 344 - 347.
*/
public abstract class GeneralDigest {
private byte[] xBuf;
private int xBufOff;
private long byteCount;
/**
* Standard constructor
*/
protected GeneralDigest()
{
xBuf = new byte[4];
xBufOff = 0;
}
/**
* Copy constructor. We are using copy constructors in place
* of the Object.clone() interface as this interface is not
* supported by J2ME.
*/
protected GeneralDigest(GeneralDigest t)
{
xBuf = new byte[t.xBuf.length];
System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length);
xBufOff = t.xBufOff;
byteCount = t.byteCount;
}
public void update(
byte in)
{
xBuf[xBufOff++] = in;
if (xBufOff == xBuf.length)
{
processWord(xBuf, 0);
xBufOff = 0;
}
byteCount++;
}
public void update(
byte[] in,
int inOff,
int len)
{
//
// fill the current word
//
while ((xBufOff != 0) && (len > 0))
{
update(in[inOff]);
inOff++;
len--;
}
//
// process whole words.
//
while (len > xBuf.length)
{
processWord(in, inOff);
inOff += xBuf.length;
len -= xBuf.length;
byteCount += xBuf.length;
}
//
// load in the remainder.
//
while (len > 0)
{
update(in[inOff]);
inOff++;
len--;
}
}
public void finish()
{
long bitLength = (byteCount << 3);
//
// add the pad bytes.
//
update((byte)128);
while (xBufOff != 0)
{
update((byte)0);
}
processLength(bitLength);
processBlock();
}
public void reset()
{
byteCount = 0;
xBufOff = 0;
for ( int i = 0; i < xBuf.length; i++ ) {
xBuf[i] = 0;
}
}
protected abstract void processWord(byte[] in, int inOff);
protected abstract void processLength(long bitLength);
protected abstract void processBlock();
}

View File

@ -1,548 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSFunctor;
import org.teavm.jso.JSObject;
import org.teavm.jso.typedarrays.ArrayBuffer;
import net.lax1dude.eaglercraft.sp.ipc.*;
import net.minecraft.src.AchievementList;
import net.minecraft.src.AchievementMap;
import net.minecraft.src.CompressedStreamTools;
import net.minecraft.src.EnumGameType;
import net.minecraft.src.ILogAgent;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.StringTranslate;
import net.minecraft.src.WorldSettings;
import net.minecraft.src.WorldType;
public class IntegratedServer {
private static final LinkedList<PKT> messageQueue = new LinkedList<>();
protected static class PKT {
protected final String channel;
protected final byte[] data;
protected PKT(String channel, byte[] data) {
this.channel = channel;
this.data = data;
}
}
private static EAGMinecraftServer currentProcess = null;
private static WorldSettings newWorldSettings = null;
public static EAGMinecraftServer getServer() {
return currentProcess;
}
public static final ILogAgent logger = new EAGLogAgent();
@JSFunctor
private static interface WorkerBinaryPacketHandler extends JSObject {
public void onMessage(String channel, ArrayBuffer buf);
}
private static class WorkerBinaryPacketHandlerImpl implements WorkerBinaryPacketHandler {
public void onMessage(String channel, ArrayBuffer buf) {
if(channel == null) {
System.err.println("Recieved IPC packet with null channel");
return;
}
if(buf == null) {
System.err.println("Recieved IPC packet with null buffer");
return;
}
synchronized(messageQueue) {
messageQueue.add(new PKT(channel, TeaVMUtils.wrapByteArrayBuffer(buf)));
}
}
}
private static void tryStopServer() {
if(currentProcess != null) {
try {
currentProcess.stopServer();
}catch(Throwable t) {
System.err.println("Failed to stop server!");
throwExceptionToClient("Failed to stop server!", t);
}
currentProcess = null;
}
}
public static void updateStatusString(String stat, float prog) {
sendIPCPacket(new IPCPacket0DProgressUpdate(stat, prog));
}
private static boolean isServerStopped() {
return currentProcess == null || !currentProcess.isServerRunning();
}
public static void throwExceptionToClient(String msg, Throwable t) {
String str = t.toString();
System.err.println("Exception was raised to client: " + str);
t.printStackTrace();
List<String> arr = new LinkedList<>();
for(StackTraceElement e : t.getStackTrace()) {
String st = e.toString();
arr.add(st);
}
sendIPCPacket(new IPCPacket15ThrowException(str, arr));
}
public static void sendTaskFailed() {
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacketFFProcessKeepAlive.FAILURE));
}
private static void processAsyncMessageQueue() {
ArrayList<PKT> cur;
synchronized(messageQueue) {
if(messageQueue.size() <= 0) {
return;
}
cur = new ArrayList<PKT>(messageQueue);
messageQueue.clear();
}
Iterator<PKT> itr = cur.iterator();
while(itr.hasNext()) {
PKT msg = itr.next();
if(msg.channel.equals("IPC")) {
IPCPacketBase packet;
try {
packet = IPCPacketManager.IPCDeserialize(msg.data);
}catch(IOException e) {
System.err.print("Failed to deserialize IPC packet: ");
e.printStackTrace();
continue;
}
int id = packet.id();
try {
switch(id) {
case IPCPacket00StartServer.ID: {
IPCPacket00StartServer pkt = (IPCPacket00StartServer)packet;
if(!isServerStopped()) {
currentProcess.stopServer();
}
currentProcess = new EAGMinecraftServer(pkt.worldName, pkt.ownerName, newWorldSettings);
currentProcess.setBaseServerProperties(pkt.initialDifficulty, newWorldSettings == null ? EnumGameType.SURVIVAL : newWorldSettings.getGameType());
currentProcess.startServer();
String[] worlds = SYS.VFS.getFile("worlds.txt").getAllLines();
if(worlds == null || (worlds.length == 1 && worlds[0].trim().length() <= 0)) {
worlds = null;
}
if(worlds == null) {
SYS.VFS.getFile("worlds.txt").setAllChars(pkt.worldName);
}else {
boolean found = false;
for(String s : worlds) {
if(s.equals(pkt.worldName)) {
found = true;
break;
}
}
if(!found) {
String[] s = new String[worlds.length + 1];
s[0] = pkt.worldName;
System.arraycopy(worlds, 0, s, 1, worlds.length);
SYS.VFS.getFile("worlds.txt").setAllChars(String.join("\n", s));
}
}
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket00StartServer.ID));
}
break;
case IPCPacket01StopServer.ID: {
if(!isServerStopped()) {
try {
currentProcess.stopServer();
currentProcess = null;
}catch(Throwable t) {
throwExceptionToClient("Failed to stop server!", t);
}
}else {
System.err.println("Client tried to stop server while it wasn't running for some reason");
}
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket01StopServer.ID));
}
break;
case IPCPacket02InitWorld.ID: {
tryStopServer();
IPCPacket02InitWorld pkt = (IPCPacket02InitWorld)packet;
newWorldSettings = new WorldSettings(pkt.seed, pkt.gamemode == 1 ? EnumGameType.CREATIVE : EnumGameType.SURVIVAL, pkt.structures,
pkt.gamemode == 2, pkt.worldType == 1 ? WorldType.FLAT : (pkt.worldType == 2 ? WorldType.LARGE_BIOMES : WorldType.DEFAULT_1_1));
newWorldSettings.func_82750_a(pkt.worldArgs);
if(pkt.bonusChest) {
newWorldSettings.enableBonusChest();
}
if(pkt.cheats) {
newWorldSettings.enableCommands();
}
}
break;
case IPCPacket03DeleteWorld.ID: {
tryStopServer();
IPCPacket03DeleteWorld pkt = (IPCPacket03DeleteWorld)packet;
if(SYS.VFS.deleteFiles("worlds/" + pkt.worldName + "/") <= 0) {
throwExceptionToClient("Failed to delete world!", new RuntimeException("VFS did not delete directory 'worlds/" + pkt.worldName + "' correctly"));
sendTaskFailed();
break;
}
String[] worldsTxt = SYS.VFS.getFile("worlds.txt").getAllLines();
if(worldsTxt != null) {
LinkedList<String> newWorlds = new LinkedList<>();
for(String str : worldsTxt) {
if(!str.equalsIgnoreCase(pkt.worldName)) {
newWorlds.add(str);
}
}
SYS.VFS.getFile("worlds.txt").setAllChars(String.join("\n", newWorlds));
}
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket03DeleteWorld.ID));
}
break;
case IPCPacket04RenameWorld.ID: {
tryStopServer();
IPCPacket04RenameWorld pkt = (IPCPacket04RenameWorld)packet;
if(SYS.VFS.renameFiles("worlds/" + pkt.worldOldName + "/", "worlds/" + pkt.worldNewName + "/", pkt.copy) <= 0) {
throwExceptionToClient("Failed to copy/rename server!", new RuntimeException("VFS did not copy/rename directory 'worlds/" + pkt.worldOldName + "' correctly"));
sendTaskFailed();
break;
}else {
String[] worldsTxt = SYS.VFS.getFile("worlds.txt").getAllLines();
LinkedList<String> newWorlds = new LinkedList<>();
if(worldsTxt != null) {
for(String str : worldsTxt) {
if(pkt.copy || !str.equalsIgnoreCase(pkt.worldOldName)) {
newWorlds.add(str);
}
}
}
newWorlds.add(pkt.worldNewName);
SYS.VFS.getFile("worlds.txt").setAllChars(String.join("\n", newWorlds));
VFile worldDat = new VFile("worlds", pkt.worldNewName, "level.dat");
if(worldDat.canRead()) {
NBTTagCompound worldDatNBT = CompressedStreamTools.decompress(worldDat.getAllBytes());
worldDatNBT.getCompoundTag("Data").setString("LevelName", pkt.displayName);
worldDat.setAllBytes(CompressedStreamTools.compress(worldDatNBT));
}else {
throwExceptionToClient("Failed to copy/rename world!", new RuntimeException("Failed to change level.dat world '" + pkt.worldNewName + "' display name to '" + pkt.displayName + "' because level.dat was missing"));
sendTaskFailed();
break;
}
}
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket04RenameWorld.ID));
}
break;
case IPCPacket05RequestData.ID: {
IPCPacket05RequestData pkt = (IPCPacket05RequestData)packet;
if(pkt.request == IPCPacket05RequestData.REQUEST_LEVEL_EAG) {
try {
sendIPCPacket(new IPCPacket09RequestResponse(WorldConverterEPK.exportWorld(pkt.worldName)));
} catch (Throwable t) {
String realWorldName = pkt.worldName;
int i = realWorldName.lastIndexOf(new String(new char[] { (char)253, (char)233, (char)233 }));
if(i != -1) {
realWorldName = realWorldName.substring(0, i);
}
throwExceptionToClient("Failed to export world '" + realWorldName+ "' as EPK", t);
sendTaskFailed();
}
}else if(pkt.request == IPCPacket05RequestData.REQUEST_LEVEL_MCA) {
try {
sendIPCPacket(new IPCPacket09RequestResponse(WorldConverterMCA.exportWorld(pkt.worldName)));
} catch (Throwable t) {
throwExceptionToClient("Failed to export world '" + pkt.worldName+ "' as MCA", t);
sendTaskFailed();
}
}
}
break;
case IPCPacket06RenameWorldNBT.ID: {
IPCPacket06RenameWorldNBT pkt = (IPCPacket06RenameWorldNBT)packet;
if(isServerStopped()) {
VFile worldDat = new VFile("worlds", pkt.worldName, "level.dat");
if(worldDat.canRead()) {
NBTTagCompound worldDatNBT = CompressedStreamTools.decompress(worldDat.getAllBytes());
worldDatNBT.getCompoundTag("Data").setString("LevelName", pkt.displayName);
worldDat.setAllBytes(CompressedStreamTools.compress(worldDatNBT));
}else {
throwExceptionToClient("Failed to rename world!", new RuntimeException("Failed to change level.dat world '" + pkt.worldName + "' display name to '" + pkt.displayName + "' because level.dat was missing"));
}
}else {
System.err.println("Client tried to rename a world '" + pkt.worldName + "' to have name '" + pkt.displayName + "' while the server is running");
sendTaskFailed();
}
}
break;
case IPCPacket07ImportWorld.ID: {
IPCPacket07ImportWorld pkt = (IPCPacket07ImportWorld)packet;
if(isServerStopped()) {
if(pkt.worldFormat == IPCPacket07ImportWorld.WORLD_FORMAT_EAG) {
try {
WorldConverterEPK.importWorld(pkt.worldData, pkt.worldName);
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket07ImportWorld.ID));
}catch(Throwable t) {
SYS.VFS.deleteFiles("worlds/" + VFSSaveHandler.worldNameToFolderName(pkt.worldName) + "/");
throwExceptionToClient("Failed to import world '" + pkt.worldName + "' as EPK", t);
sendTaskFailed();
}
}else if(pkt.worldFormat == IPCPacket07ImportWorld.WORLD_FORMAT_MCA) {
try {
WorldConverterMCA.importWorld(pkt.worldData, pkt.worldName);
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket07ImportWorld.ID));
}catch(Throwable t) {
SYS.VFS.deleteFiles("worlds/" + VFSSaveHandler.worldNameToFolderName(pkt.worldName) + "/");
throwExceptionToClient("Failed to import world '" + pkt.worldName + "' as MCA", t);
sendTaskFailed();
}
}else {
System.err.println("Client tried to import a world in an unknown format: 0x" + Integer.toHexString(pkt.worldFormat));
sendTaskFailed();
}
}else {
System.err.println("Client tried to import a world '" + pkt.worldName + "' while the server is running");
sendTaskFailed();
}
}
break;
case IPCPacket09RequestResponse.ID:
break;
case IPCPacket0ASetWorldDifficulty.ID: {
IPCPacket0ASetWorldDifficulty pkt = (IPCPacket0ASetWorldDifficulty)packet;
if(!isServerStopped()) {
currentProcess.setDifficultyForAllWorlds(pkt.difficulty);
}else {
System.err.println("Client tried to set difficulty '" + pkt.difficulty + "' while server was stopped");
sendTaskFailed();
}
}
break;
case IPCPacket0BPause.ID: {
IPCPacket0BPause pkt = (IPCPacket0BPause)packet;
if(!isServerStopped()) {
if(!pkt.pause && !currentProcess.getPaused()) {
currentProcess.saveAllWorlds(true);
}else {
currentProcess.setPaused(pkt.pause);
if(pkt.pause) {
currentProcess.saveAllWorlds(true);
}
}
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket0BPause.ID));
}else {
System.err.println("Client tried to " + (pkt.pause ? "pause" : "unpause") + " while server was stopped");
}
}
break;
case IPCPacket0CPlayerChannel.ID: {
IPCPacket0CPlayerChannel pkt = (IPCPacket0CPlayerChannel)packet;
if(!isServerStopped()) {
if(pkt.open) {
if(!currentProcess.getNetworkThread().openChannel(pkt.channel)) {
System.err.println("Client tried to open a duplicate channel '" + pkt.channel + "'");
}
}else {
if(!currentProcess.getNetworkThread().closeChannel(pkt.channel)) {
System.err.println("Client tried to close a null channel '" + pkt.channel + "'");
}
}
}else {
System.err.println("Client tried to " + (pkt.open ? "open" : "close") + " channel '" + pkt.channel + "' while server was stopped");
}
}
break;
case IPCPacket0EListWorlds.ID: {
if(isServerStopped()) {
String[] worlds = SYS.VFS.getFile("worlds.txt").getAllLines();
if(worlds == null || (worlds.length == 1 && worlds[0].trim().length() <= 0)) {
worlds = null;
}
if(worlds == null) {
sendIPCPacket(new IPCPacket16NBTList(IPCPacket16NBTList.WORLD_LIST, new LinkedList<NBTTagCompound>()));
break;
}
LinkedList<String> updatedList = new LinkedList<>();
LinkedList<NBTTagCompound> sendListNBT = new LinkedList<>();
boolean rewrite = false;
for(String w : worlds) {
byte[] dat = (new VFile("worlds", w, "level.dat")).getAllBytes();
if(dat != null) {
NBTTagCompound worldDatNBT;
try {
worldDatNBT = CompressedStreamTools.decompress(dat);
worldDatNBT.setString("folderName", w);
sendListNBT.add(worldDatNBT);
updatedList.add(w);
continue;
}catch(IOException e) {
// shit fuck
}
}
rewrite = true;
System.err.println("World level.dat for '" + w + "' was not found, attempting to delete 'worlds/" + w + "/*'");
if(SYS.VFS.deleteFiles("worlds/" + w) <= 0) {
System.err.println("No files were deleted in 'worlds/" + w + "/*', this may be corruption but '" + w + "' will still be removed from worlds.txt");
}
}
if(rewrite) {
SYS.VFS.getFile("worlds.txt").setAllChars(String.join("\n", updatedList));
}
sendIPCPacket(new IPCPacket16NBTList(IPCPacket16NBTList.WORLD_LIST, sendListNBT));
}else {
System.err.println("Client tried to list worlds while server was running");
sendTaskFailed();
}
}
break;
case IPCPacket0FListFiles.ID:
break;
case IPCPacket10FileRead.ID:
break;
case IPCPacket12FileWrite.ID:
break;
case IPCPacket13FileCopyMove.ID:
break;
case IPCPacket14StringList.ID: {
IPCPacket14StringList pkt = (IPCPacket14StringList)packet;
switch(pkt.opCode) {
case IPCPacket14StringList.LOCALE:
StringTranslate.init(pkt.stringList);
break;
case IPCPacket14StringList.STAT_GUID:
AchievementMap.init(pkt.stringList);
AchievementList.init();
break;
default:
System.err.println("Strange string list 0x" + Integer.toHexString(pkt.opCode) + " with length " + pkt.stringList.size() + " recieved");
break;
}
}
break;
case IPCPacket17ConfigureLAN.ID: {
IPCPacket17ConfigureLAN pkt = (IPCPacket17ConfigureLAN)packet;
//currentProcess.getConfigurationManager().configureLAN(pkt.gamemode, pkt.cheats, pkt.iceServers); // FIX THIS SHIT
}
break;
case IPCPacket18ClearPlayers.ID: {
SYS.VFS.deleteFiles("worlds/" + ((IPCPacket18ClearPlayers)packet).worldName + "/player");
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket18ClearPlayers.ID));
}
break;
default:
System.err.println("IPC packet type 0x" + Integer.toHexString(id) + " class '" + packet.getClass().getSimpleName() + "' was not handled");
sendTaskFailed();
break;
}
}catch(Throwable t) {
String str = "IPC packet 0x" + Integer.toHexString(id) + " class '" + packet.getClass().getSimpleName() + "' was not processed correctly";
System.err.println(str);
throwExceptionToClient(str, t);
sendTaskFailed();
}
continue;
}
}
long watchDog = SysUtil.steadyTimeMillis();
itr = cur.iterator();
int overflow = 0;
while(itr.hasNext()) {
PKT msg = itr.next();
if(!msg.channel.equals("IPC")) {
if(SysUtil.steadyTimeMillis() - watchDog > 500l) {
++overflow;
continue;
}
if(!msg.channel.startsWith("NET|") || currentProcess == null) {
//System.err.println("Unknown ICP channel: '" + msg.channel + "' passed " + msg.data.length + " bytes");
continue;
}
String u = msg.channel.substring(4);
currentProcess.getNetworkThread().recievePacket(u, msg.data);
}
}
if(overflow > 0) {
System.err.println("Async ICP queue is overloaded, server dropped " + overflow + " player packets");
}
}
@JSBody(params = { "ch", "dat" }, script = "postMessage({ ch: ch, dat : dat });")
private static native void sendWorkerPacket(String channel, ArrayBuffer arr);
public static void sendIPCPacket(IPCPacketBase pkt) {
byte[] serialized;
try {
serialized = IPCPacketManager.IPCSerialize(pkt);
} catch (IOException e) {
System.err.println("Could not serialize IPC packet 0x" + Integer.toHexString(pkt.id()) + " class '" + pkt.getClass().getSimpleName() + "'");
e.printStackTrace();
return;
}
sendWorkerPacket("IPC", TeaVMUtils.unwrapArrayBuffer(serialized));
}
public static void sendPlayerPacket(String channel, byte[] buf) {
//System.out.println("[Server][SEND][" + channel + "]: " + buf.length);
sendWorkerPacket("NET|" + channel, TeaVMUtils.unwrapArrayBuffer(buf));
}
private static boolean isRunning = false;
public static void halt() {
isRunning = false;
}
private static void mainLoop() {
processAsyncMessageQueue();
if(currentProcess != null) {
currentProcess.mainLoop();
if(currentProcess.isServerStopped()) {
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket01StopServer.ID));
currentProcess = null;
}
}else {
SysUtil.sleep(50);
}
}
@JSBody(params = { "wb" }, script = "onmessage = function(o) { wb(o.data.ch, o.data.dat); };")
private static native void registerPacketHandler(WorkerBinaryPacketHandler wb);
public static void startIntegratedServer() {
System.out.println("Starting integrated server (kinda)");
registerPacketHandler(new WorkerBinaryPacketHandlerImpl());
isRunning = true;
sendIPCPacket(new IPCPacketFFProcessKeepAlive(0xFF));
while(isRunning) {
mainLoop();
SysUtil.immediateContinue();
}
}
}

View File

@ -1,244 +0,0 @@
package net.lax1dude.eaglercraft.sp;
/**
* implementation of MD5 as outlined in "Handbook of Applied Cryptography",
* pages 346 - 347.
*/
public class MD5Digest extends GeneralDigest {
private static final int DIGEST_LENGTH = 16;
private int H1, H2, H3, H4; // IV's
private int[] X = new int[16];
private int xOff;
public String getAlgorithmName() {
return "MD5";
}
public int getDigestSize() {
return DIGEST_LENGTH;
}
protected void processWord(byte[] in, int inOff) {
X[xOff++] = littleEndianToInt(in, inOff);
if (xOff == 16) {
processBlock();
}
}
private int littleEndianToInt(byte[] bs, int off) {
int n = bs[off] & 0xff;
n |= (bs[++off] & 0xff) << 8;
n |= (bs[++off] & 0xff) << 16;
n |= bs[++off] << 24;
return n;
}
protected void processLength(long bitLength) {
if (xOff > 14) {
processBlock();
}
X[14] = (int) (bitLength & 0xffffffff);
X[15] = (int) (bitLength >>> 32);
}
public int doFinal(byte[] out, int outOff) {
finish();
intToLittleEndian(H1, out, outOff);
intToLittleEndian(H2, out, outOff + 4);
intToLittleEndian(H3, out, outOff + 8);
intToLittleEndian(H4, out, outOff + 12);
reset();
return DIGEST_LENGTH;
}
private void intToLittleEndian(int n, byte[] bs, int off) {
bs[off] = (byte) (n);
bs[++off] = (byte) (n >>> 8);
bs[++off] = (byte) (n >>> 16);
bs[++off] = (byte) (n >>> 24);
}
/**
* reset the chaining variables to the IV values.
*/
public void reset() {
super.reset();
H1 = 0x67452301;
H2 = 0xefcdab89;
H3 = 0x98badcfe;
H4 = 0x10325476;
xOff = 0;
for (int i = 0; i != X.length; i++) {
X[i] = 0;
}
}
//
// round 1 left rotates
//
private static final int S11 = 7;
private static final int S12 = 12;
private static final int S13 = 17;
private static final int S14 = 22;
//
// round 2 left rotates
//
private static final int S21 = 5;
private static final int S22 = 9;
private static final int S23 = 14;
private static final int S24 = 20;
//
// round 3 left rotates
//
private static final int S31 = 4;
private static final int S32 = 11;
private static final int S33 = 16;
private static final int S34 = 23;
//
// round 4 left rotates
//
private static final int S41 = 6;
private static final int S42 = 10;
private static final int S43 = 15;
private static final int S44 = 21;
/*
* rotate int x left n bits.
*/
private int rotateLeft(int x, int n) {
return (x << n) | (x >>> (32 - n));
}
/*
* F, G, H and I are the basic MD5 functions.
*/
private int F(int u, int v, int w) {
return (u & v) | (~u & w);
}
private int G(int u, int v, int w) {
return (u & w) | (v & ~w);
}
private int H(int u, int v, int w) {
return u ^ v ^ w;
}
private int K(int u, int v, int w) {
return v ^ (u | ~w);
}
protected void processBlock() {
int a = H1;
int b = H2;
int c = H3;
int d = H4;
//
// Round 1 - F cycle, 16 times.
//
a = rotateLeft(a + F(b, c, d) + X[0] + 0xd76aa478, S11) + b;
d = rotateLeft(d + F(a, b, c) + X[1] + 0xe8c7b756, S12) + a;
c = rotateLeft(c + F(d, a, b) + X[2] + 0x242070db, S13) + d;
b = rotateLeft(b + F(c, d, a) + X[3] + 0xc1bdceee, S14) + c;
a = rotateLeft(a + F(b, c, d) + X[4] + 0xf57c0faf, S11) + b;
d = rotateLeft(d + F(a, b, c) + X[5] + 0x4787c62a, S12) + a;
c = rotateLeft(c + F(d, a, b) + X[6] + 0xa8304613, S13) + d;
b = rotateLeft(b + F(c, d, a) + X[7] + 0xfd469501, S14) + c;
a = rotateLeft(a + F(b, c, d) + X[8] + 0x698098d8, S11) + b;
d = rotateLeft(d + F(a, b, c) + X[9] + 0x8b44f7af, S12) + a;
c = rotateLeft(c + F(d, a, b) + X[10] + 0xffff5bb1, S13) + d;
b = rotateLeft(b + F(c, d, a) + X[11] + 0x895cd7be, S14) + c;
a = rotateLeft(a + F(b, c, d) + X[12] + 0x6b901122, S11) + b;
d = rotateLeft(d + F(a, b, c) + X[13] + 0xfd987193, S12) + a;
c = rotateLeft(c + F(d, a, b) + X[14] + 0xa679438e, S13) + d;
b = rotateLeft(b + F(c, d, a) + X[15] + 0x49b40821, S14) + c;
//
// Round 2 - G cycle, 16 times.
//
a = rotateLeft(a + G(b, c, d) + X[1] + 0xf61e2562, S21) + b;
d = rotateLeft(d + G(a, b, c) + X[6] + 0xc040b340, S22) + a;
c = rotateLeft(c + G(d, a, b) + X[11] + 0x265e5a51, S23) + d;
b = rotateLeft(b + G(c, d, a) + X[0] + 0xe9b6c7aa, S24) + c;
a = rotateLeft(a + G(b, c, d) + X[5] + 0xd62f105d, S21) + b;
d = rotateLeft(d + G(a, b, c) + X[10] + 0x02441453, S22) + a;
c = rotateLeft(c + G(d, a, b) + X[15] + 0xd8a1e681, S23) + d;
b = rotateLeft(b + G(c, d, a) + X[4] + 0xe7d3fbc8, S24) + c;
a = rotateLeft(a + G(b, c, d) + X[9] + 0x21e1cde6, S21) + b;
d = rotateLeft(d + G(a, b, c) + X[14] + 0xc33707d6, S22) + a;
c = rotateLeft(c + G(d, a, b) + X[3] + 0xf4d50d87, S23) + d;
b = rotateLeft(b + G(c, d, a) + X[8] + 0x455a14ed, S24) + c;
a = rotateLeft(a + G(b, c, d) + X[13] + 0xa9e3e905, S21) + b;
d = rotateLeft(d + G(a, b, c) + X[2] + 0xfcefa3f8, S22) + a;
c = rotateLeft(c + G(d, a, b) + X[7] + 0x676f02d9, S23) + d;
b = rotateLeft(b + G(c, d, a) + X[12] + 0x8d2a4c8a, S24) + c;
//
// Round 3 - H cycle, 16 times.
//
a = rotateLeft(a + H(b, c, d) + X[5] + 0xfffa3942, S31) + b;
d = rotateLeft(d + H(a, b, c) + X[8] + 0x8771f681, S32) + a;
c = rotateLeft(c + H(d, a, b) + X[11] + 0x6d9d6122, S33) + d;
b = rotateLeft(b + H(c, d, a) + X[14] + 0xfde5380c, S34) + c;
a = rotateLeft(a + H(b, c, d) + X[1] + 0xa4beea44, S31) + b;
d = rotateLeft(d + H(a, b, c) + X[4] + 0x4bdecfa9, S32) + a;
c = rotateLeft(c + H(d, a, b) + X[7] + 0xf6bb4b60, S33) + d;
b = rotateLeft(b + H(c, d, a) + X[10] + 0xbebfbc70, S34) + c;
a = rotateLeft(a + H(b, c, d) + X[13] + 0x289b7ec6, S31) + b;
d = rotateLeft(d + H(a, b, c) + X[0] + 0xeaa127fa, S32) + a;
c = rotateLeft(c + H(d, a, b) + X[3] + 0xd4ef3085, S33) + d;
b = rotateLeft(b + H(c, d, a) + X[6] + 0x04881d05, S34) + c;
a = rotateLeft(a + H(b, c, d) + X[9] + 0xd9d4d039, S31) + b;
d = rotateLeft(d + H(a, b, c) + X[12] + 0xe6db99e5, S32) + a;
c = rotateLeft(c + H(d, a, b) + X[15] + 0x1fa27cf8, S33) + d;
b = rotateLeft(b + H(c, d, a) + X[2] + 0xc4ac5665, S34) + c;
//
// Round 4 - K cycle, 16 times.
//
a = rotateLeft(a + K(b, c, d) + X[0] + 0xf4292244, S41) + b;
d = rotateLeft(d + K(a, b, c) + X[7] + 0x432aff97, S42) + a;
c = rotateLeft(c + K(d, a, b) + X[14] + 0xab9423a7, S43) + d;
b = rotateLeft(b + K(c, d, a) + X[5] + 0xfc93a039, S44) + c;
a = rotateLeft(a + K(b, c, d) + X[12] + 0x655b59c3, S41) + b;
d = rotateLeft(d + K(a, b, c) + X[3] + 0x8f0ccc92, S42) + a;
c = rotateLeft(c + K(d, a, b) + X[10] + 0xffeff47d, S43) + d;
b = rotateLeft(b + K(c, d, a) + X[1] + 0x85845dd1, S44) + c;
a = rotateLeft(a + K(b, c, d) + X[8] + 0x6fa87e4f, S41) + b;
d = rotateLeft(d + K(a, b, c) + X[15] + 0xfe2ce6e0, S42) + a;
c = rotateLeft(c + K(d, a, b) + X[6] + 0xa3014314, S43) + d;
b = rotateLeft(b + K(c, d, a) + X[13] + 0x4e0811a1, S44) + c;
a = rotateLeft(a + K(b, c, d) + X[4] + 0xf7537e82, S41) + b;
d = rotateLeft(d + K(a, b, c) + X[11] + 0xbd3af235, S42) + a;
c = rotateLeft(c + K(d, a, b) + X[2] + 0x2ad7d2bb, S43) + d;
b = rotateLeft(b + K(c, d, a) + X[9] + 0xeb86d391, S44) + c;
H1 += a;
H2 += b;
H3 += c;
H4 += d;
//
// reset the offset and clean out the word buffer.
//
xOff = 0;
for (int i = 0; i != X.length; i++) {
X[i] = 0;
}
}
}

View File

@ -1,36 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSClass;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
import org.teavm.jso.workers.MessagePort;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
@JSClass
public class MessageChannel implements JSObject {
@JSBody(params = { }, script = "return (typeof MessageChannel !== \"undefined\");")
public static native boolean supported();
@JSProperty
public native MessagePort getPort1();
@JSProperty
public native MessagePort getPort2();
}

View File

@ -1,412 +0,0 @@
package net.lax1dude.eaglercraft.sp;
public class NoCatchParse {
public static final int INT_EXCEPTION = Integer.MIN_VALUE;
public static final float FLOAT_EXCEPTION = Float.NaN;
public static final double DOUBLE_EXCEPTION = Double.NaN;
public static int parseInt(String s) {
return parseInt(s, 10, false, INT_EXCEPTION);
}
public static int parseInt(String s, int radix) {
return parseInt(s, radix, false, INT_EXCEPTION);
}
public static int parseInt(String s, int radix, boolean log) {
return parseInt(s, radix, log, INT_EXCEPTION);
}
public static int parseInt(String s, int radix, boolean log, int exceptionResult) {
if (s == null) {
if (log) {
System.err.println("parseInt: string was null");
}
return exceptionResult;
}
if (s.isEmpty()) {
if (log) {
System.err.println("parseInt: string was empty");
}
return exceptionResult;
}
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
if (log) {
System.err.println("parseInt: invalid radix '" + radix + "'");
}
return exceptionResult;
}
tryFail: {
int result = 0;
boolean negative = false;
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE;
int multmin;
int digit;
if (len > 0) {
char firstChar = s.charAt(0);
if (firstChar < '0') { // Possible leading "+" or "-"
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;
} else if (firstChar != '+')
break tryFail;
if (len == 1)
break tryFail;
i++;
}
multmin = limit / radix;
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(s.charAt(i++), radix);
if (digit < 0 || result < multmin) {
break tryFail;
}
result *= radix;
if (result < limit + digit) {
break tryFail;
}
result -= digit;
}
} else {
break tryFail;
}
int ret = negative ? result : -result;
if (ret == exceptionResult) {
System.err.println(
"parseInt: number '" + s + "' was parsed successfully but it is equal to exceptionResult");
}
return ret;
}
if (log) {
System.err.println("parseInt: cannot parse '" + s + "'");
}
return exceptionResult;
}
public static double parseDouble(String s) {
return parseDouble(s, false, DOUBLE_EXCEPTION);
}
public static double parseDouble(String s, boolean log) {
return parseDouble(s, log, DOUBLE_EXCEPTION);
}
public static double parseDouble(String s, boolean log, double exceptionResult) {
if (s == null) {
if (log) {
System.err.println("parseDouble: string was null");
}
return exceptionResult;
}
if (s.isEmpty()) {
if (log) {
System.err.println("parseDouble: string was empty");
}
return exceptionResult;
}
tryFail: {
int start = 0;
int end = s.length();
while (s.charAt(start) <= ' ') {
if (++start == end) {
break tryFail;
}
}
while (s.charAt(end - 1) <= ' ') {
--end;
}
boolean negative = false;
int index = start;
if (s.charAt(index) == '-') {
++index;
negative = true;
} else if (s.charAt(index) == '+') {
++index;
}
if (index == end) {
break tryFail;
}
char c = s.charAt(index);
long mantissa = 0;
int exp = 0;
boolean hasOneDigit = false;
if (c != '.') {
hasOneDigit = true;
if (c < '0' || c > '9') {
break tryFail;
}
while (index < end && s.charAt(index) == '0') {
++index;
}
while (index < end) {
c = s.charAt(index);
if (c < '0' || c > '9') {
break;
}
if (mantissa < Long.MAX_VALUE / 10 - 9) {
mantissa = mantissa * 10 + (c - '0');
} else {
++exp;
}
++index;
}
}
if (index < end && s.charAt(index) == '.') {
++index;
while (index < end) {
c = s.charAt(index);
if (c < '0' || c > '9') {
break;
}
if (mantissa < Long.MAX_VALUE / 10 - 9) {
mantissa = mantissa * 10 + (c - '0');
--exp;
}
++index;
hasOneDigit = true;
}
if (!hasOneDigit) {
break tryFail;
}
}
if (index < end) {
c = s.charAt(index);
if (c != 'e' && c != 'E') {
break tryFail;
}
++index;
boolean negativeExp = false;
if (index == end) {
break tryFail;
}
if (s.charAt(index) == '-') {
++index;
negativeExp = true;
} else if (s.charAt(index) == '+') {
++index;
}
int numExp = 0;
hasOneDigit = false;
while (index < end) {
c = s.charAt(index);
if (c < '0' || c > '9') {
break;
}
numExp = 10 * numExp + (c - '0');
hasOneDigit = true;
++index;
}
if (!hasOneDigit) {
break tryFail;
}
if (negativeExp) {
numExp = -numExp;
}
exp += numExp;
}
if (exp > 308 || exp == 308 && mantissa > 17976931348623157L) {
return !negative ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
}
if (negative) {
mantissa = -mantissa;
}
return mantissa * doubleDecimalExponent(exp);
}
if (log) {
System.err.println("parseDouble: cannot parse '" + s + "'");
}
return exceptionResult;
}
public static double doubleDecimalExponent(int n) {
double d;
if (n < 0) {
d = 0.1;
n = -n;
} else {
d = 10;
}
double result = 1;
while (n != 0) {
if (n % 2 != 0) {
result *= d;
}
d *= d;
n /= 2;
}
return result;
}
public static float parseFloat(String s) {
return parseFloat(s, false, FLOAT_EXCEPTION);
}
public static float parseFloat(String s, boolean log) {
return parseFloat(s, log, FLOAT_EXCEPTION);
}
public static float parseFloat(String s, boolean log, float exceptionResult) {
if (s == null) {
if (log) {
System.err.println("parseFloat: string was null");
}
return exceptionResult;
}
if (s.isEmpty()) {
if (log) {
System.err.println("parseFloat: string was empty");
}
return exceptionResult;
}
tryFail: {
int start = 0;
int end = s.length();
while (s.charAt(start) <= ' ') {
if (++start == end) {
break tryFail;
}
}
while (s.charAt(end - 1) <= ' ') {
--end;
}
boolean negative = false;
int index = start;
if (s.charAt(index) == '-') {
++index;
negative = true;
} else if (s.charAt(index) == '+') {
++index;
}
if (index == end) {
break tryFail;
}
char c = s.charAt(index);
int mantissa = 0;
int exp = 0;
boolean hasOneDigit = false;
if (c != '.') {
hasOneDigit = true;
if (c < '0' || c > '9') {
break tryFail;
}
while (index < end && s.charAt(index) == '0') {
++index;
}
while (index < end) {
c = s.charAt(index);
if (c < '0' || c > '9') {
break;
}
if (mantissa < (Integer.MAX_VALUE / 10) - 9) {
mantissa = mantissa * 10 + (c - '0');
} else {
++exp;
}
++index;
}
}
if (index < end && s.charAt(index) == '.') {
++index;
while (index < end) {
c = s.charAt(index);
if (c < '0' || c > '9') {
break;
}
if (mantissa < (Integer.MAX_VALUE / 10) - 9) {
mantissa = mantissa * 10 + (c - '0');
--exp;
}
++index;
hasOneDigit = true;
}
if (!hasOneDigit) {
break tryFail;
}
}
if (index < end) {
c = s.charAt(index);
if (c != 'e' && c != 'E') {
break tryFail;
}
++index;
boolean negativeExp = false;
if (index == end) {
break tryFail;
}
if (s.charAt(index) == '-') {
++index;
negativeExp = true;
} else if (s.charAt(index) == '+') {
++index;
}
int numExp = 0;
hasOneDigit = false;
while (index < end) {
c = s.charAt(index);
if (c < '0' || c > '9') {
break;
}
numExp = 10 * numExp + (c - '0');
hasOneDigit = true;
++index;
}
if (!hasOneDigit) {
break tryFail;
}
if (negativeExp) {
numExp = -numExp;
}
exp += numExp;
}
if (exp > 38 || exp == 38 && mantissa > 34028234) {
return !negative ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
}
if (negative) {
mantissa = -mantissa;
}
return mantissa * floatDecimalExponent(exp);
}
if (log) {
System.err.println("parseFloat: cannot parse '" + s + "'");
}
return exceptionResult;
}
private static float floatDecimalExponent(int n) {
double d;
if (n < 0) {
d = 0.1;
n = -n;
} else {
d = 10;
}
double result = 1;
while (n != 0) {
if (n % 2 != 0) {
result *= d;
}
d *= d;
n /= 2;
}
return (float) result;
}
}

View File

@ -1,310 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.EOFException;
import java.io.IOException;
/**
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class RandomAccessMemoryFile implements DataInput, DataOutput {
private byte[] buffer;
private int length;
private int pos;
public RandomAccessMemoryFile(byte[] initialBuffer, int initialLength) {
this.buffer = initialBuffer;
this.length = initialLength;
this.pos = 0;
}
private void grow(int newMaxSize) {
if (length < newMaxSize) {
if (buffer.length < newMaxSize) {
byte[] newBuffer = new byte[newMaxSize | 0x7FFFF];
System.arraycopy(buffer, 0, newBuffer, 0, length);
buffer = newBuffer;
}
length = newMaxSize;
}
}
public byte[] getByteArray() {
byte[] b = new byte[length];
System.arraycopy(buffer, 0, b, 0, length);
return b;
}
public int read() throws IOException {
return (pos < length) ? (buffer[pos++] & 0xff) : -1;
}
private int readBytes(byte b[], int off, int len) throws IOException {
if (pos >= length) {
return -1;
}
int avail = length - pos;
if (len > avail) {
len = avail;
}
if (len <= 0) {
return 0;
}
System.arraycopy(buffer, pos, b, off, len);
pos += len;
return len;
}
public int read(byte b[], int off, int len) throws IOException {
return readBytes(b, off, len);
}
public int read(byte b[]) throws IOException {
return readBytes(b, 0, b.length);
}
public final void readFully(byte b[]) throws IOException {
readFully(b, 0, b.length);
}
public final void readFully(byte b[], int off, int len) throws IOException {
int n = 0;
do {
int count = this.read(b, off + n, len - n);
if (count < 0)
throw new EOFException();
n += count;
} while (n < len);
}
public int skipBytes(int n) throws IOException {
int newpos;
if (n <= 0) {
return 0;
}
newpos = pos + n;
if (newpos > length) {
newpos = length;
}
seek(newpos);
return (int) (newpos - pos);
}
public void write(int b) throws IOException {
grow(pos + 1);
buffer[pos] = (byte) b;
pos += 1;
}
private void writeBytes(byte b[], int off, int len) throws IOException {
grow(pos + len);
System.arraycopy(b, off, buffer, pos, len);
pos += len;
}
public void write(byte b[]) throws IOException {
writeBytes(b, 0, b.length);
}
public void write(byte b[], int off, int len) throws IOException {
writeBytes(b, off, len);
}
public void seek(int pos) {
this.pos = pos;
}
public int getLength() {
return length;
}
public void setLength(int newLength) {
grow(newLength);
}
public final boolean readBoolean() throws IOException {
int ch = this.read();
if (ch < 0)
throw new EOFException();
return (ch != 0);
}
public final byte readByte() throws IOException {
int ch = this.read();
if (ch < 0)
throw new EOFException();
return (byte) (ch);
}
public final int readUnsignedByte() throws IOException {
int ch = this.read();
if (ch < 0)
throw new EOFException();
return ch;
}
public final short readShort() throws IOException {
int ch1 = this.read();
int ch2 = this.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (short) ((ch1 << 8) + (ch2 << 0));
}
public final int readUnsignedShort() throws IOException {
int ch1 = this.read();
int ch2 = this.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (ch1 << 8) + (ch2 << 0);
}
public final char readChar() throws IOException {
int ch1 = this.read();
int ch2 = this.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (char) ((ch1 << 8) + (ch2 << 0));
}
public final int readInt() throws IOException {
int ch1 = this.read();
int ch2 = this.read();
int ch3 = this.read();
int ch4 = this.read();
if ((ch1 | ch2 | ch3 | ch4) < 0)
throw new EOFException();
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}
public final long readLong() throws IOException {
return ((long) (readInt()) << 32) + (readInt() & 0xFFFFFFFFL);
}
public final float readFloat() throws IOException {
return Float.intBitsToFloat(readInt());
}
public final double readDouble() throws IOException {
return Double.longBitsToDouble(readLong());
}
public final String readLine() throws IOException {
StringBuilder input = new StringBuilder();
int c = -1;
boolean eol = false;
while (!eol) {
switch (c = read()) {
case -1:
case '\n':
eol = true;
break;
case '\r':
eol = true;
int cur = pos;
if ((read()) != '\n') {
seek(cur);
}
break;
default:
input.append((char) c);
break;
}
}
if ((c == -1) && (input.length() == 0)) {
return null;
}
return input.toString();
}
public final String readUTF() throws IOException {
throw new IOException("TODO");
}
public final void writeBoolean(boolean v) throws IOException {
write(v ? 1 : 0);
}
public final void writeByte(int v) throws IOException {
write(v);
}
public final void writeShort(int v) throws IOException {
write((v >>> 8) & 0xFF);
write((v >>> 0) & 0xFF);
}
public final void writeChar(int v) throws IOException {
write((v >>> 8) & 0xFF);
write((v >>> 0) & 0xFF);
}
public final void writeInt(int v) throws IOException {
write((v >>> 24) & 0xFF);
write((v >>> 16) & 0xFF);
write((v >>> 8) & 0xFF);
write((v >>> 0) & 0xFF);
}
public final void writeLong(long v) throws IOException {
write((int) (v >>> 56) & 0xFF);
write((int) (v >>> 48) & 0xFF);
write((int) (v >>> 40) & 0xFF);
write((int) (v >>> 32) & 0xFF);
write((int) (v >>> 24) & 0xFF);
write((int) (v >>> 16) & 0xFF);
write((int) (v >>> 8) & 0xFF);
write((int) (v >>> 0) & 0xFF);
}
public final void writeFloat(float v) throws IOException {
writeInt(Float.floatToIntBits(v));
}
public final void writeDouble(double v) throws IOException {
writeLong(Double.doubleToLongBits(v));
}
public final void writeBytes(String s) throws IOException {
int len = s.length();
byte[] b = new byte[len];
s.getBytes(0, len, b, 0);
writeBytes(b, 0, len);
}
public final void writeChars(String s) throws IOException {
int clen = s.length();
int blen = 2 * clen;
byte[] b = new byte[blen];
char[] c = new char[clen];
s.getChars(0, clen, c, 0);
for (int i = 0, j = 0; i < clen; i++) {
b[j++] = (byte) (c[i] >>> 8);
b[j++] = (byte) (c[i] >>> 0);
}
writeBytes(b, 0, blen);
}
public final void writeUTF(String str) throws IOException {
throw new IOException("TODO");
}
}

View File

@ -1,213 +0,0 @@
package net.lax1dude.eaglercraft.sp;
/**
* implementation of SHA-1 as outlined in "Handbook of Applied Cryptography",
* pages 346 - 349.
*
* It is interesting to ponder why the, apart from the extra IV, the other
* difference here from MD5 is the "endienness" of the word processing!
*/
public class SHA1Digest extends GeneralDigest {
private static final int DIGEST_LENGTH = 20;
private int H1, H2, H3, H4, H5;
private int[] X = new int[80];
private int xOff;
/**
* Standard constructor
*/
public SHA1Digest() {
reset();
}
/**
* Copy constructor. This will copy the state of the provided message digest.
*/
public SHA1Digest(SHA1Digest t) {
super(t);
H1 = t.H1;
H2 = t.H2;
H3 = t.H3;
H4 = t.H4;
H5 = t.H5;
System.arraycopy(t.X, 0, X, 0, t.X.length);
xOff = t.xOff;
}
public String getAlgorithmName() {
return "SHA-1";
}
public int getDigestSize() {
return DIGEST_LENGTH;
}
protected void processWord(byte[] in, int inOff) {
X[xOff++] = ((in[inOff] & 0xff) << 24) | ((in[inOff + 1] & 0xff) << 16) | ((in[inOff + 2] & 0xff) << 8)
| ((in[inOff + 3] & 0xff));
if (xOff == 16) {
processBlock();
}
}
private void unpackWord(int word, byte[] out, int outOff) {
out[outOff] = (byte) (word >>> 24);
out[outOff + 1] = (byte) (word >>> 16);
out[outOff + 2] = (byte) (word >>> 8);
out[outOff + 3] = (byte) word;
}
protected void processLength(long bitLength) {
if (xOff > 14) {
processBlock();
}
X[14] = (int) (bitLength >>> 32);
X[15] = (int) (bitLength & 0xffffffff);
}
public int doFinal(byte[] out, int outOff) {
finish();
unpackWord(H1, out, outOff);
unpackWord(H2, out, outOff + 4);
unpackWord(H3, out, outOff + 8);
unpackWord(H4, out, outOff + 12);
unpackWord(H5, out, outOff + 16);
reset();
return DIGEST_LENGTH;
}
/**
* reset the chaining variables
*/
public void reset() {
super.reset();
H1 = 0x67452301;
H2 = 0xefcdab89;
H3 = 0x98badcfe;
H4 = 0x10325476;
H5 = 0xc3d2e1f0;
xOff = 0;
for (int i = 0; i != X.length; i++) {
X[i] = 0;
}
}
//
// Additive constants
//
private static final int Y1 = 0x5a827999;
private static final int Y2 = 0x6ed9eba1;
private static final int Y3 = 0x8f1bbcdc;
private static final int Y4 = 0xca62c1d6;
private int f(int u, int v, int w) {
return ((u & v) | ((~u) & w));
}
private int h(int u, int v, int w) {
return (u ^ v ^ w);
}
private int g(int u, int v, int w) {
return ((u & v) | (u & w) | (v & w));
}
private int rotateLeft(int x, int n) {
return (x << n) | (x >>> (32 - n));
}
protected void processBlock() {
//
// expand 16 word block into 80 word block.
//
for (int i = 16; i <= 79; i++) {
X[i] = rotateLeft((X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]), 1);
}
//
// set up working variables.
//
int A = H1;
int B = H2;
int C = H3;
int D = H4;
int E = H5;
//
// round 1
//
for (int j = 0; j <= 19; j++) {
int t = rotateLeft(A, 5) + f(B, C, D) + E + X[j] + Y1;
E = D;
D = C;
C = rotateLeft(B, 30);
B = A;
A = t;
}
//
// round 2
//
for (int j = 20; j <= 39; j++) {
int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y2;
E = D;
D = C;
C = rotateLeft(B, 30);
B = A;
A = t;
}
//
// round 3
//
for (int j = 40; j <= 59; j++) {
int t = rotateLeft(A, 5) + g(B, C, D) + E + X[j] + Y3;
E = D;
D = C;
C = rotateLeft(B, 30);
B = A;
A = t;
}
//
// round 4
//
for (int j = 60; j <= 79; j++) {
int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y4;
E = D;
D = C;
C = rotateLeft(B, 30);
B = A;
A = t;
}
H1 += A;
H2 += B;
H3 += C;
H4 += D;
H5 += E;
//
// reset the offset and clean out the word buffer.
//
xOff = 0;
for (int i = 0; i != X.length; i++) {
X[i] = 0;
}
}
}

View File

@ -1,28 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import org.teavm.jso.JSBody;
import net.lax1dude.eaglercraft.sp.VirtualFilesystem.VFSHandle;
public class SYS {
public static final VirtualFilesystem VFS;
@JSBody(params = { }, script = "return eaglercraftServerOpts.worldDatabaseName;")
private static native String getWorldDatabaseName();
static {
VFSHandle vh = VirtualFilesystem.openVFS("_net_lax1dude_eaglercraft_sp_VirtualFilesystem_1_5_2_" + getWorldDatabaseName());
if(vh.vfs == null) {
System.err.println("Could not init filesystem!");
IntegratedServer.throwExceptionToClient("Could not init filesystem!", new RuntimeException("VFSHandle.vfs was null"));
}
VFS = vh.vfs;
}
}

View File

@ -1,108 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import net.minecraft.src.EntityPlayerMP;
import net.minecraft.src.Packet250CustomPayload;
public class SkinsPlugin {
private static final HashMap<String,byte[]> skinCollection = new HashMap<>();
private static final HashMap<String,byte[]> capeCollection = new HashMap<>();
private static final HashMap<String,Long> lastSkinLayerUpdate = new HashMap<>();
private static final int[] SKIN_DATA_SIZE = new int[] { 64*32*4, 64*64*4, -9, -9, 1, 64*64*4, -9 }; // 128 pixel skins crash clients
private static final int[] CAPE_DATA_SIZE = new int[] { 32*32*4, -9, 1 };
public static boolean handleMessage(EntityPlayerMP player, Packet250CustomPayload payload) {
if(payload.data.length > 0) {
String user = player.username;
byte[] msg = payload.data;
try {
if("EAG|MySkin".equals(payload.channel)) {
if(!skinCollection.containsKey(user)) {
int t = (int)msg[0] & 0xFF;
if(t < SKIN_DATA_SIZE.length && msg.length == (SKIN_DATA_SIZE[t] + 1)) {
skinCollection.put(user, msg);
}
}
return true;
}
if("EAG|MyCape".equals(payload.channel)) {
if(!capeCollection.containsKey(user)) {
int t = (int)msg[0] & 0xFF;
if(t < CAPE_DATA_SIZE.length && msg.length == (CAPE_DATA_SIZE[t] + 2)) {
capeCollection.put(user, msg);
}
}
return true;
}
if("EAG|FetchSkin".equals(payload.channel)) {
if(msg.length > 2) {
String fetch = new String(msg, 2, msg.length - 2, StandardCharsets.UTF_8);
byte[] data;
if((data = skinCollection.get(fetch)) != null) {
byte[] conc = new byte[data.length + 2];
conc[0] = msg[0]; conc[1] = msg[1]; //synchronization cookie
System.arraycopy(data, 0, conc, 2, data.length);
if((data = capeCollection.get(fetch)) != null) {
byte[] conc2 = new byte[conc.length + data.length];
System.arraycopy(conc, 0, conc2, 0, conc.length);
System.arraycopy(data, 0, conc2, conc.length, data.length);
conc = conc2;
}
player.playerNetServerHandler.sendPacketToPlayer(new Packet250CustomPayload("EAG|UserSkin", conc));
}
}
return true;
}
if("EAG|SkinLayers".equals(payload.channel)) {
long millis = SysUtil.steadyTimeMillis();
Long lsu = lastSkinLayerUpdate.get(user);
if(lsu != null && millis - lsu < 700L) { // DoS protection
return true;
}
lastSkinLayerUpdate.put(user, millis);
byte[] data;
if((data = capeCollection.get(user)) != null) {
data[1] = msg[0];
}else {
data = new byte[] { (byte)2, msg[0], (byte)0 };
capeCollection.put(user, data);
}
ByteArrayOutputStream bao = new ByteArrayOutputStream();
DataOutputStream dd = new DataOutputStream(bao);
dd.write(msg[0]);
dd.writeUTF(user);
byte[] bpacket = bao.toByteArray();
for(Object o : player.mcServer.getConfigurationManager().playerEntityList) {
EntityPlayerMP pl = (EntityPlayerMP) o;
if(!pl.username.equals(user)) {
pl.playerNetServerHandler.sendPacketToPlayer(new Packet250CustomPayload("EAG|SkinLayers", bpacket));
}
}
return true;
}
}catch(Throwable t) {
// hacker
}
}
return false;
}
public static void handleDisconnect(EntityPlayerMP player) {
skinCollection.remove(player.username);
capeCollection.remove(player.username);
lastSkinLayerUpdate.remove(player.username);
}
public static void reset() {
skinCollection.clear();
capeCollection.clear();
lastSkinLayerUpdate.clear();
}
}

View File

@ -1,152 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import org.teavm.interop.Async;
import org.teavm.interop.AsyncCallback;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.browser.Window;
import org.teavm.jso.core.JSString;
import org.teavm.jso.dom.events.EventListener;
import org.teavm.jso.dom.events.MessageEvent;
import org.teavm.platform.Platform;
import org.teavm.platform.PlatformRunnable;
public class SysUtil {
private static final JSObject steadyTimeFunc = getSteadyTimeFunc();
@JSBody(params = { }, script = "return ((typeof performance !== \"undefined\") && (typeof performance.now === \"function\"))"
+ "? performance.now.bind(performance)"
+ ": (function(epochStart){ return function() { return Date.now() - epochStart; }; })(Date.now());")
private static native JSObject getSteadyTimeFunc();
@JSBody(params = { "steadyTimeFunc" }, script = "return steadyTimeFunc();")
private static native double steadyTimeMillis0(JSObject steadyTimeFunc);
public static long steadyTimeMillis() {
return (long)steadyTimeMillis0(steadyTimeFunc);
}
public static long nanoTime() {
return (long)(steadyTimeMillis0(steadyTimeFunc) * 1000000.0);
}
@Async
public static native void sleep(int millis);
private static void sleep(int millis, final AsyncCallback<Void> callback) {
Platform.schedule(new DumbSleepHandler(callback), millis);
}
private static class DumbSleepHandler implements PlatformRunnable {
private final AsyncCallback<Void> callback;
private DumbSleepHandler(AsyncCallback<Void> callback) {
this.callback = callback;
}
@Override
public void run() {
callback.complete(null);
}
}
private static boolean hasCheckedImmediateContinue = false;
private static MessageChannel immediateContinueChannel = null;
private static Runnable currentContinueHack = null;
private static final JSString emptyJSString = JSString.valueOf("");
public static void immediateContinue() {
if(!hasCheckedImmediateContinue) {
hasCheckedImmediateContinue = true;
checkImmediateContinueSupport();
}
if(immediateContinueChannel != null) {
immediateContinueTeaVM();
}else {
sleep(0);
}
}
@Async
private static native void immediateContinueTeaVM();
private static void immediateContinueTeaVM(final AsyncCallback<Void> cb) {
if(currentContinueHack != null) {
cb.error(new IllegalStateException("Worker thread is already waiting for an immediate continue callback!"));
return;
}
currentContinueHack = () -> {
cb.complete(null);
};
try {
immediateContinueChannel.getPort2().postMessage(emptyJSString);
}catch(Throwable t) {
System.err.println("Caught error posting immediate continue, using setTimeout instead");
Window.setTimeout(() -> cb.complete(null), 0);
}
}
private static void checkImmediateContinueSupport() {
try {
immediateContinueChannel = null;
if(!MessageChannel.supported()) {
System.err.println("Fast immediate continue will be disabled for server context due to MessageChannel being unsupported");
return;
}
immediateContinueChannel = new MessageChannel();
immediateContinueChannel.getPort1().addEventListener("message", new EventListener<MessageEvent>() {
@Override
public void handleEvent(MessageEvent evt) {
Runnable toRun = currentContinueHack;
currentContinueHack = null;
if(toRun != null) {
toRun.run();
}
}
});
immediateContinueChannel.getPort1().start();
immediateContinueChannel.getPort2().start();
final boolean[] checkMe = new boolean[1];
checkMe[0] = false;
currentContinueHack = () -> {
checkMe[0] = true;
};
immediateContinueChannel.getPort2().postMessage(emptyJSString);
if(checkMe[0]) {
currentContinueHack = null;
if(immediateContinueChannel != null) {
safeShutdownChannel(immediateContinueChannel);
}
immediateContinueChannel = null;
System.err.println("Fast immediate continue will be disabled for server context due to actually continuing immediately");
return;
}
sleep(10);
currentContinueHack = null;
if(!checkMe[0]) {
if(immediateContinueChannel != null) {
safeShutdownChannel(immediateContinueChannel);
}
immediateContinueChannel = null;
System.err.println("Fast immediate continue will be disabled for server context due to startup check failing");
}
}catch(Throwable t) {
System.err.println("Fast immediate continue will be disabled for server context due to exceptions");
if(immediateContinueChannel != null) {
safeShutdownChannel(immediateContinueChannel);
}
immediateContinueChannel = null;
}
}
private static void safeShutdownChannel(MessageChannel chan) {
try {
chan.getPort1().close();
}catch(Throwable tt) {
}
try {
chan.getPort2().close();
}catch(Throwable tt) {
}
}
}

View File

@ -1,93 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import org.teavm.backend.javascript.spi.GeneratedBy;
import org.teavm.backend.javascript.spi.InjectedBy;
import org.teavm.jso.typedarrays.ArrayBuffer;
import org.teavm.jso.typedarrays.ArrayBufferView;
import org.teavm.jso.typedarrays.Float32Array;
import org.teavm.jso.typedarrays.Int16Array;
import org.teavm.jso.typedarrays.Int32Array;
import org.teavm.jso.typedarrays.Int8Array;
import org.teavm.jso.typedarrays.Uint8Array;
public class TeaVMUtils {
@InjectedBy(TeaVMUtilsUnwrapGenerator.UnwrapTypedArray.class)
public static native Int8Array unwrapByteArray(byte[] buf);
@InjectedBy(TeaVMUtilsUnwrapGenerator.UnwrapArrayBuffer.class)
public static native ArrayBuffer unwrapArrayBuffer(byte[] buf);
@InjectedBy(TeaVMUtilsUnwrapGenerator.UnwrapTypedArray.class)
public static native ArrayBufferView unwrapArrayBufferView(byte[] buf);
@GeneratedBy(TeaVMUtilsUnwrapGenerator.WrapTypedArray.class)
public static native byte[] wrapByteArray(Int8Array buf);
@GeneratedBy(TeaVMUtilsUnwrapGenerator.WrapArrayBuffer.class)
public static native byte[] wrapByteArrayBuffer(ArrayBuffer buf);
@GeneratedBy(TeaVMUtilsUnwrapGenerator.WrapArrayBufferView.class)
public static native byte[] wrapByteArrayBufferView(ArrayBufferView buf);
@InjectedBy(TeaVMUtilsUnwrapGenerator.UnwrapUnsignedTypedArray.class)
public static native Uint8Array unwrapUnsignedByteArray(byte[] buf);
@GeneratedBy(TeaVMUtilsUnwrapGenerator.WrapArrayBufferView.class)
public static native byte[] wrapUnsignedByteArray(Uint8Array buf);
@InjectedBy(TeaVMUtilsUnwrapGenerator.UnwrapTypedArray.class)
public static native Int32Array unwrapIntArray(int[] buf);
@InjectedBy(TeaVMUtilsUnwrapGenerator.UnwrapArrayBuffer.class)
public static native ArrayBuffer unwrapArrayBuffer(int[] buf);
@InjectedBy(TeaVMUtilsUnwrapGenerator.UnwrapTypedArray.class)
public static native ArrayBufferView unwrapArrayBufferView(int[] buf);
@GeneratedBy(TeaVMUtilsUnwrapGenerator.WrapTypedArray.class)
public static native int[] wrapIntArray(Int32Array buf);
@GeneratedBy(TeaVMUtilsUnwrapGenerator.WrapArrayBuffer.class)
public static native int[] wrapIntArrayBuffer(ArrayBuffer buf);
@GeneratedBy(TeaVMUtilsUnwrapGenerator.WrapArrayBufferView.class)
public static native int[] wrapIntArrayBufferView(ArrayBufferView buf);
@InjectedBy(TeaVMUtilsUnwrapGenerator.UnwrapTypedArray.class)
public static native Float32Array unwrapFloatArray(float[] buf);
@InjectedBy(TeaVMUtilsUnwrapGenerator.UnwrapArrayBuffer.class)
public static native ArrayBuffer unwrapArrayBuffer(float[] buf);
@InjectedBy(TeaVMUtilsUnwrapGenerator.UnwrapTypedArray.class)
public static native ArrayBufferView unwrapArrayBufferView(float[] buf);
@GeneratedBy(TeaVMUtilsUnwrapGenerator.WrapTypedArray.class)
public static native float[] wrapFloatArray(Float32Array buf);
@GeneratedBy(TeaVMUtilsUnwrapGenerator.WrapArrayBuffer.class)
public static native float[] wrapFloatArrayBuffer(ArrayBuffer buf);
@GeneratedBy(TeaVMUtilsUnwrapGenerator.WrapArrayBufferView.class)
public static native float[] wrapFloatArrayBufferView(ArrayBufferView buf);
@InjectedBy(TeaVMUtilsUnwrapGenerator.UnwrapTypedArray.class)
public static native Int16Array unwrapShortArray(short[] buf);
@InjectedBy(TeaVMUtilsUnwrapGenerator.UnwrapArrayBuffer.class)
public static native ArrayBuffer unwrapArrayBuffer(short[] buf);
@InjectedBy(TeaVMUtilsUnwrapGenerator.UnwrapTypedArray.class)
public static native ArrayBufferView unwrapArrayBufferView(short[] buf);
@GeneratedBy(TeaVMUtilsUnwrapGenerator.WrapTypedArray.class)
public static native short[] wrapShortArray(Int16Array buf);
@GeneratedBy(TeaVMUtilsUnwrapGenerator.WrapArrayBuffer.class)
public static native short[] wrapShortArrayBuffer(ArrayBuffer buf);
@GeneratedBy(TeaVMUtilsUnwrapGenerator.WrapArrayBufferView.class)
public static native short[] wrapShortArrayBuffer(ArrayBufferView buf);
}

View File

@ -1,158 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import org.teavm.backend.javascript.codegen.SourceWriter;
import org.teavm.backend.javascript.spi.Generator;
import org.teavm.backend.javascript.spi.GeneratorContext;
import org.teavm.backend.javascript.spi.Injector;
import org.teavm.backend.javascript.spi.InjectorContext;
import org.teavm.model.MethodReference;
public class TeaVMUtilsUnwrapGenerator {
// WARNING: This code uses internal TeaVM APIs that may not have
// been intended for end users of the compiler to program with
public static class UnwrapArrayBuffer implements Injector {
@Override
public void generate(InjectorContext context, MethodReference methodRef) {
context.writeExpr(context.getArgument(0));
context.getWriter().append(".data.buffer");
}
}
public static class UnwrapTypedArray implements Injector {
@Override
public void generate(InjectorContext context, MethodReference methodRef) {
context.writeExpr(context.getArgument(0));
context.getWriter().append(".data");
}
}
public static class WrapArrayBuffer implements Generator {
@Override
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) {
String parName = context.getParameterName(1);
switch (methodRef.getName()) {
case "wrapByteArrayBuffer":
writer.append("return ").append(parName).ws().append('?').ws();
writer.appendFunction("$rt_wrapArray").append('(').appendFunction("$rt_bytecls").append(',').ws();
writer.append("new Int8Array(").append(parName).append("))").ws();
writer.append(':').ws().append("null;").softNewLine();
break;
case "wrapIntArrayBuffer":
writer.append("return ").append(parName).ws().append('?').ws();
writer.appendFunction("$rt_wrapArray").append('(').appendFunction("$rt_intcls").append(',').ws();
writer.append("new Int32Array(").append(parName).append("))").ws();
writer.append(':').ws().append("null;").softNewLine();
break;
case "wrapFloatArrayBuffer":
writer.append("return ").append(parName).ws().append('?').ws();
writer.appendFunction("$rt_wrapArray").append('(').appendFunction("$rt_floatcls").append(',').ws();
writer.append("new Float32Array(").append(parName).append("))").ws();
writer.append(':').ws().append("null;").softNewLine();
break;
case "wrapShortArrayBuffer":
writer.append("return ").append(parName).ws().append('?').ws();
writer.appendFunction("$rt_wrapArray").append('(').appendFunction("$rt_shortcls").append(',').ws();
writer.append("new Int16Array(").append(parName).append("))").ws();
writer.append(':').ws().append("null;").softNewLine();
break;
default:
break;
}
}
}
public static class WrapArrayBufferView implements Generator {
@Override
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) {
String parName = context.getParameterName(1);
switch (methodRef.getName()) {
case "wrapByteArrayBufferView":
case "wrapUnsignedByteArray":
writer.append("return ").append(parName).ws().append('?').ws();
writer.appendFunction("$rt_wrapArray").append('(').appendFunction("$rt_bytecls").append(',').ws();
writer.append("new Int8Array(").append(parName).append(".buffer))").ws();
writer.append(':').ws().append("null;").softNewLine();
break;
case "wrapIntArrayBufferView":
writer.append("return ").append(parName).ws().append('?').ws();
writer.appendFunction("$rt_wrapArray").append('(').appendFunction("$rt_intcls").append(',').ws();
writer.append("new Int32Array(").append(parName).append(".buffer))").ws();
writer.append(':').ws().append("null;").softNewLine();
break;
case "wrapFloatArrayBufferView":
writer.append("return ").append(parName).ws().append('?').ws();
writer.appendFunction("$rt_wrapArray").append('(').appendFunction("$rt_floatcls").append(',').ws();
writer.append("new Float32Array(").append(parName).append(".buffer))").ws();
writer.append(':').ws().append("null;").softNewLine();
break;
case "wrapShortArrayBufferView":
writer.append("return ").append(parName).ws().append('?').ws();
writer.appendFunction("$rt_wrapArray").append('(').appendFunction("$rt_shortcls").append(',').ws();
writer.append("new Int16Array(").append(parName).append(".buffer))").ws();
writer.append(':').ws().append("null;").softNewLine();
break;
default:
break;
}
}
}
public static class WrapTypedArray implements Generator {
@Override
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) {
String parName = context.getParameterName(1);
switch (methodRef.getName()) {
case "wrapByteArray":
writer.append("return ").append(parName).ws().append('?').ws();
writer.appendFunction("$rt_wrapArray").append('(').appendFunction("$rt_shortcls").append(',').ws();
writer.append(parName).append(")").ws();
writer.append(':').ws().append("null;").softNewLine();
break;
case "wrapIntArray":
writer.append("return ").append(parName).ws().append('?').ws();
writer.appendFunction("$rt_wrapArray").append('(').appendFunction("$rt_intcls").append(',').ws();
writer.append(parName).append(")").ws();
writer.append(':').ws().append("null;").softNewLine();
break;
case "wrapFloatArray":
writer.append("return ").append(parName).ws().append('?').ws();
writer.appendFunction("$rt_wrapArray").append('(').appendFunction("$rt_floatcls").append(',').ws();
writer.append(parName).append(")").ws();
writer.append(':').ws().append("null;").softNewLine();
break;
case "wrapShortArray":
writer.append("return ").append(parName).ws().append('?').ws();
writer.appendFunction("$rt_wrapArray").append('(').appendFunction("$rt_shortcls").append(',').ws();
writer.append(parName).append(")").ws();
writer.append(':').ws().append("null;").softNewLine();
break;
default:
break;
}
}
}
public static class UnwrapUnsignedTypedArray implements Injector {
@Override
public void generate(InjectorContext context, MethodReference methodRef) {
context.getWriter().append("new Uint8Array(");
context.writeExpr(context.getArgument(0));
context.getWriter().append(".data.buffer)");
}
}
}

View File

@ -1,307 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import net.minecraft.src.Chunk;
import net.minecraft.src.ChunkCoordIntPair;
import net.minecraft.src.CompressedStreamTools;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityList;
import net.minecraft.src.ExtendedBlockStorage;
import net.minecraft.src.IChunkLoader;
import net.minecraft.src.MinecraftException;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.NBTTagList;
import net.minecraft.src.NextTickListEntry;
import net.minecraft.src.NibbleArray;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
public class VFSChunkLoader implements IChunkLoader {
public final VFile chunkDirectory;
private static final String hex = "0123456789ABCDEF";
public static String getChunkPath(int x, int z) {
int unsignedX = x + 1900000;
int unsignedZ = z + 1900000;
char[] path = new char[12];
for(int i = 5; i >= 0; --i) {
path[i] = hex.charAt((unsignedX >> (i * 4)) & 0xF);
path[i + 6] = hex.charAt((unsignedZ >> (i * 4)) & 0xF);
}
return new String(path);
}
public static ChunkCoordIntPair getChunkCoords(String filename) {
String strX = filename.substring(0, 6);
String strZ = filename.substring(6);
int retX = 0;
int retZ = 0;
for(int i = 0; i < 6; ++i) {
retX |= hex.indexOf(strX.charAt(i)) << (i << 2);
retZ |= hex.indexOf(strZ.charAt(i)) << (i << 2);
}
return new ChunkCoordIntPair(retX - 1900000, retZ - 1900000);
}
public VFSChunkLoader(VFile chunkDirectory) {
this.chunkDirectory = chunkDirectory;
}
@Override
public Chunk loadChunk(World var1, int var2, int var3) throws IOException {
VFile file = new VFile(chunkDirectory, getChunkPath(var2, var3) + ".dat");
byte[] bytes = file.getAllBytes();
if(bytes == null) {
return null;
}
try {
NBTTagCompound nbt = CompressedStreamTools.decompress(bytes);
nbt = nbt.getCompoundTag("Level");
return readChunkFromNBT(var1, nbt, var2, var3);
}catch(Throwable t) {
file.delete();
System.err.println("Corrupted chunk has been deleted: [" + var2 + ", " + var3 + "]");
t.printStackTrace();
return null;
}
}
@Override
public void saveChunk(World var1, Chunk var2) throws MinecraftException, IOException {
NBTTagCompound chunkFile = new NBTTagCompound();
this.writeChunkToNBT(var2, var1, chunkFile);
byte[] save;
try {
NBTTagCompound chunkFileSave = new NBTTagCompound();
chunkFileSave.setCompoundTag("Level", chunkFile);
save = CompressedStreamTools.compress(chunkFileSave);
}catch(IOException e) {
System.err.println("Corrupted chunk could not be serialized: [" + var2.xPosition + ", " + var2.zPosition + "]");
return;
}
VFile file = new VFile(chunkDirectory, getChunkPath(var2.xPosition, var2.zPosition) + ".dat");
if(!file.setAllBytes(save)) {
System.err.println("Corrupted chunk could not be written: [" + var2.xPosition + ", " + var2.zPosition + "] to file \"" + file.toString() + "\")");
}
}
@Override
public void saveExtraChunkData(World var1, Chunk var2) {
// ?
}
@Override
public void chunkTick() {
// TODO Auto-generated method stub
}
@Override
public void saveExtraData() {
// unused
}
private Chunk readChunkFromNBT(World par1World, NBTTagCompound par2NBTTagCompound, int x, int z) {
int var3 = x; //par2NBTTagCompound.getInteger("xPos");
int var4 = z; //par2NBTTagCompound.getInteger("zPos");
Chunk var5 = new Chunk(par1World, var3, var4);
var5.heightMap = par2NBTTagCompound.getIntArray("HeightMap");
var5.isTerrainPopulated = par2NBTTagCompound.getBoolean("TerrainPopulated");
NBTTagList var6 = par2NBTTagCompound.getTagList("Sections");
byte var7 = 16;
ExtendedBlockStorage[] var8 = new ExtendedBlockStorage[var7];
boolean var9 = !par1World.provider.hasNoSky;
for (int var10 = 0; var10 < var6.tagCount(); ++var10) {
NBTTagCompound var11 = (NBTTagCompound) var6.tagAt(var10);
byte var12 = var11.getByte("Y");
ExtendedBlockStorage var13 = new ExtendedBlockStorage(var12 << 4, var9);
var13.setBlockLSBArray(var11.getByteArray("Blocks"));
if (var11.hasKey("Add")) {
var13.setBlockMSBArray(new NibbleArray(var11.getByteArray("Add"), 4));
}
var13.setBlockMetadataArray(new NibbleArray(var11.getByteArray("Data"), 4));
var13.setBlocklightArray(new NibbleArray(var11.getByteArray("BlockLight"), 4));
if (var9) {
var13.setSkylightArray(new NibbleArray(var11.getByteArray("SkyLight"), 4));
}
var13.removeInvalidBlocks();
var8[var12] = var13;
}
var5.setStorageArrays(var8);
if (par2NBTTagCompound.hasKey("Biomes")) {
var5.setBiomeArray(par2NBTTagCompound.getByteArray("Biomes"));
}
NBTTagList var17 = par2NBTTagCompound.getTagList("Entities");
if (var17 != null) {
for (int var18 = 0; var18 < var17.tagCount(); ++var18) {
NBTTagCompound var20 = (NBTTagCompound) var17.tagAt(var18);
Entity var22 = EntityList.createEntityFromNBT(var20, par1World);
var5.hasEntities = true;
if (var22 != null) {
var5.addEntity(var22);
Entity var14 = var22;
for (NBTTagCompound var15 = var20; var15.hasKey("Riding"); var15 = var15.getCompoundTag("Riding")) {
Entity var16 = EntityList.createEntityFromNBT(var15.getCompoundTag("Riding"), par1World);
if (var16 != null) {
var5.addEntity(var16);
var14.mountEntity(var16);
}
var14 = var16;
}
}
}
}
NBTTagList var19 = par2NBTTagCompound.getTagList("TileEntities");
if (var19 != null) {
for (int var21 = 0; var21 < var19.tagCount(); ++var21) {
NBTTagCompound var24 = (NBTTagCompound) var19.tagAt(var21);
TileEntity var26 = TileEntity.createAndLoadEntity(var24);
if (var26 != null) {
var5.addTileEntity(var26);
}
}
}
if (par2NBTTagCompound.hasKey("TileTicks")) {
NBTTagList var23 = par2NBTTagCompound.getTagList("TileTicks");
if (var23 != null) {
for (int var25 = 0; var25 < var23.tagCount(); ++var25) {
NBTTagCompound var27 = (NBTTagCompound) var23.tagAt(var25);
par1World.scheduleBlockUpdateFromLoad(var27.getInteger("x"), var27.getInteger("y"),
var27.getInteger("z"), var27.getInteger("i"), var27.getInteger("t"), var27.getInteger("p"));
}
}
}
return var5;
}
private void writeChunkToNBT(Chunk par1Chunk, World par2World, NBTTagCompound par3NBTTagCompound) {
par3NBTTagCompound.setInteger("xPos", par1Chunk.xPosition);
par3NBTTagCompound.setInteger("zPos", par1Chunk.zPosition);
par3NBTTagCompound.setLong("LastUpdate", par2World.getTotalWorldTime());
par3NBTTagCompound.setIntArray("HeightMap", par1Chunk.heightMap);
par3NBTTagCompound.setBoolean("TerrainPopulated", par1Chunk.isTerrainPopulated);
ExtendedBlockStorage[] var4 = par1Chunk.getBlockStorageArray();
NBTTagList var5 = new NBTTagList("Sections");
boolean var6 = !par2World.provider.hasNoSky;
ExtendedBlockStorage[] var7 = var4;
int var8 = var4.length;
NBTTagCompound var11;
for (int var9 = 0; var9 < var8; ++var9) {
ExtendedBlockStorage var10 = var7[var9];
if (var10 != null) {
var11 = new NBTTagCompound();
var11.setByte("Y", (byte) (var10.getYLocation() >> 4 & 255));
var11.setByteArray("Blocks", var10.getBlockLSBArray());
if (var10.getBlockMSBArray() != null) {
var11.setByteArray("Add", var10.getBlockMSBArray().data);
}
var11.setByteArray("Data", var10.getMetadataArray().data);
var11.setByteArray("BlockLight", var10.getBlocklightArray().data);
if (var6) {
var11.setByteArray("SkyLight", var10.getSkylightArray().data);
} else {
var11.setByteArray("SkyLight", new byte[var10.getBlocklightArray().data.length]);
}
var5.appendTag(var11);
}
}
par3NBTTagCompound.setTag("Sections", var5);
par3NBTTagCompound.setByteArray("Biomes", par1Chunk.getBiomeArray());
par1Chunk.hasEntities = false;
NBTTagList var16 = new NBTTagList();
Iterator var18;
for (var8 = 0; var8 < par1Chunk.entityLists.length; ++var8) {
var18 = par1Chunk.entityLists[var8].iterator();
while (var18.hasNext()) {
Entity var20 = (Entity) var18.next();
var11 = new NBTTagCompound();
if (var20.writeToNBTOptional(var11)) {
par1Chunk.hasEntities = true;
var16.appendTag(var11);
}
}
}
par3NBTTagCompound.setTag("Entities", var16);
NBTTagList var17 = new NBTTagList();
var18 = par1Chunk.chunkTileEntityMap.values().iterator();
while (var18.hasNext()) {
TileEntity var21 = (TileEntity) var18.next();
var11 = new NBTTagCompound();
var21.writeToNBT(var11);
var17.appendTag(var11);
}
par3NBTTagCompound.setTag("TileEntities", var17);
List var19 = par2World.getPendingBlockUpdates(par1Chunk, false);
if (var19 != null) {
long var22 = par2World.getTotalWorldTime();
NBTTagList var12 = new NBTTagList();
Iterator var13 = var19.iterator();
while (var13.hasNext()) {
NextTickListEntry var14 = (NextTickListEntry) var13.next();
NBTTagCompound var15 = new NBTTagCompound();
var15.setInteger("i", var14.blockID);
var15.setInteger("x", var14.xCoord);
var15.setInteger("y", var14.yCoord);
var15.setInteger("z", var14.zCoord);
var15.setInteger("t", (int) (var14.scheduledTime - var22));
var15.setInteger("p", var14.priority);
var12.appendTag(var15);
}
par3NBTTagCompound.setTag("TileTicks", var12);
}
}
}

View File

@ -1,17 +0,0 @@
package net.lax1dude.eaglercraft.sp;
public interface VFSIterator {
public static class BreakLoop extends RuntimeException {
public BreakLoop() {
super("iterator loop break request");
}
}
public default void end() {
throw new BreakLoop();
}
public void next(VIteratorFile entry);
}

View File

@ -1,39 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import net.minecraft.src.IProgressUpdate;
import net.minecraft.src.ISaveFormat;
import net.minecraft.src.ISaveHandler;
public class VFSSaveFormat implements ISaveFormat {
private VFSSaveHandler folder;
public VFSSaveFormat(VFSSaveHandler dir) {
folder = dir;
}
@Override
public ISaveHandler getSaveLoader(String var1, boolean var2) {
return folder;
}
@Override
public void flushCache() {
}
@Override
public boolean deleteWorldDirectory(String var1) {
return true;
}
@Override
public boolean isOldMapFormat(String var1) {
return false;
}
@Override
public boolean convertMapFormat(String var1, IProgressUpdate var2) {
return false;
}
}

View File

@ -1,172 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.io.IOException;
import java.util.HashMap;
import net.minecraft.src.CompressedStreamTools;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.IChunkLoader;
import net.minecraft.src.IPlayerFileData;
import net.minecraft.src.ISaveHandler;
import net.minecraft.src.MinecraftException;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.WorldInfo;
import net.minecraft.src.WorldProvider;
public class VFSSaveHandler implements ISaveHandler, IPlayerFileData {
public final VFile worldDirectory;
private final HashMap<Integer, VFSChunkLoader> chunkLoaders = new HashMap<>();
public VFSSaveHandler(VFile worldDirectory) {
this.worldDirectory = worldDirectory;
}
@Override
public WorldInfo loadWorldInfo() {
byte[] level_dat_bin = (new VFile(worldDirectory, "level.dat")).getAllBytes();
if(level_dat_bin == null) {
return null;
}
try {
NBTTagCompound level_dat = CompressedStreamTools.decompress(level_dat_bin);
return new WorldInfo(level_dat.getCompoundTag("Data"));
}catch(Throwable t) {
System.err.println("Could not parse level.dat!");
t.printStackTrace();
}
return null;
}
@Override
public void checkSessionLock() throws MinecraftException {
// no
}
@Override
public IChunkLoader getChunkLoader(WorldProvider var1) {
VFSChunkLoader loader = chunkLoaders.get(var1.dimensionId);
if(loader == null) {
loader = new VFSChunkLoader(new VFile(worldDirectory, "level" + var1.dimensionId));
chunkLoaders.put(var1.dimensionId, loader);
}
return loader;
}
@Override
public void saveWorldInfoWithPlayer(WorldInfo var1, NBTTagCompound var2) {
NBTTagCompound var3 = var2 != null ? var1.cloneNBTCompound(var2) : var1.getNBTTagCompound();
NBTTagCompound var4 = new NBTTagCompound();
var4.setTag("Data", var3);
VFile level_dat = new VFile(worldDirectory, "level.dat");
byte[] compressed;
try {
compressed = CompressedStreamTools.compress(var4);
}catch(IOException e) {
System.err.println("Could not serialize \"" + level_dat + "\"");
e.printStackTrace();
return;
}
if(!level_dat.setAllBytes(compressed)) {
System.err.println("Could not save \"" + level_dat + "\" to filesystem");
}
}
@Override
public void saveWorldInfo(WorldInfo var1) {
saveWorldInfoWithPlayer(var1, null);
}
@Override
public IPlayerFileData getSaveHandler() {
return this;
}
@Override
public void flush() {
}
@Override
public VFile getMapFileFromName(String var1) {
return new VFile(worldDirectory, "data", var1 + ".dat");
}
@Override
public String getWorldDirectoryName() {
return worldDirectory.toString();
}
@Override
public void writePlayerData(EntityPlayer var1) {
NBTTagCompound var2 = new NBTTagCompound();
var1.writeToNBT(var2);
byte[] bin;
try {
bin = CompressedStreamTools.compress(var2);
}catch(Throwable t) {
System.err.println("Could not serialize player data for \"" + var1.username + "\"");
t.printStackTrace();
return;
}
VFile playerData = new VFile(worldDirectory, "player", var1.username.toLowerCase() + ".dat");
if(!playerData.setAllBytes(bin)) {
System.err.println("Could not write player data for \"" + var1.username + "\" to file \"" + playerData.toString() + "\"");
}
}
@Override
public NBTTagCompound readPlayerData(EntityPlayer var1) {
VFile playerData = new VFile(worldDirectory, "player", var1.username.toLowerCase() + ".dat");
NBTTagCompound ret = null;
byte[] playerBin = playerData.getAllBytes();
if(playerBin != null) {
try {
ret = CompressedStreamTools.decompress(playerBin);
var1.readFromNBT(ret);
}catch(IOException e) {
System.err.println("Could not deserialize player data for \"" + var1.username + "\"");
e.printStackTrace();
}
}
return ret;
}
@Override
public String[] getAvailablePlayerDat() {
return null;
}
public static String worldNameToFolderName(String par1Str) {
par1Str = par1Str.replaceAll("[\\./\"]", "_");
boolean shit = true;
while(shit) {
shit = (new VFile("worlds", par1Str, "level.dat")).exists();
if(shit) {
par1Str = par1Str + "_";
}
}
return par1Str;
}
}

View File

@ -1,117 +0,0 @@
package net.lax1dude.eaglercraft.sp;
public class VFSTestClass {
public static void test(VirtualFilesystem vfs) {
/*
System.out.println("'test1' exists: " + vfs.getFile("test1").exists());
System.out.println("'test1' chars: " + vfs.getFile("test1").getAllChars());
System.out.println("'test2' chars: " + vfs.getFile("test2").getAllChars());
System.out.println("'test3' chars: " + vfs.getFile("test3").getAllChars());
System.out.println("'test2' exists: " + vfs.getFile("test2").exists());
System.out.println("'test3' exists: " + vfs.getFile("test3").exists());
System.out.println("'test1' set chars 'test string 1': " + vfs.getFile("test1").setAllChars("test string 1"));
System.out.println("'test2' set chars 'test string 2': " + vfs.getFile("test2").setAllChars("test string 2"));
System.out.println("'test3' set chars 'test string 3': " + vfs.getFile("test3").setAllChars("test string 3"));
System.out.println("'test1' exists: " + vfs.getFile("test1").exists());
System.out.println("'test2' exists: " + vfs.getFile("test2").exists());
System.out.println("'test3' exists: " + vfs.getFile("test3").exists());
System.out.println("'test1' chars: " + vfs.getFile("test1").getAllChars());
System.out.println("'test2' chars: " + vfs.getFile("test2").getAllChars());
System.out.println("'test3' chars: " + vfs.getFile("test3").getAllChars());
System.out.println("'test3' delete: " + vfs.getFile("test3").delete());
System.out.println("'test3' exists: " + vfs.getFile("test3").exists());
System.out.println("'test2' delete: " + vfs.getFile("test2").delete());
System.out.println("'test2' chars: " + vfs.getFile("test2").getAllChars());
System.out.println("'test4' exists: " + vfs.getFile("test4").exists());
System.out.println("'test1' to 'test4' rename: " + vfs.getFile("test1").rename("test4"));
System.out.println("'test4' exists: " + vfs.getFile("test4").exists());
System.out.println("'test4' chars: " + vfs.getFile("test4").getAllChars());
System.out.println("'test1' exists: " + vfs.getFile("test1").exists());
System.out.println("'test4' to 'test1' rename: " + vfs.getFile("test4").rename("test1"));
System.out.println("'test4' exists: " + vfs.getFile("test4").exists());
System.out.println("'test4' chars: " + vfs.getFile("test4").getAllChars());
System.out.println("'test1' exists: " + vfs.getFile("test1").exists());
System.out.println("'test1' chars: " + vfs.getFile("test1").getAllChars());
System.out.println("'test1' cache get chars: " + vfs.getFile("test1", true).getAllChars());
System.out.println("'test1' cache exists: " + vfs.getFile("test1", true).exists());
System.out.println("'test1' cache delete: " + vfs.getFile("test1", true).delete());
System.out.println("'test1' cache exists: " + vfs.getFile("test1", true).exists());
System.out.println("'test1' cache get chars: " + vfs.getFile("test1", true).getAllChars());
System.out.println("'test1' cache set chars 'test cache string 1': " + vfs.getFile("test1", true).setAllChars("test cache string 1"));
System.out.println("'test2' cache set chars 'test cache string 2': " + vfs.getFile("test2", true).setAllChars("test cache string 2"));
System.out.println("'test3' cache set chars 'test cache string 3': " + vfs.getFile("test3", true).setAllChars("test cache string 3"));
System.out.println("'test1' cache chars: " + vfs.getFile("test1").getAllChars());
System.out.println("'test2' cache chars: " + vfs.getFile("test2").getAllChars());
System.out.println("'test3' cache chars: " + vfs.getFile("test3").getAllChars());
System.out.println("'test1' cache copy chars: " + VirtualFilesystem.utf8(vfs.getFile("test1").getAllBytes(true)));
System.out.println("'test2' cache copy chars: " + VirtualFilesystem.utf8(vfs.getFile("test2").getAllBytes(true)));
System.out.println("'test3' cache copy chars: " + VirtualFilesystem.utf8(vfs.getFile("test3").getAllBytes(true)));
*/
VFile f = new VFile("test1");
System.out.println(f);
f = new VFile("/test1");
System.out.println(f);
f = new VFile("/test2/");
System.out.println(f);
f = new VFile("test2/");
System.out.println(f);
f = new VFile("test2/teste");
System.out.println(f);
f = new VFile("\\test2\\teste");
System.out.println(f);
f = new VFile("\\test2\\teste\\..\\eag");
System.out.println(f);
f = new VFile("test2", "teste", "eag");
System.out.println(f);
f = new VFile(f, "../", "test2", "teste", "eag");
System.out.println(f);
f = new VFile(f, "../../", "test2", ".", "eag");
System.out.println(f);
f = new VFile("you/eag", f);
System.out.println(f);
f = new VFile(" you/ eag ", f);
System.out.println(f);
f = new VFile("\\yee\\", f);
System.out.println(f);
f = new VFile("\\yee\\", "yeeler", f, new VFile("yee"));
System.out.println(f);
f = new VFile(f, new VFile("yee2"));
System.out.println(f);
f = new VFile("yee/deevler/", new VFile("yee2"));
System.out.println(f);
f = new VFile("yee/../../../../", new VFile("yee2"));
System.out.println(f);
f = new VFile("yee/../../deevler../../", new VFile("yee2"));
System.out.println(f);
}
}

View File

@ -1,227 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class VFile {
public static final String pathSeperator = "/";
public static final String[] altPathSeperator = new String[] { "\\" };
public static String normalizePath(String p) {
for(int i = 0; i < altPathSeperator.length; ++i) {
p = p.replace(altPathSeperator[i], pathSeperator);
}
if(p.startsWith(pathSeperator)) {
p = p.substring(1);
}
if(p.endsWith(pathSeperator)) {
p = p.substring(0, p.length() - pathSeperator.length());
}
return p;
}
public static String[] splitPath(String p) {
String[] pth = normalizePath(p).split(pathSeperator);
for(int i = 0; i < pth.length; ++i) {
pth[i] = pth[i].trim();
}
return pth;
}
protected String path;
public static String createPath(Object... p) {
ArrayList<String> r = new ArrayList<>();
for(int i = 0; i < p.length; ++i) {
if(p[i] == null) {
continue;
}
String gg = p[i].toString();
if(gg == null) {
continue;
}
String[] parts = splitPath(gg);
for(int j = 0; j < parts.length; ++j) {
if(parts[j] == null || parts[j].equals(".")) {
continue;
}else if(parts[j].equals("..") && r.size() > 0) {
int k = r.size() - 1;
if(!r.get(k).equals("..")) {
r.remove(k);
}else {
r.add("..");
}
}else {
r.add(parts[j]);
}
}
}
if(r.size() > 0) {
StringBuilder s = new StringBuilder();
for(int i = 0; i < r.size(); ++i) {
if(i > 0) {
s.append(pathSeperator);
}
s.append(r.get(i));
}
return s.toString();
}else {
return null;
}
}
public VFile(Object... p) {
this.path = createPath(p);
}
public InputStream getInputStream() {
return isRelative() ? null : SYS.VFS.getFile(path).getInputStream();
}
public OutputStream getOutputStream() {
return isRelative() ? null : SYS.VFS.getFile(path).getOutputStream();
}
public String toString() {
return path;
}
public boolean isRelative() {
return path == null || path.contains("..");
}
public boolean canRead() {
return !isRelative() && SYS.VFS.fileExists(path);
}
public String getPath() {
return path.equals("unnamed") ? null : path;
}
public String getName() {
if(path == null) {
return null;
}
int i = path.lastIndexOf(pathSeperator);
return i == -1 ? path : path.substring(i + 1);
}
public boolean canWrite() {
return !isRelative();
}
public String getParent() {
if(path == null) {
return null;
}
int i = path.indexOf(pathSeperator);
return i == -1 ? ".." : path.substring(0, i);
}
public int hashCode() {
return path == null ? 0 : path.hashCode();
}
public boolean equals(Object o) {
return path != null && o != null && (o instanceof VFile) && path.equals(((VFile)o).path);
}
public boolean exists() {
return !isRelative() && SYS.VFS.fileExists(path);
}
public boolean delete() {
return !isRelative() && SYS.VFS.deleteFile(path);
}
public boolean renameTo(String p, boolean copy) {
if(!isRelative() && SYS.VFS.renameFile(path, p, copy)) {
path = p;
return true;
}
return false;
}
public int length() {
return isRelative() ? -1 : SYS.VFS.getFile(path).getSize();
}
public void getBytes(int fileOffset, byte[] array, int offset, int length) {
if(isRelative()) {
throw new ArrayIndexOutOfBoundsException("File is relative");
}
SYS.VFS.getFile(path).getBytes(fileOffset, array, offset, length);
}
public void setCacheEnabled() {
if(isRelative()) {
throw new RuntimeException("File is relative");
}
SYS.VFS.getFile(path).setCacheEnabled();
}
public byte[] getAllBytes() {
if(isRelative()) {
return null;
}
return SYS.VFS.getFile(path).getAllBytes();
}
public String getAllChars() {
if(isRelative()) {
return null;
}
return SYS.VFS.getFile(path).getAllChars();
}
public String[] getAllLines() {
if(isRelative()) {
return null;
}
return SYS.VFS.getFile(path).getAllLines();
}
public byte[] getAllBytes(boolean copy) {
if(isRelative()) {
return null;
}
return SYS.VFS.getFile(path).getAllBytes(copy);
}
public boolean setAllChars(String bytes) {
if(isRelative()) {
return false;
}
return SYS.VFS.getFile(path).setAllChars(bytes);
}
public boolean setAllBytes(byte[] bytes) {
if(isRelative()) {
return false;
}
return SYS.VFS.getFile(path).setAllBytes(bytes);
}
public boolean setAllBytes(byte[] bytes, boolean copy) {
if(isRelative()) {
return false;
}
return SYS.VFS.getFile(path).setAllBytes(bytes, copy);
}
public List<String> list() {
if(isRelative()) {
return Arrays.asList(path);
}
return SYS.VFS.listFiles(path);
}
public int deleteAll() {
return isRelative() ? 0 : SYS.VFS.deleteFiles(path);
}
}

View File

@ -1,289 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import org.teavm.interop.Async;
import org.teavm.interop.AsyncCallback;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.dom.events.Event;
import org.teavm.jso.dom.events.EventListener;
import org.teavm.jso.indexeddb.IDBCursor;
import org.teavm.jso.indexeddb.IDBRequest;
import org.teavm.jso.typedarrays.ArrayBuffer;
import org.teavm.jso.typedarrays.Uint8Array;
/**
* Do not use an instance of this class outside of the VFSIterator.next() method
*/
public class VIteratorFile extends VFile {
static final VIteratorFile instance = new VIteratorFile();
private VIteratorFile() {
super("");
this.idx = -1;
this.cur = null;
this.vfs = null;
}
private static class VirtualIteratorOutputStream extends ByteArrayOutputStream {
private final VIteratorFile itr;
protected VirtualIteratorOutputStream(VIteratorFile itr) {
this.itr = itr;
}
public void close() throws IOException {
if(!itr.setAllBytes(super.toByteArray(), false)) {
throw new IOException("Could not close stream and write to \"" + itr.path + "\" on VFS \"" + itr.vfs.database + "\" (the file was probably deleted)");
}
}
}
private int idx;
private IDBCursor cur;
private VirtualFilesystem vfs;
private boolean wasDeleted;
@JSBody(params = { "k" }, script = "return ((typeof k) === \"string\") ? k : (((typeof k) === \"undefined\") ? null : (((typeof k[0]) === \"string\") ? k[0] : null));")
private static native String readKey(JSObject k);
static VIteratorFile create(int idx, VirtualFilesystem vfs, IDBCursor cur) {
String k = readKey(cur.getKey());
if(k == null) {
return null;
}
instance.update(idx, k, vfs, cur);
return instance;
}
public VFile makeVFile() {
return new VFile(path);
}
private void update(int idx, String path, VirtualFilesystem vfs, IDBCursor cur) {
this.idx = idx;
this.path = path;
this.vfs = vfs;
this.cur = cur;
this.wasDeleted = false;
}
public InputStream getInputStream() {
return !wasDeleted ? new ByteArrayInputStream(getAllBytes()) : null;
}
public OutputStream getOutputStream() {
return !wasDeleted ? new VirtualIteratorOutputStream(this) : null;
}
public String toString() {
return path;
}
public boolean isRelative() {
return false;
}
public boolean canRead() {
return !wasDeleted;
}
public String getPath() {
return path;
}
public String getName() {
if(path == null) {
return null;
}
int i = path.indexOf(pathSeperator);
return i == -1 ? path : path.substring(i + 1);
}
public boolean canWrite() {
return !wasDeleted;
}
public String getParent() {
if(path == null) {
return null;
}
int i = path.indexOf(pathSeperator);
return i == -1 ? ".." : path.substring(0, i);
}
public int hashCode() {
return path == null ? 0 : path.hashCode();
}
public boolean equals(Object o) {
return path != null && o != null && (o instanceof VFile) && path.equals(((VFile)o).path);
}
public boolean exists() {
return !wasDeleted;
}
public boolean delete() {
return wasDeleted = AsyncHandlers.awaitRequest(cur.delete()).bool;
}
public boolean renameTo(String p) {
byte[] data = getAllBytes();
String op = path;
path = p;
if(!setAllBytes(data)) {
path = op;
return false;
}
path = op;
if(!delete()) {
return false;
}
path = p;
return true;
}
public int length() {
JSObject obj = cur.getValue();
if(obj == null) {
throw new RuntimeException("Value of entry is missing");
}
ArrayBuffer arr = readRow(obj);
if(arr == null) {
throw new RuntimeException("Value of the fucking value of the entry is missing");
}
return arr.getByteLength();
}
public void getBytes(int fileOffset, byte[] array, int offset, int length) {
JSObject obj = cur.getValue();
if(obj == null) {
throw new ArrayIndexOutOfBoundsException("Value of entry is missing");
}
ArrayBuffer arr = readRow(obj);
if(arr == null) {
throw new ArrayIndexOutOfBoundsException("Value of the fucking value of the entry is missing");
}
Uint8Array a = new Uint8Array(arr);
if(a.getLength() < fileOffset + length) {
throw new ArrayIndexOutOfBoundsException("file '" + path + "' size was "+a.getLength()+" but user tried to read index "+(fileOffset + length - 1));
}
for(int i = 0; i < length; ++i) {
array[i + offset] = (byte)a.get(i + fileOffset);
}
}
public void setCacheEnabled() {
// no
}
@JSBody(params = { "obj" }, script = "return (typeof obj === 'undefined') ? null : ((typeof obj.data === 'undefined') ? null : obj.data);")
private static native ArrayBuffer readRow(JSObject obj);
public byte[] getAllBytes() {
JSObject obj = cur.getValue();
if(obj == null) {
return null;
}
ArrayBuffer arr = readRow(obj);
if(arr == null) {
return null;
}
Uint8Array a = new Uint8Array(arr);
int ii = a.getByteLength();
byte[] array = new byte[ii];
for(int i = 0; i < ii; ++i) {
array[i] = (byte)a.get(i);
}
return array;
}
public String getAllChars() {
return VirtualFilesystem.utf8(getAllBytes());
}
public String[] getAllLines() {
return VirtualFilesystem.lines(VirtualFilesystem.utf8(getAllBytes()));
}
public byte[] getAllBytes(boolean copy) {
return getAllBytes();
}
public boolean setAllChars(String bytes) {
return setAllBytes(VirtualFilesystem.utf8(bytes));
}
public List<String> list() {
throw new RuntimeException("Cannot perform list all in VFS callback");
}
public int deleteAll() {
throw new RuntimeException("Cannot perform delete all in VFS callback");
}
@JSBody(params = { "pat", "dat" }, script = "return { path: pat, data: dat };")
private static native JSObject writeRow(String name, ArrayBuffer data);
public boolean setAllBytes(byte[] bytes) {
ArrayBuffer a = new ArrayBuffer(bytes.length);
Uint8Array ar = new Uint8Array(a);
ar.set(bytes);
JSObject obj = writeRow(path, a);
BooleanResult r = AsyncHandlers.awaitRequest(cur.update(obj));
return r.bool;
}
public boolean setAllBytes(byte[] bytes, boolean copy) {
return setAllBytes(bytes);
}
public static class AsyncHandlers {
@Async
public static native BooleanResult awaitRequest(IDBRequest r);
private static void awaitRequest(IDBRequest r, final AsyncCallback<BooleanResult> cb) {
r.addEventListener("success", new EventListener<Event>() {
@Override
public void handleEvent(Event evt) {
cb.complete(BooleanResult._new(true));
}
});
r.addEventListener("error", new EventListener<Event>() {
@Override
public void handleEvent(Event evt) {
cb.complete(BooleanResult._new(false));
}
});
}
}
}

View File

@ -1,688 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.teavm.interop.Async;
import org.teavm.interop.AsyncCallback;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.dom.events.EventListener;
import org.teavm.jso.indexeddb.EventHandler;
import org.teavm.jso.indexeddb.IDBCountRequest;
import org.teavm.jso.indexeddb.IDBCursor;
import org.teavm.jso.indexeddb.IDBCursorRequest;
import org.teavm.jso.indexeddb.IDBDatabase;
import org.teavm.jso.indexeddb.IDBFactory;
import org.teavm.jso.indexeddb.IDBGetRequest;
import org.teavm.jso.indexeddb.IDBObjectStoreParameters;
import org.teavm.jso.indexeddb.IDBOpenDBRequest;
import org.teavm.jso.indexeddb.IDBRequest;
import org.teavm.jso.indexeddb.IDBTransaction;
import org.teavm.jso.indexeddb.IDBVersionChangeEvent;
import org.teavm.jso.typedarrays.ArrayBuffer;
import org.teavm.jso.typedarrays.Int8Array;
import org.teavm.jso.typedarrays.Uint8Array;
public class VirtualFilesystem {
protected static class VirtualOutputStream extends ByteArrayOutputStream {
private final VFSFile file;
protected VirtualOutputStream(VFSFile file) {
this.file = file;
}
public void close() throws IOException {
if(!file.setAllBytes(super.toByteArray(), false)) {
throw new IOException("Could not close stream and write to \"" + file.filePath + "\" on VFS \"" + file.virtualFilesystem.database + "\" (the file was probably deleted)");
}
}
}
public static class VFSFile {
public final VirtualFilesystem virtualFilesystem;
protected boolean cacheEnabled;
protected String filePath;
protected int fileSize = -1;
protected boolean hasBeenDeleted = false;
protected boolean hasBeenAccessed = false;
protected boolean exists = false;
protected byte[] cache = null;
protected long cacheHit;
protected VFSFile(VirtualFilesystem vfs, String filePath, boolean cacheEnabled) {
this.virtualFilesystem = vfs;
this.filePath = filePath;
this.cacheHit = SysUtil.steadyTimeMillis();
if(cacheEnabled) {
setCacheEnabled();
}
}
public boolean equals(Object o) {
return (o instanceof VFSFile) && ((VFSFile)o).filePath.equals(filePath);
}
public int hashCode() {
return filePath.hashCode();
}
public String getPath() {
return filePath;
}
public int getSize() {
cacheHit = SysUtil.steadyTimeMillis();
if(fileSize < 0) {
if(cacheEnabled) {
byte[] b = getAllBytes(false);
if(b != null) {
fileSize = b.length;
}
}else {
ArrayBuffer dat = AsyncHandlers.readWholeFile(virtualFilesystem.indexeddb, filePath);
if(dat != null) {
fileSize = dat.getByteLength();
}
}
}
return fileSize;
}
public InputStream getInputStream() {
byte[] dat = getAllBytes(false);
if(dat == null) {
return null;
}
return new ByteArrayInputStream(dat);
}
public OutputStream getOutputStream() {
return new VirtualOutputStream(this);
}
public void getBytes(int fileOffset, byte[] array, int offset, int length) {
if(hasBeenDeleted) {
throw new ArrayIndexOutOfBoundsException("file '" + filePath + "' has been deleted");
}else if(hasBeenAccessed && !exists) {
throw new ArrayIndexOutOfBoundsException("file '" + filePath + "' does not exist");
}
cacheHit = SysUtil.steadyTimeMillis();
if(cacheEnabled && cache != null) {
System.arraycopy(cache, fileOffset, array, offset, length);
}else {
ArrayBuffer aa = AsyncHandlers.readWholeFile(virtualFilesystem.indexeddb, filePath);
hasBeenAccessed = true;
if(aa != null) {
exists = true;
}else {
exists = false;
throw new ArrayIndexOutOfBoundsException("file '" + filePath + "' does not exist");
}
this.fileSize = aa.getByteLength();
if(cacheEnabled) {
cache = TeaVMUtils.wrapByteArrayBuffer(aa);
}
if(fileSize < fileOffset + length) {
throw new ArrayIndexOutOfBoundsException("file '" + filePath + "' size was "+fileSize+" but user tried to read index "+(fileOffset + length - 1));
}
TeaVMUtils.unwrapByteArray(array).set(new Int8Array(aa, fileOffset, length), offset);
}
}
public void setCacheEnabled() {
if(!cacheEnabled && !hasBeenDeleted && !(hasBeenAccessed && !exists)) {
cacheHit = SysUtil.steadyTimeMillis();
cache = getAllBytes(false);
cacheEnabled = true;
}
}
public byte[] getAllBytes() {
return getAllBytes(false);
}
public String getAllChars() {
return utf8(getAllBytes(false));
}
public String[] getAllLines() {
return lines(getAllChars());
}
public byte[] getAllBytes(boolean copy) {
if(hasBeenDeleted || (hasBeenAccessed && !exists)) {
return null;
}
cacheHit = SysUtil.steadyTimeMillis();
if(cacheEnabled && cache != null) {
byte[] b = cache;
if(copy) {
b = new byte[cache.length];
System.arraycopy(cache, 0, b, 0, cache.length);
}
return b;
}else {
hasBeenAccessed = true;
ArrayBuffer b = AsyncHandlers.readWholeFile(virtualFilesystem.indexeddb, filePath);
if(b != null) {
exists = true;
}else {
exists = false;
return null;
}
this.fileSize = b.getByteLength();
if(cacheEnabled) {
if(copy) {
cache = new byte[fileSize];
TeaVMUtils.unwrapByteArray(cache).set(new Int8Array(b));
}else {
cache = TeaVMUtils.wrapByteArrayBuffer(b);
}
}
return TeaVMUtils.wrapByteArrayBuffer(b);
}
}
public boolean setAllChars(String bytes) {
return setAllBytes(utf8(bytes), true);
}
public boolean setAllBytes(byte[] bytes) {
return setAllBytes(bytes, true);
}
public boolean setAllBytes(byte[] bytes, boolean copy) {
if(hasBeenDeleted || bytes == null) {
return false;
}
cacheHit = SysUtil.steadyTimeMillis();
this.fileSize = bytes.length;
if(cacheEnabled) {
byte[] copz = bytes;
if(copy) {
copz = new byte[bytes.length];
System.arraycopy(bytes, 0, copz, 0, bytes.length);
}
cache = copz;
return sync();
}else {
boolean s = AsyncHandlers.writeWholeFile(virtualFilesystem.indexeddb, filePath,
TeaVMUtils.unwrapArrayBuffer(bytes)).bool;
hasBeenAccessed = true;
exists = exists || s;
return s;
}
}
public boolean sync() {
if(cacheEnabled && cache != null && !hasBeenDeleted) {
cacheHit = SysUtil.steadyTimeMillis();
boolean tryWrite = AsyncHandlers.writeWholeFile(virtualFilesystem.indexeddb, filePath,
TeaVMUtils.unwrapArrayBuffer(cache)).bool;
hasBeenAccessed = true;
exists = exists || tryWrite;
return tryWrite;
}
return false;
}
public boolean delete() {
if(!hasBeenDeleted && !(hasBeenAccessed && !exists)) {
cacheHit = SysUtil.steadyTimeMillis();
if(!AsyncHandlers.deleteFile(virtualFilesystem.indexeddb, filePath).bool) {
hasBeenAccessed = true;
return false;
}
virtualFilesystem.fileMap.remove(filePath);
hasBeenDeleted = true;
hasBeenAccessed = true;
exists = false;
return true;
}
return false;
}
public boolean rename(String newName, boolean copy) {
if(!hasBeenDeleted && !(hasBeenAccessed && !exists)) {
cacheHit = SysUtil.steadyTimeMillis();
ArrayBuffer arr = AsyncHandlers.readWholeFile(virtualFilesystem.indexeddb, filePath);
hasBeenAccessed = true;
if(arr != null) {
exists = true;
if(!AsyncHandlers.writeWholeFile(virtualFilesystem.indexeddb, newName, arr).bool) {
return false;
}
if(!copy && !AsyncHandlers.deleteFile(virtualFilesystem.indexeddb, filePath).bool) {
return false;
}
}else {
exists = false;
}
if(!copy) {
virtualFilesystem.fileMap.remove(filePath);
filePath = newName;
virtualFilesystem.fileMap.put(newName, this);
}
return true;
}
return false;
}
public boolean exists() {
if(hasBeenDeleted) {
return false;
}
cacheHit = SysUtil.steadyTimeMillis();
if(hasBeenAccessed) {
return exists;
}
exists = AsyncHandlers.fileExists(virtualFilesystem.indexeddb, filePath).bool;
hasBeenAccessed = true;
return exists;
}
}
private final HashMap<String, VFSFile> fileMap = new HashMap<>();
public final String database;
private final IDBDatabase indexeddb;
public static class VFSHandle {
public final boolean failedInit;
public final boolean failedLocked;
public final String failedError;
public final VirtualFilesystem vfs;
public VFSHandle(boolean init, boolean locked, String error, VirtualFilesystem db) {
failedInit = init;
failedLocked = locked;
failedError = error;
vfs = db;
}
public String toString() {
if(failedInit) {
return "IDBFactory threw an exception, IndexedDB is most likely not supported in this browser." + (failedError == null ? "" : "\n\n" + failedError);
}
if(failedLocked) {
return "The filesystem requested is already in use on a different tab.";
}
if(failedError != null) {
return "The IDBFactory.open() request failed, reason: " + failedError;
}
return "Virtual Filesystem Object: " + vfs.database;
}
}
public static VFSHandle openVFS(String db) {
DatabaseOpen evt = AsyncHandlers.openDB(db);
if(evt.failedInit) {
return new VFSHandle(true, false, evt.failedError, null);
}
if(evt.failedLocked) {
return new VFSHandle(false, true, null, null);
}
if(evt.failedError != null) {
return new VFSHandle(false, false, evt.failedError, null);
}
return new VFSHandle(false, false, null, new VirtualFilesystem(db, evt.database));
}
private VirtualFilesystem(String db, IDBDatabase idb) {
database = db;
indexeddb = idb;
}
public void close() {
indexeddb.close();
}
public VFSFile getFile(String path) {
return getFile(path, false);
}
public VFSFile getFile(String path, boolean cache) {
VFSFile f = fileMap.get(path);
if(f == null) {
fileMap.put(path, f = new VFSFile(this, path, cache));
}else {
if(cache) {
f.setCacheEnabled();
}
}
return f;
}
public boolean renameFile(String oldName, String newName, boolean copy) {
return getFile(oldName).rename(newName, copy);
}
public boolean deleteFile(String path) {
return getFile(path).delete();
}
public boolean fileExists(String path) {
return getFile(path).exists();
}
public List<String> listFiles(String prefix) {
final ArrayList<String> list = new ArrayList<>();
AsyncHandlers.iterateFiles(indexeddb, this, prefix, false, (v) -> {
list.add(v.getPath());
});
return list;
}
public List<VFile> listVFiles(String prefix) {
final ArrayList<VFile> list = new ArrayList<>();
AsyncHandlers.iterateFiles(indexeddb, this, prefix, false, (v) -> {
list.add(new VFile(v.getPath()));
});
return list;
}
public int deleteFiles(String prefix) {
return AsyncHandlers.deleteFiles(indexeddb, prefix);
}
public int iterateFiles(String prefix, boolean rw, VFSIterator itr) {
return AsyncHandlers.iterateFiles(indexeddb, this, prefix, rw, itr);
}
public int renameFiles(String oldPrefix, String newPrefix, boolean copy) {
List<String> filesToCopy = listFiles(oldPrefix);
int i = 0;
for(String str : filesToCopy) {
String f = VFile.createPath(newPrefix, str.substring(oldPrefix.length()));
if(!renameFile(str, f, copy)) {
System.err.println("Could not " + (copy ? "copy" : "rename") + " file \"" + str + "\" to \"" + f + "\" for some reason");
}else {
++i;
}
}
return i;
}
public void flushCache(long age) {
long curr = SysUtil.steadyTimeMillis();
Iterator<VFSFile> files = fileMap.values().iterator();
while(files.hasNext()) {
if(curr - files.next().cacheHit > age) {
files.remove();
}
}
}
protected static class DatabaseOpen {
protected final boolean failedInit;
protected final boolean failedLocked;
protected final String failedError;
protected final IDBDatabase database;
protected DatabaseOpen(boolean init, boolean locked, String error, IDBDatabase db) {
failedInit = init;
failedLocked = locked;
failedError = error;
database = db;
}
}
@JSBody(script = "return ((typeof indexedDB) !== 'undefined') ? indexedDB : null;")
protected static native IDBFactory createIDBFactory();
protected static class AsyncHandlers {
@Async
protected static native DatabaseOpen openDB(String name);
private static void openDB(String name, final AsyncCallback<DatabaseOpen> cb) {
IDBFactory i = createIDBFactory();
if(i == null) {
cb.complete(new DatabaseOpen(false, false, "window.indexedDB was null or undefined", null));
return;
}
final IDBOpenDBRequest f = i.open(name, 1);
f.setOnBlocked(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(new DatabaseOpen(false, true, null, null));
}
});
f.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(new DatabaseOpen(false, false, null, f.getResult()));
}
});
f.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(new DatabaseOpen(false, false, "open error", null));
}
});
f.setOnUpgradeNeeded(new EventListener<IDBVersionChangeEvent>() {
@Override
public void handleEvent(IDBVersionChangeEvent evt) {
f.getResult().createObjectStore("filesystem", IDBObjectStoreParameters.create().keyPath("path"));
}
});
}
@Async
protected static native BooleanResult deleteFile(IDBDatabase db, String name);
private static void deleteFile(IDBDatabase db, String name, final AsyncCallback<BooleanResult> cb) {
IDBTransaction tx = db.transaction("filesystem", "readwrite");
final IDBRequest r = tx.objectStore("filesystem").delete(makeTheFuckingKeyWork(name));
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult._new(true));
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult._new(false));
}
});
}
@JSBody(params = { "obj" }, script = "return (typeof obj === 'undefined') ? null : ((typeof obj.data === 'undefined') ? null : obj.data);")
protected static native ArrayBuffer readRow(JSObject obj);
@JSBody(params = { "obj" }, script = "return [obj];")
private static native JSObject makeTheFuckingKeyWork(String k);
@Async
protected static native ArrayBuffer readWholeFile(IDBDatabase db, String name);
private static void readWholeFile(IDBDatabase db, String name, final AsyncCallback<ArrayBuffer> cb) {
IDBTransaction tx = db.transaction("filesystem", "readonly");
final IDBGetRequest r = tx.objectStore("filesystem").get(makeTheFuckingKeyWork(name));
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(readRow(r.getResult()));
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(null);
}
});
}
@JSBody(params = { "k" }, script = "return ((typeof k) === \"string\") ? k : (((typeof k) === \"undefined\") ? null : (((typeof k[0]) === \"string\") ? k[0] : null));")
private static native String readKey(JSObject k);
@JSBody(params = { "k" }, script = "return ((typeof k) === \"undefined\") ? null : (((typeof k.path) === \"undefined\") ? null : (((typeof k.path) === \"string\") ? k[0] : null));")
private static native String readRowKey(JSObject r);
@Async
protected static native Integer iterateFiles(IDBDatabase db, final VirtualFilesystem vfs, final String prefix, boolean rw, final VFSIterator itr);
private static void iterateFiles(IDBDatabase db, final VirtualFilesystem vfs, final String prefix, boolean rw, final VFSIterator itr, final AsyncCallback<Integer> cb) {
IDBTransaction tx = db.transaction("filesystem", rw ? "readwrite" : "readonly");
final IDBCursorRequest r = tx.objectStore("filesystem").openCursor();
final int[] res = new int[1];
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
IDBCursor c = r.getResult();
if(c == null || c.getKey() == null || c.getValue() == null) {
cb.complete(res[0]);
return;
}
String k = readKey(c.getKey());
if(k != null) {
if(k.startsWith(prefix)) {
int ci = res[0]++;
try {
itr.next(VIteratorFile.create(ci, vfs, c));
}catch(VFSIterator.BreakLoop ex) {
cb.complete(res[0]);
return;
}
}
}
c.doContinue();
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(res[0] > 0 ? res[0] : -1);
}
});
}
@Async
protected static native Integer deleteFiles(IDBDatabase db, final String prefix);
private static void deleteFiles(IDBDatabase db, final String prefix, final AsyncCallback<Integer> cb) {
IDBTransaction tx = db.transaction("filesystem", "readwrite");
final IDBCursorRequest r = tx.objectStore("filesystem").openCursor();
final int[] res = new int[1];
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
IDBCursor c = r.getResult();
if(c == null || c.getKey() == null || c.getValue() == null) {
cb.complete(res[0]);
return;
}
String k = readKey(c.getKey());
if(k != null) {
if(k.startsWith(prefix)) {
c.delete();
++res[0];
}
}
c.doContinue();
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(res[0] > 0 ? res[0] : -1);
}
});
}
@Async
protected static native BooleanResult fileExists(IDBDatabase db, String name);
private static void fileExists(IDBDatabase db, String name, final AsyncCallback<BooleanResult> cb) {
IDBTransaction tx = db.transaction("filesystem", "readonly");
final IDBCountRequest r = tx.objectStore("filesystem").count(makeTheFuckingKeyWork(name));
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult._new(r.getResult() > 0));
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult._new(false));
}
});
}
@JSBody(params = { "pat", "dat" }, script = "return { path: pat, data: dat };")
protected static native JSObject writeRow(String name, ArrayBuffer data);
@Async
protected static native BooleanResult writeWholeFile(IDBDatabase db, String name, ArrayBuffer data);
private static void writeWholeFile(IDBDatabase db, String name, ArrayBuffer data, final AsyncCallback<BooleanResult> cb) {
IDBTransaction tx = db.transaction("filesystem", "readwrite");
final IDBRequest r = tx.objectStore("filesystem").put(writeRow(name, data));
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult._new(true));
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult._new(false));
}
});
}
}
public static byte[] utf8(String str) {
if(str == null) return null;
return str.getBytes(Charset.forName("UTF-8"));
}
public static String utf8(byte[] str) {
if(str == null) return null;
return new String(str, Charset.forName("UTF-8"));
}
public static String CRLFtoLF(String str) {
if(str == null) return null;
str = str.indexOf('\r') != -1 ? str.replace("\r", "") : str;
str = str.trim();
if(str.endsWith("\n")) {
str = str.substring(0, str.length() - 1);
}
if(str.startsWith("\n")) {
str = str.substring(1);
}
return str;
}
public static String[] lines(String str) {
if(str == null) return null;
return CRLFtoLF(str).split("\n");
}
}

View File

@ -1,96 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import net.minecraft.server.MinecraftServer;
import net.minecraft.src.NetHandler;
public class WorkerListenThread {
/** Reference to the MinecraftServer object. */
private final MinecraftServer mcServer;
private final HashSet<NetHandler> connections = new HashSet<>();
private final HashMap<String, WorkerNetworkManager> channels = new HashMap<>();
/** Whether the network listener object is listening. */
public volatile boolean isListening = false;
public WorkerListenThread(MinecraftServer par1MinecraftServer) {
this.mcServer = par1MinecraftServer;
this.isListening = true;
}
/**
* adds this connection to the list of currently connected players
*/
public void addPlayer(NetHandler par1NetServerHandler) {
System.out.println("[Server][ADDPLAYER][" + par1NetServerHandler.getClass().getSimpleName() + "]");
this.connections.add(par1NetServerHandler);
}
public void stopListening() {
this.isListening = false;
List<String> names = new ArrayList<>(channels.keySet());
for(int i = 0, l = names.size(); i < l; ++i) {
closeChannel(names.get(i));
}
}
public boolean openChannel(String player) {
System.out.println("[Server][OPENCHANNEL][" + player + "]");
return channels.put(player, new WorkerNetworkManager(player, mcServer, this)) == null;
}
public void recievePacket(String player, byte[] data) {
WorkerNetworkManager channel = channels.get(player);
if(channel == null) {
return;
}
channel.addToRecieveQueue(data);
}
public boolean closeChannel(String player) {
System.out.println("[Server][CLOSECHANNEL][" + player + "]");
WorkerNetworkManager channel = channels.get(player);
if(channel == null) {
return false;
}
channels.remove(player);
channel.networkShutdown(null, null, null);
return true;
}
private void deleteDeadConnections() {
Iterator<NetHandler> itr = this.connections.iterator();
while (itr.hasNext()) {
NetHandler handler = itr.next();
if (handler.shouldBeRemoved()) {
itr.remove();
//System.out.println("[Client][REMOVEDEAD]");
}
}
}
/**
* Handles all incoming connections and packets
*/
public void handleNetworkListenThread() {
deleteDeadConnections();
List<NetHandler> conns = new ArrayList<>(this.connections);
for (NetHandler var2 : conns) {
var2.handlePackets();
}
deleteDeadConnections();
}
public MinecraftServer getServer() {
return this.mcServer;
}
}

View File

@ -1,156 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.LinkedList;
import net.lax1dude.eaglercraft.sp.ipc.IPCPacket0CPlayerChannel;
import net.minecraft.server.MinecraftServer;
import net.minecraft.src.INetworkManager;
import net.minecraft.src.NetHandler;
import net.minecraft.src.NetLoginHandler;
import net.minecraft.src.NetServerHandler;
import net.minecraft.src.Packet;
public class WorkerNetworkManager implements INetworkManager {
private NetHandler theNetHandler;
private MinecraftServer minecraftServer;
private String ipcChannel;
private boolean isAlive;
private WorkerListenThread listenThread;
private LinkedList<byte[]> frags = new LinkedList<>();
public WorkerNetworkManager(String ipcChannel, MinecraftServer srv, WorkerListenThread th) {
this.ipcChannel = ipcChannel;
this.theNetHandler = new NetLoginHandler(srv, this);
th.addPlayer(theNetHandler);
this.minecraftServer = srv;
this.isAlive = true;
this.listenThread = th;
}
@Override
public void setNetHandler(NetHandler var1) {
theNetHandler = var1;
listenThread.addPlayer(theNetHandler);
}
@Override
public void addToSendQueue(Packet var1) {
if(!isAlive) {
return;
}
try {
ByteArrayOutputStream bao = new ByteArrayOutputStream(var1.getPacketSize() + 1);
Packet.writePacket(var1, new DataOutputStream(bao));
IntegratedServer.sendPlayerPacket(ipcChannel, bao.toByteArray());
}catch(IOException e) {
System.err.println("Failed to serialize minecraft packet '" + var1.getPacketId() + "' for IPC channel 'NET|" + ipcChannel + "'");
e.printStackTrace();
return;
}
}
public void addToRecieveQueue(byte[] fragment) {
//System.out.println("[Server][READ][QUEUE][" + ipcChannel + "]: " + fragment.length);
if(!isAlive) {
return;
}
frags.add(fragment);
}
@Override
public void wakeThreads() {
// no
}
@Override
public void processReadPackets() {
while(frags.size() > 0) {
byte[] pktBytes = frags.remove(0);
try {
ByteArrayInputStream bai = new ByteArrayInputStream(pktBytes);
int pktId = bai.read();
if(pktId == -1) {
System.err.println("Recieved invalid '-1' packet");
continue;
}
Packet pkt = Packet.getNewPacket(minecraftServer.getLogAgent(), pktId);
if(pkt == null) {
System.err.println("Recieved invalid '" + pktId + "' packet");
continue;
}
pkt.readPacketData(new DataInputStream(bai));
//System.out.println("[Server][" + ipcChannel + "]: packet '" + pkt.getClass().getSimpleName() + "' recieved");
try {
pkt.processPacket(theNetHandler);
}catch(Throwable t) {
System.err.println("Could not process minecraft packet 0x" + Integer.toHexString(pkt.getPacketId()) + " class '" + pkt.getClass().getSimpleName() + "' on channel 'NET|" + ipcChannel + "'");
t.printStackTrace();
}
}catch(IOException ex) {
System.err.println("Could not deserialize a " + pktBytes.length + " byte long minecraft packet of type '" + (pktBytes.length <= 0 ? -1 : (int)(pktBytes[0] & 0xFF)) + "' on channel 'NET|" + ipcChannel + "'");
}
}
}
@Override
public void serverShutdown() {
if(isAlive) {
listenThread.closeChannel(ipcChannel);
IntegratedServer.sendIPCPacket(new IPCPacket0CPlayerChannel(ipcChannel, false));
}
if(theNetHandler != null && (theNetHandler instanceof NetServerHandler)) {
((NetServerHandler)theNetHandler).kickPlayerFromServer(null);
}
isAlive = false;
}
@Override
public int packetSize() { // why is this a thing
return 0;
}
@Override
public void networkShutdown(String var1, Object... var2) {
if(isAlive) {
listenThread.closeChannel(ipcChannel);
IntegratedServer.sendIPCPacket(new IPCPacket0CPlayerChannel(ipcChannel, false));
}
if(theNetHandler != null && (theNetHandler instanceof NetServerHandler)) {
((NetServerHandler)theNetHandler).kickPlayerFromServer(null);
}
isAlive = false;
}
@Override
public void closeConnections() {
}
@Override
public String getServerURI() {
return "None? I dont fucking know what a URI is";
}
public boolean equals(Object o) {
return (o instanceof WorkerNetworkManager) && ((WorkerNetworkManager)o).ipcChannel.equals(ipcChannel);
}
public int hashCode() {
return ipcChannel.hashCode();
}
}

View File

@ -1,80 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.io.IOException;
import net.minecraft.src.CompressedStreamTools;
import net.minecraft.src.NBTTagCompound;
public class WorldConverterEPK {
public static void importWorld(byte[] archiveContents, String newName) throws IOException {
String folder = VFSSaveHandler.worldNameToFolderName(newName);
VFile dir = new VFile("worlds", folder);
EPKDecompiler dc = new EPKDecompiler(archiveContents);
EPKDecompiler.FileEntry f = null;
int lastProgUpdate = 0;
int prog = 0;
boolean hasReadType = dc.isOld();
while((f = dc.readFile()) != null) {
byte[] b = f.data;
if(!hasReadType) {
if(f.type.equals("HEAD") && f.name.equals("file-type") && EPKDecompiler.readASCII(f.data).equals("epk/world152")) {
hasReadType = true;
continue;
}else {
throw new IOException("file does not contain a singleplayer 1.5.2 world!");
}
}
if(f.type.equals("FILE")) {
if(f.name.equals("level.dat")) {
NBTTagCompound worldDatNBT = CompressedStreamTools.decompress(b);
worldDatNBT.getCompoundTag("Data").setString("LevelName", newName);
worldDatNBT.getCompoundTag("Data").setLong("LastPlayed", System.currentTimeMillis());
b = CompressedStreamTools.compress(worldDatNBT);
}
VFile ff = new VFile(dir, f.name);
ff.setAllBytes(b);
prog += b.length;
if(prog - lastProgUpdate > 10000) {
lastProgUpdate = prog;
IntegratedServer.updateStatusString("selectWorld.progress.importing.0", prog);
}
}
}
String[] worldsTxt = SYS.VFS.getFile("worlds.txt").getAllLines();
if(worldsTxt == null || worldsTxt.length <= 0) {
worldsTxt = new String[] { folder };
}else {
String[] tmp = worldsTxt;
worldsTxt = new String[worldsTxt.length + 1];
System.arraycopy(tmp, 0, worldsTxt, 0, tmp.length);
worldsTxt[worldsTxt.length - 1] = folder;
}
SYS.VFS.getFile("worlds.txt").setAllChars(String.join("\n", worldsTxt));
}
public static byte[] exportWorld(String worldName) {
String realWorldName = worldName;
String worldOwner = "UNKNOWN";
int j = realWorldName.lastIndexOf(new String(new char[] { (char)253, (char)233, (char)233 }));
if(j != -1) {
worldOwner = realWorldName.substring(j + 3);
realWorldName = realWorldName.substring(0, j);
}
final int[] bytesWritten = new int[1];
final int[] lastUpdate = new int[1];
String pfx = "worlds/" + realWorldName + "/";
EPK2Compiler c = new EPK2Compiler(realWorldName, worldOwner, "epk/world152");
SYS.VFS.iterateFiles(pfx, false, (i) -> {
byte[] b = i.getAllBytes();
c.append(i.path.substring(pfx.length()), b);
bytesWritten[0] += b.length;
if (bytesWritten[0] - lastUpdate[0] > 10000) {
lastUpdate[0] = bytesWritten[0];
IntegratedServer.updateStatusString("selectWorld.progress.exporting.1", bytesWritten[0]);
}
});
return c.complete();
}
}

View File

@ -1,255 +0,0 @@
package net.lax1dude.eaglercraft.sp;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import net.minecraft.src.CompressedStreamTools;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.RegionFile;
public class WorldConverterMCA {
public static void importWorld(byte[] archiveContents, String newName) throws IOException {
String folderName = newName.replaceAll("[\\./\"]", "_");
VFile worldDir = new VFile("worlds", folderName);
while((new VFile(worldDir, "level.dat")).exists() || (new VFile(worldDir, "level.dat_old")).exists()) {
folderName += "_";
worldDir = new VFile("worlds", folderName);
}
List<char[]> fileNames = new ArrayList<>();
try(ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(archiveContents))) {
ZipEntry folderNameFile = null;
while((folderNameFile = zis.getNextEntry()) != null) {
if (folderNameFile.getName().contains("__MACOSX/")) continue;
if (folderNameFile.isDirectory()) continue;
String lowerName = folderNameFile.getName().toLowerCase();
if (!(lowerName.endsWith(".dat") || lowerName.endsWith(".dat_old") || lowerName.endsWith(".mca") || lowerName.endsWith(".mcr"))) continue;
fileNames.add(folderNameFile.getName().toCharArray());
}
}
final int[] i = new int[] { 0 };
while(fileNames.get(0).length > i[0] && fileNames.stream().allMatch(w -> w[i[0]] == fileNames.get(0)[i[0]])) i[0]++;
int folderPrefixOffset = i[0];
try(ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(archiveContents))) {
ZipEntry f = null;
int lastProgUpdate = 0;
int prog = 0;
while ((f = zis.getNextEntry()) != null) {
if (f.getName().contains("__MACOSX/")) continue;
if (f.isDirectory()) continue;
String lowerName = f.getName().toLowerCase();
if (!(lowerName.endsWith(".dat") || lowerName.endsWith(".dat_old") || lowerName.endsWith(".mca") || lowerName.endsWith(".mcr") || lowerName.endsWith(".bmp"))) continue;
byte[] b;
int sz = (int)f.getSize();
if(sz >= 0) {
b = new byte[sz];
int j = 0, k;
while(j < b.length && (k = zis.read(b, j, b.length - j)) != -1) {
j += k;
}
}else {
b = inputStreamToBytesNoClose(zis);
}
String fileName = f.getName().substring(folderPrefixOffset);
if (fileName.equals("level.dat") || fileName.equals("level.dat_old")) {
NBTTagCompound worldDatNBT = CompressedStreamTools.readCompressed(new ByteArrayInputStream(b));
worldDatNBT.getCompoundTag("Data").setString("LevelName", newName);
worldDatNBT.getCompoundTag("Data").setLong("LastPlayed", System.currentTimeMillis());
ByteArrayOutputStream bo = new ByteArrayOutputStream();
CompressedStreamTools.writeCompressed(worldDatNBT, bo);
b = bo.toByteArray();
VFile ff = new VFile(worldDir, fileName);
ff.setAllBytes(b);
prog += b.length;
} else if ((fileName.endsWith(".mcr") || fileName.endsWith(".mca")) && (fileName.startsWith("region/") || fileName.startsWith("DIM1/region/") || fileName.startsWith("DIM-1/region/"))) {
VFile chunkFolder = new VFile(worldDir, fileName.startsWith("DIM1") ? "level1" : (fileName.startsWith("DIM-1") ? "level-1" : "level0"));
RegionFile mca = new RegionFile(new RandomAccessMemoryFile(b, b.length));
for(int j = 0; j < 32; ++j) {
for(int k = 0; k < 32; ++k) {
if(mca.isChunkSaved(j, k)) {
NBTTagCompound chunkNBT;
NBTTagCompound chunkLevel;
try {
chunkNBT = CompressedStreamTools.read(mca.getChunkDataInputStream(j, k));
if(!chunkNBT.hasKey("Level")) {
throw new IOException("Chunk is missing level data!");
}
chunkLevel = chunkNBT.getCompoundTag("Level");
}catch(Throwable t) {
System.err.println("Could not read chunk: " + j + ", " + k);
t.printStackTrace();
continue;
}
int chunkX = chunkLevel.getInteger("xPos");
int chunkZ = chunkLevel.getInteger("zPos");
VFile chunkOut = new VFile(chunkFolder, VFSChunkLoader.getChunkPath(chunkX, chunkZ) + ".dat");
if(chunkOut.exists()) {
System.err.println("Chunk already exists: " + chunkOut.getPath());
continue;
}
ByteArrayOutputStream bao = new ByteArrayOutputStream();
CompressedStreamTools.writeCompressed(chunkNBT, bao);
b = bao.toByteArray();
chunkOut.setAllBytes(b);
prog += b.length;
if (prog - lastProgUpdate > 25000) {
lastProgUpdate = prog;
IntegratedServer.updateStatusString("selectWorld.progress.importing.1", prog);
}
}
}
}
} else if (fileName.startsWith("data/") || fileName.startsWith("players/")) {
VFile ff = new VFile(worldDir, fileName);
ff.setAllBytes(b);
prog += b.length;
}
}
}
String[] worldsTxt = SYS.VFS.getFile("worlds.txt").getAllLines();
if(worldsTxt == null || worldsTxt.length <= 0 || (worldsTxt.length == 1 && worldsTxt[0].trim().length() <= 0)) {
worldsTxt = new String[] { folderName };
}else {
String[] tmp = worldsTxt;
worldsTxt = new String[worldsTxt.length + 1];
System.arraycopy(tmp, 0, worldsTxt, 0, tmp.length);
worldsTxt[worldsTxt.length - 1] = folderName;
}
SYS.VFS.getFile("worlds.txt").setAllChars(String.join("\n", worldsTxt));
}
public static byte[] exportWorld(String folderName) throws IOException {
ByteArrayOutputStream bao = new ByteArrayOutputStream();
VFile worldFolder;
try(ZipOutputStream zos = new ZipOutputStream(bao)) {
zos.setComment("contains backup of world '" + folderName + "'");
worldFolder = new VFile("worlds", folderName);
VFile vf = new VFile(worldFolder, "level.dat");
byte[] b;
int lastProgUpdate = 0;
int prog = 0;
boolean safe = false;
if(vf.exists()) {
zos.putNextEntry(new ZipEntry(folderName + "/level.dat"));
b = vf.getAllBytes();
zos.write(b);
prog += b.length;
safe = true;
}
vf = new VFile(worldFolder, "level.dat_old");
if(vf.exists()) {
zos.putNextEntry(new ZipEntry(folderName + "/level.dat_old"));
b = vf.getAllBytes();
zos.write(b);
prog += b.length;
safe = true;
}
if (prog - lastProgUpdate > 25000) {
lastProgUpdate = prog;
IntegratedServer.updateStatusString("selectWorld.progress.exporting.2", prog);
}
String[] srcFolderNames = new String[] { "level0", "level-1", "level1" };
String[] dstFolderNames = new String[] { "/region/", "/DIM-1/region/", "/DIM1/region/" };
List<VFile> fileList;
for(int i = 0; i < 3; ++i) {
vf = new VFile(worldFolder, srcFolderNames[i]);
fileList = SYS.VFS.listVFiles(vf.getPath());
String regionFolder = folderName + dstFolderNames[i];
Map<String,RegionFile> regionFiles = new HashMap<>();
for(int k = 0, l = fileList.size(); k < l; ++k) {
VFile chunkFile = fileList.get(k);
NBTTagCompound chunkNBT;
NBTTagCompound chunkLevel;
try {
b = chunkFile.getAllBytes();
chunkNBT = CompressedStreamTools.readCompressed(new ByteArrayInputStream(b));
if(!chunkNBT.hasKey("Level")) {
throw new IOException("Chunk is missing level data!");
}
chunkLevel = chunkNBT.getCompoundTag("Level");
}catch(IOException t) {
System.err.println("Could not read chunk: " + chunkFile.getPath());
t.printStackTrace();
continue;
}
int chunkX = chunkLevel.getInteger("xPos");
int chunkZ = chunkLevel.getInteger("zPos");
String regionFileName = "r." + (chunkX >> 5) + "." + (chunkZ >> 5) + ".mca";
RegionFile rf = regionFiles.get(regionFileName);
if(rf == null) {
rf = new RegionFile(new RandomAccessMemoryFile(new byte[65536], 0));
regionFiles.put(regionFileName, rf);
}
try(DataOutputStream dos = rf.getChunkDataOutputStream(chunkX & 31, chunkZ & 31)) {
CompressedStreamTools.write(chunkNBT, dos);
}catch(IOException t) {
System.err.println("Could not write chunk to " + regionFileName + ": " + chunkFile.getPath());
t.printStackTrace();
continue;
}
prog += b.length;
if (prog - lastProgUpdate > 25000) {
lastProgUpdate = prog;
IntegratedServer.updateStatusString("selectWorld.progress.exporting.2", prog);
}
}
if(regionFiles.isEmpty()) {
System.err.println("No region files were generated");
continue;
}
for(Entry<String,RegionFile> etr : regionFiles.entrySet()) {
String regionPath = regionFolder + etr.getKey();
zos.putNextEntry(new ZipEntry(regionPath));
zos.write(etr.getValue().getFile().getByteArray());
}
}
fileList = SYS.VFS.listVFiles((new VFile(worldFolder, "data")).getPath());
for(int k = 0, l = fileList.size(); k < l; ++k) {
VFile dataFile = fileList.get(k);
zos.putNextEntry(new ZipEntry(folderName + "/data/" + dataFile.getName()));
b = dataFile.getAllBytes();
zos.write(b);
prog += b.length;
if (prog - lastProgUpdate > 25000) {
lastProgUpdate = prog;
IntegratedServer.updateStatusString("selectWorld.progress.exporting.2", prog);
}
}
fileList = SYS.VFS.listVFiles((new VFile(worldFolder, "players")).getPath());
for(int k = 0, l = fileList.size(); k < l; ++k) {
VFile dataFile = fileList.get(k);
zos.putNextEntry(new ZipEntry(folderName + "/players/" + dataFile.getName()));
b = dataFile.getAllBytes();
zos.write(b);
prog += b.length;
if (prog - lastProgUpdate > 25000) {
lastProgUpdate = prog;
IntegratedServer.updateStatusString("selectWorld.progress.exporting.2", prog);
}
}
}
return bao.toByteArray();
}
private static byte[] inputStreamToBytesNoClose(InputStream is) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
byte[] buf = new byte[1024];
int i;
while ((i = is.read(buf)) != -1) {
os.write(buf, 0, i);
}
return os.toByteArray();
}
}

View File

@ -6,14 +6,8 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import net.lax1dude.eaglercraft.sp.IntegratedServer;
import net.lax1dude.eaglercraft.sp.SYS;
import net.lax1dude.eaglercraft.sp.SysUtil;
import net.lax1dude.eaglercraft.sp.VFSSaveHandler;
import net.lax1dude.eaglercraft.sp.VFile;
import net.lax1dude.eaglercraft.sp.WorkerListenThread;
import net.lax1dude.eaglercraft.EaglerAdapter;
import net.lax1dude.eaglercraft.sp.ipc.IPCPacket0DProgressUpdate;
import net.lax1dude.eaglercraft.sp.ipc.IPCPacket14StringList;
import net.minecraft.src.AxisAlignedBB;
import net.minecraft.src.ChunkCoordinates;
import net.minecraft.src.CommandBase;
@ -146,95 +140,14 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
* Typically "menu.convertingLevel", "menu.loadingLevel" or others.
*/
protected void setUserMessage(String par1Str) {
IntegratedServer.sendIPCPacket(new IPCPacket0DProgressUpdate(par1Str, 0.0f));
this.logInfo(par1Str);
this.userMessage = par1Str;
}
protected void setUserMessage(String par1Str, float prog) {
IntegratedServer.sendIPCPacket(new IPCPacket0DProgressUpdate(par1Str, prog));
this.logInfo(par1Str + ": " + (prog > 1.0f ? "" + (int)prog : "" + (int)(prog * 100.0f) + "%"));
this.userMessage = par1Str;
}
protected void loadAllWorlds(String par1Str, long par3, WorldSettings par5WorldType) {
this.setUserMessage("menu.loadingLevel");
this.worldServers = new WorldServer[3];
this.timeOfLastDimensionTick = new long[this.worldServers.length][100];
ISaveHandler var7 = new VFSSaveHandler(new VFile("worlds", par1Str));
WorldInfo var9 = var7.loadWorldInfo();
WorldSettings var8;
if (var9 == null) {
if(par5WorldType == null) {
throw new IllegalArgumentException("World '" + par1Str + "' does not exist and WorldSettings is null");
}
var8 = par5WorldType;
} else {
var8 = new WorldSettings(var9);
}
for (int var10 = 0; var10 < this.worldServers.length; ++var10) {
byte var11 = 0;
if (var10 == 1) {
var11 = -1;
}
if (var10 == 2) {
var11 = 1;
}
if (var10 == 0) {
this.worldServers[var10] = new WorldServer(this, var7, par1Str, var11, var8, this.getLogAgent());
} else {
this.worldServers[var10] = new WorldServerMulti(this, var7, par1Str, var11, var8, this.worldServers[0], this.getLogAgent());
}
this.worldServers[var10].addWorldAccess(new WorldManager(this, this.worldServers[var10]));
this.worldServers[var10].getWorldInfo().setGameType(this.getGameType());
this.serverConfigManager.setPlayerManager(this.worldServers);
}
this.setDifficultyForAllWorlds(this.getDifficulty());
this.setGameType(var8.getGameType());
this.initialWorldChunkLoad();
}
protected void initialWorldChunkLoad() {
int var5 = 0;
//this.setUserMessage("menu.generatingTerrain");
byte var6 = 0;
this.setUserMessage("Preparing start region for level " + var6);
// Removed 'spawn chunks' for performance, they are unnecessary
/*
WorldServer var7 = this.worldServers[var6];
ChunkCoordinates var8 = var7.getSpawnPoint();
long var9 = System.currentTimeMillis();
int prepareRadius = 64;
for (int var11 = -prepareRadius; var11 <= prepareRadius && this.isServerRunning(); var11 += 16) {
for (int var12 = -prepareRadius; var12 <= prepareRadius && this.isServerRunning(); var12 += 16) {
long var13 = System.currentTimeMillis();
if (var13 - var9 > 1000L) {
setUserMessage("Preparing spawn area", Math.min(var5 / 64.0f, 0.99f));
var9 = var13;
}
++var5;
var7.theChunkProviderServer.loadChunk(var8.posX + var11 >> 4, var8.posZ + var12 >> 4);
}
}
*/
this.clearCurrentTask();
}
public abstract boolean canStructuresSpawn();
public abstract EnumGameType getGameType();
@ -298,10 +211,6 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
if (!this.worldIsBeingDeleted) {
setUserMessage("Stopping server");
if (this.getNetworkThread() != null) {
this.getNetworkThread().stopListening();
}
if (this.serverConfigManager != null) {
this.getLogAgent().logInfo("Saving players");
this.serverConfigManager.saveAllPlayerData();
@ -344,10 +253,10 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
public void run() {
try {
if (this.startServer()) {
long var1 = SysUtil.steadyTimeMillis();
long var1 = EaglerAdapter.steadyTimeMillis();
for (long var50 = 0L; this.serverRunning; this.serverIsRunning = true) {
long var5 = SysUtil.steadyTimeMillis();
long var5 = EaglerAdapter.steadyTimeMillis();
long var7 = var5 - var1;
if (var7 > 2000L && var1 - this.timeOfLastWarning >= 15000L) {
@ -375,7 +284,7 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
}
}
SysUtil.sleep(1);
EaglerAdapter.sleep(1);
}
} else {
throw new RuntimeException("Server did not init correctly");
@ -384,7 +293,7 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
this.getLogAgent().logSevereException(
"Encountered an unexpected exception " + var48.getClass().getSimpleName(), var48);
var48.printStackTrace();
IntegratedServer.throwExceptionToClient("Encountered an unexpected exception", var48);
//IntegratedServer.throwExceptionToClient("Encountered an unexpected exception", var48);
} finally {
try {
this.stopServer();
@ -397,10 +306,6 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
}
}
protected VFile getDataDirectory() {
return new VFile(".");
}
/**
* Directly calls System.exit(0), instantly killing the program.
*/
@ -496,7 +401,6 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
this.timeOfLastDimensionTick[var1][this.tickCounter % 100] = System.nanoTime() - var2;
}
this.getNetworkThread().handleNetworkListenThread();
this.serverConfigManager.sendPlayerInfoToAllPlayers();
for (var1 = 0; var1 < this.playersOnline.size(); ++var1) {
@ -511,13 +415,6 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
public void func_82010_a(IUpdatePlayerListBox par1IUpdatePlayerListBox) {
this.playersOnline.add(par1IUpdatePlayerListBox);
}
/**
* Returns a File object from the specified string.
*/
public VFile getFile(String par1Str) {
return new VFile(folderName, par1Str);
}
/**
* Logs the message with a level of INFO.
@ -540,34 +437,6 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
return par1 == -1 ? this.worldServers[1] : (par1 == 1 ? this.worldServers[2] : this.worldServers[0]);
}
/**
* Returns the server's hostname.
*/
public String getHostname() {
return this.getServerHostname();
}
/**
* Never used, but "getServerPort" is already taken.
*/
public int getPort() {
return this.getServerPort();
}
/**
* Returns the server message of the day
*/
public String getMotd() {
return this.motd;
}
/**
* Returns the server's Minecraft version as string.
*/
public String getMinecraftVersion() {
return "1.5.2";
}
/**
* Returns the number of players currently on the server.
*/
@ -589,47 +458,7 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
return this.serverConfigManager.getAllUsernames();
}
/**
* Used by RCon's Query in the form of "MajorServerMod 1.2.3: MyPlugin 1.3;
* AnotherPlugin 2.1; AndSoForth 1.0".
*/
public String getPlugins() {
return "";
}
/**
* Handle a command received by an RCon instance
*/
public String handleRConCommand(String par1Str) {
return "fuck off";
}
/**
* Returns true if debugging is enabled, false otherwise.
*/
public boolean isDebuggingEnabled() {
return true;
}
/**
* Logs the error message with a level of SEVERE.
*/
public void logSevere(String par1Str) {
this.getLogAgent().logSevere(par1Str);
}
/**
* If isDebuggingEnabled(), logs the message with a level of INFO.
*/
public void logDebug(String par1Str) {
if (this.isDebuggingEnabled()) {
this.getLogAgent().logInfo(par1Str);
}
}
public String getServerModName() {
return "eaglercraft";
}
/**
* If par2Str begins with /, then it searches for commands, otherwise it returns
@ -701,13 +530,6 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
return par2Str.equals(this.getServerOwner());
}
/**
* Translates and formats the given string key with the given arguments.
*/
public String translateString(String par1Str, Object... par2ArrayOfObj) {
return StringTranslate.getInstance().translateKeyFormat(par1Str, par2ArrayOfObj);
}
public ICommandManager getCommandManager() {
return this.commandManager;
}
@ -719,10 +541,6 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
return 1;
}
public void setServerPort(int par1) {
throw new IllegalArgumentException("variable removed");
}
/**
* Returns the username of the server owner (for integrated servers)
*/
@ -730,25 +548,11 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
return this.serverOwner;
}
/**
* Sets the username of the owner of this server (in the case of an integrated
* server)
*/
public void setServerOwner(String par1Str) {
this.serverOwner = par1Str;
}
public boolean isSinglePlayer() {
return this.serverOwner != null;
}
public String getFolderName() {
return this.folderName;
}
public void setFolderName(String par1Str) {
this.folderName = par1Str;
}
public void setDifficultyForAllWorlds(int par1) {
for (int var2 = 0; var2 < this.worldServers.length; ++var2) {
@ -773,23 +577,6 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
return true;
}
/**
* Gets whether this is a demo or not.
*/
public boolean isDemo() {
return false;
}
/**
* Sets whether this is a demo or not.
*/
public void setDemo(boolean par1) {
throw new IllegalArgumentException("variable removed");
}
public void canCreateBonusChest(boolean par1) {
throw new IllegalArgumentException("variable removed");
}
/**
* WARNING : directly calls
@ -807,17 +594,6 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
}
String dir = this.worldServers[0].getSaveHandler().getWorldDirectoryName();
SYS.VFS.deleteFiles(dir);
String[] worldsTxt = SYS.VFS.getFile("worlds.txt").getAllLines();
if(worldsTxt != null) {
LinkedList<String> newWorlds = new LinkedList();
for(String str : worldsTxt) {
if(!str.equalsIgnoreCase(dir)) {
newWorlds.add(str);
}
}
SYS.VFS.getFile("worlds.txt").setAllChars(String.join("\n", newWorlds));
}
this.initiateShutdown();
}
@ -826,9 +602,6 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
return null;
}
public void setTexturePack(String par1Str) {
throw new IllegalArgumentException("variable removed");
}
/**
* This is checked to be 16 upon receiving the packet, otherwise the packet is
@ -840,71 +613,41 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
public abstract boolean isDedicatedServer();
public boolean isServerInOnlineMode() {
return false;
}
public void setOnlineMode(boolean par1) {
throw new IllegalArgumentException("variable removed");
}
public boolean getCanSpawnAnimals() {
return this.canSpawnAnimals;
}
public void setCanSpawnAnimals(boolean par1) {
this.canSpawnAnimals = par1;
}
public boolean getCanSpawnNPCs() {
return this.canSpawnNPCs;
}
public void setCanSpawnNPCs(boolean par1) {
this.canSpawnNPCs = par1;
}
public boolean isPVPEnabled() {
return this.pvpEnabled;
}
public void setAllowPvp(boolean par1) {
this.pvpEnabled = par1;
}
public boolean isFlightAllowed() {
return this.allowFlight;
}
public void setAllowFlight(boolean par1) {
this.allowFlight = par1;
}
/**
* Return whether command blocks are enabled.
*/
public abstract boolean isCommandBlockEnabled();
public String getMOTD() {
return this.motd;
}
public void setMOTD(String par1Str) {
this.motd = par1Str;
}
public int getBuildLimit() {
return 256;
}
public void setBuildLimit(int par1) {
throw new IllegalArgumentException("variable removed");
}
public boolean isServerStopped() {
return this.serverStopped;
}
public ServerConfigurationManager getConfigurationManager() {
return this.serverConfigManager;
}
@ -922,8 +665,6 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
}
}
public abstract WorkerListenThread getNetworkThread();
public boolean getGuiEnabled() {
return false;
}
@ -958,18 +699,4 @@ public abstract class MinecraftServer implements ICommandSender, Runnable {
public abstract ILogAgent getLogAgent();
public void func_104055_i(boolean par1) {
this.field_104057_T = par1;
}
public boolean func_104056_am() {
return this.field_104057_T;
}
/**
* Gets the current player count, maximum player count, and player entity list.
*/
public static ServerConfigurationManager getServerConfigurationManager(MinecraftServer par0MinecraftServer) {
return par0MinecraftServer.serverConfigManager;
}
}

View File

@ -1,7 +1,5 @@
package net.minecraft.src;
import net.lax1dude.eaglercraft.sp.VFile;
public interface ISaveHandler
{
/**
@ -39,11 +37,6 @@ public interface ISaveHandler
*/
void flush();
/**
* Gets the file location of the given map
*/
VFile getMapFileFromName(String var1);
/**
* Returns the name of the directory where world information is saved.
*/

View File

@ -13,7 +13,7 @@ public class ItemMap extends ItemMapBase
public static MapData getMPMapData(short par0, World par1World)
{
String var2 = "map_" + par0;
MapData var3 = (MapData)par1World.loadItemData((s) -> new MapData(s), var2);
MapData var3 = (MapData)par1World.loadItemData(MapData.class, var2);
if (var3 == null)
{
@ -27,7 +27,7 @@ public class ItemMap extends ItemMapBase
public MapData getMapData(ItemStack par1ItemStack, World par2World)
{
String var3 = "map_" + par1ItemStack.getItemDamage();
MapData var4 = (MapData)par2World.loadItemData((s) -> new MapData(s), var3);
MapData var4 = (MapData)par2World.loadItemData(MapData.class, var3);
if (var4 == null && !par2World.isRemote)
{

View File

@ -219,7 +219,7 @@ public abstract class MapGenStructure extends MapGenBase
{
if (this.field_143029_e == null)
{
this.field_143029_e = (MapGenStructureData)par1World.loadItemData((s) -> new MapGenStructureData(s), this.func_143025_a());
this.field_143029_e = (MapGenStructureData)par1World.loadItemData(MapGenStructure.class, this.func_143025_a());
if (this.field_143029_e == null)
{

View File

@ -1,14 +1,11 @@
package net.minecraft.src;
import net.lax1dude.eaglercraft.sp.VFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.io.*;
import java.util.*;
import java.util.function.Function;
public class MapStorage
{
private ISaveHandler saveHandler;
public class MapStorage {
/** Map of item data String id to loaded MapDataBases */
private Map loadedDataMap = new HashMap();
@ -17,73 +14,33 @@ public class MapStorage
private List loadedDataList = new ArrayList();
/**
* Map of MapDataBase id String prefixes ('map' etc) to max known unique Short id (the 0 part etc) for that prefix
* Map of MapDataBase id String prefixes ('map' etc) to max known unique Short
* id (the 0 part etc) for that prefix
*/
private Map idCounts = new HashMap();
public MapStorage(ISaveHandler par1ISaveHandler)
{
this.saveHandler = par1ISaveHandler;
this.loadIdCounts();
}
public MapStorage() // FIX THIS SHIT
{
this.saveHandler = null;
public MapStorage() {
this.loadIdCounts();
}
/**
* Loads an existing MapDataBase corresponding to the given String id from disk, instantiating the given Class, or
* returns null if none such file exists. args: Class to instantiate, String dataid
* Loads an existing MapDataBase corresponding to the given String id from disk,
* instantiating the given Class, or returns null if none such file exists.
* args: Class to instantiate, String dataid
*/
public WorldSavedData loadData(Function<String, WorldSavedData> par1Class, String par2Str) {
WorldSavedData var3 = (WorldSavedData) this.loadedDataMap.get(par2Str);
if (var3 != null) {
return var3;
} else {
if (this.saveHandler != null) {
try {
VFile var4 = this.saveHandler.getMapFileFromName(par2Str);
if (var4 != null && var4.exists()) {
try {
var3 = (WorldSavedData) par1Class.apply(par2Str);
} catch (Exception var7) {
throw new RuntimeException("Failed to instantiate " + par1Class.toString(), var7);
}
NBTTagCompound var6 = CompressedStreamTools.readCompressed(var4.getInputStream());
var3.readFromNBT(var6.getCompoundTag("data"));
}
} catch (Exception var8) {
var8.printStackTrace();
}
}
if (var3 != null) {
this.loadedDataMap.put(par2Str, var3);
this.loadedDataList.add(var3);
}
return var3;
}
public WorldSavedData loadData(Class par1Class, String par2Str) {
return (WorldSavedData) this.loadedDataMap.get(par2Str);
}
/**
* Assigns the given String id to the given MapDataBase, removing any existing ones of the same id.
* Assigns the given String id to the given MapDataBase, removing any existing
* ones of the same id.
*/
public void setData(String par1Str, WorldSavedData par2WorldSavedData)
{
if (par2WorldSavedData == null)
{
public void setData(String par1Str, WorldSavedData par2WorldSavedData) {
if (par2WorldSavedData == null) {
throw new RuntimeException("Can\'t set null data");
}
else
{
if (this.loadedDataMap.containsKey(par1Str))
{
} else {
if (this.loadedDataMap.containsKey(par1Str)) {
this.loadedDataList.remove(this.loadedDataMap.remove(par1Str));
}
@ -95,14 +52,11 @@ public class MapStorage
/**
* Saves all dirty loaded MapDataBases to disk.
*/
public void saveAllData()
{
for (int var1 = 0; var1 < this.loadedDataList.size(); ++var1)
{
WorldSavedData var2 = (WorldSavedData)this.loadedDataList.get(var1);
public void saveAllData() {
for (int var1 = 0; var1 < this.loadedDataList.size(); ++var1) {
WorldSavedData var2 = (WorldSavedData) this.loadedDataList.get(var1);
if (var2.isDirty())
{
if (var2.isDirty()) {
this.saveData(var2);
var2.setDirty(false);
}
@ -113,23 +67,7 @@ public class MapStorage
* Saves the given MapDataBase to disk.
*/
private void saveData(WorldSavedData par1WorldSavedData) {
if (this.saveHandler != null) {
try {
VFile var2 = this.saveHandler.getMapFileFromName(par1WorldSavedData.mapName);
if (var2 != null) {
NBTTagCompound var3 = new NBTTagCompound();
par1WorldSavedData.writeToNBT(var3);
NBTTagCompound var4 = new NBTTagCompound();
var4.setCompoundTag("data", var3);
OutputStream st = var2.getOutputStream();
CompressedStreamTools.writeCompressed(var4, st);
st.close();
}
} catch (Exception var6) {
var6.printStackTrace();
}
}
}
/**
@ -138,37 +76,14 @@ public class MapStorage
private void loadIdCounts() {
try {
this.idCounts.clear();
if (this.saveHandler == null) {
return;
}
VFile var1 = this.saveHandler.getMapFileFromName("idcounts");
if (var1 != null && var1.exists()) {
DataInputStream var2 = new DataInputStream(var1.getInputStream());
NBTTagCompound var3 = CompressedStreamTools.read(var2);
var2.close();
Iterator var4 = var3.getTags().iterator();
while (var4.hasNext()) {
NBTBase var5 = (NBTBase) var4.next();
if (var5 instanceof NBTTagShort) {
NBTTagShort var6 = (NBTTagShort) var5;
String var7 = var6.getName();
short var8 = var6.data;
this.idCounts.put(var7, Short.valueOf(var8));
}
}
}
} catch (Exception var9) {
var9.printStackTrace();
}
}
/**
* Returns an unique new data id for the given prefix and saves the idCounts map to the 'idcounts' file.
* Returns an unique new data id for the given prefix and saves the idCounts map
* to the 'idcounts' file.
*/
public int getUniqueDataId(String par1Str) {
Short var2 = (Short) this.idCounts.get(par1Str);
@ -181,32 +96,6 @@ public class MapStorage
this.idCounts.put(par1Str, var2);
if (this.saveHandler == null) {
return var2.shortValue();
} else {
try {
VFile var3 = this.saveHandler.getMapFileFromName("idcounts");
if (var3 != null) {
NBTTagCompound var4 = new NBTTagCompound();
Iterator var5 = this.idCounts.keySet().iterator();
while (var5.hasNext()) {
String var6 = (String) var5.next();
short var7 = ((Short) this.idCounts.get(var6)).shortValue();
var4.setShort(var6, var7);
}
OutputStream os = var3.getOutputStream();
DataOutputStream var9 = new DataOutputStream(os);
CompressedStreamTools.write(var4, var9);
os.close();
}
} catch (Exception var8) {
var8.printStackTrace();
}
return var2.shortValue();
}
return var2.shortValue();
}
}
}

View File

@ -1,242 +0,0 @@
package net.minecraft.src;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import net.lax1dude.eaglercraft.sp.EaglercraftRandom;
import net.lax1dude.eaglercraft.sp.WorkerNetworkManager;
import net.minecraft.server.MinecraftServer;
public class NetLoginHandler extends NetHandler {
/** The Random object used to generate serverId hex strings. */
private static EaglercraftRandom rand = new EaglercraftRandom();
/** Reference to the MinecraftServer object. */
private final MinecraftServer mcServer;
public final WorkerNetworkManager myTCPConnection;
/**
* Returns if the login handler is finished and can be removed. It is set to
* true on either error or successful login.
*/
public boolean finishedProcessing = false;
/** While waiting to login, if this field ++'s to 600 it will kick you. */
private int loginTimer = 0;
private String clientUsername = null;
private volatile boolean field_72544_i = false;
private boolean field_92079_k = false;
private int hash = 0;
private static int hashBase = 69696969;
private int viewDistance = 2;
public NetLoginHandler(MinecraftServer par1MinecraftServer, WorkerNetworkManager par2Socket) {
this.mcServer = par1MinecraftServer;
this.myTCPConnection = par2Socket;
hash = ++hashBase;
}
public boolean shouldBeRemoved() {
return this.finishedProcessing;
}
/**
* Logs the user in if a login packet is found, otherwise keeps processing
* network packets unless the timeout has occurred.
*/
public void handlePackets() {
System.out.println("[Server][LOGIN][HANDLE][" + clientUsername + "]");
if (this.field_72544_i) {
this.initializePlayerConnection();
return;
}
if (this.loginTimer++ == 600) {
this.kickUser("Took too long to log in");
} else {
this.myTCPConnection.processReadPackets();
}
}
public boolean equals(Object o) {
return (o instanceof NetLoginHandler) && ((NetLoginHandler)o).hash == hash;
}
public int hashCode() {
return hash;
}
/**
* Disconnects the user with the given reason.
*/
public void kickUser(String par1Str) {
try {
this.mcServer.getLogAgent().logInfo("Disconnecting " + this.getUsernameAndAddress() + ": " + par1Str);
this.myTCPConnection.addToSendQueue(new Packet255KickDisconnect(par1Str));
this.myTCPConnection.serverShutdown();
this.finishedProcessing = true;
} catch (Exception var3) {
var3.printStackTrace();
}
}
public void handleClientProtocol(Packet2ClientProtocol par1Packet2ClientProtocol) {
this.clientUsername = par1Packet2ClientProtocol.getUsername();
int var2 = 64 << 3 - par1Packet2ClientProtocol.getViewDistance();
if(var2 > 400) {
var2 = 400;
}
var2 = (var2 >> 5) + 2;
this.viewDistance = var2;
System.out.println("[Server][HANDSHAKE][" + this.clientUsername + "]");
if (!this.clientUsername.equals(StringUtils.stripControlCodes(this.clientUsername))) {
this.kickUser("Invalid username!");
} else {
if (par1Packet2ClientProtocol.getProtocolVersion() != 61) {
if (par1Packet2ClientProtocol.getProtocolVersion() > 61) {
this.kickUser("Outdated server!");
} else {
this.kickUser("Outdated client!");
}
}else {
this.initializePlayerConnection();
}
}
}
public void handleClientCommand(Packet205ClientCommand par1Packet205ClientCommand) {
if (par1Packet205ClientCommand.forceRespawn == 0) {
if (this.field_92079_k) {
this.kickUser("Duplicate login");
return;
}
this.field_92079_k = true;
this.field_72544_i = true;
}
}
public void handleLogin(Packet1Login par1Packet1Login) {
}
/**
* on success the specified username is connected to the minecraftInstance,
* otherwise they are packet255'd
*/
public void initializePlayerConnection() {
String var1 = this.mcServer.getConfigurationManager().allowUserToConnect(this.clientUsername);
if (var1 != null) {
this.kickUser(var1);
} else {
EntityPlayerMP var2 = this.mcServer.getConfigurationManager().createPlayerForUser(this.clientUsername);
if (var2 != null) {
if (this.mcServer.getServerOwner().equals(this.clientUsername)) {
var2.renderDistance = this.viewDistance;
} else {
EntityPlayerMP fard = this.mcServer.getConfigurationManager().getPlayerForUsername(this.mcServer.getServerOwner());
int maxRenderDistance = fard == null ? 10 : (fard.renderDistance > 10 ? 10 : fard.renderDistance);
var2.renderDistance = this.viewDistance > maxRenderDistance ? maxRenderDistance : this.viewDistance;
}
this.mcServer.getConfigurationManager().initializeConnectionToPlayer(this.myTCPConnection, var2);
}else {
this.kickUser("Could not construct EntityPlayerMP for '" + var1 + "'");
}
}
this.finishedProcessing = true;
}
public void handleErrorMessage(String par1Str, Object[] par2ArrayOfObj) {
this.mcServer.getLogAgent().logInfo(this.getUsernameAndAddress() + " lost connection");
this.finishedProcessing = true;
}
/**
* Handle a server ping packet.
*/
public void handleServerPing(Packet254ServerPing par1Packet254ServerPing) {
try {
ServerConfigurationManager var2 = this.mcServer.getConfigurationManager();
String var3 = null;
if (par1Packet254ServerPing.readSuccessfully == 1) {
List var4 = Arrays.asList(new Serializable[] { Integer.valueOf(1), Integer.valueOf(61),
this.mcServer.getMinecraftVersion(), this.mcServer.getMOTD(),
Integer.valueOf(var2.getCurrentPlayerCount()), Integer.valueOf(var2.getMaxPlayers()) });
Object var6;
for (Iterator var5 = var4.iterator(); var5
.hasNext(); var3 = var3 + var6.toString().replaceAll("\u0000", "")) {
var6 = var5.next();
if (var3 == null) {
var3 = "\u00a7";
} else {
var3 = var3 + "\u0000";
}
}
} else {
var3 = this.mcServer.getMOTD() + "\u00a7" + var2.getCurrentPlayerCount() + "\u00a7"
+ var2.getMaxPlayers();
}
this.myTCPConnection.addToSendQueue(new Packet255KickDisconnect(var3));
this.myTCPConnection.serverShutdown();
this.finishedProcessing = true;
} catch (Exception var7) {
var7.printStackTrace();
}
}
/**
* Default handler called for packets that don't have their own handlers in
* NetServerHandler; kicks player from the server.
*/
public void unexpectedPacket(Packet par1Packet) {
this.kickUser("Protocol error");
}
public String getUsernameAndAddress() {
return this.clientUsername + "[EAG]";
}
/**
* determine if it is a server handler
*/
public boolean isServerHandler() {
return true;
}
/**
* Returns the server Id randomly generated by this login handler.
*/
static String getServerId(NetLoginHandler par0NetLoginHandler) {
return "you eagler";
}
/**
* Returns the reference to Minecraft Server.
*/
static MinecraftServer getLoginMinecraftServer(NetLoginHandler par0NetLoginHandler) {
return par0NetLoginHandler.mcServer;
}
/**
* Returns the connecting client username.
*/
static String getClientUsername(NetLoginHandler par0NetLoginHandler) {
return par0NetLoginHandler.clientUsername;
}
static boolean func_72531_a(NetLoginHandler par0NetLoginHandler, boolean par1) {
return par0NetLoginHandler.field_72544_i = par1;
}
}

View File

@ -1,332 +0,0 @@
package net.minecraft.src;
import net.lax1dude.eaglercraft.EaglerAdapter;
import net.lax1dude.eaglercraft.sp.RandomAccessMemoryFile;
import net.minecraft.server.MinecraftServer;
import java.io.*;
import java.util.ArrayList;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;
public class RegionFile
{
private static final byte[] emptySector = new byte[4096];
private RandomAccessMemoryFile dataFile;
private final int[] offsets = new int[1024];
private final int[] chunkTimestamps = new int[1024];
private ArrayList sectorFree;
/** McRegion sizeDelta */
private int sizeDelta;
private long lastModified;
public RegionFile(RandomAccessMemoryFile par1File)
{
this.sizeDelta = 0;
try
{
this.dataFile = par1File;
int var2;
if (this.dataFile.getLength() < 4096L)
{
for (var2 = 0; var2 < 1024; ++var2)
{
this.dataFile.writeInt(0);
}
for (var2 = 0; var2 < 1024; ++var2)
{
this.dataFile.writeInt(0);
}
this.sizeDelta += 8192;
}
if ((this.dataFile.getLength() & 4095L) != 0L)
{
for (var2 = 0; (long)var2 < (this.dataFile.getLength() & 4095L); ++var2)
{
this.dataFile.write(0);
}
}
var2 = (int)this.dataFile.getLength() / 4096;
this.sectorFree = new ArrayList(var2);
int var3;
for (var3 = 0; var3 < var2; ++var3)
{
this.sectorFree.add(Boolean.valueOf(true));
}
this.sectorFree.set(0, Boolean.valueOf(false));
this.sectorFree.set(1, Boolean.valueOf(false));
this.dataFile.seek(0);
int var4;
for (var3 = 0; var3 < 1024; ++var3)
{
var4 = this.dataFile.readInt();
this.offsets[var3] = var4;
if (var4 != 0 && (var4 >> 8) + (var4 & 255) <= this.sectorFree.size())
{
for (int var5 = 0; var5 < (var4 & 255); ++var5)
{
this.sectorFree.set((var4 >> 8) + var5, Boolean.valueOf(false));
}
}
}
for (var3 = 0; var3 < 1024; ++var3)
{
var4 = this.dataFile.readInt();
this.chunkTimestamps[var3] = var4;
}
}
catch (IOException var6)
{
var6.printStackTrace();
}
}
/**
* args: x, y - get uncompressed chunk stream from the region file
*/
public synchronized DataInputStream getChunkDataInputStream(int par1, int par2) {
if (this.outOfBounds(par1, par2)) {
return null;
} else {
try {
int var3 = this.getOffset(par1, par2);
if (var3 == 0) {
return null;
} else {
int var4 = var3 >> 8;
int var5 = var3 & 255;
if (var4 + var5 > this.sectorFree.size()) {
return null;
} else {
this.dataFile.seek(var4 * 4096);
int var6 = this.dataFile.readInt();
if (var6 > 4096 * var5) {
return null;
} else if (var6 <= 0) {
return null;
} else {
byte var7 = this.dataFile.readByte();
byte[] var8;
if (var7 == 1) {
var8 = new byte[var6 - 1];
this.dataFile.read(var8);
return new DataInputStream(
new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(var8))));
} else if (var7 == 2) {
var8 = new byte[var6 - 1];
this.dataFile.read(var8);
return new DataInputStream(new BufferedInputStream(
new InflaterInputStream(new ByteArrayInputStream(var8))));
} else {
return null;
}
}
}
}
} catch (IOException var9) {
return null;
}
}
}
/**
* args: x, z - get an output stream used to write chunk data, data is on disk when the returned stream is closed
*/
public DataOutputStream getChunkDataOutputStream(int par1, int par2)
{
return this.outOfBounds(par1, par2) ? null : new DataOutputStream(new DeflaterOutputStream(new RegionFileChunkBuffer(this, par1, par2)));
}
/**
* args: x, z, data, length - write chunk data at (x, z) to disk
*/
protected synchronized void write(int par1, int par2, byte[] par3ArrayOfByte, int par4)
{
try
{
int var5 = this.getOffset(par1, par2);
int var6 = var5 >> 8;
int var7 = var5 & 255;
int var8 = (par4 + 5) / 4096 + 1;
if (var8 >= 256)
{
return;
}
if (var6 != 0 && var7 == var8)
{
this.write(var6, par3ArrayOfByte, par4);
}
else
{
int var9;
for (var9 = 0; var9 < var7; ++var9)
{
this.sectorFree.set(var6 + var9, Boolean.valueOf(true));
}
var9 = this.sectorFree.indexOf(Boolean.valueOf(true));
int var10 = 0;
int var11;
if (var9 != -1)
{
for (var11 = var9; var11 < this.sectorFree.size(); ++var11)
{
if (var10 != 0)
{
if (((Boolean)this.sectorFree.get(var11)).booleanValue())
{
++var10;
}
else
{
var10 = 0;
}
}
else if (((Boolean)this.sectorFree.get(var11)).booleanValue())
{
var9 = var11;
var10 = 1;
}
if (var10 >= var8)
{
break;
}
}
}
if (var10 >= var8)
{
var6 = var9;
this.setOffset(par1, par2, var9 << 8 | var8);
for (var11 = 0; var11 < var8; ++var11)
{
this.sectorFree.set(var6 + var11, Boolean.valueOf(false));
}
this.write(var6, par3ArrayOfByte, par4);
}
else
{
this.dataFile.seek(this.dataFile.getLength());
var6 = this.sectorFree.size();
for (var11 = 0; var11 < var8; ++var11)
{
this.dataFile.write(emptySector);
this.sectorFree.add(Boolean.valueOf(false));
}
this.sizeDelta += 4096 * var8;
this.write(var6, par3ArrayOfByte, par4);
this.setOffset(par1, par2, var6 << 8 | var8);
}
}
this.setChunkTimestamp(par1, par2, (int)(EaglerAdapter.steadyTimeMillis() / 1000L));
}
catch (IOException var12)
{
var12.printStackTrace();
}
}
/**
* args: sectorNumber, data, length - write the chunk data to this RegionFile
*/
private void write(int par1, byte[] par2ArrayOfByte, int par3) throws IOException
{
this.dataFile.seek(par1 * 4096);
this.dataFile.writeInt(par3 + 1);
this.dataFile.writeByte(2);
this.dataFile.write(par2ArrayOfByte, 0, par3);
}
/**
* args: x, z - check region bounds
*/
private boolean outOfBounds(int par1, int par2)
{
return par1 < 0 || par1 >= 32 || par2 < 0 || par2 >= 32;
}
/**
* args: x, y - get chunk's offset in region file
*/
private int getOffset(int par1, int par2)
{
return this.offsets[par1 + par2 * 32];
}
/**
* args: x, z, - true if chunk has been saved / converted
*/
public boolean isChunkSaved(int par1, int par2)
{
return this.getOffset(par1, par2) != 0;
}
/**
* args: x, z, offset - sets the chunk's offset in the region file
*/
private void setOffset(int par1, int par2, int par3) throws IOException
{
this.offsets[par1 + par2 * 32] = par3;
this.dataFile.seek((par1 + par2 * 32) * 4);
this.dataFile.writeInt(par3);
}
/**
* args: x, z, timestamp - sets the chunk's write timestamp
*/
private void setChunkTimestamp(int par1, int par2, int par3) throws IOException
{
this.chunkTimestamps[par1 + par2 * 32] = par3;
this.dataFile.seek(4096 + (par1 + par2 * 32) * 4);
this.dataFile.writeInt(par3);
}
public RandomAccessMemoryFile getFile() {
return dataFile;
}
class ChunkBuffer extends ByteArrayOutputStream {
private int chunkX;
private int chunkZ;
public ChunkBuffer(int x, int z) {
super(8096);
this.chunkX = x;
this.chunkZ = z;
}
/**+
* close this RegionFile and prevent further writes
*/
public void close() throws IOException {
RegionFile.this.write(this.chunkX, this.chunkZ, this.buf, this.count);
}
}
}

View File

@ -1,25 +0,0 @@
package net.minecraft.src;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
class RegionFileChunkBuffer extends ByteArrayOutputStream
{
private int chunkX;
private int chunkZ;
final RegionFile regionFile;
public RegionFileChunkBuffer(RegionFile par1RegionFile, int par2, int par3)
{
super(8096);
this.regionFile = par1RegionFile;
this.chunkX = par2;
this.chunkZ = par3;
}
public void close() throws IOException
{
this.regionFile.write(this.chunkX, this.chunkZ, this.buf, this.count);
}
}

View File

@ -1,66 +0,0 @@
package net.minecraft.src;
import net.lax1dude.eaglercraft.sp.VFile;
public class SaveHandlerMP implements ISaveHandler
{
/**
* Loads and returns the world info
*/
public WorldInfo loadWorldInfo()
{
return null;
}
/**
* Checks the session lock to prevent save collisions
*/
public void checkSessionLock() throws MinecraftException {}
/**
* Returns the chunk loader with the provided world provider
*/
public IChunkLoader getChunkLoader(WorldProvider par1WorldProvider)
{
return null;
}
/**
* Saves the given World Info with the given NBTTagCompound as the Player.
*/
public void saveWorldInfoWithPlayer(WorldInfo par1WorldInfo, NBTTagCompound par2NBTTagCompound) {}
/**
* Saves the passed in world info.
*/
public void saveWorldInfo(WorldInfo par1WorldInfo) {}
/**
* returns null if no saveHandler is relevent (eg. SMP)
*/
public IPlayerFileData getSaveHandler()
{
return null;
}
/**
* Called to flush all changes to disk, waiting for them to complete.
*/
public void flush() {}
/**
* Gets the file location of the given map
*/
public VFile getMapFileFromName(String par1Str)
{
return null;
}
/**
* Returns the name of the directory where world information is saved.
*/
public String getWorldDirectoryName()
{
return "none";
}
}

View File

@ -143,8 +143,8 @@ public abstract class World implements IBlockAccess
this.saveHandler = par1ISaveHandler;
this.worldInfo = new WorldInfo(par4WorldSettings, par2Str);
this.provider = par3WorldProvider;
this.mapStorage = new MapStorage(par1ISaveHandler);
VillageCollection var7 = (VillageCollection) this.mapStorage.loadData((s) -> new VillageCollection(s), "villages");
this.mapStorage = new MapStorage();
VillageCollection var7 = (VillageCollection) this.mapStorage.loadData(VillageCollection.class, "villages");
if (var7 == null)
{
@ -168,7 +168,7 @@ public abstract class World implements IBlockAccess
this.ambientTickCountdown = this.rand.nextInt(12000);
this.lightUpdateBlockList = new int[32768];
this.saveHandler = par1ISaveHandler;
this.mapStorage = new MapStorage(par1ISaveHandler);
this.mapStorage = new MapStorage();
this.worldInfo = par1ISaveHandler.loadWorldInfo();
if (par4WorldProvider != null)
@ -203,7 +203,7 @@ public abstract class World implements IBlockAccess
this.worldInfo.setServerInitialized(true);
}
VillageCollection var7 = (VillageCollection) this.mapStorage.loadData((s) -> new VillageCollection(s), "villages");
VillageCollection var7 = (VillageCollection) this.mapStorage.loadData(VillageCollection.class, "villages");
if (var7 == null)
{
@ -3899,7 +3899,7 @@ public abstract class World implements IBlockAccess
* Loads an existing MapDataBase corresponding to the given String id from disk using the MapStorage, instantiating
* the given Class, or returns null if none such file exists. args: Class to instantiate, String dataid
*/
public WorldSavedData loadItemData(Function<String, WorldSavedData> par1Class, String par2Str) {
public WorldSavedData loadItemData(Class par1Class, String par2Str) {
return this.mapStorage.loadData(par1Class, par2Str);
}

View File

@ -32,7 +32,7 @@ public class WorldClient extends World
public WorldClient(NetClientHandler par1NetClientHandler, WorldSettings par2WorldSettings, int par3, int par4)
{
super(new SaveHandlerMP(), "MpServer", WorldProvider.getProviderForDimension(par3), par2WorldSettings);
super(null, "MpServer", WorldProvider.getProviderForDimension(par3), par2WorldSettings);
this.sendQueue = par1NetClientHandler;
this.difficultySetting = par4;
this.setSpawnLocation(8, 64, 8);

View File

@ -1,7 +1,7 @@
package net.minecraft.src;
import net.lax1dude.eaglercraft.EaglerAdapter;
import net.lax1dude.eaglercraft.EaglercraftRandom;
import net.lax1dude.eaglercraft.sp.SysUtil;
import net.minecraft.server.MinecraftServer;
import java.util.*;
@ -84,7 +84,7 @@ public class WorldServer extends World
this.worldTeleporter = new Teleporter(this);
this.worldScoreboard = new ServerScoreboard(par1MinecraftServer);
ScoreboardSaveData var8 = (ScoreboardSaveData) this.mapStorage.loadData((s) -> new ScoreboardSaveData(s), "scoreboard");
ScoreboardSaveData var8 = (ScoreboardSaveData) this.mapStorage.loadData(ScoreboardSaveData.class, "scoreboard");
if (var8 == null)
{
@ -155,7 +155,7 @@ public class WorldServer extends World
_lu += Chunk.totalBlockLightUpdates;
Chunk.totalBlockLightUpdates = 0;
long millis = SysUtil.steadyTimeMillis();
long millis = EaglerAdapter.steadyTimeMillis();
if(millis - rwgtuluTimer >= 1000l) {
rwgtuluTimer = millis;
r = _r; _r = 0;

View File

@ -22,13 +22,9 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import net.lax1dude.eaglercraft.sp.WorkerNetworkManager;
import org.json.JSONObject;
import org.teavm.interop.Async;
import org.teavm.interop.AsyncCallback;
@ -76,8 +72,6 @@ import org.teavm.jso.webaudio.DecodeSuccessCallback;
import org.teavm.jso.webaudio.GainNode;
import org.teavm.jso.webaudio.MediaElementAudioSourceNode;
import org.teavm.jso.webaudio.MediaEvent;
import org.teavm.jso.webaudio.MediaStream;
import org.teavm.jso.webaudio.MediaStreamAudioSourceNode;
import org.teavm.jso.webaudio.PannerNode;
import org.teavm.jso.webgl.WebGLBuffer;
import org.teavm.jso.webgl.WebGLFramebuffer;