Commit 00c2e3c3 by Jonathan Thomas

Fully integrate loading / saving data when players join the server, by sending a…

Fully integrate loading / saving data when players join the server, by sending a "light" version of the chat data on login.
parent c8c7eeea
Pipeline #11864 passed with stage
in 28 seconds
package com.owlmaddie;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
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;
......@@ -14,6 +16,8 @@ import net.minecraft.world.World;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
......@@ -61,6 +65,20 @@ public class ClickHandler {
});
});
// Client-side player login: get all chat data
ClientPlayNetworking.registerGlobalReceiver(ModInit.PACKET_S2C_LOGIN, (client, handler, buffer, responseSender) -> {
// Read the data from the server packet
int length = buffer.readInt();
String chatDataJSON = buffer.readString(length);
// Update the chat data manager on the client-side
Gson GSON = new Gson();
client.execute(() -> { // Make sure to run on the client thread
// Parse JSON and override client chat data
Type type = new TypeToken<HashMap<Integer, ChatDataManager.EntityChatData>>(){}.getType();
ChatDataManager.getClientInstance().entityChatDataMap = GSON.fromJson(chatDataJSON, type);
});
});
}
public static void handleUseKeyClick(MinecraftClient client) {
......
......@@ -47,13 +47,6 @@ public class ClientInit implements ClientModInitializer {
// Clear or reset the ChatDataManager
ChatDataManager.getClientInstance().clearData();
});
// Register an event callback for when the player joins a server or world
ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> {
// Possibly re-initialize or prepare the ChatDataManager for the new session
ChatDataManager.getClientInstance().clearData();
});
}
public void drawTextBubbleBackground(MatrixStack matrices, Entity entity, float x, float y, float width, float height) {
......
......@@ -46,7 +46,7 @@ public class ChatDataManager {
}
// HashMap to associate unique entity IDs with their chat data
private HashMap<Integer, EntityChatData> entityChatDataMap;
public HashMap<Integer, EntityChatData> entityChatDataMap;
public static class ChatMessage {
public String message;
......@@ -78,6 +78,28 @@ public class ChatDataManager {
this.sender = ChatSender.USER;
}
// Light version with no 'previousMessages' attribute
public class EntityChatDataLight {
public int entityId;
public String currentMessage;
public int currentLineNumber;
public ChatStatus status;
public ChatSender sender;
}
// Generate light version of chat data (no previous messages)
public EntityChatDataLight toLightVersion() {
EntityChatDataLight light = new EntityChatDataLight();
light.entityId = this.entityId;
if (light.status != ChatStatus.END) {
light.currentMessage = this.currentMessage;
}
light.currentLineNumber = this.currentLineNumber;
light.status = this.status;
light.sender = this.sender;
return light;
}
public static String extractGreeting(String inputText) {
// Regex pattern to match the "Short Greeting" line and capture the greeting text
Pattern pattern = Pattern.compile("- Short Greeting: \"?([^\"]+)\"?");
......@@ -206,7 +228,7 @@ public class ChatDataManager {
if (server_only) {
// Generate initial quest
// TODO: Complete the quest flow
generateQuest();
//generateQuest();
}
}
......@@ -259,6 +281,21 @@ public class ChatDataManager {
}
// Save chat data to file
public String GetLightChatData() {
try {
// Create "light" version of entire chat data HashMap
HashMap<Integer, EntityChatData.EntityChatDataLight> lightVersionMap = new HashMap<>();
this.entityChatDataMap.forEach((id, entityChatData) -> lightVersionMap.put(id, entityChatData.toLightVersion()));
// Convert light chat data to JSON string
return GSON.toJson(lightVersionMap).toString();
} catch (Exception e) {
// Handle exceptions
return "";
}
}
// Save chat data to file
public void saveChatData(MinecraftServer server) {
try {
File saveFile = new File(server.getSavePath(WorldSavePath.ROOT).toFile(), "chatdata.json");
......@@ -272,7 +309,6 @@ public class ChatDataManager {
}
// Load chat data from file
@SuppressWarnings("unchecked")
public void loadChatData(MinecraftServer server) {
try {
File loadFile = new File(server.getSavePath(WorldSavePath.ROOT).toFile(), "chatdata.json");
......
......@@ -3,24 +3,20 @@ package com.owlmaddie;
import io.netty.buffer.Unpooled;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.item.Item;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.Rarity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
public class ModInit implements ModInitializer {
public static final Logger LOGGER = LoggerFactory.getLogger("mobgpt");
......@@ -30,6 +26,7 @@ public class ModInit implements ModInitializer {
public static final Identifier PACKET_C2S_START_CHAT = new Identifier("mobgpt", "packet_c2s_start_chat");
public static final Identifier PACKET_C2S_SEND_CHAT = new Identifier("mobgpt", "packet_c2s_send_chat");
public static final Identifier PACKET_S2C_MESSAGE = new Identifier("mobgpt", "packet_s2c_message");
public static final Identifier PACKET_S2C_LOGIN = new Identifier("mobgpt", "packet_s2c_login");
@Override
public void onInitialize() {
......@@ -119,6 +116,21 @@ public class ModInit implements ModInitializer {
});
});
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
ServerPlayerEntity player = handler.player;
LOGGER.info("Server send login message packet to player: " + player.getName().getString());
// Get chat data for logged in player (light version)
String chatDataJSON = ChatDataManager.getServerInstance().GetLightChatData();
// Write the light chat data
PacketByteBuf buffer = new PacketByteBuf(Unpooled.buffer());
buffer.writeInt(chatDataJSON.length());
buffer.writeString(chatDataJSON);
ServerPlayNetworking.send(player, PACKET_S2C_LOGIN, buffer);
});
ServerWorldEvents.LOAD.register((server, world) -> {
String world_name = world.getRegistryKey().getValue().getPath();
if (world_name == "overworld") {
......
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