Commit aa6a8087 by Jonathan Thomas

Adding S2C messages for client / server sync of chat messages. This should allow…

Adding S2C messages for client / server sync of chat messages. This should allow full multi-player testing.
parent e1c3ea8d
Pipeline #11653 passed with stage
in 24 seconds
......@@ -3,6 +3,7 @@ package com.owlmaddie;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.client.render.Camera;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
......@@ -23,7 +24,6 @@ public class ClickHandler {
private static boolean wasClicked = false;
public static void register() {
ClientTickEvents.END_CLIENT_TICK.register(client -> {
if (client.options.useKey.isPressed()) {
if (!wasClicked) {
// The key has just been pressed down, so handle the 'click'
......@@ -34,8 +34,31 @@ public class ClickHandler {
// The key has been released, so reset the wasClicked flag
wasClicked = false;
}
});
// Client-side packet handler, message sync
ClientPlayNetworking.registerGlobalReceiver(ModInit.PACKET_S2C_MESSAGE, (client, handler, buffer, responseSender) -> {
// Read the data from the server packet
int entityId = buffer.readInt();
String message = buffer.readString(32767);
int line = buffer.readInt();
String status_name = buffer.readString(32767);
// Update the chat data manager on the client-side
client.execute(() -> { // Make sure to run on the client thread
Entity entity = client.world.getEntityById(entityId);
if (entity != null) {
ChatDataManager chatDataManager = ChatDataManager.getClientInstance();
ChatDataManager.EntityChatData chatData = chatDataManager.getOrCreateChatData(entityId);
if (!message.isEmpty()) {
chatData.currentMessage = message;
}
chatData.currentLineNumber = line;
chatData.status = ChatDataManager.ChatStatus.valueOf(status_name);
}
});
});
}
public static void handleUseKeyClick(MinecraftClient client) {
......
......@@ -12,8 +12,6 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.text.OrderedText;
import net.minecraft.text.StringVisitable;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper;
......
......@@ -23,13 +23,15 @@ public class ChatDataManager {
// Inner class to hold entity-specific data
public static class EntityChatData {
public int entityId;
public String currentMessage;
public int currentLineNumber;
public ChatStatus status;
public List<String> previousMessages;
public String characterSheet;
public EntityChatData() {
public EntityChatData(int entityId) {
this.entityId = entityId;
this.currentMessage = "";
this.currentLineNumber = 0;
this.previousMessages = new ArrayList<>();
......@@ -45,6 +47,9 @@ public class ChatDataManager {
this.addMessage(greeting);
}
});
// Broadcast to all players
ModInit.BroadcastPacketMessage(this);
}
// Add a message to the history and update the current message
......@@ -55,8 +60,11 @@ public class ChatDataManager {
currentMessage = message;
// Set line number of displayed text
this.currentLineNumber = 0;
this.status = ChatStatus.DISPLAY;
currentLineNumber = 0;
status = ChatStatus.DISPLAY;
// Broadcast to all players
ModInit.BroadcastPacketMessage(this);
}
// Get wrapped lines
......@@ -67,10 +75,13 @@ public class ChatDataManager {
// Update starting line number of displayed text
public void setLineNumber(Integer lineNumber) {
// Update displayed starting line # (between 0 and # of lines)
this.currentLineNumber = Math.min(Math.max(lineNumber, 0), this.getWrappedLines().size());
currentLineNumber = Math.min(Math.max(lineNumber, 0), this.getWrappedLines().size());
if (lineNumber == this.getWrappedLines().size()) {
this.status = ChatStatus.END;
status = ChatStatus.END;
}
// Broadcast to all players
ModInit.BroadcastPacketMessage(this);
}
}
......@@ -90,6 +101,6 @@ public class ChatDataManager {
// Retrieve chat data for a specific entity, or create it if it doesn't exist
public EntityChatData getOrCreateChatData(int entityId) {
return entityChatDataMap.computeIfAbsent(entityId, k -> new EntityChatData());
return entityChatDataMap.computeIfAbsent(entityId, k -> new EntityChatData(entityId));
}
}
\ No newline at end of file
......@@ -8,14 +8,20 @@ import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.server.MinecraftServer;
import io.netty.buffer.Unpooled;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ModInit implements ModInitializer {
public static final Logger LOGGER = LoggerFactory.getLogger("mobgpt");
private static MinecraftServer serverInstance;
public static final Identifier PACKET_C2S_GREETING = new Identifier("mobgpt", "packet_c2s_greeting");
public static final Identifier PACKET_C2S_READ_NEXT = new Identifier("mobgpt", "packet_c2s_read_next");
public static final Identifier PACKET_S2C_MESSAGE = new Identifier("mobgpt", "packet_s2c_message");
@Override
public void onInitialize() {
......@@ -29,10 +35,8 @@ public class ModInit implements ModInitializer {
// Ensure that the task is synced with the server thread
server.execute(() -> {
// Your logic here, e.g., handle the entity click
Entity entity = player.getServerWorld().getEntityById(entityId);
if (entity != null) {
// Perform action with the clicked entity
// Slow entity
SlowEntity((LivingEntity) entity, 3.5F);
......@@ -54,10 +58,8 @@ public class ModInit implements ModInitializer {
// Ensure that the task is synced with the server thread
server.execute(() -> {
// Your logic here, e.g., handle the entity click
Entity entity = player.getServerWorld().getEntityById(entityId);
if (entity != null) {
// Perform action with the clicked entity
// Slow entity
SlowEntity((LivingEntity) entity, 3.5F);
......@@ -74,15 +76,38 @@ public class ModInit implements ModInitializer {
ServerWorldEvents.LOAD.register((server, world) -> {
// Load chat data...
LOGGER.info("LOAD chat data from NBT: " + world.getRegistryKey().getValue());
serverInstance = server;
});
ServerWorldEvents.UNLOAD.register((server, world) -> {
// Save chat data...
LOGGER.info("SAVE chat data to NBT: " + world.getRegistryKey().getValue());
serverInstance = null;
});
LOGGER.info("MobGPT Initialized!");
}
// Send new message to all connected players
public static void BroadcastPacketMessage(ChatDataManager.EntityChatData chatData) {
// TODO: Fix static OVERWORLD reference
Entity entity = serverInstance.getOverworld().getEntityById(chatData.entityId);
if (entity != null) {
PacketByteBuf buffer = new PacketByteBuf(Unpooled.buffer());
// Write the entity's chat updated data
buffer.writeInt(entity.getId());
buffer.writeString(chatData.currentMessage);
buffer.writeInt(chatData.currentLineNumber);
buffer.writeString(chatData.status.toString());
// Iterate over all players and send the packet
for (ServerPlayerEntity player : serverInstance.getPlayerManager().getPlayerList()) {
LOGGER.info("Server send message packet to player: " + player.getName().getString());
ServerPlayNetworking.send(player, PACKET_S2C_MESSAGE, buffer);
}
}
}
public void SlowEntity(LivingEntity entity, float numSeconds) {
// Slow the entity temporarily (so they don't run away)
// Apply a slowness effect with a high amplifier for a short duration
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment