From 424643bbd836073d555f3468f92afe8a512cb734 Mon Sep 17 00:00:00 2001 From: xDark Date: Fri, 19 Apr 2019 17:04:04 +0300 Subject: [PATCH 1/8] Use joptsimple, allow version specification, io => nio --- pom.xml | 5 ++ .../org/feathercore/protogen/Bootstrap.java | 90 +++++++++++-------- .../protogen/CachedDataSource.java | 8 +- .../feathercore/protogen/GeneratorType.java | 26 ++++++ .../protogen/burger/BurgerItem.java | 52 ++++++++++- .../protogen/burger/BurgerReader.java | 14 +-- .../protogen/generate/MaterialGenerator.java | 4 +- .../feathercore/protogen/util/FileUtil.java | 45 +++++++--- .../feathercore/protogen/wiki/WikiReader.java | 15 +--- 9 files changed, 182 insertions(+), 77 deletions(-) create mode 100644 src/main/java/org/feathercore/protogen/GeneratorType.java diff --git a/pom.xml b/pom.xml index 8b84cb9..2d8ade0 100644 --- a/pom.xml +++ b/pom.xml @@ -46,6 +46,11 @@ gson 2.8.5 + + net.sf.jopt-simple + jopt-simple + 5.0.4 + diff --git a/src/main/java/org/feathercore/protogen/Bootstrap.java b/src/main/java/org/feathercore/protogen/Bootstrap.java index cd36905..b6b4da3 100644 --- a/src/main/java/org/feathercore/protogen/Bootstrap.java +++ b/src/main/java/org/feathercore/protogen/Bootstrap.java @@ -16,6 +16,10 @@ 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; @@ -25,7 +29,8 @@ 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 +39,86 @@ * @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 String DEFAULT_VERSION = "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") + .withOptionalArg() + .ofType(String.class) + .defaultsTo(DEFAULT_VERSION); + OptionSet options = parser.parse(args); + GeneratorType type = options.valueOf(specType); + String 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(DEFAULT_VERSION.equals(version) ? + "http://wiki.vg/Protocol" : + String.format("http://wiki.vg/index.php?title=Protocol&oldid=%s", version))); + 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..3d234af 100644 --- a/src/main/java/org/feathercore/protogen/burger/BurgerItem.java +++ b/src/main/java/org/feathercore/protogen/burger/BurgerItem.java @@ -22,16 +22,62 @@ * @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(); this.enumName = textId.toUpperCase().replace(".", "_"); this.maxStackSize = json.get("max_stack_size").getAsInt(); + /*if (jar != null && methodName != null && desc != null) { + // Parse isSolid + JsonPrimitive primitive = json.getAsJsonPrimitive("class"); + if (primitive != null) { + String className = primitive.getAsString(); + if (className == null) { + System.err.println("No class name for item: " + this.textId + "/" + this.id); + return; + } + JarEntry entry = jar.getJarEntry(className.concat(".class")); + if (entry == null) { + System.err.println("No class entry for item: " + this.textId + "/" + this.id + "/" + className); + return; + } + byte[] buffer = new byte[256]; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (InputStream in = jar.getInputStream(entry)) { + for (int r; ((r = in.read(buffer)) != -1); ) { + baos.write(buffer, 0, r); + } + } catch (IOException ex) { + System.err.println( + "Could not load class entry for item: " + this.textId + "/" + this.id + "/" + className); + ex.printStackTrace(); + return; + } + ClassNode cn = new ClassNode(); + new ClassReader(baos.toByteArray()).accept(cn, 0); + cn.methods.forEach(System.out::println); + for (MethodNode o : cn.methods) { + if (methodName.equals(o.name) && desc.equals(o.name)) { + InsnList list = o.instructions; + for (AbstractInsnNode node : list.toArray()) { + System.out.println(node); + } + break; + } + } + } + } else if (!warned) { + System.err.println("No jar file or method name/descriptor was specified. isSolid will not be resolved"); + warned = true; + }*/ } public String getEnumName() { @@ -49,4 +95,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..6b055fa 100644 --- a/src/main/java/org/feathercore/protogen/burger/BurgerReader.java +++ b/src/main/java/org/feathercore/protogen/burger/BurgerReader.java @@ -22,10 +22,7 @@ import com.google.gson.JsonParser; import org.feathercore.protogen.util.NetworkUtil; -import java.io.File; import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; import java.util.*; /** @@ -34,18 +31,15 @@ * @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(String version) throws IOException { + parse(NetworkUtil.get(String.format(URL, version))); } private void parse(String str) { 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..44f4333 100644 --- a/src/main/java/org/feathercore/protogen/util/FileUtil.java +++ b/src/main/java/org/feathercore/protogen/util/FileUtil.java @@ -16,31 +16,48 @@ 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 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/wiki/WikiReader.java b/src/main/java/org/feathercore/protogen/wiki/WikiReader.java index 86adf74..48ac6d6 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,22 +43,14 @@ * @author Kristian */ public class WikiReader { - public static final String STANDARD_URL = "http://www.wiki.vg/Protocol"; + public static final String STANDARD_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)); + public WikiReader(String version) throws IOException { + load(Jsoup.connect(String.format(STANDARD_URL, version)).get()); } private void load(Document doc) { From 675128e01f075e81f465f578394cdaf7863d9e4d Mon Sep 17 00:00:00 2001 From: xDark Date: Fri, 19 Apr 2019 17:06:44 +0300 Subject: [PATCH 2/8] Remove commented code --- .../protogen/burger/BurgerItem.java | 43 ------------------- 1 file changed, 43 deletions(-) diff --git a/src/main/java/org/feathercore/protogen/burger/BurgerItem.java b/src/main/java/org/feathercore/protogen/burger/BurgerItem.java index 3d234af..a01ef42 100644 --- a/src/main/java/org/feathercore/protogen/burger/BurgerItem.java +++ b/src/main/java/org/feathercore/protogen/burger/BurgerItem.java @@ -35,49 +35,6 @@ public BurgerItem(JsonObject json) { this.id = json.get("numeric_id").getAsInt(); this.enumName = textId.toUpperCase().replace(".", "_"); this.maxStackSize = json.get("max_stack_size").getAsInt(); - /*if (jar != null && methodName != null && desc != null) { - // Parse isSolid - JsonPrimitive primitive = json.getAsJsonPrimitive("class"); - if (primitive != null) { - String className = primitive.getAsString(); - if (className == null) { - System.err.println("No class name for item: " + this.textId + "/" + this.id); - return; - } - JarEntry entry = jar.getJarEntry(className.concat(".class")); - if (entry == null) { - System.err.println("No class entry for item: " + this.textId + "/" + this.id + "/" + className); - return; - } - byte[] buffer = new byte[256]; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (InputStream in = jar.getInputStream(entry)) { - for (int r; ((r = in.read(buffer)) != -1); ) { - baos.write(buffer, 0, r); - } - } catch (IOException ex) { - System.err.println( - "Could not load class entry for item: " + this.textId + "/" + this.id + "/" + className); - ex.printStackTrace(); - return; - } - ClassNode cn = new ClassNode(); - new ClassReader(baos.toByteArray()).accept(cn, 0); - cn.methods.forEach(System.out::println); - for (MethodNode o : cn.methods) { - if (methodName.equals(o.name) && desc.equals(o.name)) { - InsnList list = o.instructions; - for (AbstractInsnNode node : list.toArray()) { - System.out.println(node); - } - break; - } - } - } - } else if (!warned) { - System.err.println("No jar file or method name/descriptor was specified. isSolid will not be resolved"); - warned = true; - }*/ } public String getEnumName() { From 1091b91ecafe09e1d1ccf52ecfbc675e5f09c01b Mon Sep 17 00:00:00 2001 From: xDark Date: Fri, 19 Apr 2019 17:09:10 +0300 Subject: [PATCH 3/8] Fix WikiReader does not work correct --- src/main/java/org/feathercore/protogen/Bootstrap.java | 2 +- src/main/java/org/feathercore/protogen/wiki/WikiReader.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/feathercore/protogen/Bootstrap.java b/src/main/java/org/feathercore/protogen/Bootstrap.java index b6b4da3..21afb3d 100644 --- a/src/main/java/org/feathercore/protogen/Bootstrap.java +++ b/src/main/java/org/feathercore/protogen/Bootstrap.java @@ -83,7 +83,7 @@ public static void main(String[] args) throws Exception { // TODO workaround please WIKI.setHandle(() -> new WikiReader(DEFAULT_VERSION.equals(version) ? "http://wiki.vg/Protocol" : - String.format("http://wiki.vg/index.php?title=Protocol&oldid=%s", version))); + String.format(WikiReader.URL, version))); GENERATORS.get(type).run(); } diff --git a/src/main/java/org/feathercore/protogen/wiki/WikiReader.java b/src/main/java/org/feathercore/protogen/wiki/WikiReader.java index 48ac6d6..aa37375 100644 --- a/src/main/java/org/feathercore/protogen/wiki/WikiReader.java +++ b/src/main/java/org/feathercore/protogen/wiki/WikiReader.java @@ -43,14 +43,14 @@ * @author Kristian */ public class WikiReader { - public static final String STANDARD_URL = "http://wiki.vg/index.php?title=Protocol&oldid=%s"; + 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(String version) throws IOException { - load(Jsoup.connect(String.format(STANDARD_URL, version)).get()); + public WikiReader(String url) throws IOException { + load(Jsoup.connect(url).get()); } private void load(Document doc) { From 564929545676b61b6adb27737f77bb43e5ddef7a Mon Sep 17 00:00:00 2001 From: xDark Date: Fri, 19 Apr 2019 17:16:05 +0300 Subject: [PATCH 4/8] Fix travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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: From 8593c2aa1fb494d2bef34e80cdf67e563198ce69 Mon Sep 17 00:00:00 2001 From: xDark Date: Fri, 19 Apr 2019 19:29:30 +0300 Subject: [PATCH 5/8] Simplify NetworkUtil --- .../org/feathercore/protogen/util/NetworkUtil.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/feathercore/protogen/util/NetworkUtil.java b/src/main/java/org/feathercore/protogen/util/NetworkUtil.java index 1488660..8493076 100644 --- a/src/main/java/org/feathercore/protogen/util/NetworkUtil.java +++ b/src/main/java/org/feathercore/protogen/util/NetworkUtil.java @@ -21,6 +21,7 @@ import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; +import java.util.stream.Collectors; /** * @author xtrafrancyz @@ -43,22 +44,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(); From 3cad9f5d1a9b428fced42d7be50524a3400183f5 Mon Sep 17 00:00:00 2001 From: xDark Date: Sat, 20 Apr 2019 15:24:16 +0300 Subject: [PATCH 6/8] List of supported versions, use required argument instead of optional --- pom.xml | 5 ++ .../org/feathercore/protogen/Bootstrap.java | 25 ++++---- .../protogen/version/MinecraftVersion.java | 59 +++++++++++++++++++ 3 files changed, 79 insertions(+), 10 deletions(-) create mode 100644 src/main/java/org/feathercore/protogen/version/MinecraftVersion.java diff --git a/pom.xml b/pom.xml index 2d8ade0..2ad4272 100644 --- a/pom.xml +++ b/pom.xml @@ -51,6 +51,11 @@ jopt-simple 5.0.4 + + org.ow2.asm + asm-all + 5.0.3 + diff --git a/src/main/java/org/feathercore/protogen/Bootstrap.java b/src/main/java/org/feathercore/protogen/Bootstrap.java index 21afb3d..3426732 100644 --- a/src/main/java/org/feathercore/protogen/Bootstrap.java +++ b/src/main/java/org/feathercore/protogen/Bootstrap.java @@ -26,6 +26,7 @@ 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; @@ -42,7 +43,7 @@ public class Bootstrap { private static final Path VALID_DIR; private static final Path BROKEN_DIR; - private static final String DEFAULT_VERSION = "1.13.2"; + private static final MinecraftVersion DEFAULT_VERSION = MinecraftVersion._1_13_2; private static final CachedDataSource BURGER = new CachedDataSource<>(); private static final CachedDataSource WIKI = new CachedDataSource<>(); @@ -66,24 +67,28 @@ public static void main(String[] args) throws Exception { .ofType(GeneratorType.class) .withValuesConvertedBy(new EnumConverter(GeneratorType.class) {}) .required(); - OptionSpec specVersion = parser.accepts("version") - .withOptionalArg() - .ofType(String.class) - .defaultsTo(DEFAULT_VERSION); + 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); - String version = options.valueOf(specVersion); + MinecraftVersion version = options.valueOf(specVersion); System.out.println("Generator: " + type + ", version: " + version); FileUtil.deleteRecursive(VALID_DIR); FileUtil.deleteRecursive(BROKEN_DIR); - BURGER.setHandle(() -> new BurgerReader(version)); + BURGER.setHandle(() -> new BurgerReader(version.getName())); // TODO workaround please - WIKI.setHandle(() -> new WikiReader(DEFAULT_VERSION.equals(version) ? - "http://wiki.vg/Protocol" : - String.format(WikiReader.URL, version))); + WIKI.setHandle(() -> new WikiReader(version.getLink())); GENERATORS.get(type).run(); } 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..cc208d6 --- /dev/null +++ b/src/main/java/org/feathercore/protogen/version/MinecraftVersion.java @@ -0,0 +1,59 @@ +/* + * 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"), + _1_8_9(47, createOldIdLink("7368"), "1.8.9"), + _1_9_4(110, createOldIdLink("7959"), "1.9.4"), + _1_10_2(210, createOldIdLink("8235"), "1.10.2"), + _1_11_2(316, createOldIdLink("8543"), "1.11.2"), + _1_12_2(340, createOldIdLink("14204"), "1.12.2"), + _1_13_2(404, "http://wiki.vg/Protocol", "1.13.2"); + + 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; + + MinecraftVersion(int protocolVersion, String link, String name) { + this.protocolVersion = protocolVersion; + this.link = link; + this.name = name; + } + + 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); + } + + @Override + public String toString() { + return name + "/" + protocolVersion; + } +} From b9ee929a0a1e0ff832ca589419860de3c4e152c7 Mon Sep 17 00:00:00 2001 From: xDark Date: Sat, 20 Apr 2019 15:34:38 +0300 Subject: [PATCH 7/8] Start working on isSolid parser --- pom.xml | 14 ++++- .../feathercore/protogen/util/FileUtil.java | 5 +- .../protogen/util/MaterialUtil.java | 59 +++++++++++++++++++ .../protogen/util/NetworkUtil.java | 5 +- 4 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/feathercore/protogen/util/MaterialUtil.java diff --git a/pom.xml b/pom.xml index 2ad4272..e98a500 100644 --- a/pom.xml +++ b/pom.xml @@ -53,8 +53,18 @@ org.ow2.asm - asm-all - 5.0.3 + 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/util/FileUtil.java b/src/main/java/org/feathercore/protogen/util/FileUtil.java index 44f4333..8b23ee4 100644 --- a/src/main/java/org/feathercore/protogen/util/FileUtil.java +++ b/src/main/java/org/feathercore/protogen/util/FileUtil.java @@ -24,7 +24,10 @@ /** * @author xtrafrancyz */ -public class FileUtil { +public final class FileUtil { + + private FileUtil() { } + public static void writeFile(Path file, String content) { try { Path parent = file.getParent(); 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..f172bba --- /dev/null +++ b/src/main/java/org/feathercore/protogen/util/MaterialUtil.java @@ -0,0 +1,59 @@ +/* + * 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 org.objectweb.asm.ClassReader; +import org.objectweb.asm.tree.ClassNode; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.net.URI; +import java.nio.file.*; +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +public final class MaterialUtil { + + private MaterialUtil() { } + + public static Set buildSolidMaterials(Path jar, String initClass, MinecraftVersion version) throws IOException { + URI uri = jar.toUri(); + // Prevent encoding issues, meh + try { + Field field = URI.class.getDeclaredField("scheme"); + field.setAccessible(true); + field.set(uri, "jar:file"); + } catch (IllegalAccessException | NoSuchFieldException ex) { + ex.printStackTrace(); + uri = URI.create("jar:file:" + uri.getPath()); + } + ClassNode classNode; + try (FileSystem fs = FileSystems.newFileSystem(uri, Collections.emptyMap())) { + Path path = fs.getPath(initClass.concat(".class").replace('.', '/')); + if (!Files.exists(path)) { + throw new FileSystemException("No such class: " + initClass); + } + try (InputStream in = Files.newInputStream(path)) { + classNode = new ClassNode(); + new ClassReader(in).accept(classNode, 0); + } + } + } +} diff --git a/src/main/java/org/feathercore/protogen/util/NetworkUtil.java b/src/main/java/org/feathercore/protogen/util/NetworkUtil.java index 8493076..a0ef7fe 100644 --- a/src/main/java/org/feathercore/protogen/util/NetworkUtil.java +++ b/src/main/java/org/feathercore/protogen/util/NetworkUtil.java @@ -26,7 +26,10 @@ /** * @author xtrafrancyz */ -public class NetworkUtil { +public final class NetworkUtil { + + private NetworkUtil() { } + public static String get(String url) throws IOException { HttpURLConnection conn = null; try { From 05dbbd79309cc56d1bdad8c2fd44a7a1dd0b0a12 Mon Sep 17 00:00:00 2001 From: xDark Date: Sat, 20 Apr 2019 16:27:51 +0300 Subject: [PATCH 8/8] More stuff for searching --- .../org/feathercore/protogen/Bootstrap.java | 2 +- .../protogen/burger/BurgerReader.java | 9 ++- .../protogen/util/MaterialUtil.java | 74 ++++++++++++------- .../protogen/version/MinecraftVersion.java | 44 +++++++++-- 4 files changed, 92 insertions(+), 37 deletions(-) diff --git a/src/main/java/org/feathercore/protogen/Bootstrap.java b/src/main/java/org/feathercore/protogen/Bootstrap.java index 3426732..10572a2 100644 --- a/src/main/java/org/feathercore/protogen/Bootstrap.java +++ b/src/main/java/org/feathercore/protogen/Bootstrap.java @@ -86,7 +86,7 @@ public MinecraftVersion convert(String value) { FileUtil.deleteRecursive(VALID_DIR); FileUtil.deleteRecursive(BROKEN_DIR); - BURGER.setHandle(() -> new BurgerReader(version.getName())); + BURGER.setHandle(() -> new BurgerReader(version)); // TODO workaround please WIKI.setHandle(() -> new WikiReader(version.getLink())); GENERATORS.get(type).run(); diff --git a/src/main/java/org/feathercore/protogen/burger/BurgerReader.java b/src/main/java/org/feathercore/protogen/burger/BurgerReader.java index 6b055fa..881b1c0 100644 --- a/src/main/java/org/feathercore/protogen/burger/BurgerReader.java +++ b/src/main/java/org/feathercore/protogen/burger/BurgerReader.java @@ -21,6 +21,7 @@ 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.IOException; import java.util.*; @@ -38,11 +39,11 @@ public class BurgerReader { private List items; private Map blocks; - public BurgerReader(String version) throws IOException { - parse(NetworkUtil.get(String.format(URL, version))); + 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() @@ -56,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/util/MaterialUtil.java b/src/main/java/org/feathercore/protogen/util/MaterialUtil.java index f172bba..2feb5fe 100644 --- a/src/main/java/org/feathercore/protogen/util/MaterialUtil.java +++ b/src/main/java/org/feathercore/protogen/util/MaterialUtil.java @@ -17,43 +17,67 @@ package org.feathercore.protogen.util; import org.feathercore.protogen.version.MinecraftVersion; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.tree.ClassNode; import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.net.URI; -import java.nio.file.*; +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.Map; +import java.util.Optional; import java.util.Set; public final class MaterialUtil { private MaterialUtil() { } - public static Set buildSolidMaterials(Path jar, String initClass, MinecraftVersion version) throws IOException { - URI uri = jar.toUri(); - // Prevent encoding issues, meh + 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 { - Field field = URI.class.getDeclaredField("scheme"); - field.setAccessible(true); - field.set(uri, "jar:file"); - } catch (IllegalAccessException | NoSuchFieldException ex) { + klass = Class.forName(version.getBlockClass(), true, loader); + } catch (ClassNotFoundException ex) { + System.err.println("Class loader failed to load class, skipping isSolid"); ex.printStackTrace(); - uri = URI.create("jar:file:" + uri.getPath()); + return Collections.emptySet(); } - ClassNode classNode; - try (FileSystem fs = FileSystems.newFileSystem(uri, Collections.emptyMap())) { - Path path = fs.getPath(initClass.concat(".class").replace('.', '/')); - if (!Files.exists(path)) { - throw new FileSystemException("No such class: " + initClass); - } - try (InputStream in = Files.newInputStream(path)) { - classNode = new ClassNode(); - new ClassReader(in).accept(classNode, 0); - } + // 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/version/MinecraftVersion.java b/src/main/java/org/feathercore/protogen/version/MinecraftVersion.java index cc208d6..24e63a4 100644 --- a/src/main/java/org/feathercore/protogen/version/MinecraftVersion.java +++ b/src/main/java/org/feathercore/protogen/version/MinecraftVersion.java @@ -17,23 +17,31 @@ package org.feathercore.protogen.version; public enum MinecraftVersion { - _1_8_8(47, createOldIdLink("7368"), "1.8.8"), - _1_8_9(47, createOldIdLink("7368"), "1.8.9"), - _1_9_4(110, createOldIdLink("7959"), "1.9.4"), - _1_10_2(210, createOldIdLink("8235"), "1.10.2"), - _1_11_2(316, createOldIdLink("8543"), "1.11.2"), - _1_12_2(340, createOldIdLink("14204"), "1.12.2"), - _1_13_2(404, "http://wiki.vg/Protocol", "1.13.2"); + _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) { + 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() { @@ -52,6 +60,26 @@ 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;