diff --git a/build.gradle b/build.gradle index 1b9a8e35ce3..4b1e1e6ad50 100644 --- a/build.gradle +++ b/build.gradle @@ -162,6 +162,11 @@ dependencies { exclude group: "net.fabricmc.fabric-api" } + modImplementation("fuzs.forgeconfigapiport:forgeconfigapiport-fabric:${project.config_version}") { + exclude group: "net.fabricmc" + exclude group: "net.fabricmc.fabric-api" + } + // unit test dependencies testImplementation(platform("org.junit:junit-bom:${project.junit_version}")) testImplementation(platform("org.assertj:assertj-bom:${project.assertj_version}")) @@ -235,6 +240,13 @@ allprojects { includeGroup "mezz.jei" } } + maven { + name = "Fuzs Mod Resources" + url = "https://raw.githubusercontent.com/Fuzss/modresources/main/maven/" + content { + includeGroup "fuzs.forgeconfigapiport" + } + } mavenCentral() } } diff --git a/gradle.properties b/gradle.properties index dbb45427913..d3bf7025895 100644 --- a/gradle.properties +++ b/gradle.properties @@ -25,6 +25,7 @@ jade_version=15.1.5+fabric trinkets_version=3.10.0 fabric_version=0.102.0+1.21 energy_version=3.0.0 +config_version=21.0.8 # Pick which item list mod gets picked at runtime in dev # Available options: emi, rei, none diff --git a/src/main/java/appeng/core/AEConfig.java b/src/main/java/appeng/core/AEConfig.java index 8efbca6da60..7ff8090976d 100644 --- a/src/main/java/appeng/core/AEConfig.java +++ b/src/main/java/appeng/core/AEConfig.java @@ -22,9 +22,10 @@ import java.util.Map; import java.util.function.DoubleSupplier; -import net.neoforged.fml.ModContainer; +import fuzs.forgeconfigapiport.fabric.api.neoforge.v4.NeoForgeConfigRegistry; +import fuzs.forgeconfigapiport.fabric.api.neoforge.v4.NeoForgeModConfigEvents; + import net.neoforged.fml.config.ModConfig; -import net.neoforged.fml.event.config.ModConfigEvent; import net.neoforged.neoforge.common.ModConfigSpec; import net.neoforged.neoforge.common.ModConfigSpec.BooleanValue; import net.neoforged.neoforge.common.ModConfigSpec.DoubleValue; @@ -51,26 +52,23 @@ public final class AEConfig { private static AEConfig instance; - private AEConfig(ModContainer container) { - container.registerConfig(ModConfig.Type.CLIENT, client.spec); - container.registerConfig(ModConfig.Type.COMMON, common.spec); - container.getEventBus().addListener((ModConfigEvent.Loading evt) -> { - if (evt.getConfig().getSpec() == common.spec) { + private AEConfig(String modId) { + NeoForgeConfigRegistry.INSTANCE.register(modId, ModConfig.Type.CLIENT, client.spec); + NeoForgeConfigRegistry.INSTANCE.register(modId, ModConfig.Type.COMMON, common.spec); + NeoForgeModConfigEvents.loading(modId).register(config -> { + if (config.getSpec() == common.spec) { common.sync(); } }); - container.getEventBus().addListener((ModConfigEvent.Reloading evt) -> { - if (evt.getConfig().getSpec() == common.spec) { + NeoForgeModConfigEvents.reloading(modId).register(config -> { + if (config.getSpec() == common.spec) { common.sync(); } }); } - public static void register(ModContainer container) { - if (!container.getModId().equals(AppEng.MOD_ID)) { - throw new IllegalArgumentException(); - } - instance = new AEConfig(container); + public static void register(String modId) { + instance = new AEConfig(modId); } // Tunnels diff --git a/src/main/java/appeng/core/AppEngBase.java b/src/main/java/appeng/core/AppEngBase.java index fb8f0ccb7f7..da46712ebf5 100644 --- a/src/main/java/appeng/core/AppEngBase.java +++ b/src/main/java/appeng/core/AppEngBase.java @@ -21,8 +21,18 @@ import java.util.Collection; import java.util.Collections; +import appeng.core.network.CustomAppEngPayload; +import appeng.hooks.ToolItemHook; +import appeng.util.NetworkUtil; import com.mojang.brigadier.CommandDispatcher; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.fabricmc.fabric.api.event.player.UseBlockCallback; +import net.fabricmc.fabric.api.networking.v1.PacketSender; +import net.fabricmc.fabric.api.networking.v1.PlayerLookup; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.gametest.framework.GameTestRegistry; +import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; import net.minecraft.commands.CommandSourceStack; @@ -37,21 +47,6 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.level.Level; -import net.neoforged.bus.api.EventPriority; -import net.neoforged.bus.api.IEventBus; -import net.neoforged.fml.ModContainer; -import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; -import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.event.RegisterGameTestsEvent; -import net.neoforged.neoforge.event.server.ServerAboutToStartEvent; -import net.neoforged.neoforge.event.server.ServerStartingEvent; -import net.neoforged.neoforge.event.server.ServerStoppedEvent; -import net.neoforged.neoforge.event.server.ServerStoppingEvent; -import net.neoforged.neoforge.network.PacketDistributor; -import net.neoforged.neoforge.registries.NewRegistryEvent; -import net.neoforged.neoforge.registries.RegisterEvent; -import net.neoforged.neoforge.registries.RegistryBuilder; -import net.neoforged.neoforge.server.ServerLifecycleHooks; import appeng.api.ids.AEComponents; import appeng.api.parts.CableRenderMode; @@ -112,90 +107,93 @@ public abstract class AppEngBase implements AppEng { static AppEngBase INSTANCE; - public AppEngBase(IEventBus modEventBus, ModContainer container) { + private MinecraftServer currentServer; + + public AppEngBase() { if (INSTANCE != null) { throw new IllegalStateException(); } INSTANCE = this; - AEConfig.register(container); + AEConfig.register("ae2"); InitGridServices.init(); InitBlockEntityMoveStrategies.init(); AEParts.init(); - AEBlocks.DR.register(modEventBus); - AEItems.DR.register(modEventBus); - AEBlockEntities.DR.register(modEventBus); - AEComponents.DR.register(modEventBus); - AEEntities.DR.register(modEventBus); - InitStructures.register(modEventBus); - - modEventBus.addListener(this::registerRegistries); - modEventBus.addListener(MainCreativeTab::initExternal); - modEventBus.addListener(InitNetwork::init); - modEventBus.addListener(ChunkLoadingService.getInstance()::register); - modEventBus.addListener(InitCapabilityProviders::register); - modEventBus.addListener(EventPriority.LOWEST, InitCapabilityProviders::registerGenericAdapters); - modEventBus.addListener((RegisterEvent event) -> { - if (event.getRegistryKey() == Registries.SOUND_EVENT) { - registerSounds(BuiltInRegistries.SOUND_EVENT); - } else if (event.getRegistryKey() == Registries.CREATIVE_MODE_TAB) { - registerCreativeTabs(BuiltInRegistries.CREATIVE_MODE_TAB); - } else if (event.getRegistryKey() == Registries.CUSTOM_STAT) { - InitStats.init(event.getRegistry(Registries.CUSTOM_STAT)); - } else if (event.getRegistryKey() == Registries.TRIGGER_TYPE) { - InitAdvancementTriggers.init(event.getRegistry(Registries.TRIGGER_TYPE)); - } else if (event.getRegistryKey() == Registries.PARTICLE_TYPE) { - InitParticleTypes.init(event.getRegistry(Registries.PARTICLE_TYPE)); - } else if (event.getRegistryKey() == Registries.MENU) { - InitMenuTypes.init(event.getRegistry(Registries.MENU)); - } else if (event.getRegistryKey() == Registries.RECIPE_TYPE) { - InitRecipeTypes.init(event.getRegistry(Registries.RECIPE_TYPE)); - } else if (event.getRegistryKey() == Registries.RECIPE_SERIALIZER) { - InitRecipeSerializers.init(event.getRegistry(Registries.RECIPE_SERIALIZER)); - } else if (event.getRegistryKey() == Registries.RECIPE_SERIALIZER) { - InitRecipeSerializers.init(event.getRegistry(Registries.RECIPE_SERIALIZER)); - } else if (event.getRegistryKey() == Registries.CHUNK_GENERATOR) { - Registry.register(BuiltInRegistries.CHUNK_GENERATOR, SpatialStorageDimensionIds.CHUNK_GENERATOR_ID, - SpatialStorageChunkGenerator.CODEC); - } else if (event.getRegistryKey() == Registries.VILLAGER_PROFESSION) { - InitVillager.initProfession(event.getRegistry(Registries.VILLAGER_PROFESSION)); - } else if (event.getRegistryKey() == Registries.POINT_OF_INTEREST_TYPE) { - InitVillager.initPointOfInterestType(event.getRegistry(Registries.POINT_OF_INTEREST_TYPE)); - } else if (event.getRegistryKey() == AEKeyType.REGISTRY_KEY) { - registerKeyTypes(event.getRegistry(AEKeyType.REGISTRY_KEY)); - } - }); - - NeoForge.EVENT_BUS.addListener(InitVillager::initTrades); - - modEventBus.addListener(Integrations::enqueueIMC); - modEventBus.addListener(this::commonSetup); - - modEventBus.addListener(this::registerTests); +// AEBlocks.DR.register(modEventBus); +// AEItems.DR.register(modEventBus); +// AEBlockEntities.DR.register(modEventBus); +// AEComponents.DR.register(modEventBus); +// AEEntities.DR.register(modEventBus); +// InitStructures.register(modEventBus); + +// modEventBus.addListener(this::registerRegistries); +// modEventBus.addListener(MainCreativeTab::initExternal); +// modEventBus.addListener(InitNetwork::init); +// modEventBus.addListener(ChunkLoadingService.getInstance()::register); +// modEventBus.addListener(InitCapabilityProviders::register); +// modEventBus.addListener(EventPriority.LOWEST, InitCapabilityProviders::registerGenericAdapters); +// modEventBus.addListener((RegisterEvent event) -> { +// if (event.getRegistryKey() == Registries.SOUND_EVENT) { +// registerSounds(BuiltInRegistries.SOUND_EVENT); +// } else if (event.getRegistryKey() == Registries.CREATIVE_MODE_TAB) { +// registerCreativeTabs(BuiltInRegistries.CREATIVE_MODE_TAB); +// } else if (event.getRegistryKey() == Registries.CUSTOM_STAT) { +// InitStats.init(event.getRegistry(Registries.CUSTOM_STAT)); +// } else if (event.getRegistryKey() == Registries.TRIGGER_TYPE) { +// InitAdvancementTriggers.init(event.getRegistry(Registries.TRIGGER_TYPE)); +// } else if (event.getRegistryKey() == Registries.PARTICLE_TYPE) { +// InitParticleTypes.init(event.getRegistry(Registries.PARTICLE_TYPE)); +// } else if (event.getRegistryKey() == Registries.MENU) { +// InitMenuTypes.init(event.getRegistry(Registries.MENU)); +// } else if (event.getRegistryKey() == Registries.RECIPE_TYPE) { +// InitRecipeTypes.init(event.getRegistry(Registries.RECIPE_TYPE)); +// } else if (event.getRegistryKey() == Registries.RECIPE_SERIALIZER) { +// InitRecipeSerializers.init(event.getRegistry(Registries.RECIPE_SERIALIZER)); +// } else if (event.getRegistryKey() == Registries.RECIPE_SERIALIZER) { +// InitRecipeSerializers.init(event.getRegistry(Registries.RECIPE_SERIALIZER)); +// } else if (event.getRegistryKey() == Registries.CHUNK_GENERATOR) { +// Registry.register(BuiltInRegistries.CHUNK_GENERATOR, SpatialStorageDimensionIds.CHUNK_GENERATOR_ID, +// SpatialStorageChunkGenerator.CODEC); +// } else if (event.getRegistryKey() == Registries.VILLAGER_PROFESSION) { +// InitVillager.initProfession(event.getRegistry(Registries.VILLAGER_PROFESSION)); +// } else if (event.getRegistryKey() == Registries.POINT_OF_INTEREST_TYPE) { +// InitVillager.initPointOfInterestType(event.getRegistry(Registries.POINT_OF_INTEREST_TYPE)); +// } else if (event.getRegistryKey() == AEKeyType.REGISTRY_KEY) { +// registerKeyTypes(event.getRegistry(AEKeyType.REGISTRY_KEY)); +// } +// }); + + registerCreativeTabs(BuiltInRegistries.CREATIVE_MODE_TAB); +// registerDimension(); +// registerBlocks(BuiltInRegistries.BLOCK); +// registerItems(BuiltInRegistries.ITEM); +// registerEntities(BuiltInRegistries.ENTITY_TYPE); +// registerParticleTypes(BuiltInRegistries.PARTICLE_TYPE); +// registerBlockEntities(BuiltInRegistries.BLOCK_ENTITY_TYPE); +// registerMenuTypes(BuiltInRegistries.MENU); +// registerRecipeSerializers(BuiltInRegistries.RECIPE_SERIALIZER); +// registerStructures(BuiltInRegistries.STRUCTURE_TYPE); + registerSounds(BuiltInRegistries.SOUND_EVENT); + + //NeoForge.EVENT_BUS.addListener(InitVillager::initTrades); + + postRegistrationInitialization(); TickHandler.instance().init(); - NeoForge.EVENT_BUS.addListener(this::onServerAboutToStart); - NeoForge.EVENT_BUS.addListener(this::serverStopped); - NeoForge.EVENT_BUS.addListener(this::serverStopping); - NeoForge.EVENT_BUS.addListener(this::registerCommands); + ServerLifecycleEvents.SERVER_STARTING.register(this::onServerAboutToStart); + ServerLifecycleEvents.SERVER_STOPPED.register(this::serverStopped); + ServerLifecycleEvents.SERVER_STOPPING.register(this::serverStopping); + ServerLifecycleEvents.SERVER_STARTING.register(this::registerCommands); - NeoForge.EVENT_BUS.addListener(WrenchHook::onPlayerUseBlockEvent); - NeoForge.EVENT_BUS.addListener(SkyStoneBreakSpeed::handleBreakFaster); + UseBlockCallback.EVENT.register(WrenchHook::onPlayerUseBlock); + UseBlockCallback.EVENT.register(ToolItemHook::onPlayerUseBlock); HotkeyActions.init(); } - private void commonSetup(FMLCommonSetupEvent event) { - event.enqueueWork(this::postRegistrationInitialization).whenComplete((res, err) -> { - if (err != null) { - AELog.warn(err); - } - }); - } - /** * Runs after all mods have had time to run their registrations into registries. */ @@ -217,8 +215,8 @@ public void registerKeyTypes(Registry registry) { Registry.register(registry, AEKeyType.fluids().getId(), AEKeyType.fluids()); } - public void registerCommands(ServerStartingEvent evt) { - CommandDispatcher dispatcher = evt.getServer().getCommands().getDispatcher(); + public void registerCommands(MinecraftServer server) { + CommandDispatcher dispatcher = server.getCommands().getDispatcher(); new AECommand().register(dispatcher); } @@ -226,23 +224,28 @@ public void registerSounds(Registry registry) { AppEngSounds.register(registry); } - public void registerRegistries(NewRegistryEvent e) { - var registry = e.create(new RegistryBuilder<>(AEKeyType.REGISTRY_KEY) - .sync(true) - .maxId(127)); - AEKeyTypesInternal.setRegistry(registry); - } +// public void registerRegistries(NewRegistryEvent e) { +// var registry = e.create(new RegistryBuilder<>(AEKeyType.REGISTRY_KEY) +// .sync(true) +// .maxId(127)); +// AEKeyTypesInternal.setRegistry(registry); +// } - private void onServerAboutToStart(final ServerAboutToStartEvent evt) { - ChunkLoadingService.getInstance().onServerAboutToStart(evt); + private void onServerAboutToStart(MinecraftServer server) { + this.currentServer = server; + ChunkLoadingService.getInstance().onServerAboutToStart(); } - private void serverStopping(final ServerStoppingEvent event) { - ChunkLoadingService.getInstance().onServerStopping(event); + private void serverStopping(MinecraftServer server) { + this.currentServer = server; + ChunkLoadingService.getInstance().onServerStopping(); } - private void serverStopped(final ServerStoppedEvent event) { + private void serverStopped(MinecraftServer server) { TickHandler.instance().shutdown(); + if (this.currentServer == server) { + this.currentServer = null; + } } public void registerCreativeTabs(Registry registry) { @@ -265,11 +268,7 @@ public Collection getPlayers() { public void sendToAllNearExcept(Player p, double x, double y, double z, double dist, Level level, ClientboundPacket packet) { if (level instanceof ServerLevel serverLevel) { - ServerPlayer except = null; - if (p instanceof ServerPlayer) { - except = (ServerPlayer) p; - } - PacketDistributor.sendToPlayersNear(serverLevel, except, x, y, z, dist, packet); + NetworkUtil.sendToPlayersNear(serverLevel, x, y, z, dist, packet); } } @@ -286,7 +285,7 @@ public CableRenderMode getCableRenderMode() { @Nullable @Override public MinecraftServer getCurrentServer() { - return ServerLifecycleHooks.getCurrentServer(); + return currentServer; } protected final CableRenderMode getCableRenderModeForPlayer(@Nullable Player player) { @@ -300,9 +299,9 @@ protected final CableRenderMode getCableRenderModeForPlayer(@Nullable Player pla return CableRenderMode.STANDARD; } - private void registerTests(RegisterGameTestsEvent e) { + private void registerTests() { if ("true".equals(System.getProperty("appeng.tests"))) { - e.register(GameTestPlotAdapter.class); + GameTestRegistry.register(GameTestPlotAdapter.class); } } } diff --git a/src/main/java/appeng/core/AppEngClient.java b/src/main/java/appeng/core/AppEngClient.java index 27ee1510052..afcad45840c 100644 --- a/src/main/java/appeng/core/AppEngClient.java +++ b/src/main/java/appeng/core/AppEngClient.java @@ -23,6 +23,7 @@ import com.mojang.blaze3d.platform.InputConstants; import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import fuzs.forgeconfigapiport.fabric.api.neoforge.v4.client.ConfigScreenFactoryRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,7 +60,6 @@ import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent; import net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent; import net.neoforged.neoforge.client.gui.ConfigurationScreen; -import net.neoforged.neoforge.client.gui.IConfigScreenFactory; import net.neoforged.neoforge.client.settings.KeyConflictContext; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.event.server.ServerStartingEvent; @@ -128,7 +128,6 @@ /** * Client-specific functionality. */ -@Mod(value = AppEng.MOD_ID, dist = Dist.CLIENT) public class AppEngClient extends AppEngBase { private static final Logger LOGGER = LoggerFactory.getLogger(AppEngClient.class); @@ -149,7 +148,7 @@ public class AppEngClient extends AppEngBase { private final Guide guide; - public AppEngClient(IEventBus modEventBus, ModContainer container) { + public AppEngClient() { super(modEventBus, container); InitBuiltInModels.init(); @@ -191,8 +190,7 @@ public AppEngClient(IEventBus modEventBus, ModContainer container) { Hotkeys.checkHotkeys(); }); - container.registerExtensionPoint(IConfigScreenFactory.class, - (mc, parent) -> new ConfigurationScreen(container, parent)); + ConfigScreenFactoryRegistry.INSTANCE.register("ae2", (string, screen) -> new ConfigurationScreen("ae2", screen)); } private void enqueueImcMessages(InterModEnqueueEvent event) { diff --git a/src/main/java/appeng/core/AppEngClientInitializer.java b/src/main/java/appeng/core/AppEngClientInitializer.java new file mode 100644 index 00000000000..b281d8b4c9d --- /dev/null +++ b/src/main/java/appeng/core/AppEngClientInitializer.java @@ -0,0 +1,10 @@ +package appeng.core; + +import net.fabricmc.api.ClientModInitializer; + +public class AppEngClientInitializer implements ClientModInitializer { + @Override + public void onInitializeClient() { + new AppEngClient(); + } +} diff --git a/src/main/java/appeng/core/AppEngServer.java b/src/main/java/appeng/core/AppEngServer.java index 35dc8272b75..60a6f557010 100644 --- a/src/main/java/appeng/core/AppEngServer.java +++ b/src/main/java/appeng/core/AppEngServer.java @@ -19,20 +19,15 @@ package appeng.core; import net.minecraft.world.level.Level; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.bus.api.IEventBus; -import net.neoforged.fml.ModContainer; -import net.neoforged.fml.common.Mod; import appeng.client.EffectType; /** * Contains mod functionality specific to a dedicated server. */ -@Mod(value = AppEng.MOD_ID, dist = Dist.DEDICATED_SERVER) public class AppEngServer extends AppEngBase { - public AppEngServer(IEventBus modEventBus, ModContainer container) { - super(modEventBus, container); + public AppEngServer() { + super(); } @Override diff --git a/src/main/java/appeng/core/AppEngServerInitializer.java b/src/main/java/appeng/core/AppEngServerInitializer.java new file mode 100644 index 00000000000..697e547039f --- /dev/null +++ b/src/main/java/appeng/core/AppEngServerInitializer.java @@ -0,0 +1,10 @@ +package appeng.core; + +import net.fabricmc.api.DedicatedServerModInitializer; + +public class AppEngServerInitializer implements DedicatedServerModInitializer { + @Override + public void onInitializeServer() { + new AppEngServer(); + } +} diff --git a/src/main/java/appeng/core/FacadeCreativeTab.java b/src/main/java/appeng/core/FacadeCreativeTab.java index bd1ec4b4e2f..3635ad7155d 100644 --- a/src/main/java/appeng/core/FacadeCreativeTab.java +++ b/src/main/java/appeng/core/FacadeCreativeTab.java @@ -21,6 +21,7 @@ import java.util.Collection; import java.util.Set; +import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; import net.minecraft.core.Registry; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.CreativeModeTabs; @@ -37,9 +38,9 @@ public final class FacadeCreativeTab { private static CreativeModeTab group; public static void init(Registry registry) { - group = CreativeModeTab.builder() + group = FabricItemGroup.builder() .title(GuiText.CreativeTabFacades.text()) - .withTabsBefore(AECreativeTabIds.MAIN) + //.withTabsBefore(AECreativeTabIds.MAIN) .icon(() -> { if (group == null) { return ItemStack.EMPTY; diff --git a/src/main/java/appeng/core/MainCreativeTab.java b/src/main/java/appeng/core/MainCreativeTab.java index af50ee4a190..766d28ab808 100644 --- a/src/main/java/appeng/core/MainCreativeTab.java +++ b/src/main/java/appeng/core/MainCreativeTab.java @@ -24,10 +24,10 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; +import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; import net.minecraft.core.Registry; import net.minecraft.resources.ResourceKey; import net.minecraft.world.item.CreativeModeTab; -import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; import appeng.api.ids.AECreativeTabIds; import appeng.block.AEBaseBlock; @@ -44,7 +44,7 @@ public final class MainCreativeTab { private static final List> itemDefs = new ArrayList<>(); public static void init(Registry registry) { - var tab = CreativeModeTab.builder() + var tab = FabricItemGroup.builder() .title(GuiText.CreativeTab.text()) .icon(() -> AEBlocks.CONTROLLER.stack(1)) .displayItems(MainCreativeTab::buildDisplayItems) @@ -52,12 +52,6 @@ public static void init(Registry registry) { Registry.register(registry, AECreativeTabIds.MAIN, tab); } - public static void initExternal(BuildCreativeModeTabContentsEvent contents) { - for (var itemDefinition : externalItemDefs.get(contents.getTabKey())) { - contents.accept(itemDefinition); - } - } - public static void add(ItemDefinition itemDef) { itemDefs.add(itemDef); } diff --git a/src/main/java/appeng/hooks/AEToolItem.java b/src/main/java/appeng/hooks/AEToolItem.java index de8bd774274..c38757523c9 100644 --- a/src/main/java/appeng/hooks/AEToolItem.java +++ b/src/main/java/appeng/hooks/AEToolItem.java @@ -1,5 +1,9 @@ package appeng.hooks; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.UseOnContext; + public interface AEToolItem { - /* On Forge, we use onItemUseFirst to the same effect */ + InteractionResult onItemUseFirst(ItemStack stack, UseOnContext context); } diff --git a/src/main/java/appeng/hooks/SkyStoneBreakSpeed.java b/src/main/java/appeng/hooks/SkyStoneBreakSpeed.java index a62711ba5db..de312680c49 100644 --- a/src/main/java/appeng/hooks/SkyStoneBreakSpeed.java +++ b/src/main/java/appeng/hooks/SkyStoneBreakSpeed.java @@ -19,8 +19,9 @@ package appeng.hooks; import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Tiers; -import net.neoforged.neoforge.event.entity.player.PlayerEvent; +import net.minecraft.world.level.block.state.BlockState; import appeng.core.definitions.AEBlocks; @@ -35,13 +36,13 @@ public final class SkyStoneBreakSpeed { private SkyStoneBreakSpeed() { } - public static void handleBreakFaster(PlayerEvent.BreakSpeed event) { - var blockState = event.getState(); + public static Float handleBreakFaster(Player player, BlockState blockState, float speed) { if (blockState.getBlock() == AEBlocks.SKY_STONE_BLOCK.block()) { - var tool = event.getEntity().getItemBySlot(EquipmentSlot.MAINHAND); + var tool = player.getItemBySlot(EquipmentSlot.MAINHAND); if (tool.getDestroySpeed(blockState) > Tiers.IRON.getSpeed()) { - event.setNewSpeed(event.getNewSpeed() * SPEEDUP_FACTOR); + return speed * SPEEDUP_FACTOR; } } + return null; } } diff --git a/src/main/java/appeng/hooks/ToolItemHook.java b/src/main/java/appeng/hooks/ToolItemHook.java new file mode 100644 index 00000000000..25c336407e3 --- /dev/null +++ b/src/main/java/appeng/hooks/ToolItemHook.java @@ -0,0 +1,34 @@ +package appeng.hooks; + +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.BlockHitResult; + +/** + * This hooks allows item-specific behavior to be triggered when an item is used on a block, without shift being held or + * the block being called first. + */ +public final class ToolItemHook { + + private ToolItemHook() { + } + + public static InteractionResult onPlayerUseBlock(Player player, Level level, InteractionHand hand, BlockHitResult blockHitResult) { + + if (player.isSpectator()) { + return InteractionResult.PASS; + } + + var itemStack = player.getItemInHand(hand); + var item = itemStack.getItem(); + if (item instanceof AEToolItem toolItem) { + UseOnContext context = new UseOnContext(player, hand, blockHitResult); + return toolItem.onItemUseFirst(itemStack, context); + } + + return InteractionResult.PASS; + } +} diff --git a/src/main/java/appeng/hooks/WrenchHook.java b/src/main/java/appeng/hooks/WrenchHook.java index d9c78ca0028..df860bd5db6 100644 --- a/src/main/java/appeng/hooks/WrenchHook.java +++ b/src/main/java/appeng/hooks/WrenchHook.java @@ -8,7 +8,6 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.phys.BlockHitResult; -import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; import appeng.api.orientation.BlockOrientation; import appeng.api.orientation.IOrientationStrategy; @@ -33,18 +32,6 @@ public static boolean isDisassembling() { return Boolean.TRUE.equals(IS_DISASSEMBLING.get()); } - public static void onPlayerUseBlockEvent(PlayerInteractEvent.RightClickBlock event) { - if (event.isCanceled()) { - // See https://github.com/AppliedEnergistics/Applied-Energistics-2/issues/6900 - return; - } - var result = onPlayerUseBlock(event.getEntity(), event.getLevel(), event.getHand(), event.getHitVec()); - if (result != InteractionResult.PASS) { - event.setCanceled(true); - event.setCancellationResult(result); - } - } - public static InteractionResult onPlayerUseBlock(Player player, Level level, InteractionHand hand, diff --git a/src/main/java/appeng/mixins/BreakSpeedMixin.java b/src/main/java/appeng/mixins/BreakSpeedMixin.java new file mode 100644 index 00000000000..e0320504c45 --- /dev/null +++ b/src/main/java/appeng/mixins/BreakSpeedMixin.java @@ -0,0 +1,24 @@ +package appeng.mixins; + +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; + +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.block.state.BlockState; + +import appeng.hooks.SkyStoneBreakSpeed; + +@Mixin(value = Player.class) +public class BreakSpeedMixin { + @SuppressWarnings("ConstantConditions") + @Inject(method = "getDestroySpeed", at = @At("RETURN"), cancellable = true) + public void modifyBreakSpeed(BlockState blockState, CallbackInfoReturnable cri) { + var self = (Player) (Object) this; + var result = SkyStoneBreakSpeed.handleBreakFaster(self, blockState, cri.getReturnValue()); + if (result != null) { + cri.setReturnValue(result); + } + } +} diff --git a/src/main/java/appeng/server/services/ChunkLoadingService.java b/src/main/java/appeng/server/services/ChunkLoadingService.java index 037883764a9..406187fae5c 100644 --- a/src/main/java/appeng/server/services/ChunkLoadingService.java +++ b/src/main/java/appeng/server/services/ChunkLoadingService.java @@ -45,11 +45,11 @@ public void register(RegisterTicketControllersEvent event) { event.register(controller); } - public void onServerAboutToStart(ServerAboutToStartEvent evt) { + public void onServerAboutToStart() { this.running = true; } - public void onServerStopping(ServerStoppingEvent event) { + public void onServerStopping() { this.running = false; } diff --git a/src/main/java/appeng/util/NetworkUtil.java b/src/main/java/appeng/util/NetworkUtil.java new file mode 100644 index 00000000000..c84315b100f --- /dev/null +++ b/src/main/java/appeng/util/NetworkUtil.java @@ -0,0 +1,17 @@ +package appeng.util; + +import appeng.core.network.CustomAppEngPayload; +import net.fabricmc.fabric.api.networking.v1.PlayerLookup; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.phys.Vec3; + +public class NetworkUtil { + public static void sendToPlayersNear(ServerLevel serverLevel, double x, double y, double z, double radius, CustomAppEngPayload packet) { + var players = PlayerLookup.around(serverLevel, new Vec3(x, y, z), radius); + for (ServerPlayer player : players) { + ServerPlayNetworking.send(player, packet); + } + } +} diff --git a/src/main/java/appeng/util/Platform.java b/src/main/java/appeng/util/Platform.java index 4fe39ab7a78..92c6ab33dbc 100644 --- a/src/main/java/appeng/util/Platform.java +++ b/src/main/java/appeng/util/Platform.java @@ -25,9 +25,16 @@ import java.util.UUID; import java.util.concurrent.TimeUnit; +import appeng.core.AppEng; import com.google.common.annotations.VisibleForTesting; import com.mojang.authlib.GameProfile; +import net.fabricmc.api.EnvType; +import net.fabricmc.fabric.api.entity.FakePlayer; +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariantAttributes; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.nbt.CompoundTag; import org.jetbrains.annotations.Nullable; import net.minecraft.ChatFormatting; @@ -54,11 +61,6 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.material.Fluid; -import net.neoforged.fml.ModList; -import net.neoforged.fml.loading.FMLEnvironment; -import net.neoforged.fml.util.thread.SidedThreadGroups; -import net.neoforged.neoforge.common.util.FakePlayerFactory; -import net.neoforged.neoforge.fluids.FluidStack; import appeng.api.config.AccessRestriction; import appeng.api.config.PowerUnit; @@ -73,8 +75,7 @@ public class Platform { - @VisibleForTesting - public static ThreadGroup serverThreadGroup = SidedThreadGroups.SERVER; + public static final FabricLoader FABRIC = FabricLoader.getInstance(); private static final P2PHelper P2P_HELPER = new P2PHelper(); @@ -195,14 +196,15 @@ public static Direction crossProduct(Direction forward, Direction up) { */ public static boolean hasClientClasses() { // The null check is for tests - return FMLEnvironment.dist == null || FMLEnvironment.dist.isClient(); + return FABRIC.getEnvironmentType() == EnvType.CLIENT; } /* * returns true if the code is on the client. */ public static boolean isClient() { - return Thread.currentThread().getThreadGroup() != SidedThreadGroups.SERVER; + var currentServer = AppEng.instance().getCurrentServer(); + return currentServer == null || Thread.currentThread() != currentServer.getRunningThread(); } public static boolean hasPermissions(DimensionalBlockPos dc, Player player) { @@ -227,14 +229,21 @@ public static void spawnDrops(Level level, BlockPos pos, List drops) * returns true if the code is on the server. */ public static boolean isServer() { - return Thread.currentThread().getThreadGroup() == SidedThreadGroups.SERVER; + try { + var currentServer = AppEng.instance().getCurrentServer(); + return currentServer != null && Thread.currentThread() == currentServer.getRunningThread(); + } catch (NullPointerException npe) { + // FIXME TEST HACKS + // Running from tests: AppEng.instance() is null... :( + return false; + } } /** * Throws an exception if the current thread is not one of the server threads. */ public static void assertServerThread() { - if (Thread.currentThread().getThreadGroup() != serverThreadGroup) { + if (!isServer()) { throw new UnsupportedOperationException( "This code can only be called server-side and this is most likely a bug."); } @@ -246,13 +255,12 @@ public static String formatModName(String modId) { @Nullable public static String getModName(String modId) { - return ModList.get().getModContainerById(modId).map(mc -> mc.getModInfo().getDisplayName()) + return FABRIC.getModContainer(modId).map(mc -> mc.getMetadata().getName()) .orElse(modId); } public static Component getFluidDisplayName(Fluid fluid) { - var fluidStack = new FluidStack(fluid, 1); - return fluidStack.getHoverName(); + return FluidVariantAttributes.getName(FluidVariant.of(fluid)); } public static boolean isChargeable(ItemStack i) { @@ -275,7 +283,7 @@ public static Player getFakePlayer(ServerLevel level, @Nullable UUID playerUuid) playerUuid = DEFAULT_FAKE_PLAYER_UUID; } - return FakePlayerFactory.get(level, new GameProfile(playerUuid, "[AE2]")); + return FakePlayer.get(level, new GameProfile(playerUuid, "[AE2]")); } public static Direction rotateAround(Direction forward, Direction axis) { @@ -393,7 +401,7 @@ public static boolean isPonderLevel(Level level) { * @return True if AE2 is being run within a dev environment. */ public static boolean isDevelopmentEnvironment() { - return !FMLEnvironment.production; + return FABRIC.isDevelopmentEnvironment(); } /** diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index a28bebf444f..fb4165e3de9 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -14,8 +14,8 @@ "icon": "assets/ae2/logo.png", "environment": "*", "entrypoints": { - "client": ["appeng.core.AppEngClientStartup"], - "server": ["appeng.core.AppEngServerStartup"], + "client": ["appeng.core.AppEngClientInitializer"], + "server": ["appeng.core.AppEngServerInitializer"], "fabric-datagen": ["appeng.datagen.DatagenEntrypoint"], "rei_client": ["appeng.integration.modules.rei.ReiPlugin"], "jade": ["appeng.integration.modules.jade.JadeModule"]