diff --git a/build.gradle b/build.gradle index 57adf2ac3..7675cc6ad 100644 --- a/build.gradle +++ b/build.gradle @@ -73,10 +73,24 @@ task rebuildAndroidStubs(type: JavaExec, dependsOn: classes) { } classpath = sourceSets.main.runtimeClasspath - mainClass = 'com.reider745.api.hooks.RebuildJavadoc' + mainClass = 'com.reider745.api.hooks.instrument.RebuildJavadoc' args '.todo/android.jar', 'iclibs/android.jar', 'proxy' } + +task buildBlockDump(type: JavaExec, dependsOn: classes) { + javaLauncher = javaToolchains.launcherFor { + def javaVersion = JavaVersion.toVersion(targetJavaVersion) + if (JavaVersion.current() < javaVersion) { + languageVersion = JavaLanguageVersion.of(targetJavaVersion) + } + } + + classpath = sourceSets.main.runtimeClasspath + mainClass = 'com.reider745.api.hooks.instrument.BlockDump' + workingDir = "target" +} + task rebuildZoteStubs(type: JavaExec, dependsOn: jar) { javaLauncher = javaToolchains.launcherFor { def javaVersion = JavaVersion.toVersion(targetJavaVersion) diff --git a/src/main/java/com/reider745/Main.java b/src/main/java/com/reider745/Main.java index 469936070..0d7521508 100644 --- a/src/main/java/com/reider745/Main.java +++ b/src/main/java/com/reider745/Main.java @@ -4,12 +4,10 @@ import java.lang.reflect.InvocationTargetException; import java.util.Arrays; +import cn.nukkit.utils.BinaryStream; import com.reider745.api.hooks.JarEditor; -import javassist.CannotCompileException; -import javassist.CtMethod; -import javassist.Modifier; -import javassist.NotFoundException; +import javassist.*; import javassist.bytecode.LineNumberAttribute; public class Main { @@ -44,6 +42,50 @@ public static void main(String[] args) throws Throwable { add("com.reider745.hooks.block.BlockPalette"); add("com.reider745.hooks.item.ItemUtils"); add("com.reider745.hooks.item.RuntimeItemsHooks"); + loader.addInit("com.reider745.hooks.block.BlocksHooks", ctClass -> { + final ClassPool pool = loader.getClassPool(); + final BinaryStream stream = new BinaryStream(Main.class.getClassLoader().getResourceAsStream("blocksDump.bin").readAllBytes()); + + final int countClass = stream.getShort(); + for(int i = 0;i < countClass;i++) { + final CtClass classPatch = pool.get(stream.getString()); + final int countMethods = stream.getByte(); + + for(int a = 0;a < countMethods;a++) { + final CtMethod methodPatch = classPatch.getDeclaredMethod(stream.getString()); + + if(methodPatch.getName().equals("isSolid")) { + methodPatch.insertBefore("Boolean val = com.reider745.hooks.block.BlocksHooks.isSolid(this);\n" + + "if(val != null)\n" + + "return val.booleanValue();"); + } + + if(methodPatch.getName().equals("getHardness")) { + methodPatch.insertBefore("Double val = com.reider745.hooks.block.BlocksHooks.getHardness(this);\n" + + "if(val != null)\n" + + "return val.doubleValue();"); + } + + if(methodPatch.getName().equals("getResistance")) { + methodPatch.insertBefore("Double val = com.reider745.hooks.block.BlocksHooks.getResistance(this);\n" + + "if(val != null)\n" + + "return val.doubleValue();"); + } + + if(methodPatch.getName().equals("getFrictionFactor")) { + methodPatch.insertBefore("Double val = com.reider745.hooks.block.BlocksHooks.getFrictionFactor(this);\n" + + "if(val != null)\n" + + "return val.doubleValue();"); + } + + if(methodPatch.getName().equals("getLightLevel")) { + methodPatch.insertBefore("Integer val = com.reider745.hooks.block.BlocksHooks.getLightLevel(this);\n" + + "if(val != null)\n" + + "return val.intValue();"); + } + } + } + }); add("com.reider745.hooks.block.BlocksHooks"); loader.addRebuildField("com.reider745.hooks.block.BlocksHooks", (ctClass, field) -> { String name = field.getName(); diff --git a/src/main/java/com/reider745/api/hooks/JarEditor.java b/src/main/java/com/reider745/api/hooks/JarEditor.java index 1309178b8..fb41b0baf 100644 --- a/src/main/java/com/reider745/api/hooks/JarEditor.java +++ b/src/main/java/com/reider745/api/hooks/JarEditor.java @@ -5,6 +5,7 @@ import javassist.*; import javassist.bytecode.*; +import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -15,6 +16,7 @@ public class JarEditor { private final HookClassLoader classLoader; private final ClassPool classPool = new ClassPool(); private final ClassPath classPath; + private final ArrayList initClasses = new ArrayList<>(); public JarEditor() { classLoader = new HookClassLoader(Main.class.getClassLoader(), classPool); @@ -23,6 +25,10 @@ public JarEditor() { classPool.insertClassPath(classPath); } + public void addInitClass(String clazz) { + initClasses.add(clazz); + } + public static final class RetNull { } @@ -34,6 +40,10 @@ private static record HookData(String className, String method, String signature private static final HashMap> ALL_HOOKS = new HashMap<>(); private static final HashMap loadedHookClass = new HashMap<>(); + public ClassPool getClassPool() { + return classPool; + } + private void addHookInitialization(String className, String method, String sig, CtMethod replaced, TypeHook typeHook, boolean controller, ArgumentTypes argumentMap) { ArrayList hooks = ALL_HOOKS.get(className); @@ -195,7 +205,7 @@ public CtClass get(String name) throws NotFoundException { public interface IInit { - void call(CtClass ctClass); + void call(CtClass ctClass) throws IOException, NotFoundException, CannotCompileException, BadBytecode; } private HashMap inits = new HashMap<>(); @@ -532,7 +542,14 @@ public static Method get(Class clazz, String method) { public JarEditor run(String mainClass, String... args) { try { Thread.currentThread().setContextClassLoader(classLoader); - classLoader.loadClass(mainClass).getMethod("main", String[].class).invoke(null, new Object[] { args }); + for(String initClass : initClasses) { + classLoader.loadClass(initClass) + .getMethod("preInit", String.class, String[].class) + .invoke(null, mainClass, args); + } + classLoader.loadClass(mainClass) + .getMethod("main", String[].class) + .invoke(null, new Object[] { args }); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/main/java/com/reider745/api/hooks/RebuildJavadoc.java b/src/main/java/com/reider745/api/hooks/instrument/RebuildJavadoc.java similarity index 99% rename from src/main/java/com/reider745/api/hooks/RebuildJavadoc.java rename to src/main/java/com/reider745/api/hooks/instrument/RebuildJavadoc.java index f5c707491..ebc6b8d82 100644 --- a/src/main/java/com/reider745/api/hooks/RebuildJavadoc.java +++ b/src/main/java/com/reider745/api/hooks/instrument/RebuildJavadoc.java @@ -1,4 +1,4 @@ -package com.reider745.api.hooks; +package com.reider745.api.hooks.instrument; import javassist.*; import javassist.bytecode.AccessFlag; diff --git a/src/main/java/com/reider745/behavior/BehaviorPack.java b/src/main/java/com/reider745/behavior/BehaviorPack.java index 9c33d0245..4313e7be3 100644 --- a/src/main/java/com/reider745/behavior/BehaviorPack.java +++ b/src/main/java/com/reider745/behavior/BehaviorPack.java @@ -1,6 +1,7 @@ package com.reider745.behavior; import com.reider745.behavior.entities.EntitiesContent; +import com.reider745.behavior.items.ItemsContent; import com.reider745.behavior.spawnrules.SpawnRulesContent; import com.zhekasmirnov.horizon.runtime.logger.Logger; import com.zhekasmirnov.horizon.util.FileUtils; @@ -17,6 +18,7 @@ public class BehaviorPack { static { contents_api.add(new EntitiesContent()); contents_api.add(new SpawnRulesContent()); + contents_api.add(new ItemsContent()); } private final String path; diff --git a/src/main/java/com/reider745/block/BlockMethods.java b/src/main/java/com/reider745/block/BlockMethods.java index 9d66b986a..a3d55042a 100644 --- a/src/main/java/com/reider745/block/BlockMethods.java +++ b/src/main/java/com/reider745/block/BlockMethods.java @@ -27,7 +27,7 @@ private static Byte2ObjectOpenHashMap assureId2Type(int id) { return type; } - private static Object getOrDefault(int id, byte property, Object defaultValue) { + public static Object getOrDefault(int id, byte property, Object defaultValue) { Byte2ObjectOpenHashMap type = id2typeMap.get(id); return type != null ? type.getOrDefault(property, defaultValue) : defaultValue; } diff --git a/src/main/java/com/reider745/hooks/block/BlocksHooks.java b/src/main/java/com/reider745/hooks/block/BlocksHooks.java index 01a710640..29478ba9b 100644 --- a/src/main/java/com/reider745/hooks/block/BlocksHooks.java +++ b/src/main/java/com/reider745/hooks/block/BlocksHooks.java @@ -14,30 +14,23 @@ public static void init() { // ReflectHelper.setField(Block.class, "usesFakeWater", new boolean[MAX_ID]); } - // TODO: не поддерживается переопределение свойств накита - - /*@Inject - public static boolean isSolid(Block self) { - return BlockMethods.isSolid(self.getId()); + public static Boolean isSolid(Block self) { + return (Boolean) BlockMethods.getOrDefault(self.getId(), BlockMethods.SOLID, null); } - @Inject - public static double getHardness(Block self) { - return BlockMethods.getDestroyTime(self.getId()); + public static Double getHardness(Block self) { + return (Double) BlockMethods.getOrDefault(self.getId(), BlockMethods.DESTROY_TIME, null); } - @Inject - public static double getResistance(Block self) { - return BlockMethods.getExplosionResistance(self.getId()); + public static Double getResistance(Block self) { + return (Double) BlockMethods.getOrDefault(self.getId(), BlockMethods.EXPLOSION_RESISTANCE, null); } - @Inject - public static double getFrictionFactor(Block self) { - return BlockMethods.getFriction(self.getId()); + public static Double getFrictionFactor(Block self) { + return (Double) BlockMethods.getOrDefault(self.getId(), BlockMethods.FRICTION, null); } - @Inject - public static int getLightLevel(Block self) { - return BlockMethods.getLightLevel(self.getId()); - }*/ + public static Integer getLightLevel(Block self) { + return (Integer) BlockMethods.getOrDefault(self.getId(), BlockMethods.LIGHT_LEVEL, null); + } } diff --git a/src/main/java/com/zhekasmirnov/horizon/launcher/env/ClassLoaderPatch.java b/src/main/java/com/zhekasmirnov/horizon/launcher/env/ClassLoaderPatch.java index 51dfc70ac..366c24cbf 100644 --- a/src/main/java/com/zhekasmirnov/horizon/launcher/env/ClassLoaderPatch.java +++ b/src/main/java/com/zhekasmirnov/horizon/launcher/env/ClassLoaderPatch.java @@ -29,7 +29,7 @@ import java.util.stream.Stream; import com.googlecode.d2j.dex.Dex2jar; -import com.reider745.api.hooks.RebuildJavadoc; +import com.reider745.api.hooks.instrument.RebuildJavadoc; import com.zhekasmirnov.horizon.runtime.logger.Logger; import com.zhekasmirnov.horizon.util.FileUtils;