Update to 0.10 modlauncher API with performance improvements..

Signed-off-by: cpw <cpw+github@weeksfamily.ca>
This commit is contained in:
cpw 2019-02-23 14:36:05 -05:00
parent 237f9dec5a
commit bbdf52e038
No known key found for this signature in database
GPG key ID: 8EB3DF749553B1B7
9 changed files with 103 additions and 52 deletions

View file

@ -288,11 +288,11 @@ project(':forge') {
installer 'org.ow2.asm:asm:6.2'
installer 'org.ow2.asm:asm-commons:6.2'
installer 'org.ow2.asm:asm-tree:6.2'
installer 'cpw.mods:modlauncher:0.9.+'
installer 'net.minecraftforge:accesstransformers:0.14.+:shadowed'
installer 'net.minecraftforge:eventbus:0.7.+:service'
installer 'net.minecraftforge:forgespi:0.6.+'
installer 'net.minecraftforge:coremods:0.3.+'
installer 'cpw.mods:modlauncher:0.10.+'
installer 'net.minecraftforge:accesstransformers:0.15.+:shadowed'
installer 'net.minecraftforge:eventbus:0.8.+:service'
installer 'net.minecraftforge:forgespi:0.8.+'
installer 'net.minecraftforge:coremods:0.4.+'
installer 'net.minecraftforge:unsafe:0.2.+'
installer 'com.electronwill.night-config:core:3.4.2'
installer 'com.electronwill.night-config:toml:3.4.2'

View file

@ -20,7 +20,9 @@
package net.minecraftforge.common.asm;
import java.nio.file.Path;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
@ -41,14 +43,13 @@ public class CapabilityInjectDefinalize implements ILaunchPluginService {
return "capability_inject_definalize";
}
@Override public void addResource(Path resource, String name) { }
@Override public <T> T getExtension() { return null; } // ?
private static final EnumSet<Phase> YAY = EnumSet.of(Phase.AFTER);
private static final EnumSet<Phase> NAY = EnumSet.noneOf(Phase.class);
@Override
public boolean handlesClass(Type classType, boolean isEmpty)
public EnumSet<Phase> handlesClass(Type classType, boolean isEmpty)
{
return !isEmpty; //Check for annotations?
return isEmpty ? NAY : YAY;
}
private boolean hasHolder(List<AnnotationNode> lst)
@ -57,17 +58,19 @@ public class CapabilityInjectDefinalize implements ILaunchPluginService {
}
@Override
public ClassNode processClass(ClassNode classNode, Type classType)
public boolean processClass(Phase phase, ClassNode classNode, Type classType)
{
final int flags = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL;
AtomicBoolean changed = new AtomicBoolean();
classNode.fields.stream().filter(f -> ((f.access & flags) == flags) && f.desc.equals(CAP) && hasHolder(f.visibleAnnotations)).forEach(f ->
{
f.access &= ~Opcodes.ACC_FINAL; //Strip final
f.access |= Opcodes.ACC_SYNTHETIC; //Add Synthetic so we can check in runtime.
int prev = f.access;
f.access &= ~Opcodes.ACC_FINAL; //Strip final
f.access |= Opcodes.ACC_SYNTHETIC; //Add Synthetic so we can check in runtime.
changed.compareAndSet(false, prev != f.access);
});
return classNode;
return changed.get();
}
}

View file

@ -20,7 +20,9 @@
package net.minecraftforge.common.asm;
import java.nio.file.Path;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
@ -41,14 +43,14 @@ public class ObjectHolderDefinalize implements ILaunchPluginService {
return "object_holder_definalize";
}
@Override public void addResource(Path resource, String name) { }
@Override public <T> T getExtension() { return null; } // ?
private static final EnumSet<Phase> YAY = EnumSet.of(Phase.AFTER);
private static final EnumSet<Phase> NAY = EnumSet.noneOf(Phase.class);
@Override
public boolean handlesClass(Type classType, boolean isEmpty)
public EnumSet<Phase> handlesClass(Type classType, boolean isEmpty)
{
return !isEmpty; //Check for annotations?
return isEmpty ? NAY : YAY;
}
private boolean hasHolder(List<AnnotationNode> lst)
@ -71,16 +73,19 @@ public class ObjectHolderDefinalize implements ILaunchPluginService {
}
@Override
public ClassNode processClass(ClassNode classNode, Type classType)
public boolean processClass(Phase phase, ClassNode classNode, Type classType)
{
AtomicBoolean changes = new AtomicBoolean();
//Must be public static finals, and non-array objects
final int flags = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL;
//Fix Annotated Fields before injecting from class level
classNode.fields.stream().filter(f -> ((f.access & flags) == flags) && f.desc.startsWith("L") && hasHolder(f.visibleAnnotations)).forEach(f ->
{
f.access &= ~Opcodes.ACC_FINAL; //Strip final
f.access |= Opcodes.ACC_SYNTHETIC; //Add Synthetic so we can check in runtime. ? Good idea?
int prev = f.access;
f.access &= ~Opcodes.ACC_FINAL; //Strip final
f.access |= Opcodes.ACC_SYNTHETIC; //Add Synthetic so we can check in runtime. ? Good idea?
changes.compareAndSet(false, prev != f.access);
});
if (hasHolder(classNode.visibleAnnotations)) //Class level, de-finalize all fields and add @ObjectHolder to them!
@ -89,18 +94,20 @@ public class ObjectHolderDefinalize implements ILaunchPluginService {
String value = getValue(classNode.visibleAnnotations);
classNode.fields.stream().filter(f -> ((f.access & flags) == flags) && f.desc.startsWith("L")).forEach(f ->
{
f.access &= ~Opcodes.ACC_FINAL;
f.access |= Opcodes.ACC_SYNTHETIC;
/*if (!hasHolder(f.visibleAnnotations)) //Add field level annotation, doesn't do anything until after we figure out how ASMDataTable is gatherered
{
int prev = f.access;
f.access &= ~Opcodes.ACC_FINAL;
f.access |= Opcodes.ACC_SYNTHETIC;
/*if (!hasHolder(f.visibleAnnotations)) //Add field level annotation, doesn't do anything until after we figure out how ASMDataTable is gatherered
{
if (value == null)
f.visitAnnotation(OBJECT_HOLDER, true);
else
f.visitAnnotation(OBJECT_HOLDER, true).visit("value", value + ":" + f.name.toLowerCase());
}*/
}*/
changes.compareAndSet(false, prev != f.access);
});
}
return classNode;
return changes.get();
}
}

View file

@ -20,6 +20,7 @@
package net.minecraftforge.common.asm;
import java.nio.file.Path;
import java.util.EnumSet;
import java.util.List;
import java.util.stream.Collectors;
@ -58,21 +59,20 @@ public class RuntimeEnumExtender implements ILaunchPluginService {
return "runtime_enum_extender";
}
@Override public void addResource(Path resource, String name) { }
@Override public <T> T getExtension() { return null; } // ?
private static final EnumSet<Phase> YAY = EnumSet.of(Phase.AFTER);
private static final EnumSet<Phase> NAY = EnumSet.noneOf(Phase.class);
@Override
public boolean handlesClass(Type classType, boolean isEmpty)
public EnumSet<Phase> handlesClass(Type classType, boolean isEmpty)
{
return !isEmpty; //Any way to determine if its a enum at this level?
return isEmpty ? NAY : YAY;
}
@Override
public ClassNode processClass(ClassNode classNode, Type classType)
public boolean processClass(Phase phase, ClassNode classNode, Type classType)
{
if ((classNode.access & Opcodes.ACC_ENUM) == 0)
return classNode;
return false;
Type array = Type.getType("[" + classType.getDescriptor());
final int flags = Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC;
@ -80,7 +80,7 @@ public class RuntimeEnumExtender implements ILaunchPluginService {
FieldNode values = classNode.fields.stream().filter(f -> f.desc.contentEquals(array.getDescriptor()) && ((f.access & flags) == flags)).findFirst().orElse(null);
if (!classNode.interfaces.contains(MARKER_IFACE.getInternalName())) {
return classNode;
return false;
}
//Static methods named "create", with first argument as a string, and returning this type
@ -205,7 +205,7 @@ public class RuntimeEnumExtender implements ILaunchPluginService {
ins.areturn(classType);
}
});
return classNode;
return true;
}
}

View file

@ -19,11 +19,12 @@
package net.minecraftforge.fml.loading;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import com.google.common.collect.Streams;
@ -57,17 +58,12 @@ public class RuntimeDistCleaner implements ILaunchPluginService
}
@Override
public void addResource(Path resource, String name)
{
}
@Override
public ClassNode processClass(ClassNode classNode, Type classType)
public boolean processClass(Phase phase, ClassNode classNode, Type classType)
{
AtomicBoolean changes = new AtomicBoolean();
if (remove(classNode.visibleAnnotations, DIST))
{
LOGGER.debug(DISTXFORM, "Attempted to load class {} for invalid dist {}", classNode.name, DIST);
LOGGER.fatal(DISTXFORM, "Attempted to load class {} for invalid dist {}", classNode.name, DIST);
throw new RuntimeException("Attempted to load class "+ classNode.name + " for invalid dist "+ DIST);
}
@ -79,6 +75,7 @@ public class RuntimeDistCleaner implements ILaunchPluginService
{
LOGGER.debug(DISTXFORM,"Removing field: {}.{}", classNode.name, field.name);
fields.remove();
changes.compareAndSet(false, true);
}
}
@ -92,6 +89,7 @@ public class RuntimeDistCleaner implements ILaunchPluginService
LOGGER.debug(DISTXFORM,"Removing method: {}.{}{}", classNode.name, method.name, method.desc);
methods.remove();
lambdaGatherer.accept(method);
changes.compareAndSet(false, true);
}
}
@ -109,11 +107,12 @@ public class RuntimeDistCleaner implements ILaunchPluginService
{
LOGGER.debug(DISTXFORM,"Removing lambda method: {}.{}{}", classNode.name, method.name, method.desc);
methods.remove();
changes.compareAndSet(false, true);
}
}
}
}
return classNode;
return changes.get();
}
private boolean remove(final List<AnnotationNode> anns, final String side)
@ -133,10 +132,13 @@ public class RuntimeDistCleaner implements ILaunchPluginService
};
}
private static final EnumSet<Phase> YAY = EnumSet.of(Phase.AFTER);
private static final EnumSet<Phase> NAY = EnumSet.noneOf(Phase.class);
@Override
public boolean handlesClass(Type classType, boolean isEmpty)
public EnumSet<Phase> handlesClass(Type classType, boolean isEmpty)
{
return !isEmpty;
return isEmpty ? NAY : YAY;
}
private static class LambdaGatherer extends MethodVisitor {

View file

@ -98,4 +98,9 @@ public class ModFileInfo implements IModFileInfo
public Optional<Manifest> getManifest() {
return modFile.getLocator().findManifest(modFile.getFilePath());
}
@Override
public boolean showAsResourcePack() {
return false; // noop right now
}
}

View file

@ -28,6 +28,7 @@ import net.minecraft.util.text.TextComponentString;
import net.minecraftforge.fml.config.ConfigTracker;
import net.minecraftforge.fml.network.simple.SimpleChannel;
import net.minecraftforge.fml.util.ThreeConsumer;
import net.minecraftforge.registries.ForgeRegistry;
import net.minecraftforge.registries.RegistryManager;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -35,10 +36,14 @@ import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
import static net.minecraftforge.registries.ForgeRegistry.REGISTRIES;
/**
* Instance responsible for handling the overall FML network handshake.
*
@ -176,6 +181,9 @@ public class FMLHandshakeHandler {
private final NetworkDirection direction;
private final NetworkManager manager;
private int packetPosition;
private ForgeRegistry.Snapshot registrySnapshot;
private Set<String> registriesToReceive;
private FMLHandshakeHandler(NetworkManager networkManager, NetworkDirection side)
{
this.direction = side;
@ -199,6 +207,8 @@ public class FMLHandshakeHandler {
LOGGER.debug(FMLHSMARKER, "Accepted server connection");
// Set the modded marker on the channel so we know we got packets
c.get().getNetworkManager().channel().attr(FMLNetworking.FML_MARKER).set(NetworkHooks.NETVERSION);
this.registriesToReceive = new HashSet<>(serverModList.getRegistries());
LOGGER.debug(REGISTRIES, "Expecting {} registries: {}", ()->this.registriesToReceive.size(), ()->this.registriesToReceive);
}
private <MSG extends FMLHandshakeMessages.LoginIndexedMessage> void handleIndexedMessage(MSG message, Supplier<NetworkEvent.Context> c)
@ -223,10 +233,12 @@ public class FMLHandshakeHandler {
LOGGER.debug(FMLHSMARKER, "Accepted client connection mod list");
}
private void handleRegistryMessage(final FMLHandshakeMessages.S2CRegistry registryPacket, final Supplier<NetworkEvent.Context> contextSupplier) {
this.registriesToReceive.remove(registryPacket.getRegistryName());
RegistryManager.acceptRegistry(registryPacket, contextSupplier);
contextSupplier.get().setPacketHandled(true);
final FMLHandshakeMessages.C2SAcknowledge reply = new FMLHandshakeMessages.C2SAcknowledge();
channel.reply(reply, contextSupplier.get());
if (this.registriesToReceive.isEmpty()) {}//injectSnapshot
}
private void handleClientAck(final FMLHandshakeMessages.C2SAcknowledge msg, final Supplier<NetworkEvent.Context> contextSupplier) {

View file

@ -29,6 +29,7 @@ import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
import net.minecraftforge.registries.ForgeRegistry;
import net.minecraftforge.registries.IForgeRegistryEntry;
import net.minecraftforge.registries.RegistryManager;
import java.util.List;
import java.util.stream.Collectors;
@ -51,6 +52,7 @@ public class FMLHandshakeMessages
*/
public static class S2CModList extends LoginIndexedMessage
{
private List<String> registries;
private NBTTagList channels;
private List<String> modList;
@ -62,6 +64,7 @@ public class FMLHandshakeMessages
{
this.modList = nbtTagCompound.getList("modlist", 8).stream().map(INBTBase::getString).collect(Collectors.toList());
this.channels = nbtTagCompound.getList("channels", 10);
this.registries = nbtTagCompound.getList("registries", 8).stream().map(INBTBase::getString).collect(Collectors.toList());
}
public static S2CModList decode(PacketBuffer packetBuffer)
@ -75,6 +78,7 @@ public class FMLHandshakeMessages
NBTTagCompound tag = new NBTTagCompound();
tag.setTag("modlist",modList.stream().map(NBTTagString::new).collect(Collectors.toCollection(NBTTagList::new)));
tag.setTag("channels", NetworkRegistry.buildChannelVersions());
tag.setTag("registries", RegistryManager.registryNames().stream().map(NBTTagString::new).collect(Collectors.toCollection(NBTTagList::new)));
packetBuffer.writeCompoundTag(tag);
}
@ -82,6 +86,9 @@ public class FMLHandshakeMessages
return String.join(",", modList);
}
List<String> getRegistries() {
return this.registries;
}
NBTTagList getChannels() {
return this.channels;
}
@ -119,17 +126,26 @@ public class FMLHandshakeMessages
}
public static class S2CRegistry extends LoginIndexedMessage {
private String registryName;
public S2CRegistry(final ResourceLocation key, final ForgeRegistry<? extends IForgeRegistryEntry<?>> registry) {
registryName = key.toString();
}
S2CRegistry() {
private S2CRegistry(final String registryName) {
this.registryName = registryName;
}
void encode(final PacketBuffer buffer) {
buffer.writeString(registryName, 128);
}
public static S2CRegistry decode(final PacketBuffer buffer) {
return new S2CRegistry();
return new S2CRegistry(buffer.readString(128));
}
public String getRegistryName() {
return registryName;
}
}

View file

@ -39,6 +39,8 @@ import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import static net.minecraftforge.registries.ForgeRegistry.REGISTRIES;
public class RegistryManager
{
private static final Logger LOGGER = LogManager.getLogger();
@ -154,7 +156,11 @@ public class RegistryManager
collect(Collectors.toList());
}
public static List<String> registryNames() {
return ACTIVE.registries.entrySet().stream().map(Map.Entry::getKey).map(Object::toString).collect(Collectors.toList());
}
public static void acceptRegistry(final FMLHandshakeMessages.S2CRegistry registryUpdate, final Supplier<NetworkEvent.Context> contextSupplier) {
LOGGER.debug("Received registry packet");
LOGGER.debug(REGISTRIES,"Received registry packet for {}", registryUpdate.getRegistryName());
}
}