add: broadcasting location by sending .xyz (#2)

This commit is contained in:
iceBear67 committed 2024-07-10 15:40:50 +08:00
1 parent 613bb4fdd1
commit 09a2e7330a
8 files changed
+144 -5

No files matched your search

@@ -28,4 +28,8 @@ public class Helper {
}
return null;
}
public static int fromRgb(int r, int g, int b) {
return ((r & 0x0ff) << 16) | ((g & 0x0ff) << 8) | (b & 0x0ff);
}
}
+14 -4
View File
@@ -7,6 +7,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import io.ib67.sfcraft.config.SFConfig;
import io.ib67.sfcraft.geoip.GeoIPService;
import io.ib67.sfcraft.message.SFMessageDecorator;
import io.ib67.sfcraft.registry.event.RandomEventRegistry;
import io.ib67.sfcraft.event.SFRandomEventRegistry;
import lombok.Getter;
@@ -16,6 +17,7 @@ import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.minecraft.command.CommandRegistryAccess;
import net.minecraft.network.message.MessageDecorator;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
@@ -42,6 +44,8 @@ public class SFCraft implements ModInitializer {
private String updateLog;
@Getter
private RandomEventRegistry randomEventRegistry;
@Getter
private MessageDecorator messageDecorator;
@Override
@SneakyThrows
@@ -56,15 +60,22 @@ public class SFCraft implements ModInitializer {
motd = loadMotd();
updateLog = loadUpdateLog();
geoIPService = new GeoIPService();
this.setupRandomEvents();
randomEventRegistry = setupRandomEvents();
messageDecorator = setupMessageDecorator();
ServerPlayConnectionEvents.JOIN.register(listener::onPlayerJoin);
CommandRegistrationCallback.EVENT.register(this::registerCommands);
ServerLifecycleEvents.SERVER_STARTED.register(this::onServerStarted);
}
private void setupRandomEvents() {
randomEventRegistry = new SFRandomEventRegistry();
private MessageDecorator setupMessageDecorator() {
return new SFMessageDecorator();
}
private SFRandomEventRegistry setupRandomEvents() {
return new SFRandomEventRegistry();
}
private void onServerStarted(MinecraftServer minecraftServer) {
@@ -135,5 +146,4 @@ public class SFCraft implements ModInitializer {
.executes(handler::listOffline)
);
}
}
@@ -10,7 +10,7 @@ public class SFRandomEventRegistry extends SimpleRandomEventRegistry {
registerEvent(LongNightEvent::new, World.OVERWORLD
, world -> !LongNightEvent.isRunning()
&& world.getTimeOfDay() % 24000 == 18000
&& world.getRandom().nextBetween(0,100) < 15); // At midnight
&& world.getRandom().nextBetween(0,100) < 5); // At midnight
registerEvent(DawnAfterLongNightEvent::new, World.OVERWORLD
, world -> world.getTimeOfDay() % 22200 == 0); // At dawn
}
@@ -0,0 +1,9 @@
package io.ib67.sfcraft.message;
import io.ib67.sfcraft.message.feature.SendLocationFeature;
public class SFMessageDecorator extends SimpleMessageDecorator {
public SFMessageDecorator() {
registerDecorator(new SendLocationFeature());
}
}
@@ -0,0 +1,29 @@
package io.ib67.sfcraft.message;
import net.minecraft.network.message.MessageDecorator;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class SimpleMessageDecorator implements MessageDecorator {
protected final List<MessageDecorator> decorators = new ArrayList<>();
protected SimpleMessageDecorator() {
}
protected void registerDecorator(MessageDecorator decorator) {
decorators.add(decorator);
}
@Override
public Text decorate(@Nullable ServerPlayerEntity sender, Text message) {
for (MessageDecorator decorator : decorators) {
message = decorator.decorate(sender, message);
}
return message;
}
}
@@ -0,0 +1,59 @@
package io.ib67.sfcraft.message.feature;
import io.ib67.sfcraft.Helper;
import net.minecraft.network.message.MessageDecorator;
import net.minecraft.registry.RegistryKey;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.ClickEvent;
import net.minecraft.text.Text;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
public class SendLocationFeature implements MessageDecorator {
@Override
public Text decorate(@Nullable ServerPlayerEntity sender, Text message) {
var text = message.getLiteralString().trim();
if (text == null) {
return message;
}
if (text.trim().equals(".xyz")) {
return generateLocText(sender);
}
var result = Text.literal("");
var head = 0;
var i = text.indexOf(".xyz");
while (i != -1) {
result.append(text.substring(0, i).trim());
result.append(generateLocText(sender));
head = i + 4;
i = text.indexOf(".xyz", head + 1);
}
result.append(text.substring(head).trim());
return result;
}
private static Text generateLocText(ServerPlayerEntity sender) {
if (sender == null) return Text.of(" (invalid position) ");
var x = sender.getBlockPos().getX();
var y = sender.getBlockPos().getY();
var z = sender.getBlockPos().getZ();
var key = sender.getServerWorld().getRegistryKey();
var world = translate(key);
return Text
.literal(" " + x + ", " + y + ", " + z + world + " ")
.withColor(Helper.fromRgb(63, 254, 254))
.styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/gps " + key + " " + x + " " + y + " " + z)));
}
private static String translate(RegistryKey<World> registryKey) {
if (registryKey == World.END) {
return " (末地)";
} else if (registryKey == World.NETHER) {
return " (地狱)";
} else if (registryKey == World.OVERWORLD) {
return "";
} else {
return " (未知)";
}
}
}
@@ -0,0 +1,27 @@
package io.ib67.sfcraft.mixin.server;
import io.ib67.sfcraft.SFCraft;
import net.minecraft.network.message.MessageChainTaskQueue;
import net.minecraft.network.message.MessageDecorator;
import net.minecraft.network.message.SignedMessage;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
@Mixin(ServerPlayNetworkHandler.class)
public abstract class ServerPlayNetworkHandlerMixin {
/**
* @author icybear
* @reason small method, provide custom one
*/
@Redirect(method = "method_44900", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getMessageDecorator()Lnet/minecraft/network/message/MessageDecorator;"))
public MessageDecorator getMessageDecorator(MinecraftServer instance) {
return SFCraft.getInstance().getMessageDecorator();
}
}
+1
View File
@@ -8,6 +8,7 @@
"client": [
],
"server": [
"server.ServerPlayNetworkHandlerMixin",
"server.bridge.ServerWorldBridge",
"server.SleepManagerMixin",
"server.ServerWorldMixin",