Skip to content

Commit

Permalink
Implement sided sets for mixin configurations
Browse files Browse the repository at this point in the history
  • Loading branch information
Mumfrey committed Jan 12, 2015
1 parent 412914b commit e28affd
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 5 deletions.
83 changes: 82 additions & 1 deletion src/main/java/org/spongepowered/asm/mixin/MixinEnvironment.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
*/
package org.spongepowered.asm.mixin;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -37,12 +38,72 @@
* Env interaction for mixins
*/
public class MixinEnvironment {

public static enum Side {
/**
* The environment was unable to determine current side
*/
UNKNOWN {
@Override
protected boolean detect() {
return false;
}
},

/**
* Client-side environment
*/
CLIENT {
@Override
protected boolean detect() {
String sideName = this.getSideName();
return "CLIENT".equals(sideName);
}
},

/**
* (Dedicated) Server-side environment
*/
SERVER {
@Override
protected boolean detect() {
String sideName = this.getSideName();
return "SERVER".equals(sideName) || "DEDICATEDSERVER".equals(sideName);
}
};

protected abstract boolean detect();

protected final String getSideName() {
try {
Class<?> fmlLaunchHandler = Class.forName("net.minecraftforge.fml.relauncher.FMLLaunchHandler", false, Launch.classLoader);
Method mdSide = fmlLaunchHandler.getDeclaredMethod("side");
Enum<?> side = (Enum<?>)mdSide.invoke(null);
return side.name();
} catch (Exception ex) {
// nope
}

try {
Class<?> liteLoaderCore = Class.forName("com.mumfrey.liteloader.core.LiteLoader", false, Launch.classLoader);
Method mdEnvironment = liteLoaderCore.getDeclaredMethod("getEnvironmentType");
Enum<?> envType = (Enum<?>)mdEnvironment.invoke(null);
return envType.name();
} catch (Exception ex) {
// nope
}

return "UNKNOWN";
}
}

private static final String CONFIGS_KEY = "mixin.configs";
private static final String TRANSFORMER_KEY = "mixin.transformer";

private static MixinEnvironment env;

private Side side;

private MixinEnvironment() {
// Sanity check
Object version = Launch.blackboard.get(MixinBootstrap.INIT_KEY);
Expand Down Expand Up @@ -87,6 +148,26 @@ public Object getActiveTransformer() {
public void setActiveTransformer(IClassTransformer transformer) {
Launch.blackboard.put(MixinEnvironment.TRANSFORMER_KEY, this);
}

public MixinEnvironment setSide(Side side) {
if (side != null && this.getSide() == Side.UNKNOWN && side != Side.UNKNOWN) {
this.side = side;
}
return this;
}

public Side getSide() {
if (this.side == null) {
for (Side side : Side.values()) {
if (side.detect()) {
this.side = side;
break;
}
}
}

return this.side != null ? this.side : Side.UNKNOWN;
}

public static MixinEnvironment getCurrentEnvironment() {
if (MixinEnvironment.env == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@

import net.minecraft.launchwrapper.Launch;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.spongepowered.asm.mixin.MixinEnvironment;
import org.spongepowered.asm.mixin.injection.struct.ReferenceMapper;

import com.google.gson.Gson;
Expand All @@ -41,6 +44,11 @@
* Mixin configuration bundle
*/
class MixinConfig {

/**
* Log even more things
*/
private final Logger logger = LogManager.getLogger("mixin");

/**
* Map of mixin target classes to mixin infos
Expand All @@ -60,6 +68,18 @@ class MixinConfig {
@SerializedName("mixins")
private List<String> mixinClasses;

/**
* Mixin classes to load ONLY on client, mixinPackage will be prepended
*/
@SerializedName("client")
private List<String> mixinClassesClient;

/**
* Mixin classes to load ONLY on dedicated server, mixinPackage will be prepended
*/
@SerializedName("server")
private List<String> mixinClassesServer;

/**
* True to set the sourceFile property when applying mixins
*/
Expand All @@ -72,6 +92,11 @@ class MixinConfig {
@SerializedName("referenceMap")
private String refMapperConfig;

/**
* Name of the file this config was initialised from
*/
private transient String name;

/**
* Reference mapper for injectors
*/
Expand All @@ -90,7 +115,9 @@ private MixinConfig() {}
/**
* Called immediately after deserialisation
*/
private void onLoad() {
private void onLoad(String name) {
this.name = name;

if (!this.mixinPackage.endsWith(".")) {
this.mixinPackage += ".";
}
Expand All @@ -116,7 +143,30 @@ private void onLoad() {
private void initialise() {
this.initialised = true;

for (String mixinClass : this.mixinClasses) {
this.initialiseSide(this.mixinClasses);

switch (MixinEnvironment.getCurrentEnvironment().getSide()) {
case CLIENT :
this.initialiseSide(this.mixinClassesClient);
break;
case SERVER :
this.initialiseSide(this.mixinClassesServer);
break;
case UNKNOWN :
this.logger.warn("Mixin environment was unable to detect the current side, sided mixins will not be applied");
break;
}
}

private void initialiseSide(List<String> mixinClasses) {
if (mixinClasses == null) {
return;
}

for (String mixinClass : mixinClasses) {
if (mixinClass == null) {
continue;
}
try {
MixinInfo mixin = new MixinInfo(this, mixinClass, true);
for (String targetClass : mixin.getTargetClasses()) {
Expand All @@ -127,7 +177,14 @@ private void initialise() {
}
}
}


/**
* Get the name of the file from which this configuration object was initialised
*/
public String getName() {
return this.name;
}

/**
* Get the package containing all mixin classes
*/
Expand Down Expand Up @@ -202,7 +259,7 @@ private List<MixinInfo> mixinsFor(String targetClass) {
static MixinConfig create(String configFile) {
try {
MixinConfig config = new Gson().fromJson(new InputStreamReader(Launch.classLoader.getResourceAsStream(configFile)), MixinConfig.class);
config.onLoad();
config.onLoad(configFile);
return config;
} catch (Exception ex) {
ex.printStackTrace();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ public class MixinData {
this.targetClass = target;
this.prepare();
}

/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return String.format("%s:%s", this.info.getParent().getName(), this.info.getName());
}

/**
* Get the mixin tree
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ private static byte[] getClassBytes(String className) throws IOException {
final String resourcePath = className.replace('.', '/').concat(".class");
classStream = appClassLoader.getResourceAsStream(resourcePath);
return IOUtils.toByteArray(classStream);
} catch (Exception ex) {
return null;
} finally {
IOUtils.closeQuietly(classStream);
}
Expand Down

0 comments on commit e28affd

Please sign in to comment.