Merge pull request #3543 from kosma/fabric-1.18-signs

[Fabric 1.18] Sign marker support
This commit is contained in:
mikeprimm 2021-12-03 12:45:56 -06:00 committed by GitHub
commit 12fce4c5ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 76 additions and 35 deletions

View File

@ -754,7 +754,7 @@ public class DynmapPlugin {
ServerChunkEvents.CHUNK_LOAD.register((world, chunk) -> worldTracker.handleChunkLoad(world, chunk)); ServerChunkEvents.CHUNK_LOAD.register((world, chunk) -> worldTracker.handleChunkLoad(world, chunk));
ServerChunkEvents.CHUNK_UNLOAD.register((world, chunk) -> worldTracker.handleChunkUnload(world, chunk)); ServerChunkEvents.CHUNK_UNLOAD.register((world, chunk) -> worldTracker.handleChunkUnload(world, chunk));
ChunkDataEvents.SAVE.register((world, chunk) -> worldTracker.handleChunkDataSave(world, chunk)); ChunkDataEvents.SAVE.register((world, chunk) -> worldTracker.handleChunkDataSave(world, chunk));
BlockEvents.EVENT.register((world, pos) -> worldTracker.handleBlockEvent(world, pos)); BlockEvents.BLOCK_EVENT.register((world, pos) -> worldTracker.handleBlockEvent(world, pos));
} }
// Prime the known full chunks // Prime the known full chunks
if (onchunkgenerate && (server.getWorlds() != null)) { if (onchunkgenerate && (server.getWorlds() != null)) {

View File

@ -3,6 +3,7 @@ package org.dynmap.fabric_1_18;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer; import net.fabricmc.loader.api.ModContainer;
import net.minecraft.block.AbstractSignBlock;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.network.MessageType; import net.minecraft.network.MessageType;
@ -17,6 +18,7 @@ import net.minecraft.util.UserCache;
import net.minecraft.util.Util; import net.minecraft.util.Util;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
import org.dynmap.DynmapChunk; import org.dynmap.DynmapChunk;
import org.dynmap.DynmapCommonAPIListener; import org.dynmap.DynmapCommonAPIListener;
@ -26,6 +28,7 @@ import org.dynmap.common.BiomeMap;
import org.dynmap.common.DynmapListenerManager; import org.dynmap.common.DynmapListenerManager;
import org.dynmap.common.DynmapPlayer; import org.dynmap.common.DynmapPlayer;
import org.dynmap.common.DynmapServerInterface; import org.dynmap.common.DynmapServerInterface;
import org.dynmap.fabric_1_18.event.BlockEvents;
import org.dynmap.fabric_1_18.event.ServerChatEvents; import org.dynmap.fabric_1_18.event.ServerChatEvents;
import org.dynmap.utils.MapChunkCache; import org.dynmap.utils.MapChunkCache;
import org.dynmap.utils.VisibilityLimit; import org.dynmap.utils.VisibilityLimit;
@ -92,9 +95,17 @@ public class FabricServer extends DynmapServerInterface {
return -1; return -1;
} }
@Override @SuppressWarnings("deprecation") /* Not much I can do... fix this if it breaks. */
@Override
public int isSignAt(String wname, int x, int y, int z) { public int isSignAt(String wname, int x, int y, int z) {
return -1; World world = plugin.getWorldByName(wname).getWorld();
BlockPos pos = new BlockPos(x, y, z);
if (!world.isChunkLoaded(pos))
return -1;
Block block = world.getBlockState(pos).getBlock();
return (block instanceof AbstractSignBlock ? 1 : 0);
} }
@Override @Override
@ -255,38 +266,14 @@ public class FabricServer extends DynmapServerInterface {
break; break;
case BLOCK_BREAK: case BLOCK_BREAK:
/*TODO /* Already handled by BlockEvents logic */
pm.registerEvents(new Listener() {
@EventHandler(priority=EventPriority.MONITOR)
public void onBlockBreak(BlockBreakEvent evt) {
if(evt.isCancelled()) return;
Block b = evt.getBlock();
if(b == null) return;
Location l = b.getLocation();
core.listenerManager.processBlockEvent(EventType.BLOCK_BREAK, b.getType().getId(),
BukkitWorld.normalizeWorldName(l.getWorld().getName()), l.getBlockX(), l.getBlockY(), l.getBlockZ());
}
}, DynmapPlugin.this);
*/
break; break;
case SIGN_CHANGE: case SIGN_CHANGE:
/*TODO BlockEvents.SIGN_CHANGE_EVENT.register((world, pos, lines, material, player) -> {
pm.registerEvents(new Listener() { plugin.core.processSignChange("fabric", FabricWorld.getWorldName(plugin, world),
@EventHandler(priority=EventPriority.MONITOR) pos.getX(), pos.getY(), pos.getZ(), lines, player.getName().asString());
public void onSignChange(SignChangeEvent evt) { });
if(evt.isCancelled()) return;
Block b = evt.getBlock();
Location l = b.getLocation();
String[] lines = evt.getLines();
DynmapPlayer dp = null;
Player p = evt.getPlayer();
if(p != null) dp = new BukkitPlayer(p);
core.listenerManager.processSignChangeEvent(EventType.SIGN_CHANGE, b.getType().getId(),
BukkitWorld.normalizeWorldName(l.getWorld().getName()), l.getBlockX(), l.getBlockY(), l.getBlockZ(), lines, dp);
}
}, DynmapPlugin.this);
*/
break; break;
default: default:

View File

@ -2,6 +2,9 @@ package org.dynmap.fabric_1_18.event;
import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory; import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.block.Material;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -9,7 +12,7 @@ public class BlockEvents {
private BlockEvents() { private BlockEvents() {
} }
public static Event<BlockCallback> EVENT = EventFactory.createArrayBacked(BlockCallback.class, public static Event<BlockCallback> BLOCK_EVENT = EventFactory.createArrayBacked(BlockCallback.class,
(listeners) -> (world, pos) -> { (listeners) -> (world, pos) -> {
for (BlockCallback callback : listeners) { for (BlockCallback callback : listeners) {
callback.onBlockEvent(world, pos); callback.onBlockEvent(world, pos);
@ -17,7 +20,21 @@ public class BlockEvents {
} }
); );
public static Event<SignChangeCallback> SIGN_CHANGE_EVENT = EventFactory.createArrayBacked(SignChangeCallback.class,
(listeners) -> (world, pos, lines, material, player) -> {
for (SignChangeCallback callback : listeners) {
callback.onSignChange(world, pos, lines, material, player);
}
}
);
@FunctionalInterface
public interface BlockCallback { public interface BlockCallback {
void onBlockEvent(World world, BlockPos pos); void onBlockEvent(World world, BlockPos pos);
} }
@FunctionalInterface
public interface SignChangeCallback {
void onSignChange(ServerWorld world, BlockPos pos, String[] lines, Material material, ServerPlayerEntity player);
}
} }

View File

@ -1,14 +1,26 @@
package org.dynmap.fabric_1_18.mixin; package org.dynmap.fabric_1_18.mixin;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.SignBlockEntity;
import net.minecraft.network.packet.c2s.play.UpdateSignC2SPacket;
import net.minecraft.server.filter.TextStream; import net.minecraft.server.filter.TextStream;
import net.minecraft.server.network.ServerPlayNetworkHandler; import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.LiteralText;
import net.minecraft.util.math.BlockPos;
import java.util.List;
import org.dynmap.fabric_1_18.event.BlockEvents;
import org.dynmap.fabric_1_18.event.ServerChatEvents; import org.dynmap.fabric_1_18.event.ServerChatEvents;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(ServerPlayNetworkHandler.class) @Mixin(ServerPlayNetworkHandler.class)
public abstract class ServerPlayNetworkHandlerMixin { public abstract class ServerPlayNetworkHandlerMixin {
@ -26,4 +38,29 @@ public abstract class ServerPlayNetworkHandlerMixin {
public void onGameMessage(TextStream.Message message, CallbackInfo info) { public void onGameMessage(TextStream.Message message, CallbackInfo info) {
ServerChatEvents.EVENT.invoker().onChatMessage(player, message.getRaw()); ServerChatEvents.EVENT.invoker().onChatMessage(player, message.getRaw());
} }
}
@Inject(
method = "onSignUpdate",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/block/entity/SignBlockEntity;markDirty()V",
shift = At.Shift.BEFORE
),
locals = LocalCapture.CAPTURE_FAILHARD
)
public void onSignUpdate(UpdateSignC2SPacket packet, List<TextStream.Message> signText, CallbackInfo info,
ServerWorld serverWorld, BlockPos blockPos, BlockState blockState, BlockEntity blockEntity, SignBlockEntity signBlockEntity)
{
// Pull the raw text from the input.
String[] rawTexts = new String[4];
for (int i=0; i<signText.size(); i++)
rawTexts[i] = signText.get(i).getRaw();
// Fire the event.
BlockEvents.SIGN_CHANGE_EVENT.invoker().onSignChange(serverWorld, blockPos, rawTexts, blockState.getMaterial(), player);
// Put the (possibly updated) texts in the sign. Ignore filtering (is this OK?).
for (int i=0; i<signText.size(); i++)
signBlockEntity.setTextOnRow(i, new LiteralText(rawTexts[i]));
}
}

View File

@ -19,7 +19,7 @@ public abstract class WorldChunkMixin {
@Inject(method = "setBlockState", at = @At("RETURN")) @Inject(method = "setBlockState", at = @At("RETURN"))
public void setBlockState(BlockPos pos, BlockState state, boolean moved, CallbackInfoReturnable<BlockState> info) { public void setBlockState(BlockPos pos, BlockState state, boolean moved, CallbackInfoReturnable<BlockState> info) {
if (info.getReturnValue() != null) { if (info.getReturnValue() != null) {
BlockEvents.EVENT.invoker().onBlockEvent(this.getWorld(), pos); BlockEvents.BLOCK_EVENT.invoker().onBlockEvent(this.getWorld(), pos);
} }
} }
} }