This commit is contained in:
Brian Neumann-Fopiano
2026-07-09 13:54:59 -04:00
parent d1fec88769
commit 0a7a531646
259 changed files with 11055 additions and 884 deletions
@@ -0,0 +1,31 @@
/*
* Iris is a World Generator for Minecraft Servers
* Copyright (c) 2026 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package art.arcane.iris.forge;
import art.arcane.iris.client.IrisClient;
import net.minecraftforge.event.network.CustomPayloadEvent;
public final class ForgeClientProtocol {
private ForgeClientProtocol() {
}
public static void handleInbound(CustomPayloadEvent.Context context, byte[] data) {
context.enqueueWork(() -> IrisClient.onInbound(data));
}
}
@@ -0,0 +1,86 @@
/*
* Iris is a World Generator for Minecraft Servers
* Copyright (c) 2026 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package art.arcane.iris.forge;
import art.arcane.iris.modded.ModdedIrisPayload;
import art.arcane.iris.modded.ModdedProtocolChannel;
import art.arcane.iris.modded.ModdedProtocolHandler;
import art.arcane.iris.spi.protocol.IrisProtocol;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.event.network.CustomPayloadEvent;
import net.minecraftforge.network.Channel;
import net.minecraftforge.network.ChannelBuilder;
import net.minecraftforge.network.NetworkProtocol;
import net.minecraftforge.network.PacketDistributor;
public final class ForgeProtocolNetworking {
private static volatile Channel<CustomPacketPayload> channel;
private ForgeProtocolNetworking() {
}
public static void register() {
Channel<CustomPacketPayload> boundChannel = ChannelBuilder.named(Identifier.parse(IrisProtocol.CHANNEL))
.optional()
.payloadChannel()
.protocol(NetworkProtocol.PLAY)
.bidirectional()
.add(ModdedIrisPayload.TYPE, ModdedIrisPayload.STREAM_CODEC, ForgeProtocolNetworking::onPayload)
.build();
channel = boundChannel;
ModdedProtocolHandler.bindChannel(new ForgeProtocolChannel(boundChannel));
}
public static Channel<CustomPacketPayload> channel() {
return channel;
}
private static void onPayload(ModdedIrisPayload payload, CustomPayloadEvent.Context context) {
context.setPacketHandled(true);
if (context.isClientSide()) {
ForgeClientProtocol.handleInbound(context, payload.data());
return;
}
ServerPlayer player = context.getSender();
if (player == null) {
return;
}
ModdedProtocolHandler.onInbound(player, payload.data());
}
private static final class ForgeProtocolChannel implements ModdedProtocolChannel {
private final Channel<CustomPacketPayload> channel;
private ForgeProtocolChannel(Channel<CustomPacketPayload> channel) {
this.channel = channel;
}
@Override
public boolean canReceive(ServerPlayer player) {
return true;
}
@Override
public void send(ServerPlayer player, ModdedIrisPayload payload) {
channel.send(payload, PacketDistributor.PLAYER.with(player));
}
}
}
@@ -19,22 +19,29 @@
package art.arcane.iris.forge;
import art.arcane.iris.modded.IrisModdedChunkGenerator;
import art.arcane.iris.modded.ModdedDeathLoot;
import art.arcane.iris.modded.ModdedEngineBootstrap;
import art.arcane.iris.modded.ModdedForcedDatapack;
import art.arcane.iris.modded.ModdedProtocolHandler;
import art.arcane.iris.modded.command.IrisModdedCommands;
import art.arcane.iris.modded.command.ModdedWandService;
import com.mojang.serialization.MapCodec;
import net.minecraft.core.registries.Registries;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.packs.PackType;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraftforge.event.AddPackFindersEvent;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.entity.living.LivingDropsEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.server.ServerStartingEvent;
import net.minecraftforge.event.server.ServerStoppingEvent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.registries.DeferredRegister;
@@ -49,14 +56,31 @@ public final class IrisForgeBootstrap {
chunkGenerators.register(context.getModBusGroup());
});
ForgeProtocolNetworking.register();
if (FMLEnvironment.dist == Dist.CLIENT) {
IrisForgeClient.init();
}
ServerStartingEvent.BUS.addListener((ServerStartingEvent event) -> ModdedEngineBootstrap.start(event.getServer()));
ServerStoppingEvent.BUS.addListener((ServerStoppingEvent event) -> ModdedEngineBootstrap.stop());
PlayerEvent.PlayerLoggedInEvent.BUS.addListener((PlayerEvent.PlayerLoggedInEvent event) -> {
if (event.getEntity() instanceof ServerPlayer player) {
ModdedProtocolHandler.onPlayerJoin(player);
}
});
PlayerEvent.PlayerLoggedOutEvent.BUS.addListener((PlayerEvent.PlayerLoggedOutEvent event) -> {
if (event.getEntity() instanceof ServerPlayer player) {
ModdedProtocolHandler.onPlayerDisconnect(player);
}
});
AddPackFindersEvent.BUS.addListener((AddPackFindersEvent event) -> {
if (event.getPackType() == PackType.SERVER_DATA) {
event.addRepositorySource(ModdedForcedDatapack.repositorySource());
}
});
RegisterCommandsEvent.BUS.addListener((RegisterCommandsEvent event) -> IrisModdedCommands.register(event.getDispatcher()));
LivingDropsEvent.BUS.addListener((LivingDropsEvent event) -> ModdedDeathLoot.handle(event.getEntity()));
PlayerInteractEvent.LeftClickBlock.BUS.addListener((Predicate<PlayerInteractEvent.LeftClickBlock>) (PlayerInteractEvent.LeftClickBlock event) ->
ModdedWandService.attackBlock(event.getEntity(), event.getLevel(), event.getHand(), event.getPos()));
PlayerInteractEvent.RightClickBlock.BUS.addListener((Predicate<PlayerInteractEvent.RightClickBlock>) (PlayerInteractEvent.RightClickBlock event) ->
@@ -0,0 +1,58 @@
/*
* Iris is a World Generator for Minecraft Servers
* Copyright (c) 2026 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package art.arcane.iris.forge;
import art.arcane.iris.client.IrisClient;
import art.arcane.iris.client.IrisClientHud;
import art.arcane.iris.client.IrisClientKeybinds;
import art.arcane.iris.modded.ModdedIrisPayload;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraftforge.client.event.AddGuiOverlayLayersEvent;
import net.minecraftforge.client.event.ClientPlayerNetworkEvent;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.client.event.RegisterKeyMappingsEvent;
import net.minecraftforge.network.Channel;
import net.minecraftforge.network.PacketDistributor;
public final class IrisForgeClient {
private IrisForgeClient() {
}
public static void init() {
IrisClient.bindSender(IrisForgeClient::sendToServer);
AddGuiOverlayLayersEvent.BUS.addListener((AddGuiOverlayLayersEvent event) ->
event.getLayeredDraw().add(IrisClient.HUD_ELEMENT_ID, (graphics, delta) -> IrisClientHud.render(graphics)));
RegisterKeyMappingsEvent.BUS.addListener((RegisterKeyMappingsEvent event) -> {
event.register(IrisClientKeybinds.TOGGLE_HUD);
event.register(IrisClientKeybinds.OPEN_MAP);
event.register(IrisClientKeybinds.TOGGLE_WHAT);
});
ClientPlayerNetworkEvent.LoggingIn.BUS.addListener((ClientPlayerNetworkEvent.LoggingIn event) -> IrisClient.onWorldJoin());
ClientPlayerNetworkEvent.LoggingOut.BUS.addListener((ClientPlayerNetworkEvent.LoggingOut event) -> IrisClient.onDisconnect());
InputEvent.Key.BUS.addListener((InputEvent.Key event) -> IrisClientKeybinds.pollToggle());
}
private static void sendToServer(byte[] frame) {
Channel<CustomPacketPayload> channel = ForgeProtocolNetworking.channel();
if (channel == null) {
return;
}
channel.send(new ModdedIrisPayload(frame), PacketDistributor.SERVER.noArg());
}
}
@@ -1,5 +1,5 @@
modLoader = "javafml"
loaderVersion = "[64,)"
loaderVersion = "[65,)"
license = "GPL-3.0"
[[mods]]
@@ -12,7 +12,7 @@ authors = "Arcane Arts (Volmit Software)"
[[dependencies.irisworldgen]]
modId = "forge"
mandatory = true
versionRange = "[64,)"
versionRange = "[65,)"
ordering = "NONE"
side = "BOTH"