Skip to content

Commit

Permalink
Update 1.2.20
Browse files Browse the repository at this point in the history
  • Loading branch information
Fox2Code committed Oct 17, 2023
1 parent e6f179e commit 18ad917
Show file tree
Hide file tree
Showing 18 changed files with 183 additions and 113 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ You can [join the official ReIndev Discord here](https://discord.gg/38Vfes6NpR)

A feature missing to make your mod? [Just open an issue!](https://github.com/Fox2Code/FoxLoader/issues)

## Installation

For client side installation, just run the jar file.
Either by double clicking on it, or running `java -jar FoxLoader.jar`

To run FoxLoader as a server just run `java -jar FoxLoader.jar --server`

## Documentation

For mixins usage check here: https://github.com/2xsaiko/mixin-cheatsheet
Expand Down
5 changes: 3 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ subprojects {
}

java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
toolchain {
languageVersion = JavaLanguageVersion.of(8)
}

withSourcesJar()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.fox2code.foxloader.registry.RegisteredEntity;
import com.fox2code.foxloader.registry.RegisteredWorld;
import net.minecraft.src.game.entity.Entity;
import net.minecraft.src.game.entity.other.EntityItem;
import net.minecraft.src.game.level.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
Expand Down
10 changes: 5 additions & 5 deletions common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ version project['foxloader.version']

dependencies {
// TODO Don't forget to update DependencyHelper
api 'org.ow2.asm:asm-util:9.5'
api 'org.ow2.asm:asm-commons:9.5'
api 'org.semver4j:semver4j:4.3.0'
api 'org.ow2.asm:asm-util:9.6'
api 'org.ow2.asm:asm-commons:9.6'
api 'org.semver4j:semver4j:5.2.2'
api 'org.spongepowered:mixin:0.8.5'
api 'com.github.LlamaLad7.MixinExtras:mixinextras-common:0.2.0-beta.9'
api 'com.github.LlamaLad7.MixinExtras:mixinextras-common:0.2.0'
api 'org.luaj:luaj-jse:3.0.1'

// Mixin dependencies
api 'com.google.code.gson:gson:2.2.4'
api 'com.google.code.gson:gson:2.10.1'
api 'com.google.guava:guava:21.0'
api 'org.apache.commons:commons-lang3:3.3.2'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,24 @@ public class DependencyHelper {
public static final String MODRINTH = "https://api.modrinth.com/maven";

public static final Dependency GSON_DEPENDENCY = // Used by installer.
new Dependency("com.google.code.gson:gson:2.2.4", MAVEN_CENTRAL, "com.google.gson.Gson");
new Dependency("com.google.code.gson:gson:2.10.1", MAVEN_CENTRAL, "com.google.gson.Gson");

// Extra dependencies not included in ReIndev
public static final Dependency[] commonDependencies = new Dependency[]{
new Dependency("org.ow2.asm:asm:9.5", MAVEN_CENTRAL, "org.objectweb.asm.ClassVisitor"),
new Dependency("org.ow2.asm:asm-tree:9.5", MAVEN_CENTRAL, "org.objectweb.asm.tree.ClassNode"),
new Dependency("org.ow2.asm:asm-analysis:9.5", MAVEN_CENTRAL, "org.objectweb.asm.tree.analysis.Analyzer"),
new Dependency("org.ow2.asm:asm-commons:9.5", MAVEN_CENTRAL, "org.objectweb.asm.commons.InstructionAdapter"),
new Dependency("org.ow2.asm:asm-util:9.5", MAVEN_CENTRAL, "org.objectweb.asm.util.CheckClassAdapter"),
new Dependency("org.ow2.asm:asm:9.6", MAVEN_CENTRAL, "org.objectweb.asm.ClassVisitor"),
new Dependency("org.ow2.asm:asm-tree:9.6", MAVEN_CENTRAL, "org.objectweb.asm.tree.ClassNode"),
new Dependency("org.ow2.asm:asm-analysis:9.6", MAVEN_CENTRAL, "org.objectweb.asm.tree.analysis.Analyzer"),
new Dependency("org.ow2.asm:asm-commons:9.6", MAVEN_CENTRAL, "org.objectweb.asm.commons.InstructionAdapter"),
new Dependency("org.ow2.asm:asm-util:9.6", MAVEN_CENTRAL, "org.objectweb.asm.util.CheckClassAdapter"),
GSON_DEPENDENCY, new Dependency("com.google.guava:guava:21.0", MAVEN_CENTRAL, "com.google.common.io.Files"),
new Dependency("org.semver4j:semver4j:4.3.0", MAVEN_CENTRAL, "org.semver4j.Semver"),
new Dependency("org.semver4j:semver4j:5.2.2", MAVEN_CENTRAL, "org.semver4j.Semver"),
new Dependency("org.apache.commons:commons-lang3:3.3.2", MAVEN_CENTRAL, "org.apache.commons.lang3.tuple.Pair"),
new Dependency("org.luaj:luaj-jse:3.0.1", MAVEN_CENTRAL, "org.luaj.vm2.Globals"),
new Dependency("org.spongepowered:mixin:0.8.5", SPONGE_POWERED, "org.spongepowered.asm.mixin.Mixins"),
new Dependency("com.github.LlamaLad7.MixinExtras:mixinextras-common:0.2.0-beta.9",
new Dependency("com.github.LlamaLad7.MixinExtras:mixinextras-common:0.2.0",
JITPACK, "com.llamalad7.mixinextras.MixinExtrasBootstrap",
// Need fallback URL cause JitPack links can ded at any time
"https://github.com/LlamaLad7/MixinExtras/releases/download/0.2.0-beta.9/mixinextras-common-0.2.0-beta.9.jar"),
"https://github.com/LlamaLad7/MixinExtras/releases/download/0.2.0/mixinextras-common-0.2.0.jar"),
};

public static final Dependency sparkDependency =
Expand Down Expand Up @@ -285,7 +285,7 @@ private static String fixUpPath(String path) {
}

public static boolean hasClass(String cls) {
return FoxLauncher.getFoxClassLoader().getResource(cls.replace('.', '/') + ".class") != null;
return FoxLauncher.getFoxClassLoader().isClassInClassPath(cls);
}

private static String resolvePostURL(String string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public final class FoxClassLoader extends URLClassLoader {
private final LinkedList<String> exclusions;
private final LinkedList<ClassTransformer> classTransformers;
private final HashMap<String, byte[]> injectedClasses;
private URLClassLoader minecraftExclusiveSource;
private URLClassLoader gameExclusiveSource;
private boolean allowLoadingGame;
private WrappedExtensions wrappedExtensions;
private ArrayList<URL> coreMods;
Expand All @@ -39,30 +39,25 @@ public final class FoxClassLoader extends URLClassLoader {

@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (name.startsWith("net.minecraft.") ||
name.startsWith("paulscode.sound.") ||
name.startsWith("com.jcraft.")) {
Class<?> c;
if (isGameClassName(name)) {
if (!allowLoadingGame) {
throw new ClassNotFoundException("Cannot load \"" + name + "\" during pre init");
}
Class<?> c = findLoadedClass(name);
c = findLoadedClass(name);
if (c == null) {
c = findClassImpl(name, null);
}
return c;
} else if ((name.startsWith("com.fox2code.foxloader.") &&
!name.startsWith("com.fox2code.foxloader.launcher.")) ||
// Check mixins to fix them in development environment.
name.startsWith("com.llamalad7.mixinextras.") ||
name.startsWith("org.spongepowered.") ||
name.startsWith("org.objectweb.asm.")) {
Class<?> c = findLoadedClass(name);
isSpecialClassName(name)) {
c = findLoadedClass(name);
if (c == null) {
c = findClassImpl(name, null);
}
return c;
} else {
Class<?> c = findLoadedClass(name);
c = findLoadedClass(name);
if (c == null) {
URL resource = findResource(name.replace('.', '/') + ".class");
if (resource != null) {
Expand All @@ -73,8 +68,11 @@ protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundE
throw new ClassNotFoundException(name, securityException);
}
}
return c;
}
if (resolve) {
resolveClass(c);
}
return c;
}

@Override
Expand All @@ -94,12 +92,10 @@ private Class<?> findClassImpl(String name, URL resource) throws ClassNotFoundEx
ClassLoader resourceClassLoader;
if (name.startsWith("com.fox2code.foxloader.")) {
resourceClassLoader = getParent();
} else if ((name.startsWith("net.minecraft.") ||
name.startsWith("paulscode.sound.") ||
name.startsWith("com.jcraft."))) {
} else if (isGameClassName(name)) {
resourceClassLoader = // Do not allow mods to act as jar mods blindly.
minecraftExclusiveSource != null ?
minecraftExclusiveSource : getParent();
gameExclusiveSource != null ?
gameExclusiveSource : getParent();
} else {
resourceClassLoader = this;
}
Expand Down Expand Up @@ -191,8 +187,8 @@ public URL getResource(String name) {
if ((name.startsWith("net/minecraft/") &&
name.endsWith(".class")) ||
name.equals("font.txt")) {
if (minecraftExclusiveSource != null) {
return minecraftExclusiveSource.findResource(name);
if (gameExclusiveSource != null) {
return gameExclusiveSource.findResource(name);
} else {
return this.getParent().getResource(name);
}
Expand All @@ -202,8 +198,8 @@ public URL getResource(String name) {
}
URL resource = this.findResource(name);
if (resource != null) return resource;
if (minecraftExclusiveSource != null) {
resource = minecraftExclusiveSource.findResource(name);
if (gameExclusiveSource != null) {
resource = gameExclusiveSource.findResource(name);
if (resource != null) return resource;
}
return this.getParent().getResource(name);
Expand All @@ -213,6 +209,22 @@ public boolean isClassLoaded(String className) {
return this.findLoadedClass(className) != null;
}

public boolean isClassInClassPath(String className) {
final String path = className.replace('.', '/') + ".class";

if (className.startsWith("com.fox2code.foxloader.")) {
return this.getParent().getResource(path) != null;
} else if (isGameClassName(className)) {
if (gameExclusiveSource != null)
return gameExclusiveSource.getResource(path) != null;
return this.findResource(path) != null;
} else if (isSpecialClassName(className)) {
return this.findResource(path) != null;
} else {
return this.getResource(path) != null;
}
}

public void addClassTransformers(ClassTransformer classTransformer) {
String pkg = classTransformer.getClass().getPackage().getName();
if (!isTransformExclude(pkg)) {
Expand Down Expand Up @@ -250,13 +262,13 @@ public void addCoreModURL(URL url) {
public void setMinecraftURL(URL url) {
if (allowLoadingGame)
throw new IllegalStateException("Minecraft jar already loaded!");
minecraftExclusiveSource = new URLClassLoader(makeURLClassPathForSource(url), null);
gameExclusiveSource = new URLClassLoader(makeURLClassPathForSource(url), null);
}

public void setPatchedMinecraftURL(URL url) {
if (allowLoadingGame)
throw new IllegalStateException("Minecraft jar already loaded!");
minecraftExclusiveSource = new URLClassLoader(new URL[]{url}, null);
gameExclusiveSource = new URLClassLoader(new URL[]{url}, null);
}

public URL[] makeURLClassPathForSource(URL source) {
Expand Down Expand Up @@ -314,6 +326,20 @@ public void installWrappedExtensions(WrappedExtensions wrappedExtensions) {
this.wrappedExtensions = Objects.requireNonNull(wrappedExtensions);
}

public static boolean isSpecialClassName(String cls) {
// Check mixins to fix them in development environment.
return cls.startsWith("com.llamalad7.mixinextras.") ||
cls.startsWith("org.spongepowered.") ||
cls.startsWith("org.objectweb.asm.");
}

public static boolean isGameClassName(String cls) {
// Allow game pre-transforming
return cls.startsWith("net.minecraft.") ||
cls.startsWith("paulscode.sound.") ||
cls.startsWith("com.jcraft.");
}

private static class ClassTransformException extends Exception {
public ClassTransformException(String message) {
super(message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,7 @@ public class PreLoader {
// secondary pre patched jar, so in DEV_MODE ignoreMinecraft
// is false and only mods and none of FoxLoader pre-patches
// are loaded at runtime.
if (ignoreMinecraft && (
className.startsWith("net.minecraft.") ||
className.startsWith("paulscode.sound.") ||
className.startsWith("com.jcraft."))) {
if (ignoreMinecraft && FoxClassLoader.isGameClassName(className)) {
return bytes;
}
ClassReader classReader = new ClassReader(bytes);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.fox2code.foxloader.network;

import com.fox2code.foxloader.loader.ModContainer;
import com.fox2code.foxloader.registry.RegisteredCommandSender;
import com.fox2code.foxloader.registry.RegisteredEntityLiving;

public interface NetworkPlayer extends RegisteredEntityLiving {
public interface NetworkPlayer extends RegisteredEntityLiving, RegisteredCommandSender {
/**
* Just empty byte array to reduce allocations.
*/
Expand All @@ -20,11 +21,6 @@ public interface NetworkPlayer extends RegisteredEntityLiving {
*/
default void sendNetworkData(ModContainer modContainer, byte[] data) { throw new RuntimeException(); }

/**
* Send/Display chat message to the user screen.
*/
default void displayChatMessage(String chatMessage) { throw new RuntimeException(); }

/**
* @return if the remote party has the mod loader,
* always return true for a single player world.
Expand All @@ -36,13 +32,6 @@ public interface NetworkPlayer extends RegisteredEntityLiving {
*/
default String getPlayerName() { throw new RuntimeException(); }

/**
* @return if the player as operator permission.
*
* Always false client-side when connected to a server.
*/
default boolean isOperator() { throw new RuntimeException(); }

/**
* Will kick the player.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public static void registerClientCommand(CommandCompat commandCompat) {
private final boolean opOnly;
private final boolean isHidden;
private final String[] aliases;
private final boolean supportConsole;

public CommandCompat(String name) {
this(name, true, false, NO_ALIASES);
Expand All @@ -35,35 +36,67 @@ public CommandCompat(String name, boolean opOnly) {
}

public CommandCompat(String name, boolean opOnly, boolean isHidden, String[] aliases) {
this(name, opOnly, isHidden, aliases, null);
}

public CommandCompat(String name, boolean opOnly, boolean isHidden, String[] aliases, boolean supportConsole) {
this(name, opOnly, isHidden, aliases, (Boolean) supportConsole);
}

private CommandCompat(String name, boolean opOnly, boolean isHidden, String[] aliases, Boolean supportConsole) {
this.name = name;
this.opOnly = opOnly;
this.isHidden = isHidden;
this.aliases = aliases == null ?
NO_ALIASES : aliases;
if (supportConsole == null) {
try { // Auto-detect support if not explicitly defined.
supportConsole = this.getClass().getMethod("onExecute",
String[].class, RegisteredCommandSender.class)
.getDeclaringClass() != CommandCompat.class;
} catch (Throwable ignored) {}
}
this.supportConsole = supportConsole == Boolean.TRUE;
}

public String getName() {
public final String getName() {
return this.name;
}

public boolean isOpOnly() {
public final boolean isOpOnly() {
return this.opOnly;
}

public boolean isHidden() {
public final boolean isHidden() {
return this.isHidden;
}

public String[] getAliases() {
public final String[] getAliases() {
return this.aliases;
}

public void onExecute(String[] args, NetworkPlayer commandExecutor) {}
public final boolean supportConsole() {
return this.supportConsole;
}

public void printHelpInformation(NetworkPlayer commandExecutor) {
public void onExecute(String[] args, RegisteredCommandSender commandSender) {
if (!this.supportConsole) {
if (commandSender instanceof NetworkPlayer) {
this.onExecute(args, (NetworkPlayer) commandSender);
} else {
commandSender.displayChatMessage("This command can only be executed by a player!");
}
}
}

public void onExecute(String[] args, NetworkPlayer commandExecutor) {
if (this.supportConsole) {
this.onExecute(args, (RegisteredCommandSender) commandExecutor);
}
}

public void printHelpInformation(NetworkPlayer commandExecutor) {}

public String commandSyntax() {
return this.name;
}
Expand Down
Loading

0 comments on commit 18ad917

Please sign in to comment.