added server source and VFS and IPC

This commit is contained in:
LAX1DUDE 2022-02-16 17:54:12 -08:00
parent 21d4f39927
commit 63889aa632
1167 changed files with 142749 additions and 1 deletions

4
.gitignore vendored
View File

@ -13,3 +13,7 @@ stable-download/java/spigot_command/world_the_end/*
stable-download/java/spigot_command/server.log
stable-download/java/bungee_command/proxy*
lwjgl-rundir/_eagstorage*
sp-server/.gradle
sp-server/.settings
sp-server/build
sp-server/bin

15666
javascript/classes_server.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,16 @@
<html>
<head>
<title>eaglercraft server</title>
<script type="text/javascript" src="classes_server.js"></script>
<script type="text/javascript">
window.addEventListener("load", function() {
document.getElementById("main").addEventListener("click", function() {
main();
});
});
</script>
</head>
<body>
<button id="main">main</button>
</body>
</html>

13
sp-server/.classpath Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="bin/main" path="src/main/java">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src/ipc/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>

23
sp-server/.project Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>eaglercraft-sp-server</name>
<comment>Project sp-server created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
</projectDescription>

110
sp-server/build.gradle Normal file
View File

@ -0,0 +1,110 @@
buildscript {
repositories {
flatDir {
dirs "deps"
}
}
dependencies {
classpath name: "gson-2.2.4"
classpath name: "joda-time-2.7"
classpath name: "jzlib-1.1.3"
classpath name: "teavm-classlib-0.7.0-SNAPSHOT"
classpath name: "teavm-interop-0.7.0-SNAPSHOT"
classpath name: "teavm-jso-0.7.0-SNAPSHOT"
classpath name: "teavm-jso-apis-0.7.0-SNAPSHOT"
classpath name: "teavm-jso-impl-0.7.0-SNAPSHOT"
classpath name: "teavm-platform-0.7.0-SNAPSHOT"
classpath name: "teavm-metaprogramming-api-0.7.0-SNAPSHOT"
classpath name: "teavm-metaprogramming-impl-0.7.0-SNAPSHOT"
classpath name: "teavm-core-0.7.0-SNAPSHOT"
classpath name: "teavm-tooling-0.7.0-SNAPSHOT"
classpath name: "teavm-cli-0.6.1"
classpath name: "teavm-gradle-plugin-1.0.0-patched"
}
}
apply plugin: "java"
apply plugin: "eclipse"
apply plugin: "io.github.zebalu.teavm-gradle-plugin"
sourceCompatibility = 1.8
targetCompatibility = 1.8
sourceSets {
main {
java {
srcDir "src/main/java"
srcDir "src/ipc/java"
}
}
}
repositories {
flatDir {
dirs "deps"
}
}
dependencies {
implementation name: "gson-2.2.4"
implementation name: "joda-time-2.7"
implementation name: "jzlib-1.1.3"
implementation name: "teavm-classlib-0.7.0-SNAPSHOT"
implementation name: "teavm-interop-0.7.0-SNAPSHOT"
implementation name: "teavm-jso-0.7.0-SNAPSHOT"
implementation name: "teavm-jso-apis-0.7.0-SNAPSHOT"
implementation name: "teavm-jso-impl-0.7.0-SNAPSHOT"
implementation name: "teavm-platform-0.7.0-SNAPSHOT"
implementation name: "teavm-metaprogramming-api-0.7.0-SNAPSHOT"
implementation name: "teavm-metaprogramming-impl-0.7.0-SNAPSHOT"
}
teavm {
compileScopes = null;
minifying = false;
maxTopLevelNames = 10000;
properties = null;
debugInformationGenerated = false;
sourceMapsGenerated = false;
sourceFilesCopied = false;
incremental = false;
transformers = null;
/** Where to save the result */
targetDirectory = file("../javascript");
/** The directory to monitor to decide if compile is up-to-date or not */
sourceDirectory = file("src");
/** How to name the result file. */
targetFileName = "classes_server.js";
/** Which class holds your public static void main(Strin[] args) method */
mainClass = "net.lax1dude.eaglercraft.sp.IntegratedServer";
/** This will be the name of your main method after compilation. */
entryPointName = "main";
classesToPreserve = null;
stopOnErrors = false;
optimizationLevel = "FULL"; //org.teavm.vm.TeaVMOptimizationLevel.SIMPLE;
fastGlobalAnalysis = false;
targetType = "JAVASCRIPT"; //org.teavm.tooling.TeaVMTargetType.JAVASCRIPT;
cacheDirectory = null;
wasmVersion = "V_0x1"; //org.teavm.backend.wasm.render.WasmBinaryVersion.V_0x1;
minHeapSize = 4;
maxHeapSize = 128;
outOfProcess = false;
processMemory = 512;
longjmpSupported = true;
heapDump = false;
/** Add name of configurations here where to look for jarfiles. */
includeJarsFrom = [];
/** By default teavmc taskd epends on javaCompile task, unless this varaibale is true. */
skipJavaCompile = false;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

12
sp-server/settings.gradle Normal file
View File

@ -0,0 +1,12 @@
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
*
* Detailed information about configuring a multi-project build in Gradle can be found
* in the user manual at https://docs.gradle.org/6.0/userguide/multi_project_builds.html
*/
rootProject.name = 'eaglercraft-sp-server'
// you eagler

View File

@ -0,0 +1,44 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.IOException;
import java.io.InputStream;
class IPCInputStream extends InputStream {
private byte[] currentBuffer = null;
private int idx = 0;
private String errorName = null;
void feedBuffer(byte[] b) {
currentBuffer = b;
idx = 0;
errorName = null;
}
void nameBuffer(String str) {
errorName = str;
}
@Override
public int read() throws IOException {
try {
return ((int)currentBuffer[++idx]) & 0xFF;
}catch(ArrayIndexOutOfBoundsException a) {
throw new IOException("IPCInputStream buffer underflow" + (errorName == null ? "" : (" while deserializing '" + errorName + "'")), a);
}
}
@Override
public int read(byte b[], int off, int len) throws IOException {
if(idx + len > currentBuffer.length) {
throw new IOException("IPCInputStream buffer underflow" + (errorName == null ? "" : (" while deserializing '" + errorName + "'")), new ArrayIndexOutOfBoundsException(idx + len - 1));
}
if(off + len > b.length) {
throw new ArrayIndexOutOfBoundsException(off + len - 1);
}
System.arraycopy(b, off, currentBuffer, idx, len);
idx += len;
return 0;
}
}

View File

@ -0,0 +1,55 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.IOException;
import java.io.OutputStream;
class IPCOutputStream extends OutputStream {
private String className = null;
private byte[] currentBuffer = null;
private int idx = 0;
private int originalSize = 0;
void feedBuffer(byte[] buf, String clazzName) {
currentBuffer = buf;
idx = 0;
originalSize = buf.length;
className = clazzName;
}
byte[] returnBuffer() {
if(className != null && currentBuffer.length != originalSize) {
System.err.println("WARNING: Packet '" + className + "' was supposed to be " + originalSize + " bytes but buffer has grown by " + (currentBuffer.length - originalSize) + " to " + currentBuffer.length + " bytes");
}
return currentBuffer;
}
void growBuffer(int i) {
int ii = currentBuffer.length;
int iii = i - ii;
if(iii > 0) {
byte[] n = new byte[i];
System.arraycopy(currentBuffer, 0, n, 0, ii);
currentBuffer = n;
}
}
@Override
public void write(int b) throws IOException {
if(idx >= currentBuffer.length) {
growBuffer(idx + 1);
}
currentBuffer[idx] = (byte) b;
++idx;
}
@Override
public void write(byte b[], int off, int len) throws IOException {
if(idx + len > currentBuffer.length) {
growBuffer(idx + len);
}
System.arraycopy(b, off, currentBuffer, idx, len);
idx += len;
}
}

View File

@ -0,0 +1,40 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket00StartServer implements IPCPacketBase {
public static final int ID = 0x00;
public String worldName;
public IPCPacket00StartServer() {
}
public IPCPacket00StartServer(String worldName) {
this.worldName = worldName;
}
@Override
public void deserialize(DataInput bin) throws IOException {
worldName = bin.readUTF();
}
@Override
public void serialize(DataOutput bin) throws IOException {
bin.writeUTF(worldName);
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return IPCPacketBase.strLen(worldName);
}
}

View File

@ -0,0 +1,32 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket01StopServer implements IPCPacketBase {
public static final int ID = 0x01;
public IPCPacket01StopServer() {
}
@Override
public void deserialize(DataInput bin) throws IOException {
}
@Override
public void serialize(DataOutput bin) throws IOException {
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return 0;
}
}

View File

@ -0,0 +1,68 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket02InitWorld implements IPCPacketBase {
public static final int ID = 0x02;
public String worldName;
public byte gamemode;
public byte worldType;
public String worldArgs;
public long seed;
public boolean cheats;
public boolean structures;
public boolean bonusChest;
public IPCPacket02InitWorld() {
}
public IPCPacket02InitWorld(String worldName, byte gamemode, byte worldType, String worldArgs, long seed, boolean cheats, boolean structures, boolean bonusChest) {
this.worldName = worldName;
this.gamemode = gamemode;
this.worldType = worldType;
this.worldArgs = worldArgs;
this.seed = seed;
this.cheats = cheats;
this.structures = structures;
this.bonusChest = bonusChest;
}
@Override
public void deserialize(DataInput bin) throws IOException {
worldName = bin.readUTF();
gamemode = bin.readByte();
worldType = bin.readByte();
worldArgs = bin.readUTF();
seed = bin.readLong();
cheats = bin.readBoolean();
structures = bin.readBoolean();
bonusChest = bin.readBoolean();
}
@Override
public void serialize(DataOutput bin) throws IOException {
bin.writeUTF(worldName);
bin.writeByte(gamemode);
bin.writeByte(worldType);
bin.writeUTF(worldArgs);
bin.writeLong(seed);
bin.writeBoolean(cheats);
bin.writeBoolean(structures);
bin.writeBoolean(bonusChest);
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return IPCPacketBase.strLen(worldName) + 1 + 1 + IPCPacketBase.strLen(worldArgs) + 8 + 1 + 1 + 1;
}
}

View File

@ -0,0 +1,40 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket03DeleteWorld implements IPCPacketBase {
public static final int ID = 0x03;
public String worldName;
public IPCPacket03DeleteWorld() {
}
public IPCPacket03DeleteWorld(String worldName) {
this.worldName = worldName;
}
@Override
public void deserialize(DataInput bin) throws IOException {
worldName = bin.readUTF();
}
@Override
public void serialize(DataOutput bin) throws IOException {
bin.writeUTF(worldName);
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return IPCPacketBase.strLen(worldName);
}
}

View File

@ -0,0 +1,48 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket04RenameWorld implements IPCPacketBase {
public static final int ID = 0x04;
public String worldOldName;
public String worldNewName;
public boolean copy;
public IPCPacket04RenameWorld() {
}
public IPCPacket04RenameWorld(String worldOldName, String worldNewName, boolean copy) {
this.worldOldName = worldOldName;
this.worldNewName = worldNewName;
this.copy = copy;
}
@Override
public void deserialize(DataInput bin) throws IOException {
worldOldName = bin.readUTF();
worldNewName = bin.readUTF();
copy = bin.readBoolean();
}
@Override
public void serialize(DataOutput bin) throws IOException {
bin.writeUTF(worldOldName);
bin.writeUTF(worldNewName);
bin.writeBoolean(copy);
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return IPCPacketBase.strLen(worldOldName) + IPCPacketBase.strLen(worldNewName) + 1;
}
}

View File

@ -0,0 +1,48 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket05RequestData implements IPCPacketBase {
public static final int ID = 0x05;
public static final byte REQUEST_LEVEL_DAT = 0x00;
public static final byte REQUEST_LEVEL_EAG = 0x01;
public static final byte REQUEST_LEVEL_MCA = 0x02;
public String worldName;
public byte request;
public IPCPacket05RequestData() {
}
public IPCPacket05RequestData(String worldName, byte request) {
this.worldName = worldName;
this.request = request;
}
@Override
public void deserialize(DataInput bin) throws IOException {
worldName = bin.readUTF();
request = bin.readByte();
}
@Override
public void serialize(DataOutput bin) throws IOException {
bin.writeUTF(worldName);
bin.writeByte(request);
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return IPCPacketBase.strLen(worldName) + 1;
}
}

View File

@ -0,0 +1,46 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket07ImportWorld implements IPCPacketBase {
public static final int ID = 0x07;
public String worldName;
public byte[] worldData;
public IPCPacket07ImportWorld() {
}
public IPCPacket07ImportWorld(String worldName, byte[] worldData, byte worldFormat) {
this.worldName = worldName;
this.worldData = worldData;
}
@Override
public void deserialize(DataInput bin) throws IOException {
worldName = bin.readUTF();
worldData = new byte[bin.readInt()];
bin.readFully(worldData);
}
@Override
public void serialize(DataOutput bin) throws IOException {
bin.writeUTF(worldName);
bin.writeInt(worldData.length);
bin.write(worldData);
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return IPCPacketBase.strLen(worldName) + worldData.length + 4;
}
}

View File

@ -0,0 +1,42 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket09RequestResponse implements IPCPacketBase {
public static final int ID = 0x09;
public byte[] response;
public IPCPacket09RequestResponse() {
}
public IPCPacket09RequestResponse(byte[] dat) {
this.response = dat;
}
@Override
public void deserialize(DataInput bin) throws IOException {
response = new byte[bin.readInt()];
bin.readFully(response);
}
@Override
public void serialize(DataOutput bin) throws IOException {
bin.writeInt(response.length);
bin.write(response);
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return 4 + response.length;
}
}

View File

@ -0,0 +1,40 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket0ASetWorldDifficulty implements IPCPacketBase {
public static final int ID = 0x0A;
public byte difficulty;
public IPCPacket0ASetWorldDifficulty() {
}
public IPCPacket0ASetWorldDifficulty(byte difficulty) {
this.difficulty = difficulty;
}
@Override
public void deserialize(DataInput bin) throws IOException {
difficulty = bin.readByte();
}
@Override
public void serialize(DataOutput bin) throws IOException {
bin.writeByte(difficulty);
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return 1;
}
}

View File

@ -0,0 +1,40 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket0BPause implements IPCPacketBase {
public static final int ID = 0x0B;
public boolean pause;
public IPCPacket0BPause() {
}
public IPCPacket0BPause(boolean pause) {
this.pause = pause;
}
@Override
public void deserialize(DataInput bin) throws IOException {
pause = bin.readBoolean();
}
@Override
public void serialize(DataOutput bin) throws IOException {
bin.writeBoolean(pause);
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return 1;
}
}

View File

@ -0,0 +1,44 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket0CPlayerChannel implements IPCPacketBase {
public static final int ID = 0x0C;
public String channel;
public boolean open;
public IPCPacket0CPlayerChannel() {
}
public IPCPacket0CPlayerChannel(String channel, boolean open) {
this.channel = channel;
this.open = open;
}
@Override
public void deserialize(DataInput bin) throws IOException {
channel = bin.readUTF();
open = bin.readBoolean();
}
@Override
public void serialize(DataOutput bin) throws IOException {
bin.writeUTF(channel);
bin.writeBoolean(open);
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return IPCPacketBase.strLen(channel) + 1;
}
}

View File

@ -0,0 +1,44 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket0DProgressUpdate implements IPCPacketBase {
public static final int ID = 0x0D;
public String updateMessage;
public float updateProgress;
public IPCPacket0DProgressUpdate() {
}
public IPCPacket0DProgressUpdate(String updateMessage, float updateProgress) {
this.updateMessage = updateMessage == null ? "" : updateMessage;
this.updateProgress = updateProgress;
}
@Override
public void deserialize(DataInput bin) throws IOException {
updateMessage = bin.readUTF();
updateProgress = bin.readFloat();
}
@Override
public void serialize(DataOutput bin) throws IOException {
bin.writeUTF(updateMessage);
bin.writeFloat(updateProgress);
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return IPCPacketBase.strLen(updateMessage) + 4;
}
}

View File

@ -0,0 +1,32 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket0EListWorlds implements IPCPacketBase {
public static final int ID = 0x0E;
public IPCPacket0EListWorlds() {
}
@Override
public void deserialize(DataInput bin) throws IOException {
}
@Override
public void serialize(DataOutput bin) throws IOException {
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return 0;
}
}

View File

@ -0,0 +1,40 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket0FListFiles implements IPCPacketBase {
public static final int ID = 0x0F;
public String path;
public IPCPacket0FListFiles() {
}
public IPCPacket0FListFiles(String path) {
this.path = path;
}
@Override
public void deserialize(DataInput bin) throws IOException {
this.path = bin.readUTF();
}
@Override
public void serialize(DataOutput bin) throws IOException {
bin.writeUTF(path);
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return IPCPacketBase.strLen(path);
}
}

View File

@ -0,0 +1,40 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket10FileRead implements IPCPacketBase {
public static final int ID = 0x10;
public String file;
public IPCPacket10FileRead() {
}
public IPCPacket10FileRead(String file) {
this.file = file;
}
@Override
public void deserialize(DataInput bin) throws IOException {
file = bin.readUTF();
}
@Override
public void serialize(DataOutput bin) throws IOException {
bin.writeUTF(file);
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return IPCPacketBase.strLen(file);
}
}

View File

@ -0,0 +1,44 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket12FileWrite implements IPCPacketBase {
public static final int ID = 0x12;
public String path;
public byte[] data;
public IPCPacket12FileWrite() {
}
public IPCPacket12FileWrite(String path, byte[] data) {
this.path = path;
this.data = data;
}
@Override
public void deserialize(DataInput bin) throws IOException {
path = bin.readUTF();
}
@Override
public void serialize(DataOutput bin) throws IOException {
bin.writeUTF(path);
bin.writeInt(data.length);
bin.write(data);
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return IPCPacketBase.strLen(path) + 4 + data.length;
}
}

View File

@ -0,0 +1,48 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacket13FileCopyMove implements IPCPacketBase {
public static final int ID = 0x13;
public String fileOldName;
public String fileNewName;
public boolean copy;
public IPCPacket13FileCopyMove() {
}
public IPCPacket13FileCopyMove(String fileOldName, String fileNewName, boolean copy) {
this.fileOldName = fileOldName;
this.fileNewName = fileNewName;
this.copy = copy;
}
@Override
public void deserialize(DataInput bin) throws IOException {
fileOldName = bin.readUTF();
fileNewName = bin.readUTF();
copy = bin.readBoolean();
}
@Override
public void serialize(DataOutput bin) throws IOException {
bin.writeUTF(fileOldName);
bin.writeUTF(fileNewName);
bin.writeBoolean(copy);
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return IPCPacketBase.strLen(fileOldName) + IPCPacketBase.strLen(fileNewName) + 1;
}
}

View File

@ -0,0 +1,59 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class IPCPacket14StringList implements IPCPacketBase {
public static final int ID = 0x14;
public final List<String> stringList;
public IPCPacket14StringList() {
stringList = new ArrayList();
}
public IPCPacket14StringList(String[] list) {
stringList = Arrays.asList(list);
}
public IPCPacket14StringList(List<String> list) {
stringList = list;
}
@Override
public void deserialize(DataInput bin) throws IOException {
stringList.clear();
int len = bin.readInt();
for(int i = 0; i < len; ++i) {
stringList.add(bin.readUTF());
}
}
@Override
public void serialize(DataOutput bin) throws IOException {
bin.writeInt(stringList.size());
for(String str : stringList) {
bin.writeUTF(str);
}
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
int len = 4;
for(String str : stringList) {
len += IPCPacketBase.strLen(str);
}
return len;
}
}

View File

@ -0,0 +1,32 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public interface IPCPacketBase {
public void deserialize(DataInput bin) throws IOException;
public void serialize(DataOutput bin) throws IOException;
public int id();
public int size();
public static int strLen(String s) {
int count = 0;
for (int i = 0, len = s.length(); i < len; i++) {
char ch = s.charAt(i);
if (ch <= 0x7F) {
count++;
} else if (ch <= 0x7FF) {
count += 2;
} else if (Character.isHighSurrogate(ch)) {
count += 4;
++i;
} else {
count += 3;
}
}
return count + 2;
}
}

View File

@ -0,0 +1,32 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class IPCPacketFFProcessKeepAlive implements IPCPacketBase {
public static final int ID = 0xFF;
public IPCPacketFFProcessKeepAlive() {
}
@Override
public void deserialize(DataInput bin) throws IOException {
}
@Override
public void serialize(DataOutput bin) throws IOException {
}
@Override
public int id() {
return ID;
}
@Override
public int size() {
return 0;
}
}

View File

@ -0,0 +1,75 @@
package net.lax1dude.eaglercraft.sp.ipc;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
public class IPCPacketManager {
public static final HashMap<Integer, Class<? extends IPCPacketBase>> mappings = new HashMap();
public static final IPCInputStream IPC_INPUT_STREAM = new IPCInputStream();
public static final IPCOutputStream IPC_OUTPUT_STREAM = new IPCOutputStream();
public static final DataInputStream IPC_DATA_INPUT_STREAM = new DataInputStream(IPC_INPUT_STREAM);
public static final DataOutputStream IPC_DATA_OUTPUT_STREAM = new DataOutputStream(IPC_OUTPUT_STREAM);
static {
mappings.put(IPCPacket00StartServer.ID, IPCPacket00StartServer.class);
mappings.put(IPCPacket01StopServer.ID, IPCPacket01StopServer.class);
mappings.put(IPCPacket02InitWorld.ID, IPCPacket02InitWorld.class);
mappings.put(IPCPacket03DeleteWorld.ID, IPCPacket03DeleteWorld.class);
mappings.put(IPCPacket04RenameWorld.ID, IPCPacket04RenameWorld.class);
mappings.put(IPCPacket05RequestData.ID, IPCPacket05RequestData.class);
mappings.put(IPCPacket07ImportWorld.ID, IPCPacket07ImportWorld.class);
mappings.put(IPCPacket09RequestResponse.ID, IPCPacket09RequestResponse.class);
mappings.put(IPCPacket0ASetWorldDifficulty.ID, IPCPacket0ASetWorldDifficulty.class);
mappings.put(IPCPacket0BPause.ID, IPCPacket0BPause.class);
mappings.put(IPCPacket0CPlayerChannel.ID, IPCPacket0CPlayerChannel.class);
mappings.put(IPCPacket0DProgressUpdate.ID, IPCPacket0DProgressUpdate.class);
mappings.put(IPCPacket0EListWorlds.ID, IPCPacket0EListWorlds.class);
mappings.put(IPCPacket0FListFiles.ID, IPCPacket0FListFiles.class);
mappings.put(IPCPacket10FileRead.ID, IPCPacket10FileRead.class);
mappings.put(IPCPacket12FileWrite.ID, IPCPacket12FileWrite.class);
mappings.put(IPCPacket13FileCopyMove.ID, IPCPacket13FileCopyMove.class);
mappings.put(IPCPacket14StringList.ID, IPCPacket14StringList.class);
mappings.put(IPCPacketFFProcessKeepAlive.ID, IPCPacketFFProcessKeepAlive.class);
}
public static byte[] IPCSerialize(IPCPacketBase pkt) throws IOException {
IPC_OUTPUT_STREAM.feedBuffer(new byte[1 + pkt.size()], pkt.getClass().getSimpleName());
IPC_OUTPUT_STREAM.write(pkt.id());
pkt.serialize(IPC_DATA_OUTPUT_STREAM);
return IPC_OUTPUT_STREAM.returnBuffer();
}
public static IPCPacketBase IPCDeserialize(byte[] pkt) throws IOException {
IPC_INPUT_STREAM.feedBuffer(pkt);
int i = IPC_INPUT_STREAM.read();
Class<? extends IPCPacketBase> pk = mappings.get(Integer.valueOf(i));
if(pk == null) {
throw new IOException("Packet type 0x" + Integer.toHexString(i) + " doesn't exist");
}
IPCPacketBase p;
try {
p = pk.getDeclaredConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
throw new RuntimeException("Packet type '" + pk.getSimpleName() + "' could not be constructed", e);
}
IPC_INPUT_STREAM.nameBuffer(pk.getSimpleName());
p.deserialize(IPC_DATA_INPUT_STREAM);
return p;
}
}

View File

@ -0,0 +1,18 @@
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

@ -0,0 +1,78 @@
package net.lax1dude.eaglercraft.sp;
import java.io.File;
import java.io.IOException;
import net.minecraft.server.MinecraftServer;
import net.minecraft.src.EnumGameType;
import net.minecraft.src.ILogAgent;
import net.minecraft.src.NetworkListenThread;
public class EAGMinecraftServer extends MinecraftServer {
public EAGMinecraftServer(File par1File) {
super(par1File);
// TODO Auto-generated constructor stub
}
@Override
protected boolean startServer() throws IOException {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean canStructuresSpawn() {
// TODO Auto-generated method stub
return false;
}
@Override
public EnumGameType getGameType() {
// TODO Auto-generated method stub
return null;
}
@Override
public int getDifficulty() {
// TODO Auto-generated method stub
return 0;
}
@Override
public boolean isHardcore() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isDedicatedServer() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isCommandBlockEnabled() {
// TODO Auto-generated method stub
return false;
}
@Override
public NetworkListenThread getNetworkThread() {
// TODO Auto-generated method stub
return null;
}
@Override
public String shareToLAN(EnumGameType var1, boolean var2) {
// TODO Auto-generated method stub
return null;
}
@Override
public ILogAgent getLogAgent() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -0,0 +1,165 @@
package net.lax1dude.eaglercraft.sp;
import java.io.IOException;
import java.util.LinkedList;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSFunctor;
import org.teavm.jso.typedarrays.ArrayBuffer;
import org.teavm.jso.typedarrays.Uint8Array;
import net.lax1dude.eaglercraft.sp.ipc.*;
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;
}
}
@JSFunctor
private static class WorkerBinaryPacketHandler {
@SuppressWarnings("unused")
private 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;
}
Uint8Array a = Uint8Array.create(buf);
byte[] pkt = new byte[a.getLength()];
for(int i = 0; i < a.getLength(); ++i) {
pkt[i] = (byte) a.get(i);
}
messageQueue.add(new PKT(channel, pkt));
}
}
private static void processAsyncMessageQueue() {
while(messageQueue.size() > 0) {
PKT msg = messageQueue.remove(0);
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();
return;
}
int id = packet.id();
switch(id) {
case IPCPacket00StartServer.ID:
break;
case IPCPacket01StopServer.ID:
break;
case IPCPacket02InitWorld.ID:
break;
case IPCPacket03DeleteWorld.ID:
break;
case IPCPacket04RenameWorld.ID:
break;
case IPCPacket05RequestData.ID:
break;
case IPCPacket07ImportWorld.ID:
break;
case IPCPacket09RequestResponse.ID:
break;
case IPCPacket0ASetWorldDifficulty.ID:
break;
case IPCPacket0BPause.ID:
break;
case IPCPacket0CPlayerChannel.ID:
break;
case IPCPacket0EListWorlds.ID:
break;
case IPCPacket0FListFiles.ID:
break;
case IPCPacket10FileRead.ID:
break;
case IPCPacket12FileWrite.ID:
break;
case IPCPacket13FileCopyMove.ID:
break;
case IPCPacket14StringList.ID:
break;
default:
System.err.println("IPC packet type 0x" + Integer.toHexString(id) + " class '" + packet.getClass().getSimpleName() + "' was not handled");
break;
}
return;
}
System.err.println("Unknown IPC channel: " + msg.channel);
}
}
private static boolean isRunning = false;
public static void halt() {
isRunning = false;
}
private static void mainLoop() {
processAsyncMessageQueue();
}
@JSBody(params = { "wb" }, script = "onmessage = function(o) { wb(o.ch, o.dat); };")
private static native void registerPacketHandler(WorkerBinaryPacketHandler wb);
public static void main(String[] args) {
registerPacketHandler(new WorkerBinaryPacketHandler());
isRunning = true;
while(isRunning) {
mainLoop();
try {
Thread.sleep(1l); // allow some async to occur
}catch(InterruptedException e) {
System.err.println("you eagler");
}
}
// yee
}
}

View File

@ -0,0 +1,53 @@
package net.lax1dude.eaglercraft.sp;
import org.teavm.interop.Async;
import org.teavm.interop.AsyncCallback;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSFunctor;
import org.teavm.jso.JSObject;
import org.teavm.jso.browser.Window;
import net.lax1dude.eaglercraft.sp.VirtualFilesystem.VFSHandle;
public class SYS {
public static final boolean PERSIST;
public static final VirtualFilesystem VFS;
@JSFunctor
private interface PromiseHandler extends JSObject {
void complete(JSObject result);
}
@Async
private static native BooleanResult requestPersist();
private static void requestPersist(AsyncCallback<BooleanResult> callback) {
requestPersist0(res -> callback.complete(BooleanResult._new(res != null)));
}
@JSBody(params = { "callback" }, script = "if(navigator.storage && navigator.storage.persist){"
+ "navigator.storage.persist().then(function(persistent) {callback(persistent ? {p:true} : null);});"
+ "}else{callback(null);}")
private static native void requestPersist0(PromiseHandler callback);
static {
PERSIST = requestPersist().bool;
if(!PERSIST) {
Window.alert("PERSISTENT STORAGE NOT AVAILABLE, YOUR BROWSER MAY DELETE YOUR WORLDS!");
}
VFSHandle vh = VirtualFilesystem.openVFS("_net_lax1dude_eaglercraft_sp_VirtualFilesystem_1_5_2");
if(vh.vfs == null) {
Window.alert("COULD NOT INIT FILESYSTEM: " + vh.toString());
}
VFS = vh.vfs;
}
}

View File

@ -0,0 +1,117 @@
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

@ -0,0 +1,213 @@
package net.lax1dude.eaglercraft.sp;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
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(pathSeperator.length());
}
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;
}
private 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.indexOf(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) {
if(!isRelative() && SYS.VFS.renameFile(path, p)) {
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);
}
}

View File

@ -0,0 +1,572 @@
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.HashMap;
import java.util.Iterator;
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.EventHandler;
import org.teavm.jso.indexeddb.IDBCountRequest;
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.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 = System.currentTimeMillis();
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 = System.currentTimeMillis();
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 = System.currentTimeMillis();
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");
}
Uint8Array a = Uint8Array.create(aa);
this.fileSize = a.getByteLength();
if(cacheEnabled) {
cache = new byte[fileSize];
for(int i = 0; i < fileSize; ++i) {
cache[i] = (byte)a.get(i);
}
}
if(a.getLength() < fileOffset + length) {
throw new ArrayIndexOutOfBoundsException("file '" + filePath + "' 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() {
if(!cacheEnabled && !hasBeenDeleted && !(hasBeenAccessed && !exists)) {
cacheHit = System.currentTimeMillis();
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 = System.currentTimeMillis();
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;
}
Uint8Array a = Uint8Array.create(b);
this.fileSize = a.getByteLength();
byte[] array = new byte[fileSize];
for(int i = 0; i < a.getByteLength(); ++i) {
array[i] = (byte)a.get(i);
}
if(cacheEnabled) {
if(copy) {
cache = new byte[fileSize];
System.arraycopy(b, 0, cache, 0, cache.length);
}else {
cache = array;
}
}
return array;
}
}
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 = System.currentTimeMillis();
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 {
ArrayBuffer a = ArrayBuffer.create(bytes.length);
Uint8Array ar = Uint8Array.create(a);
ar.set(bytes);
boolean s = AsyncHandlers.writeWholeFile(virtualFilesystem.indexeddb, filePath, a).bool;
hasBeenAccessed = true;
exists = exists || s;
return s;
}
}
public boolean sync() {
if(cacheEnabled && cache != null && !hasBeenDeleted) {
cacheHit = System.currentTimeMillis();
ArrayBuffer a = ArrayBuffer.create(cache.length);
Uint8Array ar = Uint8Array.create(a);
ar.set(cache);
boolean tryWrite = AsyncHandlers.writeWholeFile(virtualFilesystem.indexeddb, filePath, a).bool;
hasBeenAccessed = true;
exists = exists || tryWrite;
return tryWrite;
}
return false;
}
public boolean delete() {
if(!hasBeenDeleted && !(hasBeenAccessed && !exists)) {
cacheHit = System.currentTimeMillis();
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) {
if(!hasBeenDeleted && !(hasBeenAccessed && !exists)) {
cacheHit = System.currentTimeMillis();
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(!AsyncHandlers.deleteFile(virtualFilesystem.indexeddb, filePath).bool) {
return false;
}
}else {
exists = false;
}
virtualFilesystem.fileMap.remove(filePath);
filePath = newName;
virtualFilesystem.fileMap.put(newName, this);
return true;
}
return false;
}
public boolean exists() {
if(hasBeenDeleted) {
return false;
}
cacheHit = System.currentTimeMillis();
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) {
return getFile(oldName).rename(newName);
}
public boolean deleteFile(String path) {
return getFile(path).delete();
}
public boolean fileExists(String path) {
return getFile(path).exists();
}
public void flushCache(long age) {
long curr = System.currentTimeMillis();
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;
}
}
protected static class AsyncHandlers {
@Async
protected static native DatabaseOpen openDB(String name);
private static void openDB(String name, final AsyncCallback<DatabaseOpen> cb) {
IDBFactory i = null;
try {
i = IDBFactory.getInstance();
}catch(Throwable t) {
cb.complete(new DatabaseOpen(true, false, t.toString(), null));
}
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.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));
}
});
}
@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.addEventListener("success", new EventListener<Event>() {
@Override
public void handleEvent(Event evt) {
cb.complete(readRow(r.getResult()));
}
});
r.addEventListener("error", new EventListener<Event>() {
@Override
public void handleEvent(Event evt) {
cb.complete(null);
}
});
}
@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.addEventListener("success", new EventListener<Event>() {
@Override
public void handleEvent(Event evt) {
cb.complete(BooleanResult._new(r.getResult() > 0));
}
});
r.addEventListener("error", new EventListener<Event>() {
@Override
public void handleEvent(Event evt) {
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.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));
}
});
}
}
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;
return str.indexOf('\r') != -1 ? str.replace("\r", "") : str;
}
public static String[] lines(String str) {
if(str == null) return null;
return CRLFtoLF(str).split("\n");
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
package net.minecraft.src;
final class AABBLocalPool extends ThreadLocal {
protected AABBPool createNewDefaultPool() {
return new AABBPool(300, 2000);
}
protected Object initialValue() {
return this.createNewDefaultPool();
}
}

View File

@ -0,0 +1,86 @@
package net.minecraft.src;
import java.util.ArrayList;
import java.util.List;
public class AABBPool {
/**
* Maximum number of times the pool can be "cleaned" before the list is shrunk
*/
private final int maxNumCleans;
/**
* Number of Pool entries to remove when cleanPool is called maxNumCleans times.
*/
private final int numEntriesToRemove;
/** List of AABB stored in this Pool */
private final List listAABB = new ArrayList();
/** Next index to use when adding a Pool Entry. */
private int nextPoolIndex = 0;
/**
* Largest index reached by this Pool (can be reset to 0 upon calling cleanPool)
*/
private int maxPoolIndex = 0;
/** Number of times this Pool has been cleaned */
private int numCleans = 0;
public AABBPool(int par1, int par2) {
this.maxNumCleans = par1;
this.numEntriesToRemove = par2;
}
/**
* Creates a new AABB, or reuses one that's no longer in use. Parameters: minX,
* minY, minZ, maxX, maxY, maxZ. AABBs returned from this function should only
* be used for one frame or tick, as after that they will be reused.
*/
public AxisAlignedBB getAABB(double par1, double par3, double par5, double par7, double par9, double par11) {
AxisAlignedBB var13;
if (this.nextPoolIndex >= this.listAABB.size()) {
var13 = new AxisAlignedBB(par1, par3, par5, par7, par9, par11);
this.listAABB.add(var13);
} else {
var13 = (AxisAlignedBB) this.listAABB.get(this.nextPoolIndex);
var13.setBounds(par1, par3, par5, par7, par9, par11);
}
++this.nextPoolIndex;
return var13;
}
/**
* Marks the pool as "empty", starting over when adding new entries. If this is
* called maxNumCleans times, the list size is reduced
*/
public void cleanPool() {
if (this.nextPoolIndex > this.maxPoolIndex) {
this.maxPoolIndex = this.nextPoolIndex;
}
if (this.numCleans++ == this.maxNumCleans) {
int var1 = Math.max(this.maxPoolIndex, this.listAABB.size() - this.numEntriesToRemove);
while (this.listAABB.size() > var1) {
this.listAABB.remove(var1);
}
this.maxPoolIndex = 0;
this.numCleans = 0;
}
this.nextPoolIndex = 0;
}
public int getlistAABBsize() {
return this.listAABB.size();
}
public int getnextPoolIndex() {
return this.nextPoolIndex;
}
}

View File

@ -0,0 +1,116 @@
package net.minecraft.src;
public class Achievement extends StatBase {
/**
* Is the column (related to center of achievement gui, in 24 pixels unit) that
* the achievement will be displayed.
*/
public final int displayColumn;
/**
* Is the row (related to center of achievement gui, in 24 pixels unit) that the
* achievement will be displayed.
*/
public final int displayRow;
/**
* Holds the parent achievement, that must be taken before this achievement is
* avaiable.
*/
public final Achievement parentAchievement;
/**
* Holds the description of the achievement, ready to be formatted and/or
* displayed.
*/
private final String achievementDescription;
/**
* Holds the ItemStack that will be used to draw the achievement into the GUI.
*/
public final ItemStack theItemStack;
/**
* Special achievements have a 'spiked' (on normal texture pack) frame, special
* achievements are the hardest ones to achieve.
*/
private boolean isSpecial;
public Achievement(int par1, String par2Str, int par3, int par4, Item par5Item, Achievement par6Achievement) {
this(par1, par2Str, par3, par4, new ItemStack(par5Item), par6Achievement);
}
public Achievement(int par1, String par2Str, int par3, int par4, Block par5Block, Achievement par6Achievement) {
this(par1, par2Str, par3, par4, new ItemStack(par5Block), par6Achievement);
}
public Achievement(int par1, String par2Str, int par3, int par4, ItemStack par5ItemStack,
Achievement par6Achievement) {
super(5242880 + par1, "achievement." + par2Str);
this.theItemStack = par5ItemStack;
this.achievementDescription = "achievement." + par2Str + ".desc";
this.displayColumn = par3;
this.displayRow = par4;
if (par3 < AchievementList.minDisplayColumn) {
AchievementList.minDisplayColumn = par3;
}
if (par4 < AchievementList.minDisplayRow) {
AchievementList.minDisplayRow = par4;
}
if (par3 > AchievementList.maxDisplayColumn) {
AchievementList.maxDisplayColumn = par3;
}
if (par4 > AchievementList.maxDisplayRow) {
AchievementList.maxDisplayRow = par4;
}
this.parentAchievement = par6Achievement;
}
/**
* Indicates whether or not the given achievement or statistic is independent
* (i.e., lacks prerequisites for being update).
*/
public Achievement setIndependent() {
this.isIndependent = true;
return this;
}
/**
* Special achievements have a 'spiked' (on normal texture pack) frame, special
* achievements are the hardest ones to achieve.
*/
public Achievement setSpecial() {
this.isSpecial = true;
return this;
}
/**
* Adds the achievement on the internal list of registered achievements, also,
* it's check for duplicated id's.
*/
public Achievement registerAchievement() {
super.registerStat();
AchievementList.achievementList.add(this);
return this;
}
/**
* Register the stat into StatList.
*/
public StatBase registerStat() {
return this.registerAchievement();
}
/**
* Initializes the current stat as independent (i.e., lacking prerequisites for
* being updated) and returns the current instance.
*/
public StatBase initIndependentStat() {
return this.setIndependent();
}
}

View File

@ -0,0 +1,137 @@
package net.minecraft.src;
import java.util.ArrayList;
import java.util.List;
public class AchievementList {
/** Is the smallest column used to display a achievement on the GUI. */
public static int minDisplayColumn;
/** Is the smallest row used to display a achievement on the GUI. */
public static int minDisplayRow;
/** Is the biggest column used to display a achievement on the GUI. */
public static int maxDisplayColumn;
/** Is the biggest row used to display a achievement on the GUI. */
public static int maxDisplayRow;
/** The list holding all achievements */
public static List achievementList = new ArrayList();
/** Is the 'open inventory' achievement. */
public static Achievement openInventory = (new Achievement(0, "openInventory", 0, 0, Item.book, (Achievement) null))
.setIndependent().registerAchievement();
/** Is the 'getting wood' achievement. */
public static Achievement mineWood = (new Achievement(1, "mineWood", 2, 1, Block.wood, openInventory))
.registerAchievement();
/** Is the 'benchmarking' achievement. */
public static Achievement buildWorkBench = (new Achievement(2, "buildWorkBench", 4, -1, Block.workbench, mineWood))
.registerAchievement();
/** Is the 'time to mine' achievement. */
public static Achievement buildPickaxe = (new Achievement(3, "buildPickaxe", 4, 2, Item.pickaxeWood,
buildWorkBench)).registerAchievement();
/** Is the 'hot topic' achievement. */
public static Achievement buildFurnace = (new Achievement(4, "buildFurnace", 3, 4, Block.furnaceIdle, buildPickaxe))
.registerAchievement();
/** Is the 'acquire hardware' achievement. */
public static Achievement acquireIron = (new Achievement(5, "acquireIron", 1, 4, Item.ingotIron, buildFurnace))
.registerAchievement();
/** Is the 'time to farm' achievement. */
public static Achievement buildHoe = (new Achievement(6, "buildHoe", 2, -3, Item.hoeWood, buildWorkBench))
.registerAchievement();
/** Is the 'bake bread' achievement. */
public static Achievement makeBread = (new Achievement(7, "makeBread", -1, -3, Item.bread, buildHoe))
.registerAchievement();
/** Is the 'the lie' achievement. */
public static Achievement bakeCake = (new Achievement(8, "bakeCake", 0, -5, Item.cake, buildHoe))
.registerAchievement();
/** Is the 'getting a upgrade' achievement. */
public static Achievement buildBetterPickaxe = (new Achievement(9, "buildBetterPickaxe", 6, 2, Item.pickaxeStone,
buildPickaxe)).registerAchievement();
/** Is the 'delicious fish' achievement. */
public static Achievement cookFish = (new Achievement(10, "cookFish", 2, 6, Item.fishCooked, buildFurnace))
.registerAchievement();
/** Is the 'on a rail' achievement */
public static Achievement onARail = (new Achievement(11, "onARail", 2, 3, Block.rail, acquireIron)).setSpecial()
.registerAchievement();
/** Is the 'time to strike' achievement. */
public static Achievement buildSword = (new Achievement(12, "buildSword", 6, -1, Item.swordWood, buildWorkBench))
.registerAchievement();
/** Is the 'monster hunter' achievement. */
public static Achievement killEnemy = (new Achievement(13, "killEnemy", 8, -1, Item.bone, buildSword))
.registerAchievement();
/** is the 'cow tipper' achievement. */
public static Achievement killCow = (new Achievement(14, "killCow", 7, -3, Item.leather, buildSword))
.registerAchievement();
/** Is the 'when pig fly' achievement. */
public static Achievement flyPig = (new Achievement(15, "flyPig", 8, -4, Item.saddle, killCow)).setSpecial()
.registerAchievement();
/** The achievement for killing a Skeleton from 50 meters aways. */
public static Achievement snipeSkeleton = (new Achievement(16, "snipeSkeleton", 7, 0, Item.bow, killEnemy))
.setSpecial().registerAchievement();
/** Is the 'DIAMONDS!' achievement */
public static Achievement diamonds = (new Achievement(17, "diamonds", -1, 5, Item.diamond, acquireIron))
.registerAchievement();
/** Is the 'We Need to Go Deeper' achievement */
public static Achievement portal = (new Achievement(18, "portal", -1, 7, Block.obsidian, diamonds))
.registerAchievement();
/** Is the 'Return to Sender' achievement */
public static Achievement ghast = (new Achievement(19, "ghast", -4, 8, Item.ghastTear, portal)).setSpecial()
.registerAchievement();
/** Is the 'Into Fire' achievement */
public static Achievement blazeRod = (new Achievement(20, "blazeRod", 0, 9, Item.blazeRod, portal))
.registerAchievement();
/** Is the 'Local Brewery' achievement */
public static Achievement potion = (new Achievement(21, "potion", 2, 8, Item.potion, blazeRod))
.registerAchievement();
/** Is the 'The End?' achievement */
public static Achievement theEnd = (new Achievement(22, "theEnd", 3, 10, Item.eyeOfEnder, blazeRod)).setSpecial()
.registerAchievement();
/** Is the 'The End.' achievement */
public static Achievement theEnd2 = (new Achievement(23, "theEnd2", 4, 13, Block.dragonEgg, theEnd)).setSpecial()
.registerAchievement();
/** Is the 'Enchanter' achievement */
public static Achievement enchantments = (new Achievement(24, "enchantments", -4, 4, Block.enchantmentTable,
diamonds)).registerAchievement();
public static Achievement overkill = (new Achievement(25, "overkill", -4, 1, Item.swordDiamond, enchantments))
.setSpecial().registerAchievement();
/** Is the 'Librarian' achievement */
public static Achievement bookcase = (new Achievement(26, "bookcase", -3, 6, Block.bookShelf, enchantments))
.registerAchievement();
/**
* A stub functions called to make the static initializer for this class run.
*/
public static void init() {
}
static {
System.out.println(achievementList.size() + " achievements");
}
}

View File

@ -0,0 +1,39 @@
package net.minecraft.src;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
public class AchievementMap {
/** Holds the singleton instance of AchievementMap. */
public static AchievementMap instance = new AchievementMap();
/** Maps a achievement id with it's unique GUID. */
private Map guidMap = new HashMap();
private AchievementMap() {
try {
BufferedReader var1 = new BufferedReader(
new InputStreamReader(AchievementMap.class.getResourceAsStream("/achievement/map.txt")));
String var2;
while ((var2 = var1.readLine()) != null) {
String[] var3 = var2.split(",");
int var4 = Integer.parseInt(var3[0]);
this.guidMap.put(Integer.valueOf(var4), var3[1]);
}
var1.close();
} catch (Exception var5) {
var5.printStackTrace();
}
}
/**
* Returns the unique GUID of a achievement id.
*/
public static String getGuid(int par0) {
return (String) instance.guidMap.get(Integer.valueOf(par0));
}
}

View File

@ -0,0 +1,371 @@
package net.minecraft.src;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public class AnvilChunkLoader implements IChunkLoader, IThreadedFileIO {
private List chunksToRemove = new ArrayList();
private Set pendingAnvilChunksCoordinates = new HashSet();
private Object syncLockObject = new Object();
/** Save directory for chunks using the Anvil format */
private final File chunkSaveLocation;
public AnvilChunkLoader(File par1File) {
this.chunkSaveLocation = par1File;
}
/**
* Loads the specified(XZ) chunk into the specified world.
*/
public Chunk loadChunk(World par1World, int par2, int par3) throws IOException {
NBTTagCompound var4 = null;
ChunkCoordIntPair var5 = new ChunkCoordIntPair(par2, par3);
Object var6 = this.syncLockObject;
synchronized (this.syncLockObject) {
if (this.pendingAnvilChunksCoordinates.contains(var5)) {
for (int var7 = 0; var7 < this.chunksToRemove.size(); ++var7) {
if (((AnvilChunkLoaderPending) this.chunksToRemove.get(var7)).chunkCoordinate.equals(var5)) {
var4 = ((AnvilChunkLoaderPending) this.chunksToRemove.get(var7)).nbtTags;
break;
}
}
}
}
if (var4 == null) {
DataInputStream var10 = RegionFileCache.getChunkInputStream(this.chunkSaveLocation, par2, par3);
if (var10 == null) {
return null;
}
var4 = CompressedStreamTools.read(var10);
}
return this.checkedReadChunkFromNBT(par1World, par2, par3, var4);
}
/**
* Wraps readChunkFromNBT. Checks the coordinates and several NBT tags.
*/
protected Chunk checkedReadChunkFromNBT(World par1World, int par2, int par3, NBTTagCompound par4NBTTagCompound) {
if (!par4NBTTagCompound.hasKey("Level")) {
par1World.getWorldLogAgent()
.logSevere("Chunk file at " + par2 + "," + par3 + " is missing level data, skipping");
return null;
} else if (!par4NBTTagCompound.getCompoundTag("Level").hasKey("Sections")) {
par1World.getWorldLogAgent()
.logSevere("Chunk file at " + par2 + "," + par3 + " is missing block data, skipping");
return null;
} else {
Chunk var5 = this.readChunkFromNBT(par1World, par4NBTTagCompound.getCompoundTag("Level"));
if (!var5.isAtLocation(par2, par3)) {
par1World.getWorldLogAgent()
.logSevere("Chunk file at " + par2 + "," + par3
+ " is in the wrong location; relocating. (Expected " + par2 + ", " + par3 + ", got "
+ var5.xPosition + ", " + var5.zPosition + ")");
par4NBTTagCompound.setInteger("xPos", par2);
par4NBTTagCompound.setInteger("zPos", par3);
var5 = this.readChunkFromNBT(par1World, par4NBTTagCompound.getCompoundTag("Level"));
}
return var5;
}
}
public void saveChunk(World par1World, Chunk par2Chunk) throws MinecraftException, IOException {
par1World.checkSessionLock();
try {
NBTTagCompound var3 = new NBTTagCompound();
NBTTagCompound var4 = new NBTTagCompound();
var3.setTag("Level", var4);
this.writeChunkToNBT(par2Chunk, par1World, var4);
this.addChunkToPending(par2Chunk.getChunkCoordIntPair(), var3);
} catch (Exception var5) {
var5.printStackTrace();
}
}
protected void addChunkToPending(ChunkCoordIntPair par1ChunkCoordIntPair, NBTTagCompound par2NBTTagCompound) {
Object var3 = this.syncLockObject;
synchronized (this.syncLockObject) {
if (this.pendingAnvilChunksCoordinates.contains(par1ChunkCoordIntPair)) {
for (int var4 = 0; var4 < this.chunksToRemove.size(); ++var4) {
if (((AnvilChunkLoaderPending) this.chunksToRemove.get(var4)).chunkCoordinate
.equals(par1ChunkCoordIntPair)) {
this.chunksToRemove.set(var4,
new AnvilChunkLoaderPending(par1ChunkCoordIntPair, par2NBTTagCompound));
return;
}
}
}
this.chunksToRemove.add(new AnvilChunkLoaderPending(par1ChunkCoordIntPair, par2NBTTagCompound));
this.pendingAnvilChunksCoordinates.add(par1ChunkCoordIntPair);
ThreadedFileIOBase.threadedIOInstance.queueIO(this);
}
}
/**
* Returns a boolean stating if the write was unsuccessful.
*/
public boolean writeNextIO() {
AnvilChunkLoaderPending var1 = null;
Object var2 = this.syncLockObject;
synchronized (this.syncLockObject) {
if (this.chunksToRemove.isEmpty()) {
return false;
}
var1 = (AnvilChunkLoaderPending) this.chunksToRemove.remove(0);
this.pendingAnvilChunksCoordinates.remove(var1.chunkCoordinate);
}
if (var1 != null) {
try {
this.writeChunkNBTTags(var1);
} catch (Exception var4) {
var4.printStackTrace();
}
}
return true;
}
private void writeChunkNBTTags(AnvilChunkLoaderPending par1AnvilChunkLoaderPending) throws IOException {
DataOutputStream var2 = RegionFileCache.getChunkOutputStream(this.chunkSaveLocation,
par1AnvilChunkLoaderPending.chunkCoordinate.chunkXPos,
par1AnvilChunkLoaderPending.chunkCoordinate.chunkZPos);
CompressedStreamTools.write(par1AnvilChunkLoaderPending.nbtTags, var2);
var2.close();
}
/**
* Save extra data associated with this Chunk not normally saved during
* autosave, only during chunk unload. Currently unused.
*/
public void saveExtraChunkData(World par1World, Chunk par2Chunk) {
}
/**
* Called every World.tick()
*/
public void chunkTick() {
}
/**
* Save extra data not associated with any Chunk. Not saved during autosave,
* only during world unload. Currently unused.
*/
public void saveExtraData() {
while (this.writeNextIO()) {
;
}
}
/**
* Writes the Chunk passed as an argument to the NBTTagCompound also passed,
* using the World argument to retrieve the Chunk's last update time.
*/
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.addEntityID(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.field_82754_f);
var12.appendTag(var15);
}
par3NBTTagCompound.setTag("TileTicks", var12);
}
}
/**
* Reads the data stored in the passed NBTTagCompound and creates a Chunk with
* that data in the passed World. Returns the created Chunk.
*/
private Chunk readChunkFromNBT(World par1World, NBTTagCompound par2NBTTagCompound) {
int var3 = par2NBTTagCompound.getInteger("xPos");
int var4 = 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;
}
}

View File

@ -0,0 +1,11 @@
package net.minecraft.src;
class AnvilChunkLoaderPending {
public final ChunkCoordIntPair chunkCoordinate;
public final NBTTagCompound nbtTags;
public AnvilChunkLoaderPending(ChunkCoordIntPair par1ChunkCoordIntPair, NBTTagCompound par2NBTTagCompound) {
this.chunkCoordinate = par1ChunkCoordIntPair;
this.nbtTags = par2NBTTagCompound;
}
}

View File

@ -0,0 +1,21 @@
package net.minecraft.src;
public class AnvilConverterData {
public long lastUpdated;
public boolean terrainPopulated;
public byte[] heightmap;
public NibbleArrayReader blockLight;
public NibbleArrayReader skyLight;
public NibbleArrayReader data;
public byte[] blocks;
public NBTTagList entities;
public NBTTagList tileEntities;
public NBTTagList tileTicks;
public final int x;
public final int z;
public AnvilConverterData(int par1, int par2) {
this.x = par1;
this.z = par2;
}
}

View File

@ -0,0 +1,191 @@
package net.minecraft.src;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import net.minecraft.server.MinecraftServer;
public class AnvilSaveConverter extends SaveFormatOld {
public AnvilSaveConverter(File par1File) {
super(par1File);
}
protected int getSaveVersion() {
return 19133;
}
public void flushCache() {
RegionFileCache.clearRegionFileReferences();
}
/**
* Returns back a loader for the specified save directory
*/
public ISaveHandler getSaveLoader(String par1Str, boolean par2) {
return new AnvilSaveHandler(this.savesDirectory, par1Str, par2);
}
/**
* gets if the map is old chunk saving (true) or McRegion (false)
*/
public boolean isOldMapFormat(String par1Str) {
WorldInfo var2 = this.getWorldInfo(par1Str);
return var2 != null && var2.getSaveVersion() != this.getSaveVersion();
}
/**
* converts the map to mcRegion
*/
public boolean convertMapFormat(String par1Str, IProgressUpdate par2IProgressUpdate) {
par2IProgressUpdate.setLoadingProgress(0);
ArrayList var3 = new ArrayList();
ArrayList var4 = new ArrayList();
ArrayList var5 = new ArrayList();
File var6 = new File(this.savesDirectory, par1Str);
File var7 = new File(var6, "DIM-1");
File var8 = new File(var6, "DIM1");
MinecraftServer.getServer().getLogAgent().func_98233_a("Scanning folders...");
this.addRegionFilesToCollection(var6, var3);
if (var7.exists()) {
this.addRegionFilesToCollection(var7, var4);
}
if (var8.exists()) {
this.addRegionFilesToCollection(var8, var5);
}
int var9 = var3.size() + var4.size() + var5.size();
MinecraftServer.getServer().getLogAgent().func_98233_a("Total conversion count is " + var9);
WorldInfo var10 = this.getWorldInfo(par1Str);
Object var11 = null;
if (var10.getTerrainType() == WorldType.FLAT) {
var11 = new WorldChunkManagerHell(BiomeGenBase.plains, 0.5F, 0.5F);
} else {
var11 = new WorldChunkManager(var10.getSeed(), var10.getTerrainType());
}
this.convertFile(new File(var6, "region"), var3, (WorldChunkManager) var11, 0, var9, par2IProgressUpdate);
this.convertFile(new File(var7, "region"), var4, new WorldChunkManagerHell(BiomeGenBase.hell, 1.0F, 0.0F),
var3.size(), var9, par2IProgressUpdate);
this.convertFile(new File(var8, "region"), var5, new WorldChunkManagerHell(BiomeGenBase.sky, 0.5F, 0.0F),
var3.size() + var4.size(), var9, par2IProgressUpdate);
var10.setSaveVersion(19133);
if (var10.getTerrainType() == WorldType.DEFAULT_1_1) {
var10.setTerrainType(WorldType.DEFAULT);
}
this.createFile(par1Str);
ISaveHandler var12 = this.getSaveLoader(par1Str, false);
var12.saveWorldInfo(var10);
return true;
}
/**
* par: filename for the level.dat_mcr backup
*/
private void createFile(String par1Str) {
File var2 = new File(this.savesDirectory, par1Str);
if (!var2.exists()) {
System.out.println("Warning: Unable to create level.dat_mcr backup");
} else {
File var3 = new File(var2, "level.dat");
if (!var3.exists()) {
System.out.println("Warning: Unable to create level.dat_mcr backup");
} else {
File var4 = new File(var2, "level.dat_mcr");
if (!var3.renameTo(var4)) {
System.out.println("Warning: Unable to create level.dat_mcr backup");
}
}
}
}
private void convertFile(File par1File, Iterable par2Iterable, WorldChunkManager par3WorldChunkManager, int par4,
int par5, IProgressUpdate par6IProgressUpdate) {
Iterator var7 = par2Iterable.iterator();
while (var7.hasNext()) {
File var8 = (File) var7.next();
this.convertChunks(par1File, var8, par3WorldChunkManager, par4, par5, par6IProgressUpdate);
++par4;
int var9 = (int) Math.round(100.0D * (double) par4 / (double) par5);
par6IProgressUpdate.setLoadingProgress(var9);
}
}
/**
* copies a 32x32 chunk set from par2File to par1File, via AnvilConverterData
*/
private void convertChunks(File par1File, File par2File, WorldChunkManager par3WorldChunkManager, int par4,
int par5, IProgressUpdate par6IProgressUpdate) {
try {
String var7 = par2File.getName();
RegionFile var8 = new RegionFile(par2File);
RegionFile var9 = new RegionFile(
new File(par1File, var7.substring(0, var7.length() - ".mcr".length()) + ".mca"));
for (int var10 = 0; var10 < 32; ++var10) {
int var11;
for (var11 = 0; var11 < 32; ++var11) {
if (var8.isChunkSaved(var10, var11) && !var9.isChunkSaved(var10, var11)) {
DataInputStream var12 = var8.getChunkDataInputStream(var10, var11);
if (var12 == null) {
MinecraftServer.getServer().getLogAgent().func_98236_b("Failed to fetch input stream");
} else {
NBTTagCompound var13 = CompressedStreamTools.read(var12);
var12.close();
NBTTagCompound var14 = var13.getCompoundTag("Level");
AnvilConverterData var15 = ChunkLoader.load(var14);
NBTTagCompound var16 = new NBTTagCompound();
NBTTagCompound var17 = new NBTTagCompound();
var16.setTag("Level", var17);
ChunkLoader.convertToAnvilFormat(var15, var17, par3WorldChunkManager);
DataOutputStream var18 = var9.getChunkDataOutputStream(var10, var11);
CompressedStreamTools.write(var16, var18);
var18.close();
}
}
}
var11 = (int) Math.round(100.0D * (double) (par4 * 1024) / (double) (par5 * 1024));
int var20 = (int) Math
.round(100.0D * (double) ((var10 + 1) * 32 + par4 * 1024) / (double) (par5 * 1024));
if (var20 > var11) {
par6IProgressUpdate.setLoadingProgress(var20);
}
}
var8.close();
var9.close();
} catch (IOException var19) {
var19.printStackTrace();
}
}
/**
* filters the files in the par1 directory, and adds them to the par2
* collections
*/
private void addRegionFilesToCollection(File par1File, Collection par2Collection) {
File var3 = new File(par1File, "region");
File[] var4 = var3.listFiles(new AnvilSaveConverterFileFilter(this));
if (var4 != null) {
Collections.addAll(par2Collection, var4);
}
}
}

View File

@ -0,0 +1,16 @@
package net.minecraft.src;
import java.io.File;
import java.io.FilenameFilter;
class AnvilSaveConverterFileFilter implements FilenameFilter {
final AnvilSaveConverter parent;
AnvilSaveConverterFileFilter(AnvilSaveConverter par1AnvilSaveConverter) {
this.parent = par1AnvilSaveConverter;
}
public boolean accept(File par1File, String par2Str) {
return par2Str.endsWith(".mcr");
}
}

View File

@ -0,0 +1,50 @@
package net.minecraft.src;
import java.io.File;
public class AnvilSaveHandler extends SaveHandler {
public AnvilSaveHandler(File par1File, String par2Str, boolean par3) {
super(par1File, par2Str, par3);
}
/**
* initializes and returns the chunk loader for the specified world provider
*/
public IChunkLoader getChunkLoader(WorldProvider par1WorldProvider) {
File var2 = this.getWorldDirectory();
File var3;
if (par1WorldProvider instanceof WorldProviderHell) {
var3 = new File(var2, "DIM-1");
var3.mkdirs();
return new AnvilChunkLoader(var3);
} else if (par1WorldProvider instanceof WorldProviderEnd) {
var3 = new File(var2, "DIM1");
var3.mkdirs();
return new AnvilChunkLoader(var3);
} else {
return new AnvilChunkLoader(var2);
}
}
/**
* Saves the given World Info with the given NBTTagCompound as the Player.
*/
public void saveWorldInfoWithPlayer(WorldInfo par1WorldInfo, NBTTagCompound par2NBTTagCompound) {
par1WorldInfo.setSaveVersion(19133);
super.saveWorldInfoWithPlayer(par1WorldInfo, par2NBTTagCompound);
}
/**
* Called to flush all changes to disk, waiting for them to complete.
*/
public void flush() {
try {
ThreadedFileIOBase.threadedIOInstance.waitForFinish();
} catch (InterruptedException var2) {
var2.printStackTrace();
}
RegionFileCache.clearRegionFileReferences();
}
}

View File

@ -0,0 +1,425 @@
package net.minecraft.src;
public class AxisAlignedBB {
/** ThreadLocal AABBPool */
private static final ThreadLocal theAABBLocalPool = new AABBLocalPool();
public double minX;
public double minY;
public double minZ;
public double maxX;
public double maxY;
public double maxZ;
/**
* Returns a bounding box with the specified bounds. Args: minX, minY, minZ,
* maxX, maxY, maxZ
*/
public static AxisAlignedBB getBoundingBox(double par0, double par2, double par4, double par6, double par8,
double par10) {
return new AxisAlignedBB(par0, par2, par4, par6, par8, par10);
}
/**
* Gets the ThreadLocal AABBPool
*/
public static AABBPool getAABBPool() {
return (AABBPool) theAABBLocalPool.get();
}
protected AxisAlignedBB(double par1, double par3, double par5, double par7, double par9, double par11) {
this.minX = par1;
this.minY = par3;
this.minZ = par5;
this.maxX = par7;
this.maxY = par9;
this.maxZ = par11;
}
/**
* Sets the bounds of the bounding box. Args: minX, minY, minZ, maxX, maxY, maxZ
*/
public AxisAlignedBB setBounds(double par1, double par3, double par5, double par7, double par9, double par11) {
this.minX = par1;
this.minY = par3;
this.minZ = par5;
this.maxX = par7;
this.maxY = par9;
this.maxZ = par11;
return this;
}
/**
* Adds the coordinates to the bounding box extending it if the point lies
* outside the current ranges. Args: x, y, z
*/
public AxisAlignedBB addCoord(double par1, double par3, double par5) {
double var7 = this.minX;
double var9 = this.minY;
double var11 = this.minZ;
double var13 = this.maxX;
double var15 = this.maxY;
double var17 = this.maxZ;
if (par1 < 0.0D) {
var7 += par1;
}
if (par1 > 0.0D) {
var13 += par1;
}
if (par3 < 0.0D) {
var9 += par3;
}
if (par3 > 0.0D) {
var15 += par3;
}
if (par5 < 0.0D) {
var11 += par5;
}
if (par5 > 0.0D) {
var17 += par5;
}
return getAABBPool().getAABB(var7, var9, var11, var13, var15, var17);
}
/**
* Returns a bounding box expanded by the specified vector (if negative numbers
* are given it will shrink). Args: x, y, z
*/
public AxisAlignedBB expand(double par1, double par3, double par5) {
double var7 = this.minX - par1;
double var9 = this.minY - par3;
double var11 = this.minZ - par5;
double var13 = this.maxX + par1;
double var15 = this.maxY + par3;
double var17 = this.maxZ + par5;
return getAABBPool().getAABB(var7, var9, var11, var13, var15, var17);
}
/**
* Returns a bounding box offseted by the specified vector (if negative numbers
* are given it will shrink). Args: x, y, z
*/
public AxisAlignedBB getOffsetBoundingBox(double par1, double par3, double par5) {
return getAABBPool().getAABB(this.minX + par1, this.minY + par3, this.minZ + par5, this.maxX + par1,
this.maxY + par3, this.maxZ + par5);
}
/**
* if instance and the argument bounding boxes overlap in the Y and Z
* dimensions, calculate the offset between them in the X dimension. return var2
* if the bounding boxes do not overlap or if var2 is closer to 0 then the
* calculated offset. Otherwise return the calculated offset.
*/
public double calculateXOffset(AxisAlignedBB par1AxisAlignedBB, double par2) {
if (par1AxisAlignedBB.maxY > this.minY && par1AxisAlignedBB.minY < this.maxY) {
if (par1AxisAlignedBB.maxZ > this.minZ && par1AxisAlignedBB.minZ < this.maxZ) {
double var4;
if (par2 > 0.0D && par1AxisAlignedBB.maxX <= this.minX) {
var4 = this.minX - par1AxisAlignedBB.maxX;
if (var4 < par2) {
par2 = var4;
}
}
if (par2 < 0.0D && par1AxisAlignedBB.minX >= this.maxX) {
var4 = this.maxX - par1AxisAlignedBB.minX;
if (var4 > par2) {
par2 = var4;
}
}
return par2;
} else {
return par2;
}
} else {
return par2;
}
}
/**
* if instance and the argument bounding boxes overlap in the X and Z
* dimensions, calculate the offset between them in the Y dimension. return var2
* if the bounding boxes do not overlap or if var2 is closer to 0 then the
* calculated offset. Otherwise return the calculated offset.
*/
public double calculateYOffset(AxisAlignedBB par1AxisAlignedBB, double par2) {
if (par1AxisAlignedBB.maxX > this.minX && par1AxisAlignedBB.minX < this.maxX) {
if (par1AxisAlignedBB.maxZ > this.minZ && par1AxisAlignedBB.minZ < this.maxZ) {
double var4;
if (par2 > 0.0D && par1AxisAlignedBB.maxY <= this.minY) {
var4 = this.minY - par1AxisAlignedBB.maxY;
if (var4 < par2) {
par2 = var4;
}
}
if (par2 < 0.0D && par1AxisAlignedBB.minY >= this.maxY) {
var4 = this.maxY - par1AxisAlignedBB.minY;
if (var4 > par2) {
par2 = var4;
}
}
return par2;
} else {
return par2;
}
} else {
return par2;
}
}
/**
* if instance and the argument bounding boxes overlap in the Y and X
* dimensions, calculate the offset between them in the Z dimension. return var2
* if the bounding boxes do not overlap or if var2 is closer to 0 then the
* calculated offset. Otherwise return the calculated offset.
*/
public double calculateZOffset(AxisAlignedBB par1AxisAlignedBB, double par2) {
if (par1AxisAlignedBB.maxX > this.minX && par1AxisAlignedBB.minX < this.maxX) {
if (par1AxisAlignedBB.maxY > this.minY && par1AxisAlignedBB.minY < this.maxY) {
double var4;
if (par2 > 0.0D && par1AxisAlignedBB.maxZ <= this.minZ) {
var4 = this.minZ - par1AxisAlignedBB.maxZ;
if (var4 < par2) {
par2 = var4;
}
}
if (par2 < 0.0D && par1AxisAlignedBB.minZ >= this.maxZ) {
var4 = this.maxZ - par1AxisAlignedBB.minZ;
if (var4 > par2) {
par2 = var4;
}
}
return par2;
} else {
return par2;
}
} else {
return par2;
}
}
/**
* Returns whether the given bounding box intersects with this one. Args:
* axisAlignedBB
*/
public boolean intersectsWith(AxisAlignedBB par1AxisAlignedBB) {
return par1AxisAlignedBB.maxX > this.minX && par1AxisAlignedBB.minX < this.maxX
? (par1AxisAlignedBB.maxY > this.minY && par1AxisAlignedBB.minY < this.maxY
? par1AxisAlignedBB.maxZ > this.minZ && par1AxisAlignedBB.minZ < this.maxZ
: false)
: false;
}
/**
* Offsets the current bounding box by the specified coordinates. Args: x, y, z
*/
public AxisAlignedBB offset(double par1, double par3, double par5) {
this.minX += par1;
this.minY += par3;
this.minZ += par5;
this.maxX += par1;
this.maxY += par3;
this.maxZ += par5;
return this;
}
/**
* Returns if the supplied Vec3D is completely inside the bounding box
*/
public boolean isVecInside(Vec3 par1Vec3) {
return par1Vec3.xCoord > this.minX && par1Vec3.xCoord < this.maxX
? (par1Vec3.yCoord > this.minY && par1Vec3.yCoord < this.maxY
? par1Vec3.zCoord > this.minZ && par1Vec3.zCoord < this.maxZ
: false)
: false;
}
/**
* Returns the average length of the edges of the bounding box.
*/
public double getAverageEdgeLength() {
double var1 = this.maxX - this.minX;
double var3 = this.maxY - this.minY;
double var5 = this.maxZ - this.minZ;
return (var1 + var3 + var5) / 3.0D;
}
/**
* Returns a bounding box that is inset by the specified amounts
*/
public AxisAlignedBB contract(double par1, double par3, double par5) {
double var7 = this.minX + par1;
double var9 = this.minY + par3;
double var11 = this.minZ + par5;
double var13 = this.maxX - par1;
double var15 = this.maxY - par3;
double var17 = this.maxZ - par5;
return getAABBPool().getAABB(var7, var9, var11, var13, var15, var17);
}
/**
* Returns a copy of the bounding box.
*/
public AxisAlignedBB copy() {
return getAABBPool().getAABB(this.minX, this.minY, this.minZ, this.maxX, this.maxY, this.maxZ);
}
public MovingObjectPosition calculateIntercept(Vec3 par1Vec3, Vec3 par2Vec3) {
Vec3 var3 = par1Vec3.getIntermediateWithXValue(par2Vec3, this.minX);
Vec3 var4 = par1Vec3.getIntermediateWithXValue(par2Vec3, this.maxX);
Vec3 var5 = par1Vec3.getIntermediateWithYValue(par2Vec3, this.minY);
Vec3 var6 = par1Vec3.getIntermediateWithYValue(par2Vec3, this.maxY);
Vec3 var7 = par1Vec3.getIntermediateWithZValue(par2Vec3, this.minZ);
Vec3 var8 = par1Vec3.getIntermediateWithZValue(par2Vec3, this.maxZ);
if (!this.isVecInYZ(var3)) {
var3 = null;
}
if (!this.isVecInYZ(var4)) {
var4 = null;
}
if (!this.isVecInXZ(var5)) {
var5 = null;
}
if (!this.isVecInXZ(var6)) {
var6 = null;
}
if (!this.isVecInXY(var7)) {
var7 = null;
}
if (!this.isVecInXY(var8)) {
var8 = null;
}
Vec3 var9 = null;
if (var3 != null && (var9 == null || par1Vec3.squareDistanceTo(var3) < par1Vec3.squareDistanceTo(var9))) {
var9 = var3;
}
if (var4 != null && (var9 == null || par1Vec3.squareDistanceTo(var4) < par1Vec3.squareDistanceTo(var9))) {
var9 = var4;
}
if (var5 != null && (var9 == null || par1Vec3.squareDistanceTo(var5) < par1Vec3.squareDistanceTo(var9))) {
var9 = var5;
}
if (var6 != null && (var9 == null || par1Vec3.squareDistanceTo(var6) < par1Vec3.squareDistanceTo(var9))) {
var9 = var6;
}
if (var7 != null && (var9 == null || par1Vec3.squareDistanceTo(var7) < par1Vec3.squareDistanceTo(var9))) {
var9 = var7;
}
if (var8 != null && (var9 == null || par1Vec3.squareDistanceTo(var8) < par1Vec3.squareDistanceTo(var9))) {
var9 = var8;
}
if (var9 == null) {
return null;
} else {
byte var10 = -1;
if (var9 == var3) {
var10 = 4;
}
if (var9 == var4) {
var10 = 5;
}
if (var9 == var5) {
var10 = 0;
}
if (var9 == var6) {
var10 = 1;
}
if (var9 == var7) {
var10 = 2;
}
if (var9 == var8) {
var10 = 3;
}
return new MovingObjectPosition(0, 0, 0, var10, var9);
}
}
/**
* Checks if the specified vector is within the YZ dimensions of the bounding
* box. Args: Vec3D
*/
private boolean isVecInYZ(Vec3 par1Vec3) {
return par1Vec3 == null ? false
: par1Vec3.yCoord >= this.minY && par1Vec3.yCoord <= this.maxY && par1Vec3.zCoord >= this.minZ
&& par1Vec3.zCoord <= this.maxZ;
}
/**
* Checks if the specified vector is within the XZ dimensions of the bounding
* box. Args: Vec3D
*/
private boolean isVecInXZ(Vec3 par1Vec3) {
return par1Vec3 == null ? false
: par1Vec3.xCoord >= this.minX && par1Vec3.xCoord <= this.maxX && par1Vec3.zCoord >= this.minZ
&& par1Vec3.zCoord <= this.maxZ;
}
/**
* Checks if the specified vector is within the XY dimensions of the bounding
* box. Args: Vec3D
*/
private boolean isVecInXY(Vec3 par1Vec3) {
return par1Vec3 == null ? false
: par1Vec3.xCoord >= this.minX && par1Vec3.xCoord <= this.maxX && par1Vec3.yCoord >= this.minY
&& par1Vec3.yCoord <= this.maxY;
}
/**
* Sets the bounding box to the same bounds as the bounding box passed in. Args:
* axisAlignedBB
*/
public void setBB(AxisAlignedBB par1AxisAlignedBB) {
this.minX = par1AxisAlignedBB.minX;
this.minY = par1AxisAlignedBB.minY;
this.minZ = par1AxisAlignedBB.minZ;
this.maxX = par1AxisAlignedBB.maxX;
this.maxY = par1AxisAlignedBB.maxY;
this.maxZ = par1AxisAlignedBB.maxZ;
}
public String toString() {
return "box[" + this.minX + ", " + this.minY + ", " + this.minZ + " -> " + this.maxX + ", " + this.maxY + ", "
+ this.maxZ + "]";
}
}

View File

@ -0,0 +1,140 @@
package net.minecraft.src;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Pattern;
import net.minecraft.server.MinecraftServer;
public class BanEntry {
public static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
private final String username;
private Date banStartDate = new Date();
private String bannedBy = "(Unknown)";
private Date banEndDate = null;
private String reason = "Banned by an operator.";
public BanEntry(String par1Str) {
this.username = par1Str;
}
public String getBannedUsername() {
return this.username;
}
public Date getBanStartDate() {
return this.banStartDate;
}
/**
* null == start ban now
*/
public void setBanStartDate(Date par1Date) {
this.banStartDate = par1Date != null ? par1Date : new Date();
}
public String getBannedBy() {
return this.bannedBy;
}
public void setBannedBy(String par1Str) {
this.bannedBy = par1Str;
}
public Date getBanEndDate() {
return this.banEndDate;
}
public void setBanEndDate(Date par1Date) {
this.banEndDate = par1Date;
}
public boolean hasBanExpired() {
return this.banEndDate == null ? false : this.banEndDate.before(new Date());
}
public String getBanReason() {
return this.reason;
}
public void setBanReason(String par1Str) {
this.reason = par1Str;
}
public String buildBanString() {
StringBuilder var1 = new StringBuilder();
var1.append(this.getBannedUsername());
var1.append("|");
var1.append(dateFormat.format(this.getBanStartDate()));
var1.append("|");
var1.append(this.getBannedBy());
var1.append("|");
var1.append(this.getBanEndDate() == null ? "Forever" : dateFormat.format(this.getBanEndDate()));
var1.append("|");
var1.append(this.getBanReason());
return var1.toString();
}
public static BanEntry parse(String par0Str) {
if (par0Str.trim().length() < 2) {
return null;
} else {
String[] var1 = par0Str.trim().split(Pattern.quote("|"), 5);
BanEntry var2 = new BanEntry(var1[0].trim());
byte var3 = 0;
int var10000 = var1.length;
int var7 = var3 + 1;
if (var10000 <= var7) {
return var2;
} else {
try {
var2.setBanStartDate(dateFormat.parse(var1[var7].trim()));
} catch (ParseException var6) {
MinecraftServer.getServer().getLogAgent()
.logWarningException("Could not read creation date format for ban entry \'"
+ var2.getBannedUsername() + "\' (was: \'" + var1[var7] + "\')", var6);
}
var10000 = var1.length;
++var7;
if (var10000 <= var7) {
return var2;
} else {
var2.setBannedBy(var1[var7].trim());
var10000 = var1.length;
++var7;
if (var10000 <= var7) {
return var2;
} else {
try {
String var4 = var1[var7].trim();
if (!var4.equalsIgnoreCase("Forever") && var4.length() > 0) {
var2.setBanEndDate(dateFormat.parse(var4));
}
} catch (ParseException var5) {
MinecraftServer.getServer().getLogAgent()
.logWarningException(
"Could not read expiry date format for ban entry \'"
+ var2.getBannedUsername() + "\' (was: \'" + var1[var7] + "\')",
var5);
}
var10000 = var1.length;
++var7;
if (var10000 <= var7) {
return var2;
} else {
var2.setBanReason(var1[var7].trim());
return var2;
}
}
}
}
}
}
}

View File

@ -0,0 +1,137 @@
package net.minecraft.src;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import net.minecraft.server.MinecraftServer;
public class BanList {
private final LowerStringMap theBanList = new LowerStringMap();
private final File fileName;
/** set to true if not singlePlayer */
private boolean listActive = true;
public BanList(File par1File) {
this.fileName = par1File;
}
public boolean isListActive() {
return this.listActive;
}
public void setListActive(boolean par1) {
this.listActive = par1;
}
/**
* removes expired Bans before returning
*/
public Map getBannedList() {
this.removeExpiredBans();
return this.theBanList;
}
public boolean isBanned(String par1Str) {
if (!this.isListActive()) {
return false;
} else {
this.removeExpiredBans();
return this.theBanList.containsKey(par1Str);
}
}
public void put(BanEntry par1BanEntry) {
this.theBanList.putLower(par1BanEntry.getBannedUsername(), par1BanEntry);
this.saveToFileWithHeader();
}
public void remove(String par1Str) {
this.theBanList.remove(par1Str);
this.saveToFileWithHeader();
}
public void removeExpiredBans() {
Iterator var1 = this.theBanList.values().iterator();
while (var1.hasNext()) {
BanEntry var2 = (BanEntry) var1.next();
if (var2.hasBanExpired()) {
var1.remove();
}
}
}
/**
* Loads the ban list from the file (adds every entry, does not clear the
* current list).
*/
public void loadBanList() {
if (this.fileName.isFile()) {
BufferedReader var1;
try {
var1 = new BufferedReader(new FileReader(this.fileName));
} catch (FileNotFoundException var4) {
throw new Error();
}
String var2;
try {
while ((var2 = var1.readLine()) != null) {
if (!var2.startsWith("#")) {
BanEntry var3 = BanEntry.parse(var2);
if (var3 != null) {
this.theBanList.putLower(var3.getBannedUsername(), var3);
}
}
}
} catch (IOException var5) {
MinecraftServer.getServer().getLogAgent().logSevereException("Could not load ban list", var5);
}
}
}
public void saveToFileWithHeader() {
this.saveToFile(true);
}
/**
* par1: include header
*/
public void saveToFile(boolean par1) {
this.removeExpiredBans();
try {
PrintWriter var2 = new PrintWriter(new FileWriter(this.fileName, false));
if (par1) {
var2.println("# Updated " + (new SimpleDateFormat()).format(new Date()) + " by Minecraft " + "1.5.2");
var2.println("# victim name | ban date | banned by | banned until | reason");
var2.println();
}
Iterator var3 = this.theBanList.values().iterator();
while (var3.hasNext()) {
BanEntry var4 = (BanEntry) var3.next();
var2.println(var4.buildBanString());
}
var2.close();
} catch (IOException var5) {
MinecraftServer.getServer().getLogAgent().logSevereException("Could not save ban list", var5);
}
}
}

View File

@ -0,0 +1,61 @@
package net.minecraft.src;
public class BehaviorDefaultDispenseItem implements IBehaviorDispenseItem {
/**
* Dispenses the specified ItemStack from a dispenser.
*/
public final ItemStack dispense(IBlockSource par1IBlockSource, ItemStack par2ItemStack) {
ItemStack var3 = this.dispenseStack(par1IBlockSource, par2ItemStack);
this.playDispenseSound(par1IBlockSource);
this.spawnDispenseParticles(par1IBlockSource, BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata()));
return var3;
}
/**
* Dispense the specified stack, play the dispense sound and spawn particles.
*/
protected ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) {
EnumFacing var3 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata());
IPosition var4 = BlockDispenser.getIPositionFromBlockSource(par1IBlockSource);
ItemStack var5 = par2ItemStack.splitStack(1);
doDispense(par1IBlockSource.getWorld(), var5, 6, var3, var4);
return par2ItemStack;
}
public static void doDispense(World par0World, ItemStack par1ItemStack, int par2, EnumFacing par3EnumFacing,
IPosition par4IPosition) {
double var5 = par4IPosition.getX();
double var7 = par4IPosition.getY();
double var9 = par4IPosition.getZ();
EntityItem var11 = new EntityItem(par0World, var5, var7 - 0.3D, var9, par1ItemStack);
double var12 = par0World.rand.nextDouble() * 0.1D + 0.2D;
var11.motionX = (double) par3EnumFacing.getFrontOffsetX() * var12;
var11.motionY = 0.20000000298023224D;
var11.motionZ = (double) par3EnumFacing.getFrontOffsetZ() * var12;
var11.motionX += par0World.rand.nextGaussian() * 0.007499999832361937D * (double) par2;
var11.motionY += par0World.rand.nextGaussian() * 0.007499999832361937D * (double) par2;
var11.motionZ += par0World.rand.nextGaussian() * 0.007499999832361937D * (double) par2;
par0World.spawnEntityInWorld(var11);
}
/**
* Play the dispense sound from the specified block.
*/
protected void playDispenseSound(IBlockSource par1IBlockSource) {
par1IBlockSource.getWorld().playAuxSFX(1000, par1IBlockSource.getXInt(), par1IBlockSource.getYInt(),
par1IBlockSource.getZInt(), 0);
}
/**
* Order clients to display dispense particles from the specified block and
* facing.
*/
protected void spawnDispenseParticles(IBlockSource par1IBlockSource, EnumFacing par2EnumFacing) {
par1IBlockSource.getWorld().playAuxSFX(2000, par1IBlockSource.getXInt(), par1IBlockSource.getYInt(),
par1IBlockSource.getZInt(), this.func_82488_a(par2EnumFacing));
}
private int func_82488_a(EnumFacing par1EnumFacing) {
return par1EnumFacing.getFrontOffsetX() + 1 + (par1EnumFacing.getFrontOffsetZ() + 1) * 3;
}
}

View File

@ -0,0 +1,33 @@
package net.minecraft.src;
import java.util.List;
final class BehaviorDispenseArmor extends BehaviorDefaultDispenseItem {
/**
* Dispense the specified stack, play the dispense sound and spawn particles.
*/
protected ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) {
EnumFacing var3 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata());
int var4 = par1IBlockSource.getXInt() + var3.getFrontOffsetX();
int var5 = par1IBlockSource.getYInt() + var3.getFrontOffsetY();
int var6 = par1IBlockSource.getZInt() + var3.getFrontOffsetZ();
AxisAlignedBB var7 = AxisAlignedBB.getAABBPool().getAABB((double) var4, (double) var5, (double) var6,
(double) (var4 + 1), (double) (var5 + 1), (double) (var6 + 1));
List var8 = par1IBlockSource.getWorld().selectEntitiesWithinAABB(EntityLiving.class, var7,
new EntitySelectorArmoredMob(par2ItemStack));
if (var8.size() > 0) {
EntityLiving var9 = (EntityLiving) var8.get(0);
int var10 = var9 instanceof EntityPlayer ? 1 : 0;
int var11 = EntityLiving.getArmorPosition(par2ItemStack);
ItemStack var12 = par2ItemStack.copy();
var12.stackSize = 1;
var9.setCurrentItemOrArmor(var11 - var10, var12);
var9.func_96120_a(var11, 2.0F);
--par2ItemStack.stackSize;
return par2ItemStack;
} else {
return super.dispenseStack(par1IBlockSource, par2ItemStack);
}
}
}

View File

@ -0,0 +1,10 @@
package net.minecraft.src;
final class BehaviorDispenseItemProvider implements IBehaviorDispenseItem {
/**
* Dispenses the specified ItemStack from a dispenser.
*/
public ItemStack dispense(IBlockSource par1IBlockSource, ItemStack par2ItemStack) {
return par2ItemStack;
}
}

View File

@ -0,0 +1,45 @@
package net.minecraft.src;
final class BehaviorDispenseMinecart extends BehaviorDefaultDispenseItem {
private final BehaviorDefaultDispenseItem field_96465_b = new BehaviorDefaultDispenseItem();
/**
* Dispense the specified stack, play the dispense sound and spawn particles.
*/
public ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) {
EnumFacing var3 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata());
World var4 = par1IBlockSource.getWorld();
double var5 = par1IBlockSource.getX() + (double) ((float) var3.getFrontOffsetX() * 1.125F);
double var7 = par1IBlockSource.getY() + (double) ((float) var3.getFrontOffsetY() * 1.125F);
double var9 = par1IBlockSource.getZ() + (double) ((float) var3.getFrontOffsetZ() * 1.125F);
int var11 = par1IBlockSource.getXInt() + var3.getFrontOffsetX();
int var12 = par1IBlockSource.getYInt() + var3.getFrontOffsetY();
int var13 = par1IBlockSource.getZInt() + var3.getFrontOffsetZ();
int var14 = var4.getBlockId(var11, var12, var13);
double var15;
if (BlockRailBase.isRailBlock(var14)) {
var15 = 0.0D;
} else {
if (var14 != 0 || !BlockRailBase.isRailBlock(var4.getBlockId(var11, var12 - 1, var13))) {
return this.field_96465_b.dispense(par1IBlockSource, par2ItemStack);
}
var15 = -1.0D;
}
EntityMinecart var17 = EntityMinecart.createMinecart(var4, var5, var7 + var15, var9,
((ItemMinecart) par2ItemStack.getItem()).minecartType);
var4.spawnEntityInWorld(var17);
par2ItemStack.splitStack(1);
return par2ItemStack;
}
/**
* Play the dispense sound from the specified block.
*/
protected void playDispenseSound(IBlockSource par1IBlockSource) {
par1IBlockSource.getWorld().playAuxSFX(1000, par1IBlockSource.getXInt(), par1IBlockSource.getYInt(),
par1IBlockSource.getZInt(), 0);
}
}

View File

@ -0,0 +1,39 @@
package net.minecraft.src;
public abstract class BehaviorProjectileDispense extends BehaviorDefaultDispenseItem {
/**
* Dispense the specified stack, play the dispense sound and spawn particles.
*/
public ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) {
World var3 = par1IBlockSource.getWorld();
IPosition var4 = BlockDispenser.getIPositionFromBlockSource(par1IBlockSource);
EnumFacing var5 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata());
IProjectile var6 = this.getProjectileEntity(var3, var4);
var6.setThrowableHeading((double) var5.getFrontOffsetX(), (double) ((float) var5.getFrontOffsetY() + 0.1F),
(double) var5.getFrontOffsetZ(), this.func_82500_b(), this.func_82498_a());
var3.spawnEntityInWorld((Entity) var6);
par2ItemStack.splitStack(1);
return par2ItemStack;
}
/**
* Play the dispense sound from the specified block.
*/
protected void playDispenseSound(IBlockSource par1IBlockSource) {
par1IBlockSource.getWorld().playAuxSFX(1002, par1IBlockSource.getXInt(), par1IBlockSource.getYInt(),
par1IBlockSource.getZInt(), 0);
}
/**
* Return the projectile entity spawned by this dispense behavior.
*/
protected abstract IProjectile getProjectileEntity(World var1, IPosition var2);
protected float func_82498_a() {
return 6.0F;
}
protected float func_82500_b() {
return 1.1F;
}
}

View File

@ -0,0 +1,90 @@
package net.minecraft.src;
import java.util.ArrayList;
import java.util.List;
public class BiomeCache {
/** Reference to the WorldChunkManager */
private final WorldChunkManager chunkManager;
/** The last time this BiomeCache was cleaned, in milliseconds. */
private long lastCleanupTime = 0L;
/**
* The map of keys to BiomeCacheBlocks. Keys are based on the chunk x, z
* coordinates as (x | z << 32).
*/
private LongHashMap cacheMap = new LongHashMap();
/** The list of cached BiomeCacheBlocks */
private List cache = new ArrayList();
public BiomeCache(WorldChunkManager par1WorldChunkManager) {
this.chunkManager = par1WorldChunkManager;
}
/**
* Returns a biome cache block at location specified.
*/
public BiomeCacheBlock getBiomeCacheBlock(int par1, int par2) {
par1 >>= 4;
par2 >>= 4;
long var3 = (long) par1 & 4294967295L | ((long) par2 & 4294967295L) << 32;
BiomeCacheBlock var5 = (BiomeCacheBlock) this.cacheMap.getValueByKey(var3);
if (var5 == null) {
var5 = new BiomeCacheBlock(this, par1, par2);
this.cacheMap.add(var3, var5);
this.cache.add(var5);
}
var5.lastAccessTime = System.currentTimeMillis();
return var5;
}
/**
* Returns the BiomeGenBase related to the x, z position from the cache.
*/
public BiomeGenBase getBiomeGenAt(int par1, int par2) {
return this.getBiomeCacheBlock(par1, par2).getBiomeGenAt(par1, par2);
}
/**
* Removes BiomeCacheBlocks from this cache that haven't been accessed in at
* least 30 seconds.
*/
public void cleanupCache() {
long var1 = System.currentTimeMillis();
long var3 = var1 - this.lastCleanupTime;
if (var3 > 7500L || var3 < 0L) {
this.lastCleanupTime = var1;
for (int var5 = 0; var5 < this.cache.size(); ++var5) {
BiomeCacheBlock var6 = (BiomeCacheBlock) this.cache.get(var5);
long var7 = var1 - var6.lastAccessTime;
if (var7 > 30000L || var7 < 0L) {
this.cache.remove(var5--);
long var9 = (long) var6.xPosition & 4294967295L | ((long) var6.zPosition & 4294967295L) << 32;
this.cacheMap.remove(var9);
}
}
}
}
/**
* Returns the array of cached biome types in the BiomeCacheBlock at the given
* location.
*/
public BiomeGenBase[] getCachedBiomes(int par1, int par2) {
return this.getBiomeCacheBlock(par1, par2).biomes;
}
/**
* Get the world chunk manager object for a biome list.
*/
static WorldChunkManager getChunkManager(BiomeCache par0BiomeCache) {
return par0BiomeCache.chunkManager;
}
}

View File

@ -0,0 +1,44 @@
package net.minecraft.src;
public class BiomeCacheBlock {
/** An array of chunk temperatures saved by this cache. */
public float[] temperatureValues;
/** An array of chunk rainfall values saved by this cache. */
public float[] rainfallValues;
/** The array of biome types stored in this BiomeCacheBlock. */
public BiomeGenBase[] biomes;
/** The x coordinate of the BiomeCacheBlock. */
public int xPosition;
/** The z coordinate of the BiomeCacheBlock. */
public int zPosition;
/** The last time this BiomeCacheBlock was accessed, in milliseconds. */
public long lastAccessTime;
/** The BiomeCache object that contains this BiomeCacheBlock */
final BiomeCache theBiomeCache;
public BiomeCacheBlock(BiomeCache par1BiomeCache, int par2, int par3) {
this.theBiomeCache = par1BiomeCache;
this.temperatureValues = new float[256];
this.rainfallValues = new float[256];
this.biomes = new BiomeGenBase[256];
this.xPosition = par2;
this.zPosition = par3;
BiomeCache.getChunkManager(par1BiomeCache).getTemperatures(this.temperatureValues, par2 << 4, par3 << 4, 16,
16);
BiomeCache.getChunkManager(par1BiomeCache).getRainfall(this.rainfallValues, par2 << 4, par3 << 4, 16, 16);
BiomeCache.getChunkManager(par1BiomeCache).getBiomeGenAt(this.biomes, par2 << 4, par3 << 4, 16, 16, false);
}
/**
* Returns the BiomeGenBase related to the x, z position from the cache block.
*/
public BiomeGenBase getBiomeGenAt(int par1, int par2) {
return this.biomes[par1 & 15 | (par2 & 15) << 4];
}
}

View File

@ -0,0 +1,405 @@
package net.minecraft.src;
import java.util.Random;
public class BiomeDecorator {
/** The world the BiomeDecorator is currently decorating */
protected World currentWorld;
/** The Biome Decorator's random number generator. */
protected Random randomGenerator;
/** The X-coordinate of the chunk currently being decorated */
protected int chunk_X;
/** The Z-coordinate of the chunk currently being decorated */
protected int chunk_Z;
/** The biome generator object. */
protected BiomeGenBase biome;
/** The clay generator. */
protected WorldGenerator clayGen = new WorldGenClay(4);
/** The sand generator. */
protected WorldGenerator sandGen;
/** The gravel generator. */
protected WorldGenerator gravelAsSandGen;
/** The dirt generator. */
protected WorldGenerator dirtGen;
protected WorldGenerator gravelGen;
protected WorldGenerator coalGen;
protected WorldGenerator ironGen;
/** Field that holds gold WorldGenMinable */
protected WorldGenerator goldGen;
/** Field that holds redstone WorldGenMinable */
protected WorldGenerator redstoneGen;
/** Field that holds diamond WorldGenMinable */
protected WorldGenerator diamondGen;
/** Field that holds Lapis WorldGenMinable */
protected WorldGenerator lapisGen;
/** Field that holds one of the plantYellow WorldGenFlowers */
protected WorldGenerator plantYellowGen;
/** Field that holds one of the plantRed WorldGenFlowers */
protected WorldGenerator plantRedGen;
/** Field that holds mushroomBrown WorldGenFlowers */
protected WorldGenerator mushroomBrownGen;
/** Field that holds mushroomRed WorldGenFlowers */
protected WorldGenerator mushroomRedGen;
/** Field that holds big mushroom generator */
protected WorldGenerator bigMushroomGen;
/** Field that holds WorldGenReed */
protected WorldGenerator reedGen;
/** Field that holds WorldGenCactus */
protected WorldGenerator cactusGen;
/** The water lily generation! */
protected WorldGenerator waterlilyGen;
/** Amount of waterlilys per chunk. */
protected int waterlilyPerChunk;
/**
* The number of trees to attempt to generate per chunk. Up to 10 in forests,
* none in deserts.
*/
protected int treesPerChunk;
/**
* The number of yellow flower patches to generate per chunk. The game generates
* much less than this number, since it attempts to generate them at a random
* altitude.
*/
protected int flowersPerChunk;
/** The amount of tall grass to generate per chunk. */
protected int grassPerChunk;
/**
* The number of dead bushes to generate per chunk. Used in deserts and swamps.
*/
protected int deadBushPerChunk;
/**
* The number of extra mushroom patches per chunk. It generates 1/4 this number
* in brown mushroom patches, and 1/8 this number in red mushroom patches. These
* mushrooms go beyond the default base number of mushrooms.
*/
protected int mushroomsPerChunk;
/**
* The number of reeds to generate per chunk. Reeds won't generate if the
* randomly selected placement is unsuitable.
*/
protected int reedsPerChunk;
/**
* The number of cactus plants to generate per chunk. Cacti only work on sand.
*/
protected int cactiPerChunk;
/**
* The number of sand patches to generate per chunk. Sand patches only generate
* when part of it is underwater.
*/
protected int sandPerChunk;
/**
* The number of sand patches to generate per chunk. Sand patches only generate
* when part of it is underwater. There appear to be two separate fields for
* this.
*/
protected int sandPerChunk2;
/**
* The number of clay patches to generate per chunk. Only generates when part of
* it is underwater.
*/
protected int clayPerChunk;
/** Amount of big mushrooms per chunk */
protected int bigMushroomsPerChunk;
/** True if decorator should generate surface lava & water */
public boolean generateLakes;
public BiomeDecorator(BiomeGenBase par1BiomeGenBase) {
this.sandGen = new WorldGenSand(7, Block.sand.blockID);
this.gravelAsSandGen = new WorldGenSand(6, Block.gravel.blockID);
this.dirtGen = new WorldGenMinable(Block.dirt.blockID, 32);
this.gravelGen = new WorldGenMinable(Block.gravel.blockID, 32);
this.coalGen = new WorldGenMinable(Block.oreCoal.blockID, 16);
this.ironGen = new WorldGenMinable(Block.oreIron.blockID, 8);
this.goldGen = new WorldGenMinable(Block.oreGold.blockID, 8);
this.redstoneGen = new WorldGenMinable(Block.oreRedstone.blockID, 7);
this.diamondGen = new WorldGenMinable(Block.oreDiamond.blockID, 7);
this.lapisGen = new WorldGenMinable(Block.oreLapis.blockID, 6);
this.plantYellowGen = new WorldGenFlowers(Block.plantYellow.blockID);
this.plantRedGen = new WorldGenFlowers(Block.plantRed.blockID);
this.mushroomBrownGen = new WorldGenFlowers(Block.mushroomBrown.blockID);
this.mushroomRedGen = new WorldGenFlowers(Block.mushroomRed.blockID);
this.bigMushroomGen = new WorldGenBigMushroom();
this.reedGen = new WorldGenReed();
this.cactusGen = new WorldGenCactus();
this.waterlilyGen = new WorldGenWaterlily();
this.waterlilyPerChunk = 0;
this.treesPerChunk = 0;
this.flowersPerChunk = 2;
this.grassPerChunk = 1;
this.deadBushPerChunk = 0;
this.mushroomsPerChunk = 0;
this.reedsPerChunk = 0;
this.cactiPerChunk = 0;
this.sandPerChunk = 1;
this.sandPerChunk2 = 3;
this.clayPerChunk = 1;
this.bigMushroomsPerChunk = 0;
this.generateLakes = true;
this.biome = par1BiomeGenBase;
}
/**
* Decorates the world. Calls code that was formerly (pre-1.8) in
* ChunkProviderGenerate.populate
*/
public void decorate(World par1World, Random par2Random, int par3, int par4) {
if (this.currentWorld != null) {
throw new RuntimeException("Already decorating!!");
} else {
this.currentWorld = par1World;
this.randomGenerator = par2Random;
this.chunk_X = par3;
this.chunk_Z = par4;
this.decorate();
this.currentWorld = null;
this.randomGenerator = null;
}
}
/**
* The method that does the work of actually decorating chunks
*/
protected void decorate() {
this.generateOres();
int var1;
int var2;
int var3;
for (var1 = 0; var1 < this.sandPerChunk2; ++var1) {
var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var3 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
this.sandGen.generate(this.currentWorld, this.randomGenerator, var2,
this.currentWorld.getTopSolidOrLiquidBlock(var2, var3), var3);
}
for (var1 = 0; var1 < this.clayPerChunk; ++var1) {
var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var3 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
this.clayGen.generate(this.currentWorld, this.randomGenerator, var2,
this.currentWorld.getTopSolidOrLiquidBlock(var2, var3), var3);
}
for (var1 = 0; var1 < this.sandPerChunk; ++var1) {
var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var3 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
this.sandGen.generate(this.currentWorld, this.randomGenerator, var2,
this.currentWorld.getTopSolidOrLiquidBlock(var2, var3), var3);
}
var1 = this.treesPerChunk;
if (this.randomGenerator.nextInt(10) == 0) {
++var1;
}
int var4;
for (var2 = 0; var2 < var1; ++var2) {
var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
WorldGenerator var5 = this.biome.getRandomWorldGenForTrees(this.randomGenerator);
var5.setScale(1.0D, 1.0D, 1.0D);
var5.generate(this.currentWorld, this.randomGenerator, var3, this.currentWorld.getHeightValue(var3, var4),
var4);
}
for (var2 = 0; var2 < this.bigMushroomsPerChunk; ++var2) {
var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
this.bigMushroomGen.generate(this.currentWorld, this.randomGenerator, var3,
this.currentWorld.getHeightValue(var3, var4), var4);
}
int var7;
for (var2 = 0; var2 < this.flowersPerChunk; ++var2) {
var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var4 = this.randomGenerator.nextInt(128);
var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
this.plantYellowGen.generate(this.currentWorld, this.randomGenerator, var3, var4, var7);
if (this.randomGenerator.nextInt(4) == 0) {
var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var4 = this.randomGenerator.nextInt(128);
var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
this.plantRedGen.generate(this.currentWorld, this.randomGenerator, var3, var4, var7);
}
}
for (var2 = 0; var2 < this.grassPerChunk; ++var2) {
var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var4 = this.randomGenerator.nextInt(128);
var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
WorldGenerator var6 = this.biome.getRandomWorldGenForGrass(this.randomGenerator);
var6.generate(this.currentWorld, this.randomGenerator, var3, var4, var7);
}
for (var2 = 0; var2 < this.deadBushPerChunk; ++var2) {
var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var4 = this.randomGenerator.nextInt(128);
var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
(new WorldGenDeadBush(Block.deadBush.blockID)).generate(this.currentWorld, this.randomGenerator, var3, var4,
var7);
}
for (var2 = 0; var2 < this.waterlilyPerChunk; ++var2) {
var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
for (var7 = this.randomGenerator.nextInt(128); var7 > 0
&& this.currentWorld.getBlockId(var3, var7 - 1, var4) == 0; --var7) {
;
}
this.waterlilyGen.generate(this.currentWorld, this.randomGenerator, var3, var7, var4);
}
for (var2 = 0; var2 < this.mushroomsPerChunk; ++var2) {
if (this.randomGenerator.nextInt(4) == 0) {
var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
var7 = this.currentWorld.getHeightValue(var3, var4);
this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, var3, var7, var4);
}
if (this.randomGenerator.nextInt(8) == 0) {
var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
var7 = this.randomGenerator.nextInt(128);
this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, var3, var7, var4);
}
}
if (this.randomGenerator.nextInt(4) == 0) {
var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var3 = this.randomGenerator.nextInt(128);
var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, var2, var3, var4);
}
if (this.randomGenerator.nextInt(8) == 0) {
var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var3 = this.randomGenerator.nextInt(128);
var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, var2, var3, var4);
}
for (var2 = 0; var2 < this.reedsPerChunk; ++var2) {
var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
var7 = this.randomGenerator.nextInt(128);
this.reedGen.generate(this.currentWorld, this.randomGenerator, var3, var7, var4);
}
for (var2 = 0; var2 < 10; ++var2) {
var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var4 = this.randomGenerator.nextInt(128);
var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
this.reedGen.generate(this.currentWorld, this.randomGenerator, var3, var4, var7);
}
if (this.randomGenerator.nextInt(32) == 0) {
var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var3 = this.randomGenerator.nextInt(128);
var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
(new WorldGenPumpkin()).generate(this.currentWorld, this.randomGenerator, var2, var3, var4);
}
for (var2 = 0; var2 < this.cactiPerChunk; ++var2) {
var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var4 = this.randomGenerator.nextInt(128);
var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
this.cactusGen.generate(this.currentWorld, this.randomGenerator, var3, var4, var7);
}
if (this.generateLakes) {
for (var2 = 0; var2 < 50; ++var2) {
var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var4 = this.randomGenerator.nextInt(this.randomGenerator.nextInt(120) + 8);
var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
(new WorldGenLiquids(Block.waterMoving.blockID)).generate(this.currentWorld, this.randomGenerator, var3,
var4, var7);
}
for (var2 = 0; var2 < 20; ++var2) {
var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
var4 = this.randomGenerator
.nextInt(this.randomGenerator.nextInt(this.randomGenerator.nextInt(112) + 8) + 8);
var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
(new WorldGenLiquids(Block.lavaMoving.blockID)).generate(this.currentWorld, this.randomGenerator, var3,
var4, var7);
}
}
}
/**
* Standard ore generation helper. Generates most ores.
*/
protected void genStandardOre1(int par1, WorldGenerator par2WorldGenerator, int par3, int par4) {
for (int var5 = 0; var5 < par1; ++var5) {
int var6 = this.chunk_X + this.randomGenerator.nextInt(16);
int var7 = this.randomGenerator.nextInt(par4 - par3) + par3;
int var8 = this.chunk_Z + this.randomGenerator.nextInt(16);
par2WorldGenerator.generate(this.currentWorld, this.randomGenerator, var6, var7, var8);
}
}
/**
* Standard ore generation helper. Generates Lapis Lazuli.
*/
protected void genStandardOre2(int par1, WorldGenerator par2WorldGenerator, int par3, int par4) {
for (int var5 = 0; var5 < par1; ++var5) {
int var6 = this.chunk_X + this.randomGenerator.nextInt(16);
int var7 = this.randomGenerator.nextInt(par4) + this.randomGenerator.nextInt(par4) + (par3 - par4);
int var8 = this.chunk_Z + this.randomGenerator.nextInt(16);
par2WorldGenerator.generate(this.currentWorld, this.randomGenerator, var6, var7, var8);
}
}
/**
* Generates ores in the current chunk
*/
protected void generateOres() {
this.genStandardOre1(20, this.dirtGen, 0, 128);
this.genStandardOre1(10, this.gravelGen, 0, 128);
this.genStandardOre1(20, this.coalGen, 0, 128);
this.genStandardOre1(20, this.ironGen, 0, 64);
this.genStandardOre1(2, this.goldGen, 0, 32);
this.genStandardOre1(8, this.redstoneGen, 0, 16);
this.genStandardOre1(1, this.diamondGen, 0, 16);
this.genStandardOre2(1, this.lapisGen, 16, 16);
}
}

View File

@ -0,0 +1,35 @@
package net.minecraft.src;
public class BiomeEndDecorator extends BiomeDecorator {
protected WorldGenerator spikeGen;
public BiomeEndDecorator(BiomeGenBase par1BiomeGenBase) {
super(par1BiomeGenBase);
this.spikeGen = new WorldGenSpikes(Block.whiteStone.blockID);
}
/**
* The method that does the work of actually decorating chunks
*/
protected void decorate() {
this.generateOres();
if (this.randomGenerator.nextInt(5) == 0) {
int var1 = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
int var2 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
int var3 = this.currentWorld.getTopSolidOrLiquidBlock(var1, var2);
if (var3 > 0) {
;
}
this.spikeGen.generate(this.currentWorld, this.randomGenerator, var1, var3, var2);
}
if (this.chunk_X == 0 && this.chunk_Z == 0) {
EntityDragon var4 = new EntityDragon(this.currentWorld);
var4.setLocationAndAngles(0.0D, 128.0D, 0.0D, this.randomGenerator.nextFloat() * 360.0F, 0.0F);
this.currentWorld.spawnEntityInWorld(var4);
}
}
}

Some files were not shown because too many files have changed in this diff Show More