aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/ftbsc/lll/mixin/LilleroMixin.java
blob: 835a77f9d8a315bf3de006f28d618ac40c53d664 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package ftbsc.lll.mixin;

import ftbsc.lll.IInjector;
import ftbsc.lll.exceptions.InjectionException;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;

import java.util.*;

public class LilleroMixin implements IMixinConfigPlugin {

   private final Map<String, List<IInjector>> injectorMap = new HashMap<>();

   /**
    * Called after the plugin is instantiated, do any setup here.
    * @param mixinPackage The mixin root package from the config
    */
   @Override
   public void onLoad(String mixinPackage) {
      for (IInjector inj : ServiceLoader.load(IInjector.class, this.getClass().getClassLoader())) {
         //LOGGER.info(RESOURCE, "Registering injector {}", inj.name());
         List<IInjector> injectors = this.injectorMap.get(inj.targetClass());
         if(injectors == null) {
            injectors = new ArrayList<>();
            injectorMap.put(inj.targetClass(), injectors);
         }
         injectors.add(inj);
      }
   }

   /**
    * Called only if the "referenceMap" key in the config is <b>not</b> set.
    * This allows the refmap file name to be supplied by the plugin
    * programatically if desired. Returning <code>null</code> will revert to
    * the default behaviour of using the default refmap json file.
    *
    * @return Path to the refmap resource or null to revert to the default
    */
   @Override //TODO ?
   public String getRefMapperConfig() {
      return null;
   }

   /**
    * Called during mixin intialisation, allows this plugin to control whether
    * a specific will be applied to the specified target. Returning false will
    * remove the target from the mixin's target set, and if all targets are
    * removed then the mixin will not be applied at all.
    *
    * @param targetClassName Fully qualified class name of the target class
    * @param mixinClassName  Fully qualified class name of the mixin
    * @return True to allow the mixin to be applied, or false to remove it from
    * target's mixin set
    */
   @Override
   public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
      return true;
   }

   /**
    * Called after all configurations are initialised, this allows this plugin
    * to observe classes targetted by other mixin configs and optionally remove
    * targets from its own set. The set myTargets is a direct view of the
    * targets collection in this companion config and keys may be removed from
    * this set to suppress mixins in this config which target the specified
    * class. Adding keys to the set will have no effect.
    *
    * @param myTargets    Target class set from the companion config
    * @param otherTargets Target class set incorporating targets from all other
    *                     configs, read-only
    */
   @Override
   public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {

   }

   /**
    * After mixins specified in the configuration have been processed, this
    * method is called to allow the plugin to add any additional mixins to
    * load. It should return a list of mixin class names or return null if the
    * plugin does not wish to append any mixins of its own.
    *
    * @return additional mixins to apply
    */
   @Override
   public List<String> getMixins() {
      return null;
   }

   /**
    * Called immediately <b>before</b> a mixin is applied to a target class,
    * allows any pre-application transformations to be applied.
    *
    * @param targetClassName Transformed name of the target class
    * @param targetClass     Target class tree
    * @param mixinClassName  Name of the mixin class
    * @param mixinInfo       Information about this mixin
    */
   @Override
   public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
      injectorMap.get(targetClassName).forEach((inj) -> targetClass.methods.stream()
         .filter(m -> m.name.equals(inj.methodName()) && m.desc.equals(inj.methodDesc()))
         .forEach(m -> {
            try {
               inj.inject(targetClass, m);
            } catch (InjectionException ignored) {} //TODO log
         }));
   }

   /**
    * Called immediately <b>after</b> a mixin is applied to a target class,
    * allows any post-application transformations to be applied.
    *
    * @param targetClassName Transformed name of the target class
    * @param targetClass     Target class tree
    * @param mixinClassName  Name of the mixin class
    * @param mixinInfo       Information about this mixin
    */
   @Override
   public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {

   }
}