chore: Port to V2 mixins

This commit is contained in:
FalsePattern committed 2025-10-16 15:32:17 +02:00
1 parent 3da2da2846
commit 98cb70ab42
18 files changed
+328 -540

No files matched your search

-1
View File
@@ -17,7 +17,6 @@ minecraft_fp {
mixin {
pkg = "internal.mixin.mixins"
pluginClass = "internal.mixin.plugin.MixinPlugin"
}
core {
@@ -23,13 +23,19 @@
package com.falsepattern.chunk.internal.core;
import com.falsepattern.chunk.internal.Tags;
import com.falsepattern.chunk.internal.mixin.plugin.Mixin;
import com.gtnewhorizon.gtnhmixins.IEarlyMixinLoader;
import com.gtnewhorizon.gtnhmixins.builders.IMixins;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@IFMLLoadingPlugin.TransformerExclusions(Tags.ROOT_PKG + ".internal.core")
public class CoreLoadingPlugin implements IFMLLoadingPlugin {
public class CoreLoadingPlugin implements IFMLLoadingPlugin, IEarlyMixinLoader {
@Override
public String[] getASMTransformerClass() {
return new String[0];
@@ -54,4 +60,14 @@ public class CoreLoadingPlugin implements IFMLLoadingPlugin {
public String getAccessTransformerClass() {
return null;
}
@Override
public String getMixinConfig() {
return "mixins.chunkapi.early.json";
}
@Override
public List<String> getMixins(Set<String> loadedCoreMods) {
return IMixins.getEarlyMixins(Mixin.class, loadedCoreMods);
}
}
@@ -22,23 +22,23 @@
package com.falsepattern.chunk.internal.mixin.plugin;
import com.falsepattern.chunk.internal.mixin.plugin.fplib.ITargetedMod;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import com.gtnewhorizon.gtnhmixins.ILateMixinLoader;
import com.gtnewhorizon.gtnhmixins.LateMixin;
import com.gtnewhorizon.gtnhmixins.builders.IMixins;
import org.jetbrains.annotations.NotNull;
import java.util.function.Predicate;
import java.util.List;
import java.util.Set;
import static com.falsepattern.chunk.internal.mixin.plugin.fplib.ITargetedMod.PredicateHelpers.contains;
@LateMixin
public class LateMixins implements ILateMixinLoader {
@Override
public String getMixinConfig() {
return "mixins.chunkapi.late.json";
}
@RequiredArgsConstructor
public enum TargetedMod implements ITargetedMod {
LOOKINGGLASS("Looking Glass", false, contains("lookingglass-"))
;
@Getter
private final String modName;
@Getter
private final boolean loadInDevelopment;
@Getter
private final Predicate<String> condition;
@Override
public @NotNull List<String> getMixins(Set<String> loadedMods) {
return IMixins.getLateMixins(Mixin.class, loadedMods);
}
}
@@ -22,41 +22,84 @@
package com.falsepattern.chunk.internal.mixin.plugin;
import com.falsepattern.chunk.internal.mixin.plugin.fplib.IMixin;
import com.falsepattern.chunk.internal.mixin.plugin.fplib.ITargetedMod;
import com.falsepattern.chunk.internal.Tags;
import com.falsepattern.chunk.internal.mixin.plugin.fplib.MixinHelper;
import com.falsepattern.chunk.internal.mixin.plugin.fplib.SidedMixins;
import com.falsepattern.chunk.internal.mixin.plugin.fplib.TaggedMod;
import com.gtnewhorizon.gtnhmixins.builders.IMixins;
import com.gtnewhorizon.gtnhmixins.builders.MixinBuilder;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.intellij.lang.annotations.Language;
import java.util.List;
import java.util.function.Predicate;
import java.util.function.BooleanSupplier;
import static com.falsepattern.chunk.internal.mixin.plugin.fplib.IMixin.PredicateHelpers.always;
import static com.falsepattern.chunk.internal.mixin.plugin.fplib.IMixin.PredicateHelpers.require;
import static com.falsepattern.chunk.internal.mixin.plugin.TargetMod.LookingGlass;
import static com.falsepattern.chunk.internal.mixin.plugin.fplib.MixinHelper.avoid;
import static com.falsepattern.chunk.internal.mixin.plugin.fplib.MixinHelper.builder;
import static com.falsepattern.chunk.internal.mixin.plugin.fplib.MixinHelper.mods;
import static com.falsepattern.chunk.internal.mixin.plugin.fplib.MixinHelper.require;
@RequiredArgsConstructor
public enum Mixin implements IMixin {
// @formatter:off
AnvilChunkLoaderMixin(Side.COMMON, always(), "vanilla.AnvilChunkLoaderMixin"),
PlayerInstanceMixin(Side.COMMON, always(), "vanilla.PlayerInstanceMixin"),
S21PacketChunkDataMixin(Side.COMMON, always(), "vanilla.S21PacketChunkDataMixin"),
S22PacketMultiBlockChangeMixin(Side.COMMON, always(), "vanilla.S22PacketMultiBlockChangeMixin"),
S23PacketBlockChangeMixin(Side.COMMON, always(), "vanilla.S23PacketBlockChangeMixin"),
S26PacketMapChunkBulkMixin(Side.COMMON, always(), "vanilla.S26PacketMapChunkBulkMixin"),
public enum Mixin implements IMixins {
Core(Phase.EARLY,
common("vanilla.AnvilChunkLoaderMixin",
"vanilla.PlayerInstanceMixin",
"vanilla.S21PacketChunkDataMixin",
"vanilla.S22PacketMultiBlockChangeMixin",
"vanilla.S23PacketBlockChangeMixin",
"vanilla.S26PacketMapChunkBulkMixin"),
client("vanilla.ChunkMixin",
"vanilla.NetHandlerPlayClientMixin")),
ChunkMixin(Side.CLIENT, always(), "vanilla.ChunkMixin"),
NetHandlerPlayClientMixin(Side.CLIENT, always(), "vanilla.NetHandlerPlayClientMixin"),
//region Looking Glass
PacketChunkInfoMixin(Side.COMMON, require(TargetedMod.LOOKINGGLASS), "lookingglass.PacketChunkInfoMixin"),
//endregion
Compat_LookingGlass(Phase.LATE,
require(LookingGlass),
common("lookingglass.PacketChunkInfoMixin")),
//region boilerplate
;
// @formatter:on
@Getter
private final MixinBuilder builder;
@Getter
private final Side side;
@Getter
private final Predicate<List<ITargetedMod>> filter;
@Getter
private final String mixin;
Mixin(Phase phase, SidedMixins... mixins) {
this(builder(mixins).setPhase(phase));
}
Mixin(Phase phase, BooleanSupplier cond, SidedMixins... mixins) {
this(builder(cond, mixins).setPhase(phase));
}
Mixin(Phase phase, TaggedMod mod, SidedMixins... mixins) {
this(builder(mod, mixins).setPhase(phase));
}
Mixin(Phase phase, TaggedMod[] mods, SidedMixins... mixins) {
this(builder(mods, mixins).setPhase(phase));
}
Mixin(Phase phase, BooleanSupplier cond, TaggedMod mod, SidedMixins... mixins) {
this(builder(cond, mod, mixins).setPhase(phase));
}
Mixin(Phase phase, BooleanSupplier cond, TaggedMod[] mods, SidedMixins... mixins) {
this(builder(cond, mods, mixins).setPhase(phase));
}
private static SidedMixins common(@Language(value = "JAVA",
prefix = "import " + Tags.ROOT_PKG + ".internal.mixin.mixins.common.",
suffix = ";") String... mixins) {
return MixinHelper.common(mixins);
}
private static SidedMixins client(@Language(value = "JAVA",
prefix = "import " + Tags.ROOT_PKG + ".internal.mixin.mixins.client.",
suffix = ";") String... mixins) {
return MixinHelper.client(mixins);
}
private static SidedMixins server(@Language(value = "JAVA",
prefix = "import " + Tags.ROOT_PKG + ".mixin.mixins.server.",
suffix = ";") String... mixins) {
return MixinHelper.server(mixins);
}
//endregion
}
@@ -22,24 +22,34 @@
package com.falsepattern.chunk.internal.mixin.plugin;
import com.falsepattern.chunk.internal.Tags;
import com.falsepattern.chunk.internal.mixin.plugin.fplib.IMixin;
import com.falsepattern.chunk.internal.mixin.plugin.fplib.IMixinPlugin;
import com.falsepattern.chunk.internal.mixin.plugin.fplib.ITargetedMod;
import com.gtnewhorizon.gtnhmixins.builders.ITargetMod;
import com.gtnewhorizon.gtnhmixins.builders.TargetModBuilder;
import lombok.Getter;
import org.apache.logging.log4j.Logger;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class MixinPlugin implements IMixinPlugin {
import java.util.function.Consumer;
public enum TargetMod implements ITargetMod {
LookingGlass("com.xcompwiz.lookingglass.LookingGlass"),
;
@Getter
private final Logger logger = IMixinPlugin.createLogger(Tags.MOD_NAME);
private final TargetModBuilder builder;
@Override
public ITargetedMod[] getTargetedModEnumValues() {
return TargetedMod.values();
TargetMod(@Language(value = "JAVA",
prefix = "import ",
suffix = ";") @NotNull String className) {
this(className, null);
}
@Override
public IMixin[] getMixinEnumValues() {
return Mixin.values();
TargetMod(@Language(value = "JAVA",
prefix = "import ",
suffix = ";") @NotNull String className, @Nullable Consumer<TargetModBuilder> cfg) {
builder = new TargetModBuilder();
builder.setTargetClass(className);
if (cfg != null) {
cfg.accept(builder);
}
}
}
@@ -1,77 +0,0 @@
/*
* This file is part of FalsePatternLib.
*
* Copyright (C) 2022-2025 FalsePattern
* All Rights Reserved
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* FalsePatternLib is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, only version 3 of the License.
*
* FalsePatternLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FalsePatternLib. If not, see <https://www.gnu.org/licenses/>.
*/
package com.falsepattern.chunk.internal.mixin.plugin.fplib;
import lombok.val;
import cpw.mods.fml.relauncher.FMLLaunchHandler;
import java.util.List;
import java.util.function.Predicate;
import java.util.function.Supplier;
public interface IMixin {
String getMixin();
Side getSide();
Predicate<List<ITargetedMod>> getFilter();
default boolean shouldLoad(List<ITargetedMod> loadedMods) {
val side = getSide();
return (side == Side.COMMON
|| side == Side.SERVER && FMLLaunchHandler.side().isServer()
|| side == Side.CLIENT && FMLLaunchHandler.side().isClient()) && getFilter().test(loadedMods);
}
/**
* @since 0.10.0
*/
enum Side {
COMMON,
CLIENT,
SERVER
}
/**
* @since 0.10.0
*/
final class PredicateHelpers {
public static Predicate<List<ITargetedMod>> never() {
return (list) -> false;
}
public static Predicate<List<ITargetedMod>> condition(Supplier<Boolean> condition) {
return (list) -> condition.get();
}
public static Predicate<List<ITargetedMod>> always() {
return (list) -> true;
}
public static Predicate<List<ITargetedMod>> require(ITargetedMod mod) {
return (list) -> list.contains(mod);
}
public static Predicate<List<ITargetedMod>> avoid(ITargetedMod mod) {
return (list) -> !list.contains(mod);
}
}
}
@@ -1,218 +0,0 @@
/*
* This file is part of FalsePatternLib.
*
* Copyright (C) 2022-2025 FalsePattern
* All Rights Reserved
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* FalsePatternLib is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, only version 3 of the License.
*
* FalsePatternLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FalsePatternLib. If not, see <https://www.gnu.org/licenses/>.
*/
package com.falsepattern.chunk.internal.mixin.plugin.fplib;
import lombok.val;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.ApiStatus;
import org.spongepowered.asm.lib.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import net.minecraft.launchwrapper.Launch;
import java.io.File;
import java.net.URL;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import static java.nio.file.Files.walk;
public interface IMixinPlugin extends IMixinConfigPlugin {
Path MODS_DIRECTORY_PATH = FileUtil.getMinecraftHome().toPath().resolve("mods");
static Logger createLogger(String modName) {
return LogManager.getLogger(modName + " Mixin Loader");
}
/**
* @deprecated since 1.4.0
*/
@Deprecated
static File findJarOf(final ITargetedMod mod) {
File result = null;
try (val stream = walk(MODS_DIRECTORY_PATH)) {
result = stream.filter(mod::isMatchingJar).map(Path::toFile).findFirst().orElse(null);
} catch (Exception e) {
e.printStackTrace();
}
if (result == null) {
File found = null;
for (URL url : Launch.classLoader.getURLs()) {
try {
val file = new File(url.toURI());
Path path = file.toPath();
if (mod.isMatchingJar(path)) {
found = file;
break;
}
} catch (Exception ignored) {
}
}
result = found;
}
return result;
}
/**
* @since 1.4.0
*/
static Set<File> findJarsOf(IMixinPlugin self, final ITargetedMod mod) {
if (!self.useNewFindJar()) {
val jar = findJarOf(mod);
return jar == null ? Collections.emptySet() : Collections.singleton(jar);
}
val results = new HashSet<File>();
try (val stream = walk(MODS_DIRECTORY_PATH)) {
results.addAll(stream.filter(mod::isMatchingJar).map(Path::toFile).collect(Collectors.toSet()));
} catch (Exception e) {
e.printStackTrace();
}
for (URL url : Launch.classLoader.getURLs()) {
try {
val file = new File(url.toURI());
Path path = file.toPath();
if (mod.isMatchingJar(path)) {
results.add(file);
break;
}
} catch (Exception ignored) {
}
}
return results;
}
Logger getLogger();
IMixin[] getMixinEnumValues();
ITargetedMod[] getTargetedModEnumValues();
/**
* @since 1.4.0
*/
default boolean useNewFindJar() {
return false;
}
@Override
@ApiStatus.Internal
default void onLoad(String mixinPackage) {
}
@Override
@ApiStatus.Internal
default String getRefMapperConfig() {
return null;
}
@Override
@ApiStatus.Internal
default boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
return true;
}
@Override
@ApiStatus.Internal
default void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
}
@Override
@ApiStatus.Internal
default List<String> getMixins() {
val isDevelopmentEnvironment = (boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment");
val targetedMods = getTargetedModEnumValues();
val loadedMods = Arrays.stream(targetedMods)
//Java 21 compat
.filter(new Predicate<ITargetedMod>() {
@Override
public boolean test(ITargetedMod mod) {
boolean loadJar = IMixinPlugin.this.loadJarOf(mod);
return (mod.isLoadInDevelopment() && isDevelopmentEnvironment)
|| loadJar;
}
})
.collect(Collectors.toList());
for (val mod : targetedMods) {
if (loadedMods.contains(mod)) {
getLogger().info("Found " + mod.getModName() + "! Integrating now...");
} else {
getLogger().info("Could not find " + mod.getModName() + "! Skipping integration....");
}
}
List<String> mixins = new ArrayList<>();
for (val mixin : getMixinEnumValues()) {
if (mixin.shouldLoad(loadedMods)) {
String mixinClass = mixin.getSide().name().toLowerCase() + "." + mixin.getMixin();
mixins.add(mixinClass);
getLogger().info("Loading mixin: " + mixinClass);
}
}
return mixins;
}
@ApiStatus.Internal
default boolean loadJarOf(final ITargetedMod mod) {
try {
val jars = findJarsOf(this, mod);
if (jars.isEmpty()) {
getLogger().info("Jar not found for {}", mod);
return false;
}
for (val jar: jars) {
getLogger().info("Attempting to add {} to the URL Class Path", jar);
try {
MinecraftURLClassPath.addJar(jar);
} catch (Throwable e) {
e.printStackTrace();
}
}
} catch (Throwable e) {
e.printStackTrace();
}
return true;
}
@Override
@ApiStatus.Internal
default void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
@Override
@ApiStatus.Internal
default void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
}
@@ -1,59 +0,0 @@
/*
* This file is part of FalsePatternLib.
*
* Copyright (C) 2022-2025 FalsePattern
* All Rights Reserved
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* FalsePatternLib is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, only version 3 of the License.
*
* FalsePatternLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FalsePatternLib. If not, see <https://www.gnu.org/licenses/>.
*/
package com.falsepattern.chunk.internal.mixin.plugin.fplib;
import com.google.common.io.Files;
import java.nio.file.Path;
import java.util.function.Predicate;
public interface ITargetedMod {
String getModName();
boolean isLoadInDevelopment();
@SuppressWarnings("UnstableApiUsage")
default boolean isMatchingJar(Path path) {
String pathString = path.toString();
String nameLowerCase = Files.getNameWithoutExtension(pathString).toLowerCase();
String fileExtension = Files.getFileExtension(pathString);
return "jar".equals(fileExtension) && getCondition().test(nameLowerCase);
}
Predicate<String> getCondition();
final class PredicateHelpers {
public static Predicate<String> startsWith(String subString) {
return (name) -> name.startsWith(subString.toLowerCase());
}
public static Predicate<String> contains(String subString) {
return (name) -> name.contains(subString.toLowerCase());
}
public static Predicate<String> matches(String regex) {
return (name) -> name.matches(regex);
}
}
}
@@ -1,19 +0,0 @@
FalsePatternLib
Copyright (C) 2022-2025 FalsePattern
All Rights Reserved
The above copyright notice and this permission notice
shall be included in all copies or substantial portions of the Software.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, only version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -0,0 +1,112 @@
/*
* This file is part of FalsePatternLib.
*
* Copyright (C) 2022-2025 FalsePattern
* All Rights Reserved
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* FalsePatternLib is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, only version 3 of the License.
*
* FalsePatternLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FalsePatternLib. If not, see <https://www.gnu.org/licenses/>.
*/
package com.falsepattern.chunk.internal.mixin.plugin.fplib;
import com.gtnewhorizon.gtnhmixins.builders.IBaseTransformer;
import com.gtnewhorizon.gtnhmixins.builders.ITargetMod;
import com.gtnewhorizon.gtnhmixins.builders.MixinBuilder;
import lombok.val;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.BooleanSupplier;
public class MixinHelper {
public static @NotNull MixinBuilder builder(@NotNull SidedMixins @NotNull ... mixins) {
return builderImpl(null, null, mixins);
}
public static @NotNull MixinBuilder builder(@Nullable BooleanSupplier cond, @NotNull SidedMixins @NotNull ... mixins) {
return builderImpl(cond, null, mixins);
}
public static @NotNull MixinBuilder builder(@NotNull TaggedMod mod, @NotNull SidedMixins @NotNull ... mixins) {
return builderImpl(null, mods(mod), mixins);
}
public static @NotNull MixinBuilder builder(@NotNull TaggedMod @Nullable [] mods, @NotNull SidedMixins @NotNull ... mixins) {
return builderImpl(null, mods, mixins);
}
public static @NotNull MixinBuilder builder(@NotNull BooleanSupplier cond, @NotNull TaggedMod mod, @NotNull SidedMixins @NotNull ... mixins) {
return builderImpl(cond, mods(mod), mixins);
}
public static @NotNull MixinBuilder builder(@NotNull BooleanSupplier cond, @NotNull TaggedMod @NotNull [] mods, @NotNull SidedMixins @NotNull ... mixins) {
return builderImpl(cond, mods, mixins);
}
private static @NotNull MixinBuilder builderImpl(@Nullable BooleanSupplier cond, @NotNull TaggedMod @Nullable [] requiredMods, @NotNull SidedMixins @NotNull ... mixins) {
val builder = new MixinBuilder();
if (requiredMods != null) {
for (val mod : requiredMods) {
if (mod.require) {
builder.addRequiredMod(mod.mod);
} else {
builder.addExcludedMod(mod.mod);
}
}
}
for (val mixin : mixins) {
builder.addSidedMixins(mixin.side, mixin.mixins);
}
if (cond != null) {
builder.setApplyIf(cond::getAsBoolean);
}
return builder;
}
public static @NotNull SidedMixins common(@NotNull String @NotNull ... mixins) {
for (int i = 0; i < mixins.length; i++) {
mixins[i] = "common." + mixins[i];
}
return new SidedMixins(IBaseTransformer.Side.COMMON, mixins);
}
public static @NotNull SidedMixins client(@NotNull String @NotNull ... mixins) {
for (int i = 0; i < mixins.length; i++) {
mixins[i] = "client." + mixins[i];
}
return new SidedMixins(IBaseTransformer.Side.CLIENT, mixins);
}
public static @NotNull SidedMixins server(@NotNull String @NotNull ... mixins) {
for (int i = 0; i < mixins.length; i++) {
mixins[i] = "server." + mixins[i];
}
return new SidedMixins(IBaseTransformer.Side.SERVER, mixins);
}
public static @NotNull TaggedMod require(@NotNull ITargetMod mod) {
return new TaggedMod(true, mod);
}
public static @NotNull TaggedMod avoid(@NotNull ITargetMod mod) {
return new TaggedMod(false, mod);
}
public static @NotNull TaggedMod @NotNull [] mods(@NotNull TaggedMod @NotNull ... t) {
return t;
}
}
@@ -1 +0,0 @@
Shadowed from FalsePatternLib 1.7.0
@@ -19,23 +19,15 @@
* You should have received a copy of the GNU Lesser General Public License
* along with FalsePatternLib. If not, see <https://www.gnu.org/licenses/>.
*/
package com.falsepattern.chunk.internal.mixin.plugin.fplib;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import com.gtnewhorizon.gtnhmixins.builders.IBaseTransformer;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import java.io.File;
/**
* Backport from spongemixins 1.3 for compat with the curseforge 1.2.0 version.
* <p>
* Also added Grimoire protection.
*
* @since 0.10.0
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class MinecraftURLClassPath {
public static void addJar(File pathToJar) throws Exception {
UCPImpl.addJar(pathToJar);
}
@RequiredArgsConstructor
public class SidedMixins {
public final IBaseTransformer.@NotNull Side side;
public final @NotNull String @NotNull [] mixins;
}
@@ -19,29 +19,15 @@
* You should have received a copy of the GNU Lesser General Public License
* along with FalsePatternLib. If not, see <https://www.gnu.org/licenses/>.
*/
package com.falsepattern.chunk.internal.mixin.plugin.fplib;
import lombok.experimental.UtilityClass;
import com.gtnewhorizon.gtnhmixins.builders.ITargetMod;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import net.minecraft.launchwrapper.Launch;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* @since 0.8.2
*/
@UtilityClass
public final class FileUtil {
public static File getMinecraftHome() {
return getMinecraftHomePath().toFile();
}
/**
* @since 1.0.0
*/
public static Path getMinecraftHomePath() {
return Launch.minecraftHome == null ? Paths.get("").toAbsolutePath() : Launch.minecraftHome.toPath();
}
}
@RequiredArgsConstructor
public class TaggedMod {
public final boolean require;
public final @NotNull ITargetMod mod;
}
@@ -0,0 +1,57 @@
/*
* This file is part of FalsePatternLib.
*
* Copyright (C) 2022-2025 FalsePattern
* All Rights Reserved
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* FalsePatternLib is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, only version 3 of the License.
*
* FalsePatternLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FalsePatternLib. If not, see <https://www.gnu.org/licenses/>.
*/
package com.falsepattern.chunk.internal.mixin.plugin.fplib;
import com.gtnewhorizon.gtnhmixins.builders.ITargetMod;
import com.gtnewhorizon.gtnhmixins.builders.TargetModBuilder;
import lombok.Getter;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Consumer;
public class TargetMod implements ITargetMod {
@Getter
private final TargetModBuilder builder;
private final String name;
public TargetMod(@NotNull String name, @Language(value = "JAVA", prefix = "import ", suffix = ";") @NotNull String className) {
this(name, className, null);
}
public TargetMod(@NotNull String name, @Language(value = "JAVA", prefix = "import ", suffix = ";") @NotNull String className, @Nullable Consumer<TargetModBuilder> cfg) {
this.name = name;
builder = new TargetModBuilder();
builder.setTargetClass(className);
if (cfg != null) {
cfg.accept(builder);
}
}
@Override
public String toString() {
return name;
}
}
@@ -1,61 +0,0 @@
/*
* This file is part of FalsePatternLib.
*
* Copyright (C) 2022-2025 FalsePattern
* All Rights Reserved
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* FalsePatternLib is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, only version 3 of the License.
*
* FalsePatternLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FalsePatternLib. If not, see <https://www.gnu.org/licenses/>.
*/
package com.falsepattern.chunk.internal.mixin.plugin.fplib;
import lombok.val;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.launchwrapper.LaunchClassLoader;
import java.io.File;
import java.io.IOException;
public final class UCPImpl {
private static final boolean GRIMOIRE;
static {
boolean grimoire = false;
String[] knownGrimoireClassNames =
new String[]{"io.github.crucible.grimoire.Grimoire", "io.github.crucible.grimoire.common.GrimoireCore"};
for (val className : knownGrimoireClassNames) {
try {
if (Launch.classLoader.getClassBytes(className) != null) {
grimoire = true;
break;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
GRIMOIRE = grimoire;
}
public static void addJar(File pathToJar) throws Exception {
if (!GRIMOIRE) {
final LaunchClassLoader loader = Launch.classLoader;
loader.addURL(pathToJar.toURI().toURL());
// Act as-if we only added the mod to ucp
loader.getSources().remove(loader.getSources().size() - 1);
}
}
}
@@ -1,23 +1,23 @@
/*
* ChunkAPI
* This file is part of FalsePatternLib.
*
* Copyright (C) 2023-2025 FalsePattern, The MEGA Team, LegacyModdingMC contributors
* Copyright (C) 2022-2025 FalsePattern
* All Rights Reserved
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* This program is free software: you can redistribute it and/or modify
* FalsePatternLib is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, only version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* FalsePatternLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* along with FalsePatternLib. If not, see <https://www.gnu.org/licenses/>.
*/
@ApiStatus.Internal
@@ -2,7 +2,6 @@
"required": true,
"minVersion": "0.8.5",
"package": "com.falsepattern.chunk.internal.mixin.mixins",
"plugin": "com.falsepattern.chunk.internal.mixin.plugin.MixinPlugin",
"refmap": "mixins.chunkapi.refmap.json",
"target": "@env(DEFAULT)",
"compatibilityLevel": "JAVA_8"
@@ -0,0 +1,9 @@
{
"required": true,
"minVersion": "0.8.5",
"package": "com.falsepattern.chunk.internal.mixin.mixins",
"refmap": "mixins.chunkapi.refmap.json",
"target": "@env(DEFAULT)",
"compatibilityLevel": "JAVA_8"
}