This commit is contained in:
Armamem0t 2025-07-15 17:02:32 +08:00
parent 44d5cef52d
commit 3fc4268b76
Signed by: minglipro
GPG Key ID: 5F355A77B22AA93B
14 changed files with 302 additions and 184 deletions

View File

@ -48,6 +48,8 @@ runs {
// You can set various levels here.
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
systemProperty 'forge.logging.console.level', 'info'
jvmArgument "--add-opens=java.base/java.lang.invoke=ALL-UNNAMED"
jvmArgument "--add-opens=java.base/java.util.jar=ALL-UNNAMED"
modSource project.sourceSets.main
}
@ -154,7 +156,8 @@ publishing {
}
repositories {
maven {
url "file://${project.projectDir}/repo"
name= "Disk"
url = uri("D:/git/maven-repository-raw")
}
}
}

View File

@ -1,18 +1,13 @@
org.gradle.jvmargs=-Xmx1G
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=true
neogradle.subsystems.parchment.minecraftVersion=1.20.4
neogradle.subsystems.parchment.mappingsVersion=2024.04.14
minecraft_version=1.20.5
minecraft_version_range=[1.20.5,1.21)
neo_version=20.5.21-beta
neogradle.subsystems.parchment.minecraftVersion=1.21
neogradle.subsystems.parchment.mappingsVersion=2024.11.10
minecraft_version=1.21
minecraft_version_range=[1.21,1.22)
neo_version=21.0.167
loader_version_range=[1,)
mod_id=enchantmentdoesnotconflict
mod_name=EnchantmentDoNotConflictNeoForge
mod_license=Apache License 2.0
mod_version=1.0
mod_version=1.1
mod_group_id=com.mingliqiye.minecraft.enchantment.conflict
mod_authors=minglipro
mod_description= Any Enchantment Now is not Conflict

View File

@ -1,7 +1,9 @@
package com.mingliqiye.minecraft.enchantment.conflict;
import com.mingliqiye.minecraft.enchantment.conflict.config.ModConfig;
import com.mingliqiye.minecraft.enchantment.conflict.network.ConfigPayload;
import net.minecraft.server.MinecraftServer;
import net.neoforged.fml.ModContainer;
import static net.neoforged.fml.config.ModConfig.Type.COMMON;
import org.slf4j.Logger;
import com.mojang.logging.LogUtils;
@ -15,25 +17,28 @@ import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.server.ServerStartingEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import com.mingliqiye.minecraft.enchantment.conflict.config.ModConfig;
@Mod(EnchantmentDoNotConflictNeoForge.MODID)
public class EnchantmentDoNotConflictNeoForge {
public static final String MODID = "enchantmentdoesnotconflict";
public static final Logger LOGGER = LogUtils.getLogger();
public static MinecraftServer minecraftServer;
public EnchantmentDoNotConflictNeoForge(IEventBus modEventBus, ModContainer container) {
container.registerConfig(COMMON, ModConfig.SPEC);
modEventBus.addListener(this::commonSetup);
modEventBus.addListener(ConfigPayload::register);
NeoForge.EVENT_BUS.addListener(ConfigPayload::onPlayerLogin);
NeoForge.EVENT_BUS.register(this);
}
private void commonSetup(FMLCommonSetupEvent event) {
LOGGER.info("Mod {} Setup", MODID);
ModConfig.load();
}
// 服务端启动时执行
@SubscribeEvent
public void onServerStarting(ServerStartingEvent event) {
minecraftServer = event.getServer();
ModConfig.setInstance(ModConfig.load());
LOGGER.info("Server Mod {} Setup", MODID);
}

View File

@ -1,78 +1,85 @@
package com.mingliqiye.minecraft.enchantment.conflict.config;
import net.neoforged.neoforge.common.ModConfigSpec;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.mingliqiye.minecraft.enchantment.conflict.EnchantmentDoNotConflictNeoForge;
import com.mojang.logging.LogUtils;
import net.neoforged.fml.loading.FMLPaths;
import org.slf4j.Logger;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ModConfig {
private static final ModConfigSpec.Builder BUILDER = new ModConfigSpec.Builder();
public static final ModConfigSpec.BooleanValue AllowDamageEnchantment =
BUILDER.define("AllowDamageEnchantment", true);
public static final ModConfigSpec.BooleanValue AllowInfinityEnchantment =
BUILDER.define("AllowInfinityEnchantment", true);
public static final ModConfigSpec.BooleanValue AllowPiercingEnchantment =
BUILDER.define("AllowPiercingEnchantment", true);
public static final ModConfigSpec.BooleanValue AllowProtectionEnchantment =
BUILDER.define("AllowProtectionEnchantment", true);
public static final ModConfigSpec SPEC = BUILDER.build();
private final static Path CONFIG_PATH = FMLPaths.CONFIGDIR.get().resolve(EnchantmentDoNotConflictNeoForge.MODID +
".json");
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().serializeNulls().create();
public static final Type TYPE = new TypeToken<HashMap<String, ArrayList<String>>>() {
}.getType();
private static Map<String, List<String>> instance;
private static final Logger LOGGER = LogUtils.getLogger();
private static ConfigItem instance;
public static ConfigItem getInstance() {
return instance;
public ModConfig() {
}
public static void load() {
instance = new ConfigItem(AllowDamageEnchantment.get(), AllowInfinityEnchantment.get(),
AllowPiercingEnchantment.get(), AllowProtectionEnchantment.get());
public static Map<String, List<String>> getInstance() {
return ModConfig.instance;
}
public static class ConfigItem {
private boolean allowDamageEnchantment;
private boolean allowInfinityEnchantment;
private boolean allowPiercingEnchantment;
private boolean allowProtectionEnchantment;
ConfigItem() {
public static void reload() {
load();
}
ConfigItem(boolean a, boolean b, boolean c, boolean d) {
this.allowDamageEnchantment = a;
this.allowInfinityEnchantment = b;
this.allowPiercingEnchantment = c;
this.allowProtectionEnchantment = d;
public static void setInstance(Map<String, List<String>> instance) {
ModConfig.instance = instance;
}
public boolean isAllowDamageEnchantment() {
return allowDamageEnchantment;
public static Map<String, List<String>> load() {
try {
if (Files.exists(CONFIG_PATH)) {
return GSON.fromJson(Files.newBufferedReader(CONFIG_PATH), TYPE);
}
} catch (IOException e) {
e.printStackTrace();
}
Map<String, List<String>> modConfig = getDefData();
setInstance(modConfig);
save();
return modConfig;
}
public void setAllowDamageEnchantment(boolean allowDamageEnchantment) {
this.allowDamageEnchantment = allowDamageEnchantment;
public static void save() {
try {
Files.writeString(CONFIG_PATH, GSON.toJson(instance));
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean isAllowInfinityEnchantment() {
return allowInfinityEnchantment;
public static Map<String, List<String>> getDefData() {
try {
InputStream inputStream = ModConfig.class.getResourceAsStream(
"/assets/enchantmentdoesnotconflict" + "/EnchantmentDoNotConflict.json");
if (inputStream != null) {
try (InputStreamReader reader = new InputStreamReader(inputStream)) {
return GSON.fromJson(reader, TYPE);
}
public void setAllowInfinityEnchantment(boolean allowInfinityEnchantment) {
this.allowInfinityEnchantment = allowInfinityEnchantment;
} else {
throw new RuntimeException("resources 文件内 没有 EnchantmentDoNotConflict.json?");
}
public boolean isAllowPiercingEnchantment() {
return allowPiercingEnchantment;
}
public void setAllowPiercingEnchantment(boolean allowPiercingEnchantment) {
this.allowPiercingEnchantment = allowPiercingEnchantment;
}
public boolean isAllowProtectionEnchantment() {
return allowProtectionEnchantment;
}
public void setAllowProtectionEnchantment(boolean allowProtectionEnchantment) {
this.allowProtectionEnchantment = allowProtectionEnchantment;
} catch (RuntimeException | IOException e) {
LOGGER.error(e.getMessage(), e);
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,9 @@
package com.mingliqiye.minecraft.enchantment.conflict.enchantment;
import java.util.List;
import java.util.Map;
@FunctionalInterface
public interface AddAllowEnchantmentFunInf {
Map<String,List<String>> call();
}

View File

@ -0,0 +1,82 @@
package com.mingliqiye.minecraft.enchantment.conflict.enchantment;
import com.mingliqiye.minecraft.enchantment.conflict.EnchantmentDoNotConflictNeoForge;
import com.mingliqiye.minecraft.enchantment.conflict.config.ModConfig;
import com.mingliqiye.minecraft.enchantment.conflict.network.ConfigPayload;
import com.mojang.logging.LogUtils;
import net.minecraft.server.MinecraftServer;
import net.neoforged.neoforge.network.PacketDistributor;
import org.slf4j.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static com.mingliqiye.minecraft.enchantment.conflict.network.ConfigPayload.sendToAllPlayers;
public class Enchantment {
private static final Logger LOGGER = LogUtils.getLogger();
private final String id;
private final String father;
private final static List<AddAllowEnchantmentFunInf> allowEnchantmentFunInfs = new ArrayList<>();
public static void registerAllowEnchantment(AddAllowEnchantmentFunInf fun) {
allowEnchantmentFunInfs.add(fun);
}
public static void reload() {
ModConfig.reload();
allowEnchantmentFunInfs.forEach(e -> {
Map<String, List<String>> conf = ModConfig.getInstance();
conf.putAll(e.call());
ModConfig.setInstance(conf);
});
sendToAllPlayers();
LOGGER.info("reload {} Ok Entity: \n{}", EnchantmentDoNotConflictNeoForge.MODID, ModConfig.getInstance());
}
public Enchantment(String id, String father) {
this.id = id;
this.father = father;
}
public static List<Enchantment> ofId(String id, Map<String, List<String>> listMap) {
final List<Enchantment> enchantmentList = new ArrayList<>();
for (String i : listMap.keySet()) {
if (listMap.get(i).contains(id)) {
enchantmentList.add(new Enchantment(id, i));
}
}
return enchantmentList;
}
public static Boolean canBeCombined(String enchantmentA, String enchantmentB) {
if (enchantmentA.equals(enchantmentB)) {
return true;
}
Map<String, List<String>> config = ModConfig.getInstance();
List<Enchantment> groupsA = ofId(enchantmentA, config);
List<Enchantment> groupsB = ofId(enchantmentB, config);
if (groupsA.isEmpty() && groupsB.isEmpty()) {
return null;
}
for (Enchantment groupA : groupsA) {
for (Enchantment groupB : groupsB) {
if (groupA.getFather().equals(groupB.getFather())) {
return true;
}
}
}
return null;
}
public String getId() {
return id;
}
public String getFather() {
return father;
}
}

View File

@ -1,26 +0,0 @@
package com.mingliqiye.minecraft.enchantment.conflict.mixin;
import com.mingliqiye.minecraft.enchantment.conflict.config.ModConfig;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.ArrowInfiniteEnchantment;
import net.minecraft.world.item.enchantment.MendingEnchantment;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ArrowInfiniteEnchantment.class)
public abstract class ArrowInfiniteEnchantmentMixin {
@Inject(method = "checkCompatibility", at = @At("HEAD"), cancellable = true)
private void canAccept(
@NotNull Enchantment enchantment,
@NotNull CallbackInfoReturnable<Boolean> cir
) {
if (enchantment instanceof MendingEnchantment) {
cir.setReturnValue(ModConfig.getInstance().isAllowInfinityEnchantment());
}
}
}

View File

@ -1,26 +0,0 @@
package com.mingliqiye.minecraft.enchantment.conflict.mixin;
import com.mingliqiye.minecraft.enchantment.conflict.config.ModConfig;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.item.enchantment.ArrowPiercingEnchantment;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ArrowPiercingEnchantment.class)
public abstract class ArrowPiercingEnchantmentMixin {
@Inject(method = "checkCompatibility", at = @At("HEAD"), cancellable = true)
private void canAccept(
@NotNull Enchantment enchantment,
@NotNull CallbackInfoReturnable<Boolean> cir
) {
if (enchantment == Enchantments.MULTISHOT) {
cir.setReturnValue(ModConfig.getInstance().isAllowPiercingEnchantment());
}
}
}

View File

@ -1,26 +0,0 @@
package com.mingliqiye.minecraft.enchantment.conflict.mixin;
import com.mingliqiye.minecraft.enchantment.conflict.config.ModConfig;
import net.minecraft.world.item.enchantment.DamageEnchantment;
import net.minecraft.world.item.enchantment.Enchantment;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(DamageEnchantment.class)
public abstract class DamageEnchantmentMixin {
@Inject(method = "checkCompatibility", at = @At("HEAD"), cancellable = true)
private void canAccept(
@NotNull Enchantment enchantment,
@NotNull CallbackInfoReturnable<Boolean> cir
) {
if (enchantment instanceof DamageEnchantment) {
cir.setReturnValue(ModConfig.getInstance().isAllowDamageEnchantment());
}
}
}

View File

@ -0,0 +1,25 @@
package com.mingliqiye.minecraft.enchantment.conflict.mixin;
import com.mingliqiye.minecraft.enchantment.conflict.enchantment.Enchantment;
import net.minecraft.core.Holder;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(net.minecraft.world.item.enchantment.Enchantment.class)
public abstract class EnchantmentMixin {
@Inject(method = "areCompatible", at = @At("HEAD"), cancellable = true)
private static void canBeCombined(
Holder<net.minecraft.world.item.enchantment.Enchantment> first,
Holder<net.minecraft.world.item.enchantment.Enchantment> second, CallbackInfoReturnable<Boolean> cir
) {
Boolean cbc = Enchantment.canBeCombined(first.getRegisteredName(), second.getRegisteredName());
if (cbc == null) {
return;
}
cir.setReturnValue(cbc);
}
}

View File

@ -1,26 +0,0 @@
package com.mingliqiye.minecraft.enchantment.conflict.mixin;
import com.mingliqiye.minecraft.enchantment.conflict.config.ModConfig;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.ProtectionEnchantment;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ProtectionEnchantment.class)
public abstract class ProtectionEnchantmentMixin {
@Inject(method = "checkCompatibility", at = @At("HEAD"), cancellable = true)
private void onCheckCompatibility(
@NotNull Enchantment enchantment,
@NotNull CallbackInfoReturnable<Boolean> cir
) {
if (enchantment instanceof ProtectionEnchantment) {
cir.setReturnValue(ModConfig.getInstance().isAllowProtectionEnchantment());
}
}
}

View File

@ -0,0 +1,76 @@
package com.mingliqiye.minecraft.enchantment.conflict.network;
import com.google.gson.Gson;
import com.mingliqiye.minecraft.enchantment.conflict.EnchantmentDoNotConflictNeoForge;
import com.mingliqiye.minecraft.enchantment.conflict.config.ModConfig;
import com.mingliqiye.minecraft.enchantment.conflict.enchantment.Enchantment;
import com.mojang.logging.LogUtils;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
import net.neoforged.neoforge.network.PacketDistributor;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
import net.neoforged.neoforge.network.registration.PayloadRegistrar;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import java.util.List;
import java.util.Map;
public record ConfigPayload(Map<String, List<String>> data) implements CustomPacketPayload {
private static final Logger LOGGER = LogUtils.getLogger();
public static final CustomPacketPayload.Type<ConfigPayload> TYPE = new CustomPacketPayload.Type<>(
ResourceLocation.fromNamespaceAndPath(EnchantmentDoNotConflictNeoForge.MODID, "config_packet"));
private static final Gson GSON = new Gson();
public static final StreamCodec<FriendlyByteBuf, ConfigPayload> STREAM_CODEC =
StreamCodec.composite(ByteBufCodecs.STRING_UTF8, (p) -> GSON.toJson(p.data()),
(s) -> new ConfigPayload(GSON.fromJson(s, ModConfig.TYPE)));
public static void sendConfig(ServerPlayer player) {
Map<String, List<String>> conf = ModConfig.getInstance();
LOGGER.info("Send Server Config {} to {} data={}", EnchantmentDoNotConflictNeoForge.MODID,
player.getName().getString(), conf);
PacketDistributor.sendToPlayer(player, new ConfigPayload(conf));
}
public static void sendToAllPlayers() {
Map<String, List<String>> conf = ModConfig.getInstance();
LOGGER.info("Send Server Config {} to @a data={}", EnchantmentDoNotConflictNeoForge.MODID, conf);
PacketDistributor.sendToAllPlayers(new ConfigPayload(conf));
}
@SubscribeEvent
public static void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) {
if (event.getEntity() instanceof ServerPlayer player) {
sendConfig(player);
}
}
@SubscribeEvent
public static void register(final RegisterPayloadHandlersEvent event) {
PayloadRegistrar registrar = event.registrar(EnchantmentDoNotConflictNeoForge.MODID).versioned("1.1");
registrar.playToClient(ConfigPayload.TYPE, ConfigPayload.STREAM_CODEC, (payload, context) -> {
context.enqueueWork(() -> {
ModConfig.setInstance(payload.data());
LOGGER.info("Load Server Config {} data={}", EnchantmentDoNotConflictNeoForge.MODID, payload.data());
});
});
}
@Override
@NotNull
public CustomPacketPayload.Type<? extends CustomPacketPayload> type() {
return TYPE;
}
}

View File

@ -0,0 +1,23 @@
{
"minecraft:damageEnchantment": [
"minecraft:sharpness",
"minecraft:smite",
"minecraft:bane_of_arthropods",
"minecraft:density",
"minecraft:breach"
],
"minecraft:infinityEnchantment": [
"minecraft:infinity",
"minecraft:mending"
],
"minecraft:piercingEnchantment": [
"minecraft:piercing",
"minecraft:multishot"
],
"minecraft:protectionEnchantment": [
"minecraft:protection",
"minecraft:fire_protection",
"minecraft:blast_protection",
"minecraft:projectile_protection"
]
}

View File

@ -3,10 +3,7 @@
"package": "com.mingliqiye.minecraft.enchantment.conflict.mixin",
"compatibilityLevel": "JAVA_21",
"mixins": [
"ArrowInfiniteEnchantmentMixin",
"ArrowPiercingEnchantmentMixin",
"DamageEnchantmentMixin",
"ProtectionEnchantmentMixin"
"EnchantmentMixin"
],
"injectors": {
"defaultRequire": 1