From ea6e131b60113841f3fa69696a974d0e63661b96 Mon Sep 17 00:00:00 2001 From: Zaxar163 <zahar.vcherachny@yandex.ru> Date: Tue, 14 Jan 2020 18:01:59 +0100 Subject: [PATCH] =?UTF-8?q?[FEATURE]=20=D0=90=D0=BD=D0=BD=D0=BE=D1=82?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20LauncherInject=20=D0=B8=20=D0=B2?= =?UTF-8?q?=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D1=8C=20?= =?UTF-8?q?=D0=B5=D1=91=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F.=20=D0=94=D0=BB=D1=8F=20=D0=B8?= =?UTF-8?q?=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BD=D1=83=D0=B6=D0=B5=D0=BD=20BuildTask=20?= =?UTF-8?q?=D0=BF=D0=BE=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=80=D1=83=20Pat?= =?UTF-8?q?cher`=D0=B0,=20=D0=BD=D0=BE=20=D1=81=20=D0=BA=D0=BE=D0=BD=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D1=81=D0=B8=D0=B5=D0=B9=20=D0=B2=20=D0=BA=D0=BB?= =?UTF-8?q?=D0=B0=D1=81=D1=81=D0=BD=D0=BE=D0=B4=D1=83=20=D0=B8=20=D0=BE?= =?UTF-8?q?=D0=B1=D1=80=D0=B0=D1=82=D0=BD=D0=BE.=20=D0=A7=D1=82=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=D0=B0=20?= =?UTF-8?q?=D0=B4=D0=BE=D0=BB=D0=B6=D0=BD=D0=BE=20=D0=B1=D1=8B=D1=82=D1=8C?= =?UTF-8?q?=20=D1=81=20EXPAND=5FFRAMES,=20=D0=B0=20=D0=B7=D0=B0=D0=BF?= =?UTF-8?q?=D0=B8=D1=81=D1=8C=20=D1=81=200=20(=D0=B1=D0=B5=D0=B7=20COMPUTE?= =?UTF-8?q?=5FFRAMES).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../launchserver/asm/InjectClassAcceptor.java | 51 +++++++++++++++++++ .../pro/gravit/launcher/LauncherInject.java | 13 +++++ 2 files changed, 64 insertions(+) create mode 100644 LaunchServer/src/main/java/pro/gravit/launchserver/asm/InjectClassAcceptor.java create mode 100644 LauncherCore/src/main/java/pro/gravit/launcher/LauncherInject.java diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/asm/InjectClassAcceptor.java b/LaunchServer/src/main/java/pro/gravit/launchserver/asm/InjectClassAcceptor.java new file mode 100644 index 00000000..f8246e95 --- /dev/null +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/asm/InjectClassAcceptor.java @@ -0,0 +1,51 @@ +package pro.gravit.launchserver.asm; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; + +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.AnnotationNode; +import org.objectweb.asm.tree.ClassNode; + +import pro.gravit.launcher.LauncherInject; + +public class InjectClassAcceptor { + public static final Class<?>[] primitives = new Class<?>[] { java.lang.Boolean.class, java.lang.Character.class, + java.lang.Byte.class, java.lang.Short.class, java.lang.Integer.class, java.lang.Long.class, + java.lang.Float.class, java.lang.Double.class, java.lang.String.class }; + + public static final List<Class<?>> zPrimitivesList = Arrays.asList(primitives); + public static final String INJ_DESC = Type.getDescriptor(LauncherInject.class); + + public static void visit(ClassNode cn, Map<String, Object> object) { + if (!object.values().stream().allMatch(zPrimitivesList::contains)) + throw new IllegalArgumentException("Only primitives in values..."); + cn.fields.stream().filter(e -> e.invisibleAnnotations != null) + .filter(e -> e.invisibleAnnotations.stream().anyMatch(f -> f.desc.equals(INJ_DESC))).forEach(e -> { + // Notice that fields that will be used with this algo should not have default + // value by = ...; + AnnotationNode n = e.invisibleAnnotations.stream().filter(f -> INJ_DESC.equals(f.desc)).findFirst() + .get(); + AtomicReference<String> valueName = new AtomicReference<>(null); + n.accept(new AnnotationVisitor(Opcodes.ASM7) { + @Override + public void visit(final String name, final Object value) { + if ("value".equals(name)) { + if (value.getClass() != String.class) + throw new IllegalArgumentException( + "Invalid Annotation with value class " + e.getClass().getName()); + valueName.set(value.toString()); + } + } + }); + if (valueName.get() == null) + throw new IllegalArgumentException("Annotation should always contains 'value' key"); + if (object.containsKey(valueName.get())) + e.value = object.get(valueName.get()); + }); + } +} diff --git a/LauncherCore/src/main/java/pro/gravit/launcher/LauncherInject.java b/LauncherCore/src/main/java/pro/gravit/launcher/LauncherInject.java new file mode 100644 index 00000000..b11647c1 --- /dev/null +++ b/LauncherCore/src/main/java/pro/gravit/launcher/LauncherInject.java @@ -0,0 +1,13 @@ +package pro.gravit.launcher; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.CLASS; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(CLASS) +@Target(FIELD) +public @interface LauncherInject { + public String value(); // target of inject +}