mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
Merge branch 'dev' of https://github.com/Xiao-MoMi/craft-engine into dev
This commit is contained in:
@@ -163,7 +163,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for mod
|
// for mod
|
||||||
@EventHandler
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
public void onPlayerRegisterChannel(PlayerRegisterChannelEvent event) {
|
public void onPlayerRegisterChannel(PlayerRegisterChannelEvent event) {
|
||||||
if (!event.getChannel().equals(MOD_CHANNEL)) return;
|
if (!event.getChannel().equals(MOD_CHANNEL)) return;
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
|
|||||||
@@ -2,24 +2,27 @@ package net.momirealms.craftengine.fabric.client;
|
|||||||
|
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
|
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
|
||||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
|
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
|
||||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||||
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
|
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
|
||||||
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
|
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.color.world.BiomeColors;
|
import net.minecraft.client.color.world.BiomeColors;
|
||||||
import net.minecraft.client.gui.screen.DisconnectedScreen;
|
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||||
import net.minecraft.client.render.RenderLayer;
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
import net.minecraft.network.DisconnectionInfo;
|
||||||
import net.minecraft.registry.Registries;
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.crash.CrashReport;
|
|
||||||
import net.minecraft.world.biome.FoliageColors;
|
import net.minecraft.world.biome.FoliageColors;
|
||||||
import net.momirealms.craftengine.fabric.client.config.ModConfig;
|
import net.momirealms.craftengine.fabric.client.config.ModConfig;
|
||||||
import net.momirealms.craftengine.fabric.client.network.CraftEnginePayload;
|
import net.momirealms.craftengine.fabric.client.network.CraftEnginePayload;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class CraftEngineFabricModClient implements ClientModInitializer {
|
public class CraftEngineFabricModClient implements ClientModInitializer {
|
||||||
public static final String MOD_ID = "craftengine";
|
public static final String MOD_ID = "craftengine";
|
||||||
@@ -27,6 +30,12 @@ public class CraftEngineFabricModClient implements ClientModInitializer {
|
|||||||
@Override
|
@Override
|
||||||
public void onInitializeClient() {
|
public void onInitializeClient() {
|
||||||
PayloadTypeRegistry.playS2C().register(CraftEnginePayload.ID, CraftEnginePayload.CODEC);
|
PayloadTypeRegistry.playS2C().register(CraftEnginePayload.ID, CraftEnginePayload.CODEC);
|
||||||
|
initChannel(MinecraftClient.getInstance().getNetworkHandler());
|
||||||
|
registerRenderLayer();
|
||||||
|
ClientPlayConnectionEvents.INIT.register((handler, client) -> initChannel(handler));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void registerRenderLayer() {
|
||||||
Registries.BLOCK.forEach(block -> {
|
Registries.BLOCK.forEach(block -> {
|
||||||
Identifier id = Registries.BLOCK.getId(block);
|
Identifier id = Registries.BLOCK.getId(block);
|
||||||
if (id.getNamespace().equals(CraftEngineFabricModClient.MOD_ID)) {
|
if (id.getNamespace().equals(CraftEngineFabricModClient.MOD_ID)) {
|
||||||
@@ -36,26 +45,6 @@ public class CraftEngineFabricModClient implements ClientModInitializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ClientTickEvents.START_CLIENT_TICK.register(client -> {
|
|
||||||
if (!ModConfig.enableNetwork) {
|
|
||||||
ClientPlayNetworking.unregisterGlobalReceiver(CraftEnginePayload.ID.id());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ClientPlayNetworking.registerGlobalReceiver(CraftEnginePayload.ID, (payload, context) -> {
|
|
||||||
byte[] data = payload.data();
|
|
||||||
String decoded = new String(data, StandardCharsets.UTF_8);
|
|
||||||
if (decoded.startsWith("cp:")) {
|
|
||||||
int blockRegistrySize = Integer.parseInt(decoded.substring(3));
|
|
||||||
if (Block.STATE_IDS.size() != blockRegistrySize) {
|
|
||||||
client.disconnect(new DisconnectedScreen(
|
|
||||||
client.currentScreen,
|
|
||||||
Text.translatable("disconnect.craftengine.title"),
|
|
||||||
Text.translatable("disconnect.craftengine.block_registry_mismatch", Block.STATE_IDS.size(), blockRegistrySize))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerColor(Block block) {
|
public static void registerColor(Block block) {
|
||||||
@@ -69,4 +58,31 @@ public class CraftEngineFabricModClient implements ClientModInitializer {
|
|||||||
block
|
block
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void initChannel(ClientPlayNetworkHandler handler) {
|
||||||
|
if (ModConfig.enableNetwork) {
|
||||||
|
registerChannel(handler);
|
||||||
|
} else {
|
||||||
|
ClientPlayNetworking.unregisterGlobalReceiver(CraftEnginePayload.ID.id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void registerChannel(ClientPlayNetworkHandler handler) {
|
||||||
|
ClientPlayNetworking.registerGlobalReceiver(CraftEnginePayload.ID, (payload, context) -> {
|
||||||
|
byte[] data = payload.data();
|
||||||
|
String decoded = new String(data, StandardCharsets.UTF_8);
|
||||||
|
if (decoded.startsWith("cp:")) {
|
||||||
|
int blockRegistrySize = Integer.parseInt(decoded.substring(3));
|
||||||
|
if (Block.STATE_IDS.size() != blockRegistrySize) {
|
||||||
|
handler.getConnection().disconnect(
|
||||||
|
new DisconnectionInfo(
|
||||||
|
Text.translatable("disconnect.craftengine.block_registry_mismatch", Block.STATE_IDS.size(), blockRegistrySize),
|
||||||
|
Optional.of(FabricLoader.getInstance().getConfigDir().resolve("craft-engine-fabric-mod/mappings.yml")),
|
||||||
|
Optional.of(URI.create("https://github.com/Xiao-MoMi/craft-engine"))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import net.minecraft.network.packet.CustomPayload;
|
|||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
public record CraftEnginePayload(byte[] data) implements CustomPayload {
|
public record CraftEnginePayload(byte[] data) implements CustomPayload {
|
||||||
public static final Identifier ADD_CRAFTENGINE_BLOCK = Identifier.of("craftengine", "payload");
|
public static final Identifier CRAFTENGINE_PAYLOAD = Identifier.of("craftengine", "payload");
|
||||||
public static final Id<CraftEnginePayload> ID = new Id<>(CraftEnginePayload.ADD_CRAFTENGINE_BLOCK);
|
public static final Id<CraftEnginePayload> ID = new Id<>(CraftEnginePayload.CRAFTENGINE_PAYLOAD);
|
||||||
public static final PacketCodec<RegistryByteBuf, CraftEnginePayload> CODEC = PacketCodec.tuple(
|
public static final PacketCodec<RegistryByteBuf, CraftEnginePayload> CODEC = PacketCodec.tuple(
|
||||||
new ByteArrayCodec(), CraftEnginePayload::data,
|
new ByteArrayCodec(), CraftEnginePayload::data,
|
||||||
CraftEnginePayload::new
|
CraftEnginePayload::new
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import net.fabricmc.api.ModInitializer;
|
|||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
import net.momirealms.craftengine.fabric.client.config.ModConfig;
|
import net.momirealms.craftengine.fabric.client.config.ModConfig;
|
||||||
import net.momirealms.craftengine.fabric.util.BlockUtils;
|
import net.momirealms.craftengine.fabric.util.BlockUtils;
|
||||||
import net.momirealms.craftengine.fabric.util.LoggerFilter;
|
import net.momirealms.craftengine.fabric.util.LoggerFilter;
|
||||||
@@ -37,7 +39,8 @@ public class CraftEngineFabricMod implements ModInitializer {
|
|||||||
BlockState blockState = YamlUtils.createBlockData("minecraft:" + replacedBlockId.getPath());
|
BlockState blockState = YamlUtils.createBlockData("minecraft:" + replacedBlockId.getPath());
|
||||||
RegisterBlocks.register(
|
RegisterBlocks.register(
|
||||||
replacedBlockId.getPath() + "_" + i,
|
replacedBlockId.getPath() + "_" + i,
|
||||||
BlockUtils.canPassThrough(blockState)
|
BlockUtils.canPassThrough(blockState),
|
||||||
|
BlockUtils.getShape(blockState)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
package net.momirealms.craftengine.fabric.util;
|
package net.momirealms.craftengine.fabric.util;
|
||||||
|
|
||||||
import net.minecraft.block.AbstractBlock;
|
import net.minecraft.block.AbstractBlock;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
|
import net.minecraft.util.shape.VoxelShapes;
|
||||||
|
import net.minecraft.world.BlockView;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -43,4 +48,20 @@ public class BlockUtils {
|
|||||||
throw new RuntimeException("Failed to access 'collidable' field", e);
|
throw new RuntimeException("Failed to access 'collidable' field", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static VoxelShape getShape(BlockState state) {
|
||||||
|
if (state == null) return VoxelShapes.fullCube();
|
||||||
|
Block block = state.getBlock();
|
||||||
|
VoxelShape combinedShape = VoxelShapes.empty();
|
||||||
|
try {
|
||||||
|
for (BlockState possibleState : block.getStateManager().getStates()) {
|
||||||
|
VoxelShape currentShape = possibleState.getOutlineShape(null, BlockPos.ORIGIN);
|
||||||
|
combinedShape = VoxelShapes.union(combinedShape, currentShape);
|
||||||
|
}
|
||||||
|
return combinedShape.isEmpty() ? VoxelShapes.fullCube() : combinedShape;
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
return VoxelShapes.fullCube();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,21 +2,33 @@ package net.momirealms.craftengine.fabric.util;
|
|||||||
|
|
||||||
import net.minecraft.block.AbstractBlock;
|
import net.minecraft.block.AbstractBlock;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.ShapeContext;
|
||||||
import net.minecraft.registry.Registries;
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.registry.RegistryKey;
|
import net.minecraft.registry.RegistryKey;
|
||||||
import net.minecraft.registry.RegistryKeys;
|
import net.minecraft.registry.RegistryKeys;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
|
import net.minecraft.util.shape.VoxelShapes;
|
||||||
|
import net.minecraft.world.BlockView;
|
||||||
import net.momirealms.craftengine.fabric.CraftEngineFabricMod;
|
import net.momirealms.craftengine.fabric.CraftEngineFabricMod;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class RegisterBlocks {
|
public class RegisterBlocks {
|
||||||
@SuppressWarnings("UnusedReturnValue")
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
public static Block register(String name, boolean canPassThrough) {
|
public static Block register(String name, boolean canPassThrough, VoxelShape outlineShape) {
|
||||||
AbstractBlock.Settings settings = Block.Settings.create().nonOpaque().strength(-1.0F, 3600000.0F);
|
AbstractBlock.Settings settings = Block.Settings.create().nonOpaque().strength(-1.0F, 3600000.0F);
|
||||||
if (canPassThrough) settings.noCollision();
|
VoxelShape collisionShape;
|
||||||
return register(name, Block::new, settings);
|
if (canPassThrough) {
|
||||||
|
collisionShape = VoxelShapes.empty();
|
||||||
|
settings.noCollision();
|
||||||
|
} else {
|
||||||
|
collisionShape = outlineShape;
|
||||||
|
}
|
||||||
|
return register(name, (settingsParam) -> new CustomBlock(settingsParam, outlineShape, collisionShape), settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Block register(String name, Function<AbstractBlock.Settings, Block> blockFactory, AbstractBlock.Settings settings) {
|
public static Block register(String name, Function<AbstractBlock.Settings, Block> blockFactory, AbstractBlock.Settings settings) {
|
||||||
@@ -31,3 +43,24 @@ public class RegisterBlocks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CustomBlock extends Block {
|
||||||
|
private final VoxelShape outlineShape;
|
||||||
|
private final VoxelShape collisionShape;
|
||||||
|
|
||||||
|
public CustomBlock(Settings settings, VoxelShape outlineShape, VoxelShape collisionShape) {
|
||||||
|
super(settings);
|
||||||
|
this.outlineShape = outlineShape;
|
||||||
|
this.collisionShape = collisionShape;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||||
|
return this.outlineShape;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VoxelShape getCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||||
|
return this.collisionShape;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,5 @@
|
|||||||
"category.craftengine.general": "General",
|
"category.craftengine.general": "General",
|
||||||
"option.craftengine.enable_network": "Enable custom blocks in server",
|
"option.craftengine.enable_network": "Enable custom blocks in server",
|
||||||
"tooltip.craftengine.enable_network": "Changes requires re-entering the server to take effect",
|
"tooltip.craftengine.enable_network": "Changes requires re-entering the server to take effect",
|
||||||
"disconnect.craftengine.block_registry_mismatch": "Block registry size mismatch. Current: %s. Expected: %s. \n 1. Make sure that the configs are the same as the server's. \n 2. Do not use any mod that might register new block. \n 3. Do not install ViaVersion.",
|
"disconnect.craftengine.block_registry_mismatch": "Block registry size mismatch. Current: %s. Expected: %s. \n 1. Make sure that the configs are the same as the server's. \n 2. Do not use any mod that might register new block. \n 3. Do not install ViaVersion."
|
||||||
"disconnect.craftengine.title": "CraftEngine Connection Error"
|
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,5 @@
|
|||||||
"category.craftengine.general": "通用",
|
"category.craftengine.general": "通用",
|
||||||
"option.craftengine.enable_network": "启用服务器内自定义方块",
|
"option.craftengine.enable_network": "启用服务器内自定义方块",
|
||||||
"tooltip.craftengine.enable_network": "需要重新进入服务器以应用更改",
|
"tooltip.craftengine.enable_network": "需要重新进入服务器以应用更改",
|
||||||
"disconnect.craftengine.block_registry_mismatch": "方块注册表大小不匹配. 当前: %s. 预期: %s \n 1. 确保客户端mod配置与服务端配置一致. \n 2. 不要安装任何会注册新方块的mod. \n 3. 不要使用ViaVersion.",
|
"disconnect.craftengine.block_registry_mismatch": "方块注册表大小不匹配. 当前: %s. 预期: %s \n 1. 确保客户端mod配置与服务端配置一致. \n 2. 不要安装任何会注册新方块的mod. \n 3. 不要使用ViaVersion."
|
||||||
"disconnect.craftengine.title": "CraftEngine连接错误"
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user