Skip to content

Commit

Permalink
Made the mod a modlauncher service, so we can now transform fastutil
Browse files Browse the repository at this point in the history
YAY
  • Loading branch information
jediminer543 committed Oct 2, 2020
1 parent 1835236 commit 2edca8b
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 2 deletions.
7 changes: 6 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=false

mcmt_ver=0.16.50
mcmt_ver=0.17.52

mappings_ver =20200723-1.16.1
mappings_chan=snapshot
Expand All @@ -18,6 +18,11 @@ fg_ver=32.0.106
#mc_ver=1.16.2
#fg_ver=33.0.5

# 1.16.3
# 1.16.3-34.0.5
#mc_ver=1.16.3
#fg_ver=34.0.1

# 1.15.2
# 1.15.2-31.2.31
#mc_ver=1.15.2
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/org/jmt/mcmt/commands/StatsCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ public static void setServer(MinecraftServer nmcs) {
public static void resetAll() {
resetThreadStats = true;
}

static int warningDelay = 15000;

public static void resetWarnDelay() {
warningDelay = 15000;
}

public static void runDataThread() {
statsThread = new Thread(() -> {
Expand Down Expand Up @@ -186,8 +192,10 @@ public static void runDataThread() {
}

warnLog++;
if (warnLog % 15000 == 0) {
if (warnLog % warningDelay == 0) {
mtlog.warn("MCMT is enabled; error logs are invalid for any other mods");
warningDelay *= 1.2;
warningDelay = Math.min(warningDelay, 720000); // Max delay ~~ 2 hours
}
}
} catch (Exception e) {
Expand Down
164 changes: 164 additions & 0 deletions src/main/java/org/jmt/mcmt/modlauncher/FastUtilTransformerService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package org.jmt.mcmt.modlauncher;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.Map.Entry;
import java.util.function.Function;
import java.util.function.Supplier;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;

import cpw.mods.modlauncher.api.IEnvironment;
import cpw.mods.modlauncher.api.ITransformationService;
import cpw.mods.modlauncher.api.ITransformer;
import cpw.mods.modlauncher.api.ITransformerVotingContext;
import cpw.mods.modlauncher.api.IncompatibleEnvironmentException;
import cpw.mods.modlauncher.api.TransformerVoteResult;

public class FastUtilTransformerService implements ITransformer<ClassNode>, ITransformationService {

private static final Logger LOGGER = LogManager.getLogger();
private boolean isActive = true;

@Override
public String name() {
return "sync_fu";
}

@Override
public void initialize(IEnvironment environment) {}

@Override
public void beginScanning(IEnvironment environment) {}

@Override
public void onLoad(IEnvironment env, Set<String> otherServices) throws IncompatibleEnvironmentException {}


@Override
public Entry<Set<String>, Supplier<Function<String, Optional<URL>>>> additionalClassesLocator() {
LOGGER.info("Sync_Fu preparing...");
Optional<URL> fujarurl = Arrays.stream(System.getProperty("java.class.path").split(File.pathSeparator)).flatMap(path -> {
File file = new File(path);
if (file.isDirectory()) {
return Arrays.stream(file.list((d, n) -> n.endsWith(".jar")));
}
return Arrays.stream(new String[] {path});
})
.filter(p -> p.contains("fastutil")) // Can add more if necesary;
.map(Paths::get)
.map(path -> {
try {
return path.toUri().toURL();
} catch (Exception e) {
return null;
}
}).findFirst();
URL rootUrl = null;
try {
rootUrl = fujarurl.get();
} catch (Exception e) {
LOGGER.warn("Failed to find FastUtil jar; this WILL result in more exceptions");
isActive = false;
}
LOGGER.info("Sync_Fu found fu...");
if (!isActive) {
// We are dead
return null;
}
final URL rootURLf = rootUrl;
return new Entry<Set<String>, Supplier<Function<String, Optional<URL>>>>() {

@Override
public Set<String> getKey() {
Set<String> out = new HashSet<String>();
out.add("it.unimi.dsi.fastutil.");
return out;
}

@Override
public Supplier<Function<String, Optional<URL>>> getValue() {
return () -> {
return s -> {
URL urlOut;
try {
urlOut = new URL("jar:" + rootURLf.toString() + "!/" + s);
//LOGGER.debug(urlOut.toString());
return Optional.of(urlOut);
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
};
};
}

@Override
public Supplier<Function<String, Optional<URL>>> setValue(Supplier<Function<String, Optional<URL>>> value) {
throw new IllegalStateException();
}

};
}

@SuppressWarnings("rawtypes")
@Override
public List<ITransformer> transformers() {
List<ITransformer> out = new ArrayList<>();
out.add(this);
return out;
}

int posfilter = Opcodes.ACC_PUBLIC;
int negfilter = Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_ABSTRACT | Opcodes.ACC_BRIDGE;

private static final Marker marker = MarkerManager.getMarker("JMTSUPERTRANS");

@Override
public ClassNode transform(ClassNode input, ITransformerVotingContext context) {
LOGGER.info(marker, "sync_fu " + input.name + " Transformer Called");
for (MethodNode mn : input.methods) {
if ((mn.access & posfilter) == posfilter
&& (mn.access & negfilter) == 0
&& !mn.name.equals("<init>")) {
mn.access |= Opcodes.ACC_SYNCHRONIZED;
LOGGER.debug(marker, "Patching " + mn.name);
}
}
LOGGER.info(marker, "sync_fu " + input.name + " Transformer Complete");
return input;
}

@Override
public TransformerVoteResult castVote(ITransformerVotingContext context) {
return TransformerVoteResult.YES;
}

@Override
public Set<Target> targets() {
Set<Target> out = new HashSet<ITransformer.Target>();
if (!isActive) {
// Is Dead
return out;
}
out.add(Target.targetClass("it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap"));
out.add(Target.targetClass("it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet"));
out.add(Target.targetClass("it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap"));
return out;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.jmt.mcmt.modlauncher.FastUtilTransformerService

0 comments on commit 2edca8b

Please sign in to comment.