added server source and VFS and IPC
This commit is contained in:
parent
21d4f39927
commit
63889aa632
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -12,4 +12,8 @@ stable-download/java/spigot_command/world_nether/*
|
||||||
stable-download/java/spigot_command/world_the_end/*
|
stable-download/java/spigot_command/world_the_end/*
|
||||||
stable-download/java/spigot_command/server.log
|
stable-download/java/spigot_command/server.log
|
||||||
stable-download/java/bungee_command/proxy*
|
stable-download/java/bungee_command/proxy*
|
||||||
lwjgl-rundir/_eagstorage*
|
lwjgl-rundir/_eagstorage*
|
||||||
|
sp-server/.gradle
|
||||||
|
sp-server/.settings
|
||||||
|
sp-server/build
|
||||||
|
sp-server/bin
|
15666
javascript/classes_server.js
Normal file
15666
javascript/classes_server.js
Normal file
File diff suppressed because it is too large
Load Diff
1
javascript/classes_server.js.map
Normal file
1
javascript/classes_server.js.map
Normal file
File diff suppressed because one or more lines are too long
16
javascript/servertest.html
Normal file
16
javascript/servertest.html
Normal 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
13
sp-server/.classpath
Normal 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
23
sp-server/.project
Normal 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
110
sp-server/build.gradle
Normal 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;
|
||||||
|
}
|
BIN
sp-server/deps/gson-2.2.4-sources.jar
Normal file
BIN
sp-server/deps/gson-2.2.4-sources.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/gson-2.2.4.jar
Normal file
BIN
sp-server/deps/gson-2.2.4.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/joda-time-2.7-sources.jar
Normal file
BIN
sp-server/deps/joda-time-2.7-sources.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/joda-time-2.7.jar
Normal file
BIN
sp-server/deps/joda-time-2.7.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/jzlib-1.1.3-sources.jar
Normal file
BIN
sp-server/deps/jzlib-1.1.3-sources.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/jzlib-1.1.3.jar
Normal file
BIN
sp-server/deps/jzlib-1.1.3.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-classlib-0.7.0-SNAPSHOT-javadoc.jar
Normal file
BIN
sp-server/deps/teavm-classlib-0.7.0-SNAPSHOT-javadoc.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-classlib-0.7.0-SNAPSHOT-sources.jar
Normal file
BIN
sp-server/deps/teavm-classlib-0.7.0-SNAPSHOT-sources.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-classlib-0.7.0-SNAPSHOT.jar
Normal file
BIN
sp-server/deps/teavm-classlib-0.7.0-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-cli-0.6.1.jar
Normal file
BIN
sp-server/deps/teavm-cli-0.6.1.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-core-0.7.0-SNAPSHOT-javadoc.jar
Normal file
BIN
sp-server/deps/teavm-core-0.7.0-SNAPSHOT-javadoc.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-core-0.7.0-SNAPSHOT-sources.jar
Normal file
BIN
sp-server/deps/teavm-core-0.7.0-SNAPSHOT-sources.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-core-0.7.0-SNAPSHOT.jar
Normal file
BIN
sp-server/deps/teavm-core-0.7.0-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-gradle-plugin-1.0.0-patched.jar
Normal file
BIN
sp-server/deps/teavm-gradle-plugin-1.0.0-patched.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-interop-0.7.0-SNAPSHOT-javadoc.jar
Normal file
BIN
sp-server/deps/teavm-interop-0.7.0-SNAPSHOT-javadoc.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-interop-0.7.0-SNAPSHOT-sources.jar
Normal file
BIN
sp-server/deps/teavm-interop-0.7.0-SNAPSHOT-sources.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-interop-0.7.0-SNAPSHOT.jar
Normal file
BIN
sp-server/deps/teavm-interop-0.7.0-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-jso-0.7.0-SNAPSHOT-javadoc.jar
Normal file
BIN
sp-server/deps/teavm-jso-0.7.0-SNAPSHOT-javadoc.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-jso-0.7.0-SNAPSHOT-sources.jar
Normal file
BIN
sp-server/deps/teavm-jso-0.7.0-SNAPSHOT-sources.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-jso-0.7.0-SNAPSHOT.jar
Normal file
BIN
sp-server/deps/teavm-jso-0.7.0-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-jso-apis-0.7.0-SNAPSHOT-javadoc.jar
Normal file
BIN
sp-server/deps/teavm-jso-apis-0.7.0-SNAPSHOT-javadoc.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-jso-apis-0.7.0-SNAPSHOT-sources.jar
Normal file
BIN
sp-server/deps/teavm-jso-apis-0.7.0-SNAPSHOT-sources.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-jso-apis-0.7.0-SNAPSHOT.jar
Normal file
BIN
sp-server/deps/teavm-jso-apis-0.7.0-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-jso-impl-0.7.0-SNAPSHOT-javadoc.jar
Normal file
BIN
sp-server/deps/teavm-jso-impl-0.7.0-SNAPSHOT-javadoc.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-jso-impl-0.7.0-SNAPSHOT-sources.jar
Normal file
BIN
sp-server/deps/teavm-jso-impl-0.7.0-SNAPSHOT-sources.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-jso-impl-0.7.0-SNAPSHOT.jar
Normal file
BIN
sp-server/deps/teavm-jso-impl-0.7.0-SNAPSHOT.jar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
sp-server/deps/teavm-metaprogramming-api-0.7.0-SNAPSHOT.jar
Normal file
BIN
sp-server/deps/teavm-metaprogramming-api-0.7.0-SNAPSHOT.jar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
sp-server/deps/teavm-metaprogramming-impl-0.7.0-SNAPSHOT.jar
Normal file
BIN
sp-server/deps/teavm-metaprogramming-impl-0.7.0-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-platform-0.7.0-SNAPSHOT-javadoc.jar
Normal file
BIN
sp-server/deps/teavm-platform-0.7.0-SNAPSHOT-javadoc.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-platform-0.7.0-SNAPSHOT-sources.jar
Normal file
BIN
sp-server/deps/teavm-platform-0.7.0-SNAPSHOT-sources.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-platform-0.7.0-SNAPSHOT.jar
Normal file
BIN
sp-server/deps/teavm-platform-0.7.0-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-tooling-0.7.0-SNAPSHOT-javadoc.jar
Normal file
BIN
sp-server/deps/teavm-tooling-0.7.0-SNAPSHOT-javadoc.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-tooling-0.7.0-SNAPSHOT-sources.jar
Normal file
BIN
sp-server/deps/teavm-tooling-0.7.0-SNAPSHOT-sources.jar
Normal file
Binary file not shown.
BIN
sp-server/deps/teavm-tooling-0.7.0-SNAPSHOT.jar
Normal file
BIN
sp-server/deps/teavm-tooling-0.7.0-SNAPSHOT.jar
Normal file
Binary file not shown.
12
sp-server/settings.gradle
Normal file
12
sp-server/settings.gradle
Normal 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
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
53
sp-server/src/main/java/net/lax1dude/eaglercraft/sp/SYS.java
Normal file
53
sp-server/src/main/java/net/lax1dude/eaglercraft/sp/SYS.java
Normal 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
213
sp-server/src/main/java/net/lax1dude/eaglercraft/sp/VFile.java
Normal file
213
sp-server/src/main/java/net/lax1dude/eaglercraft/sp/VFile.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1243
sp-server/src/main/java/net/minecraft/server/MinecraftServer.java
Normal file
1243
sp-server/src/main/java/net/minecraft/server/MinecraftServer.java
Normal file
File diff suppressed because it is too large
Load Diff
11
sp-server/src/main/java/net/minecraft/src/AABBLocalPool.java
Normal file
11
sp-server/src/main/java/net/minecraft/src/AABBLocalPool.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
86
sp-server/src/main/java/net/minecraft/src/AABBPool.java
Normal file
86
sp-server/src/main/java/net/minecraft/src/AABBPool.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
116
sp-server/src/main/java/net/minecraft/src/Achievement.java
Normal file
116
sp-server/src/main/java/net/minecraft/src/Achievement.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
137
sp-server/src/main/java/net/minecraft/src/AchievementList.java
Normal file
137
sp-server/src/main/java/net/minecraft/src/AchievementList.java
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
371
sp-server/src/main/java/net/minecraft/src/AnvilChunkLoader.java
Normal file
371
sp-server/src/main/java/net/minecraft/src/AnvilChunkLoader.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
425
sp-server/src/main/java/net/minecraft/src/AxisAlignedBB.java
Normal file
425
sp-server/src/main/java/net/minecraft/src/AxisAlignedBB.java
Normal 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 + "]";
|
||||||
|
}
|
||||||
|
}
|
140
sp-server/src/main/java/net/minecraft/src/BanEntry.java
Normal file
140
sp-server/src/main/java/net/minecraft/src/BanEntry.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
137
sp-server/src/main/java/net/minecraft/src/BanList.java
Normal file
137
sp-server/src/main/java/net/minecraft/src/BanList.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
90
sp-server/src/main/java/net/minecraft/src/BiomeCache.java
Normal file
90
sp-server/src/main/java/net/minecraft/src/BiomeCache.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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];
|
||||||
|
}
|
||||||
|
}
|
405
sp-server/src/main/java/net/minecraft/src/BiomeDecorator.java
Normal file
405
sp-server/src/main/java/net/minecraft/src/BiomeDecorator.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
Loading…
Reference in New Issue
Block a user