diff --git a/.travis.yml b/.travis.yml
index 2390a3f..65fab6a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,7 @@ jdk:
install: true
script:
- mvn clean package
- - java -jar ./target/protogen-1.0-SNAPSHOT-shaded.jar all
+ - java -jar ./target/protogen-1.0-SNAPSHOT-shaded.jar --type all
cache:
directories:
diff --git a/pom.xml b/pom.xml
index 8b84cb9..e98a500 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,6 +46,26 @@
gson
2.8.5
+
+ net.sf.jopt-simple
+ jopt-simple
+ 5.0.4
+
+
+ org.ow2.asm
+ asm
+ 7.1
+
+
+ org.ow2.asm
+ asm-tree
+ 7.1
+
+
+ org.ow2.asm
+ asm-commons
+ 7.1
+
diff --git a/src/main/java/org/feathercore/protogen/Bootstrap.java b/src/main/java/org/feathercore/protogen/Bootstrap.java
index cd36905..10572a2 100644
--- a/src/main/java/org/feathercore/protogen/Bootstrap.java
+++ b/src/main/java/org/feathercore/protogen/Bootstrap.java
@@ -16,16 +16,22 @@
package org.feathercore.protogen;
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+import joptsimple.OptionSpec;
+import joptsimple.util.EnumConverter;
import org.feathercore.protogen.burger.BurgerReader;
import org.feathercore.protogen.generate.MaterialGenerator;
import org.feathercore.protogen.generate.PacketGenerator;
import org.feathercore.protogen.generate.ParticleGenerator;
import org.feathercore.protogen.generate.SoundGenerator;
import org.feathercore.protogen.util.FileUtil;
+import org.feathercore.protogen.version.MinecraftVersion;
import org.feathercore.protogen.wiki.WikiPacketInfo;
import org.feathercore.protogen.wiki.WikiReader;
-import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -34,71 +40,90 @@
* @author xtrafrancyz
*/
public class Bootstrap {
- private static final File VALID_DIR = new File("gen");
- private static final File BROKEN_DIR = new File("gen-broken");
+ private static final Path VALID_DIR;
+ private static final Path BROKEN_DIR;
- private static final CachedDataSource BURGER = new CachedDataSource<>(BurgerReader::new);
- private static final CachedDataSource WIKI = new CachedDataSource<>(WikiReader::new);
+ private static final MinecraftVersion DEFAULT_VERSION = MinecraftVersion._1_13_2;
+ private static final CachedDataSource BURGER = new CachedDataSource<>();
+ private static final CachedDataSource WIKI = new CachedDataSource<>();
- private static final Map GENERATORS = new HashMap() {{
- put("materials", Bootstrap::genMaterials);
- put("sounds", Bootstrap::genSounds);
- put("particles", Bootstrap::genParticles);
- put("packets", Bootstrap::genPackets);
+ private static final Map GENERATORS = new HashMap() {{
+ put(GeneratorType.MATERIALS, Bootstrap::genMaterials);
+ put(GeneratorType.SOUNDS, Bootstrap::genSounds);
+ put(GeneratorType.PARTICLES, Bootstrap::genParticles);
+ put(GeneratorType.PACKETS, Bootstrap::genPackets);
+ put(GeneratorType.ALL, () -> {
+ Bootstrap.genMaterials();
+ Bootstrap.genSounds();
+ Bootstrap.genParticles();
+ Bootstrap.genPackets();
+ });
}};
public static void main(String[] args) throws Exception {
- if (args.length == 0) {
- System.out.println("Choose what to generate:");
- System.out.println(" " + String.join(", ", GENERATORS.keySet()));
- System.out.println(" or");
- System.out.println(" all");
- return;
- }
+ OptionParser parser = new OptionParser();
+ OptionSpec specType = parser.accepts("type")
+ .withRequiredArg()
+ .ofType(GeneratorType.class)
+ .withValuesConvertedBy(new EnumConverter(GeneratorType.class) {})
+ .required();
+ OptionSpec specVersion = parser.accepts("version")
+ .withRequiredArg()
+ .ofType(MinecraftVersion.class)
+ .withValuesConvertedBy(new EnumConverter(MinecraftVersion.class) {
+ @Override
+ public MinecraftVersion convert(String value) {
+ return super.convert("_".concat(value.replace('.', '_')));
+ }
+ })
+ .defaultsTo(DEFAULT_VERSION);
+ OptionSet options = parser.parse(args);
+ GeneratorType type = options.valueOf(specType);
+ MinecraftVersion version = options.valueOf(specVersion);
+
+ System.out.println("Generator: " + type + ", version: " + version);
FileUtil.deleteRecursive(VALID_DIR);
FileUtil.deleteRecursive(BROKEN_DIR);
- if (args.length == 1 && args[0].equalsIgnoreCase("all")) {
- for (GenRunnable gen : GENERATORS.values()) {
- gen.run();
- }
- } else {
- for (final String arg : args) {
- GenRunnable gen = GENERATORS.get(arg.toLowerCase());
- if (gen != null) {
- gen.run();
- }
- }
- }
+ BURGER.setHandle(() -> new BurgerReader(version));
+ // TODO workaround please
+ WIKI.setHandle(() -> new WikiReader(version.getLink()));
+ GENERATORS.get(type).run();
}
private static void genMaterials() throws Exception {
String generated = new MaterialGenerator(BURGER.get()).generate();
- FileUtil.writeFile(new File(VALID_DIR, MaterialGenerator.CLASS_NAME + ".java"), generated);
+ FileUtil.writeFile(VALID_DIR.resolve(MaterialGenerator.CLASS_NAME + ".java"), generated);
}
private static void genParticles() throws Exception {
//String generated = new ParticleGenerator(new WikiReader(new File("proto.html")).getParticles()).generate();
String generated = new ParticleGenerator(WIKI.get().getParticles()).generate();
- FileUtil.writeFile(new File(VALID_DIR, ParticleGenerator.CLASS_NAME + ".java"), generated);
+ FileUtil.writeFile(VALID_DIR.resolve(ParticleGenerator.CLASS_NAME + ".java"), generated);
}
private static void genSounds() throws Exception {
String generated = new SoundGenerator(BURGER.get().getSounds()).generate();
- FileUtil.writeFile(new File(VALID_DIR, SoundGenerator.CLASS_NAME + ".java"), generated);
+ FileUtil.writeFile(VALID_DIR.resolve(SoundGenerator.CLASS_NAME + ".java"), generated);
}
private static void genPackets() throws Exception {
List packets = WIKI.get().getPackets();
for (WikiPacketInfo info : packets) {
String generated = new PacketGenerator(info).generate();
- File protoDir = new File(info.isBroken() ? BROKEN_DIR : VALID_DIR, info.getProtocol().name().toLowerCase());
- File finalDir = new File(protoDir, info.getSender().name().toLowerCase());
- FileUtil.writeFile(new File(finalDir, info.getStandardClassName() + ".java"), generated);
+ Path protoDir = (info.isBroken() ? BROKEN_DIR : VALID_DIR).resolve(info.getProtocol().name().toLowerCase());
+ Path finalDir = protoDir.resolve(info.getSender().name().toLowerCase());
+ FileUtil.writeFile(finalDir.resolve(info.getStandardClassName() + ".java"), generated);
}
}
+ static {
+ Path workingDir = Paths.get(System.getProperty("user.dir"));
+ VALID_DIR = workingDir.resolve("gen");
+ BROKEN_DIR = workingDir.resolve("gen-broken");
+ }
+
private interface GenRunnable {
void run() throws Exception;
}
diff --git a/src/main/java/org/feathercore/protogen/CachedDataSource.java b/src/main/java/org/feathercore/protogen/CachedDataSource.java
index 7f3a1ac..64d8c19 100644
--- a/src/main/java/org/feathercore/protogen/CachedDataSource.java
+++ b/src/main/java/org/feathercore/protogen/CachedDataSource.java
@@ -23,10 +23,6 @@ public class CachedDataSource {
private Creator creator;
private T cache;
- public CachedDataSource(Creator creator) {
- this.creator = creator;
- }
-
public T get() throws Exception {
if (cache == null) {
cache = creator.create();
@@ -34,6 +30,10 @@ public T get() throws Exception {
return cache;
}
+ public void setHandle(Creator creator) {
+ this.creator = creator;
+ }
+
public interface Creator {
T create() throws Exception;
}
diff --git a/src/main/java/org/feathercore/protogen/GeneratorType.java b/src/main/java/org/feathercore/protogen/GeneratorType.java
new file mode 100644
index 0000000..29a8384
--- /dev/null
+++ b/src/main/java/org/feathercore/protogen/GeneratorType.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2019 Feather Core
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.feathercore.protogen;
+
+public enum GeneratorType {
+
+ MATERIALS,
+ SOUNDS,
+ PARTICLES,
+ PACKETS,
+ ALL
+}
diff --git a/src/main/java/org/feathercore/protogen/burger/BurgerItem.java b/src/main/java/org/feathercore/protogen/burger/BurgerItem.java
index 5eb38ec..a01ef42 100644
--- a/src/main/java/org/feathercore/protogen/burger/BurgerItem.java
+++ b/src/main/java/org/feathercore/protogen/burger/BurgerItem.java
@@ -22,11 +22,14 @@
* @author xtrafrancyz
*/
public class BurgerItem {
+ //private static boolean warned;
+
private String textId;
private String enumName;
private int id;
private int maxStackSize;
-
+ private boolean solid;
+
public BurgerItem(JsonObject json) {
this.textId = json.get("text_id").getAsString();
this.id = json.get("numeric_id").getAsInt();
@@ -49,4 +52,8 @@ public int getId() {
public int getMaxStackSize() {
return maxStackSize;
}
+
+ public boolean isSolid() {
+ return solid;
+ }
}
diff --git a/src/main/java/org/feathercore/protogen/burger/BurgerReader.java b/src/main/java/org/feathercore/protogen/burger/BurgerReader.java
index 8186dd3..881b1c0 100644
--- a/src/main/java/org/feathercore/protogen/burger/BurgerReader.java
+++ b/src/main/java/org/feathercore/protogen/burger/BurgerReader.java
@@ -21,11 +21,9 @@
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.feathercore.protogen.util.NetworkUtil;
+import org.feathercore.protogen.version.MinecraftVersion;
-import java.io.File;
import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
import java.util.*;
/**
@@ -34,21 +32,18 @@
* @author xtrafrancyz
*/
public class BurgerReader {
- public static final String STANDARD_URL = "https://pokechu22.github.io/Burger/1.13.2.json";
+
+ public static final String URL = "https://pokechu22.github.io/Burger/%s.json";
private List sounds;
private List items;
private Map blocks;
- public BurgerReader() throws IOException {
- parse(NetworkUtil.get(STANDARD_URL));
- }
-
- public BurgerReader(File file) throws IOException {
- parse(new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8));
+ public BurgerReader(MinecraftVersion version) throws IOException {
+ parse(NetworkUtil.get(String.format(URL, version.getName())), version);
}
- private void parse(String str) {
+ private void parse(String str, MinecraftVersion version) {
JsonObject root = new JsonParser()
.parse(str)
.getAsJsonArray()
@@ -62,6 +57,8 @@ private void parse(String str) {
JsonObject sound = entry.getValue().getAsJsonObject();
this.sounds.add(new BurgerSound(entry.getKey(), sound.get("id").getAsInt()));
}
+ JsonObject classes = root.getAsJsonObject("classes");
+ version.setBlockClass(classes.getAsJsonPrimitive("block.register").getAsString());
// Items
this.items = new ArrayList<>();
diff --git a/src/main/java/org/feathercore/protogen/generate/MaterialGenerator.java b/src/main/java/org/feathercore/protogen/generate/MaterialGenerator.java
index 0a91d2e..187baac 100644
--- a/src/main/java/org/feathercore/protogen/generate/MaterialGenerator.java
+++ b/src/main/java/org/feathercore/protogen/generate/MaterialGenerator.java
@@ -63,6 +63,7 @@ protected void generateClass() {
sb.append(T1).append("@Getter(AccessLevel.NONE) int id;").append(LF);
sb.append(T1).append("int maxStackSize;").append(LF);
sb.append(T1).append("boolean block;").append(LF);
+ sb.append(T2).append("boolean solid;").append(LF);
sb.append(LF);
@@ -90,7 +91,8 @@ private void appendMaterials() {
sb.append(T1).append(item.getEnumName())
.append("(").append(item.getId()).append(", ")
.append(item.getMaxStackSize()).append(", ")
- .append(blocks.containsKey(item.getTextId()))
+ .append(blocks.containsKey(item.getTextId())).append(", ")
+ .append(item.isSolid())
.append(")");
if (i == this.items.size() - 1) {
diff --git a/src/main/java/org/feathercore/protogen/util/FileUtil.java b/src/main/java/org/feathercore/protogen/util/FileUtil.java
index 8cc6506..8b23ee4 100644
--- a/src/main/java/org/feathercore/protogen/util/FileUtil.java
+++ b/src/main/java/org/feathercore/protogen/util/FileUtil.java
@@ -16,31 +16,51 @@
package org.feathercore.protogen.util;
-import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
/**
* @author xtrafrancyz
*/
-@SuppressWarnings({"ConstantConditions", "ResultOfMethodCallIgnored"})
-public class FileUtil {
- public static void writeFile(File file, String content) {
- file.getParentFile().mkdirs();
- try (FileOutputStream fos = new FileOutputStream(file)) {
- fos.write(content.getBytes(StandardCharsets.UTF_8));
- } catch (IOException e) {
- e.printStackTrace();
+public final class FileUtil {
+
+ private FileUtil() { }
+
+ public static void writeFile(Path file, String content) {
+ try {
+ Path parent = file.getParent();
+ if(parent != null && !Files.isDirectory(parent)) {
+ Files.createDirectories(parent);
+ }
+ Files.write(file, content.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE);
+ } catch (IOException ex) {
+ ex.printStackTrace();
}
}
- public static void deleteRecursive(File file) {
- if (file.isDirectory()) {
- for (File f : file.listFiles()) {
- deleteRecursive(f);
+ public static void deleteRecursive(Path dir) {
+ if (Files.isDirectory(dir)) {
+ try {
+ Files.walkFileTree(dir, new SimpleFileVisitor() {
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
+ FileVisitResult result = super.postVisitDirectory(dir, exc);
+ Files.delete(dir);
+ return result;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+ Files.delete(file);
+ return super.visitFile(file, attrs);
+ }
+ });
+ } catch (IOException ex) {
+ ex.printStackTrace();
}
}
- file.delete();
}
}
diff --git a/src/main/java/org/feathercore/protogen/util/MaterialUtil.java b/src/main/java/org/feathercore/protogen/util/MaterialUtil.java
new file mode 100644
index 0000000..2feb5fe
--- /dev/null
+++ b/src/main/java/org/feathercore/protogen/util/MaterialUtil.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2019 Feather Core
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.feathercore.protogen.util;
+
+import org.feathercore.protogen.version.MinecraftVersion;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Optional;
+import java.util.Set;
+
+public final class MaterialUtil {
+
+ private MaterialUtil() { }
+
+ public static Set buildSolidMaterials(Path jar, MinecraftVersion version)
+ throws IOException {
+ if (version.getMaterialSlot() == -1) {
+ System.err.println("isSolid is unsupported for specified version, skipping");
+ return Collections.emptySet();
+ }
+ // Let's rock!
+ ClassLoader loader = MaterialUtil.class.getClassLoader();
+ try {
+ Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
+ method.setAccessible(true);
+ method.invoke(loader, jar.toUri().toURL());
+ } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException ex) {
+ System.err.println("Exception occurred while injecting jar into class path, skipping isSolid");
+ ex.printStackTrace();
+ return Collections.emptySet();
+ }
+ Class> klass;
+ try {
+ klass = Class.forName(version.getBlockClass(), true, loader);
+ } catch (ClassNotFoundException ex) {
+ System.err.println("Class loader failed to load class, skipping isSolid");
+ ex.printStackTrace();
+ return Collections.emptySet();
+ }
+ // Call init
+ Optional optional = Arrays.stream(klass.getDeclaredMethods())
+ .filter(m -> Modifier.isPublic(m.getModifiers()))
+ .filter(m -> Modifier.isStatic(m.getModifiers()))
+ .filter(m -> Void.TYPE == m.getReturnType())
+ .findFirst();
+ if (!optional.isPresent()) {
+ System.err.println("No init method in Block class, skipping isSolid");
+ return Collections.emptySet();
+ }
+ try {
+ optional.get().invoke(null);
+ } catch (IllegalAccessException | InvocationTargetException ex) {
+ System.err.println("Init method invocation failed, skipping isSolid");
+ ex.printStackTrace();
+ return Collections.emptySet();
+ }
+ // Search for material field
+ // TODO
+ return Collections.emptySet();
+ }
+}
diff --git a/src/main/java/org/feathercore/protogen/util/NetworkUtil.java b/src/main/java/org/feathercore/protogen/util/NetworkUtil.java
index 1488660..a0ef7fe 100644
--- a/src/main/java/org/feathercore/protogen/util/NetworkUtil.java
+++ b/src/main/java/org/feathercore/protogen/util/NetworkUtil.java
@@ -21,11 +21,15 @@
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.util.stream.Collectors;
/**
* @author xtrafrancyz
*/
-public class NetworkUtil {
+public final class NetworkUtil {
+
+ private NetworkUtil() { }
+
public static String get(String url) throws IOException {
HttpURLConnection conn = null;
try {
@@ -43,22 +47,14 @@ public static String get(String url) throws IOException {
}
break;
}
- StringBuilder response = new StringBuilder();
- String line;
if (conn.getResponseCode() / 200 == 1) {
- BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
- while ((line = reader.readLine()) != null) {
- response.append(line);
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
+ return br.lines().collect(Collectors.joining());
}
} else {
- BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
- while ((line = reader.readLine()) != null) {
- response.append(line);
- }
conn.getInputStream();
return null;
}
- return response.toString();
} finally {
if (conn != null) {
conn.disconnect();
diff --git a/src/main/java/org/feathercore/protogen/version/MinecraftVersion.java b/src/main/java/org/feathercore/protogen/version/MinecraftVersion.java
new file mode 100644
index 0000000..24e63a4
--- /dev/null
+++ b/src/main/java/org/feathercore/protogen/version/MinecraftVersion.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2019 Feather Core
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.feathercore.protogen.version;
+
+public enum MinecraftVersion {
+ _1_8_8(47, createOldIdLink("7368"), "1.8.8", null, -1, -1),
+ _1_8_9(47, createOldIdLink("7368"), "1.8.9", null, -1, -1),
+ _1_9_4(110, createOldIdLink("7959"), "1.9.4", null, -1, -1),
+ _1_10_2(210, createOldIdLink("8235"), "1.10.2", null, -1, -1),
+ _1_11_2(316, createOldIdLink("8543"), "1.11.2", null, -1, -1),
+ _1_12_2(340, createOldIdLink("14204"), "1.12.2", null, -1, 2),
+ _1_13_2(404, "http://wiki.vg/Protocol", "1.13.2", "bza", 11, 3);
+
+ private static final String FORMAT = "http://wiki.vg/index.php?title=Protocol&oldid=%s";
+ private final int protocolVersion;
+ private final String link;
+ private final String name;
+ private String blockClass;
+ private final String materialClass;
+ private final int materialSlot;
+ private final int registrySlot;
+
+ MinecraftVersion(int protocolVersion, String link, String name, String materialClass,
+ int materialSlot, final int registrySlot) {
+ this.protocolVersion = protocolVersion;
+ this.link = link;
+ this.name = name;
+ this.materialClass = materialClass;
+ this.materialSlot = materialSlot;
+ this.registrySlot = registrySlot;
+ }
+
+ public int getProtocolVersion() {
+ return protocolVersion;
+ }
+
+ public String getLink() {
+ return link;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ private static String createOldIdLink(String id) {
+ return String.format(FORMAT, id);
+ }
+
+ public int getMaterialSlot() {
+ return materialSlot;
+ }
+
+ public String getBlockClass() {
+ return blockClass;
+ }
+
+ public String getMaterialClass() {
+ return materialClass;
+ }
+
+ public int getRegistrySlot() {
+ return registrySlot;
+ }
+
+ public void setBlockClass(String blockClass) {
+ this.blockClass = blockClass;
+ }
+
+ @Override
+ public String toString() {
+ return name + "/" + protocolVersion;
+ }
+}
diff --git a/src/main/java/org/feathercore/protogen/wiki/WikiReader.java b/src/main/java/org/feathercore/protogen/wiki/WikiReader.java
index 86adf74..aa37375 100644
--- a/src/main/java/org/feathercore/protogen/wiki/WikiReader.java
+++ b/src/main/java/org/feathercore/protogen/wiki/WikiReader.java
@@ -31,7 +31,6 @@
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
-import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
@@ -44,24 +43,16 @@
* @author Kristian
*/
public class WikiReader {
- public static final String STANDARD_URL = "http://www.wiki.vg/Protocol";
+ public static final String URL = "http://wiki.vg/index.php?title=Protocol&oldid=%s";
// Stored packet information
private List packets;
private List particles;
- public WikiReader() throws IOException {
- this(STANDARD_URL);
- }
-
public WikiReader(String url) throws IOException {
load(Jsoup.connect(url).get());
}
- public WikiReader(File file) throws IOException {
- load(Jsoup.parse(file, null));
- }
-
private void load(Document doc) {
packets = loadPackets(doc);
particles = loadParticles(doc);