Commit 69c681ad by Jonathan Thomas

Small refactor to playerData args, and a fix to prevent "" blank player from…

Small refactor to playerData args, and a fix to prevent "" blank player from being in every entitychatdata. It should only exist with migrated data. Also made the old legacy JSON properties disappear after saving this new data structure.
parent 6ced5668
Pipeline #12736 passed with stages
in 8 minutes 13 seconds
...@@ -113,8 +113,8 @@ public class ClientPackets { ...@@ -113,8 +113,8 @@ public class ClientPackets {
MobEntity entity = ClientEntityFinder.getEntityByUUID(client.world, entityId); MobEntity entity = ClientEntityFinder.getEntityByUUID(client.world, entityId);
if (entity != null) { if (entity != null) {
ChatDataManager chatDataManager = ChatDataManager.getClientInstance(); ChatDataManager chatDataManager = ChatDataManager.getClientInstance();
EntityChatData chatData = chatDataManager.getOrCreateChatData(entity.getUuidAsString()); EntityChatData chatData = chatDataManager.getOrCreateChatData(entity.getUuidAsString(), playerId.toString());
PlayerData playerData = chatData.getPlayerData(playerId); PlayerData playerData = chatData.getPlayerData(playerId.toString());
if (!message.isEmpty()) { if (!message.isEmpty()) {
chatData.currentMessage = message; chatData.currentMessage = message;
} }
......
...@@ -479,8 +479,8 @@ public class BubbleRenderer { ...@@ -479,8 +479,8 @@ public class BubbleRenderer {
EntityChatData chatData = null; EntityChatData chatData = null;
PlayerData playerData = null; PlayerData playerData = null;
if (entity instanceof MobEntity) { if (entity instanceof MobEntity) {
chatData = ChatDataManager.getClientInstance().getOrCreateChatData(entity.getUuidAsString()); chatData = ChatDataManager.getClientInstance().getOrCreateChatData(entity.getUuidAsString(), player.getUuidAsString());
playerData = chatData.getPlayerData(player.getUuid()); playerData = chatData.getPlayerData(player.getUuidAsString());
} else if (entity instanceof PlayerEntity) { } else if (entity instanceof PlayerEntity) {
chatData = PlayerMessageManager.getMessage(entity.getUuid()); chatData = PlayerMessageManager.getMessage(entity.getUuid());
} }
......
...@@ -120,7 +120,7 @@ public class ClickHandler { ...@@ -120,7 +120,7 @@ public class ClickHandler {
MobEntity closestEntity = ClientEntityFinder.getEntityByUUID(client.world, closestEntityUUID); MobEntity closestEntity = ClientEntityFinder.getEntityByUUID(client.world, closestEntityUUID);
if (closestEntity != null) { if (closestEntity != null) {
// Look-up conversation // Look-up conversation
EntityChatData chatData = ChatDataManager.getClientInstance().getOrCreateChatData(closestEntityUUID.toString()); EntityChatData chatData = ChatDataManager.getClientInstance().getOrCreateChatData(closestEntityUUID.toString(), player.getUuidAsString());
// Determine area clicked inside chat bubble (top, left, right) // Determine area clicked inside chat bubble (top, left, right)
String hitRegion = determineHitRegion(closestHitResult.get(), closestBubbleData.position, camera, closestBubbleData.height); String hitRegion = determineHitRegion(closestHitResult.get(), closestBubbleData.position, camera, closestBubbleData.height);
......
...@@ -77,8 +77,8 @@ public class ChatDataManager { ...@@ -77,8 +77,8 @@ public class ChatDataManager {
} }
// Retrieve chat data for a specific entity, or create it if it doesn't exist // Retrieve chat data for a specific entity, or create it if it doesn't exist
public EntityChatData getOrCreateChatData(String entityId) { public EntityChatData getOrCreateChatData(String entityId, String playerId) {
return entityChatDataMap.computeIfAbsent(entityId, k -> new EntityChatData(entityId, "")); return entityChatDataMap.computeIfAbsent(entityId, k -> new EntityChatData(entityId, playerId));
} }
// Update the UUID in the map (i.e. bucketed entity and then released, changes their UUID) // Update the UUID in the map (i.e. bucketed entity and then released, changes their UUID)
......
package com.owlmaddie.chat; package com.owlmaddie.chat;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import com.owlmaddie.commands.ConfigurationHandler; import com.owlmaddie.commands.ConfigurationHandler;
import com.owlmaddie.controls.SpeedControls; import com.owlmaddie.controls.SpeedControls;
import com.owlmaddie.goals.*; import com.owlmaddie.goals.*;
...@@ -21,16 +23,13 @@ import net.minecraft.village.VillageGossipType; ...@@ -21,16 +23,13 @@ import net.minecraft.village.VillageGossipType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/** /**
* The {@code EntityChatData} class represents a conversation between an * The {@code EntityChatData} class represents a conversation between an
...@@ -48,16 +47,16 @@ public class EntityChatData { ...@@ -48,16 +47,16 @@ public class EntityChatData {
public int auto_generated; public int auto_generated;
@SerializedName("playerId") @SerializedName("playerId")
@Expose(serialize = false)
private String legacyPlayerId; private String legacyPlayerId;
@SerializedName("previousMessages") @SerializedName("previousMessages")
@Expose(serialize = false)
public List<ChatMessage> legacyMessages; public List<ChatMessage> legacyMessages;
@SerializedName("friendship") @SerializedName("friendship")
public int legacyFriendship; @Expose(serialize = false)
public Integer legacyFriendship;
public String birthDate;
public String deathDate;
// The map to store data for each player interacting with this entity // The map to store data for each player interacting with this entity
public Map<String, PlayerData> players; public Map<String, PlayerData> players;
...@@ -65,7 +64,9 @@ public class EntityChatData { ...@@ -65,7 +64,9 @@ public class EntityChatData {
public EntityChatData(String entityId, String playerId) { public EntityChatData(String entityId, String playerId) {
this.entityId = entityId; this.entityId = entityId;
this.players = new HashMap<>(); this.players = new HashMap<>();
this.players.put("", new PlayerData()); // Add default blank player if (!playerId.isEmpty()) {
this.players.put(playerId, new PlayerData());
}
this.currentMessage = ""; this.currentMessage = "";
this.currentLineNumber = 0; this.currentLineNumber = 0;
this.characterSheet = ""; this.characterSheet = "";
...@@ -73,8 +74,9 @@ public class EntityChatData { ...@@ -73,8 +74,9 @@ public class EntityChatData {
this.sender = ChatDataManager.ChatSender.USER; this.sender = ChatDataManager.ChatSender.USER;
this.auto_generated = 0; this.auto_generated = 0;
this.legacyFriendship = 0; this.legacyPlayerId = null;
this.legacyMessages = new ArrayList<>(); this.legacyMessages = null;
this.legacyFriendship = null;
} }
// Post-deserialization initialization // Post-deserialization initialization
...@@ -82,14 +84,13 @@ public class EntityChatData { ...@@ -82,14 +84,13 @@ public class EntityChatData {
if (this.players == null) { if (this.players == null) {
this.players = new HashMap<>(); // Ensure players map is initialized this.players = new HashMap<>(); // Ensure players map is initialized
} }
this.players.computeIfAbsent("", k -> new PlayerData());
if (this.legacyPlayerId != null && !this.legacyPlayerId.isEmpty()) { if (this.legacyPlayerId != null && !this.legacyPlayerId.isEmpty()) {
this.migrateData(this.legacyPlayerId); this.migrateData();
} }
} }
// Migrate old data into the new structure // Migrate old data into the new structure
private void migrateData(String oldPlayerId) { private void migrateData() {
// Ensure the blank player data entry exists // Ensure the blank player data entry exists
PlayerData blankPlayerData = this.players.computeIfAbsent("", k -> new PlayerData()); PlayerData blankPlayerData = this.players.computeIfAbsent("", k -> new PlayerData());
...@@ -102,25 +103,29 @@ public class EntityChatData { ...@@ -102,25 +103,29 @@ public class EntityChatData {
// Clean up old player data // Clean up old player data
this.legacyPlayerId = null; this.legacyPlayerId = null;
this.legacyMessages = null; this.legacyMessages = null;
this.legacyFriendship = 0; this.legacyFriendship = null;
} }
// Get the player data (or fallback to the blank player) // Get the player data (or fallback to the blank player)
public PlayerData getPlayerData(UUID playerId) { public PlayerData getPlayerData(String playerId) {
if (this.players == null) { if (this.players == null) {
return new PlayerData(); return new PlayerData();
} }
// Check if the playerId exists in the players map // Check if the playerId exists in the players map
String playerIdStr = playerId.toString(); if (this.players.containsKey("")) {
if (this.players.containsKey(playerIdStr)) { // If a blank migrated legacy entity is found, always return this
return this.players.get(playerIdStr);
} else if (this.players.containsKey("")) {
// If the specific player ID is not found, fall back to the "" blank player
return this.players.get(""); return this.players.get("");
}
} else if (this.players.containsKey(playerId)) {
// Return a specific player's data
return this.players.get(playerId);
} else {
// Return a blank player data
return new PlayerData(); return new PlayerData();
} }
}
// Generate light version of chat data (no previous messages) // Generate light version of chat data (no previous messages)
public EntityChatDataLight toLightVersion(UUID playerId) { public EntityChatDataLight toLightVersion(UUID playerId) {
...@@ -211,7 +216,7 @@ public class EntityChatData { ...@@ -211,7 +216,7 @@ public class EntityChatData {
contextData.put("entity_skills", getCharacterProp("Skills")); contextData.put("entity_skills", getCharacterProp("Skills"));
contextData.put("entity_background", getCharacterProp("Background")); contextData.put("entity_background", getCharacterProp("Background"));
PlayerData playerData = this.getPlayerData(player.getUuid()); PlayerData playerData = this.getPlayerData(player.getUuidAsString());
if (playerData != null) { if (playerData != null) {
contextData.put("entity_friendship", String.valueOf(playerData.friendship)); contextData.put("entity_friendship", String.valueOf(playerData.friendship));
} else { } else {
...@@ -248,7 +253,7 @@ public class EntityChatData { ...@@ -248,7 +253,7 @@ public class EntityChatData {
String promptText = ChatPrompt.loadPromptFromResource(ServerPackets.serverInstance.getResourceManager(), systemPrompt); String promptText = ChatPrompt.loadPromptFromResource(ServerPackets.serverInstance.getResourceManager(), systemPrompt);
// Get messages for player // Get messages for player
PlayerData playerData = this.getPlayerData(player.getUuid()); PlayerData playerData = this.getPlayerData(player.getUuidAsString());
// fetch HTTP response from ChatGPT // fetch HTTP response from ChatGPT
ChatGPTRequest.fetchMessageFromChatGPT(config, promptText, contextData, playerData.messages, false).thenAccept(output_message -> { ChatGPTRequest.fetchMessageFromChatGPT(config, promptText, contextData, playerData.messages, false).thenAccept(output_message -> {
...@@ -439,7 +444,7 @@ public class EntityChatData { ...@@ -439,7 +444,7 @@ public class EntityChatData {
String truncatedMessage = message.substring(0, Math.min(message.length(), ChatDataManager.MAX_CHAR_IN_USER_MESSAGE)); String truncatedMessage = message.substring(0, Math.min(message.length(), ChatDataManager.MAX_CHAR_IN_USER_MESSAGE));
// Get or create player data // Get or create player data
PlayerData playerData = getPlayerData(playerId); PlayerData playerData = getPlayerData(playerId.toString());
// Add message to history // Add message to history
playerData.messages.add(new ChatMessage(truncatedMessage, messageSender)); playerData.messages.add(new ChatMessage(truncatedMessage, messageSender));
......
...@@ -28,7 +28,7 @@ public class EntityChatDataLight { ...@@ -28,7 +28,7 @@ public class EntityChatDataLight {
// Initialize the players map and add only the current player's data // Initialize the players map and add only the current player's data
this.players = new HashMap<>(); this.players = new HashMap<>();
String playerIdStr = playerId.toString(); String playerIdStr = playerId.toString();
PlayerData playerData = fullData.getPlayerData(playerId); PlayerData playerData = fullData.getPlayerData(playerId.toString());
this.players.put(playerIdStr, playerData); this.players.put(playerIdStr, playerData);
} }
} }
\ No newline at end of file
...@@ -72,7 +72,7 @@ public class LeadPlayerGoal extends PlayerBaseGoal { ...@@ -72,7 +72,7 @@ public class LeadPlayerGoal extends PlayerBaseGoal {
String arrivedMessage = "<You have arrived at your destination>"; String arrivedMessage = "<You have arrived at your destination>";
ChatDataManager chatDataManager = ChatDataManager.getServerInstance(); ChatDataManager chatDataManager = ChatDataManager.getServerInstance();
EntityChatData chatData = chatDataManager.getOrCreateChatData(this.entity.getUuidAsString()); EntityChatData chatData = chatDataManager.getOrCreateChatData(this.entity.getUuidAsString(), this.targetEntity.getUuidAsString());
if (!chatData.characterSheet.isEmpty() && chatData.auto_generated < chatDataManager.MAX_AUTOGENERATE_RESPONSES) { if (!chatData.characterSheet.isEmpty() && chatData.auto_generated < chatDataManager.MAX_AUTOGENERATE_RESPONSES) {
ServerPackets.generate_chat("N/A", chatData, (ServerPlayerEntity) this.targetEntity, this.entity, arrivedMessage, true); ServerPackets.generate_chat("N/A", chatData, (ServerPlayerEntity) this.targetEntity, this.entity, arrivedMessage, true);
} }
......
...@@ -23,17 +23,17 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; ...@@ -23,17 +23,17 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(LivingEntity.class) @Mixin(LivingEntity.class)
public class MixinLivingEntity { public class MixinLivingEntity {
private EntityChatData getChatData(LivingEntity entity) { private EntityChatData getChatData(LivingEntity entity, PlayerEntity player) {
ChatDataManager chatDataManager = ChatDataManager.getServerInstance(); ChatDataManager chatDataManager = ChatDataManager.getServerInstance();
return chatDataManager.getOrCreateChatData(entity.getUuidAsString()); return chatDataManager.getOrCreateChatData(entity.getUuidAsString(), player.getUuidAsString());
} }
@Inject(method = "canTarget(Lnet/minecraft/entity/LivingEntity;)Z", at = @At("HEAD"), cancellable = true) @Inject(method = "canTarget(Lnet/minecraft/entity/LivingEntity;)Z", at = @At("HEAD"), cancellable = true)
private void modifyCanTarget(LivingEntity target, CallbackInfoReturnable<Boolean> cir) { private void modifyCanTarget(LivingEntity target, CallbackInfoReturnable<Boolean> cir) {
if (target instanceof PlayerEntity) { if (target instanceof PlayerEntity) {
LivingEntity thisEntity = (LivingEntity) (Object) this; LivingEntity thisEntity = (LivingEntity) (Object) this;
EntityChatData entityData = getChatData(thisEntity); EntityChatData entityData = getChatData(thisEntity, (PlayerEntity) target);
PlayerData playerData = entityData.getPlayerData(target.getUuid()); PlayerData playerData = entityData.getPlayerData(target.getUuidAsString());
if (playerData.friendship > 0) { if (playerData.friendship > 0) {
// Friendly creatures can't target a player // Friendly creatures can't target a player
cir.setReturnValue(false); cir.setReturnValue(false);
...@@ -56,11 +56,11 @@ public class MixinLivingEntity { ...@@ -56,11 +56,11 @@ public class MixinLivingEntity {
if (attacker instanceof PlayerEntity && thisEntity instanceof MobEntity && !thisEntity.isDead()) { if (attacker instanceof PlayerEntity && thisEntity instanceof MobEntity && !thisEntity.isDead()) {
// Generate attacked message (only if the previous user message was not an attacked message) // Generate attacked message (only if the previous user message was not an attacked message)
// We don't want to constantly generate messages during a prolonged, multi-damage event // We don't want to constantly generate messages during a prolonged, multi-damage event
EntityChatData chatData = getChatData(thisEntity); ServerPlayerEntity player = (ServerPlayerEntity) attacker;
EntityChatData chatData = getChatData(thisEntity, player);
if (!chatData.characterSheet.isEmpty() && chatData.auto_generated < ChatDataManager.MAX_AUTOGENERATE_RESPONSES) { if (!chatData.characterSheet.isEmpty() && chatData.auto_generated < ChatDataManager.MAX_AUTOGENERATE_RESPONSES) {
// Only auto-generate a response to being attacked if chat data already exists // Only auto-generate a response to being attacked if chat data already exists
// and this is the first attack event. // and this is the first attack event.
ServerPlayerEntity player = (ServerPlayerEntity) attacker;
ItemStack weapon = player.getMainHandStack(); ItemStack weapon = player.getMainHandStack();
String weaponName = weapon.isEmpty() ? "with fists" : "with " + weapon.getItem().toString(); String weaponName = weapon.isEmpty() ? "with fists" : "with " + weapon.getItem().toString();
......
...@@ -54,8 +54,8 @@ public class MixinMobEntity { ...@@ -54,8 +54,8 @@ public class MixinMobEntity {
// Get chat data for entity // Get chat data for entity
ChatDataManager chatDataManager = ChatDataManager.getServerInstance(); ChatDataManager chatDataManager = ChatDataManager.getServerInstance();
EntityChatData entityData = chatDataManager.getOrCreateChatData(thisEntity.getUuidAsString()); EntityChatData entityData = chatDataManager.getOrCreateChatData(thisEntity.getUuidAsString(), player.getUuidAsString());
PlayerData playerData = entityData.getPlayerData(player.getUuid()); PlayerData playerData = entityData.getPlayerData(player.getUuidAsString());
// Check if the player successfully interacts with an item // Check if the player successfully interacts with an item
if (player instanceof ServerPlayerEntity) { if (player instanceof ServerPlayerEntity) {
......
...@@ -65,7 +65,7 @@ public class ServerPackets { ...@@ -65,7 +65,7 @@ public class ServerPackets {
server.execute(() -> { server.execute(() -> {
MobEntity entity = (MobEntity)ServerEntityFinder.getEntityByUUID(player.getServerWorld(), entityId); MobEntity entity = (MobEntity)ServerEntityFinder.getEntityByUUID(player.getServerWorld(), entityId);
if (entity != null) { if (entity != null) {
EntityChatData chatData = ChatDataManager.getServerInstance().getOrCreateChatData(entity.getUuidAsString()); EntityChatData chatData = ChatDataManager.getServerInstance().getOrCreateChatData(entity.getUuidAsString(), player.getUuidAsString());
if (chatData.characterSheet.isEmpty()) { if (chatData.characterSheet.isEmpty()) {
generate_character(userLanguage, chatData, player, entity); generate_character(userLanguage, chatData, player, entity);
} }
...@@ -86,7 +86,7 @@ public class ServerPackets { ...@@ -86,7 +86,7 @@ public class ServerPackets {
TalkPlayerGoal talkGoal = new TalkPlayerGoal(player, entity, 3.5F); TalkPlayerGoal talkGoal = new TalkPlayerGoal(player, entity, 3.5F);
EntityBehaviorManager.addGoal(entity, talkGoal, GoalPriority.TALK_PLAYER); EntityBehaviorManager.addGoal(entity, talkGoal, GoalPriority.TALK_PLAYER);
EntityChatData chatData = ChatDataManager.getServerInstance().getOrCreateChatData(entity.getUuidAsString()); EntityChatData chatData = ChatDataManager.getServerInstance().getOrCreateChatData(entity.getUuidAsString(), player.getUuidAsString());
LOGGER.debug("Update read lines to " + lineNumber + " for: " + entity.getType().toString()); LOGGER.debug("Update read lines to " + lineNumber + " for: " + entity.getType().toString());
chatData.setLineNumber(lineNumber); chatData.setLineNumber(lineNumber);
} }
...@@ -106,7 +106,7 @@ public class ServerPackets { ...@@ -106,7 +106,7 @@ public class ServerPackets {
TalkPlayerGoal talkGoal = new TalkPlayerGoal(player, entity, 3.5F); TalkPlayerGoal talkGoal = new TalkPlayerGoal(player, entity, 3.5F);
EntityBehaviorManager.addGoal(entity, talkGoal, GoalPriority.TALK_PLAYER); EntityBehaviorManager.addGoal(entity, talkGoal, GoalPriority.TALK_PLAYER);
EntityChatData chatData = ChatDataManager.getServerInstance().getOrCreateChatData(entity.getUuidAsString()); EntityChatData chatData = ChatDataManager.getServerInstance().getOrCreateChatData(entity.getUuidAsString(), player.getUuidAsString());
LOGGER.debug("Hiding chat bubble for: " + entity.getType().toString()); LOGGER.debug("Hiding chat bubble for: " + entity.getType().toString());
chatData.setStatus(ChatDataManager.ChatStatus.valueOf(status_name)); chatData.setStatus(ChatDataManager.ChatStatus.valueOf(status_name));
} }
...@@ -150,7 +150,7 @@ public class ServerPackets { ...@@ -150,7 +150,7 @@ public class ServerPackets {
server.execute(() -> { server.execute(() -> {
MobEntity entity = (MobEntity)ServerEntityFinder.getEntityByUUID(player.getServerWorld(), entityId); MobEntity entity = (MobEntity)ServerEntityFinder.getEntityByUUID(player.getServerWorld(), entityId);
if (entity != null) { if (entity != null) {
EntityChatData chatData = ChatDataManager.getServerInstance().getOrCreateChatData(entity.getUuidAsString()); EntityChatData chatData = ChatDataManager.getServerInstance().getOrCreateChatData(entity.getUuidAsString(), player.getUuidAsString());
if (chatData.characterSheet.isEmpty()) { if (chatData.characterSheet.isEmpty()) {
generate_character(userLanguage, chatData, player, entity); generate_character(userLanguage, chatData, player, entity);
} else { } else {
...@@ -318,7 +318,7 @@ public class ServerPackets { ...@@ -318,7 +318,7 @@ public class ServerPackets {
// Iterate over all players and send the packet // Iterate over all players and send the packet
for (ServerPlayerEntity player : serverInstance.getPlayerManager().getPlayerList()) { for (ServerPlayerEntity player : serverInstance.getPlayerManager().getPlayerList()) {
PlayerData playerData = chatData.getPlayerData(player.getUuid()); PlayerData playerData = chatData.getPlayerData(player.getUuidAsString());
PacketByteBuf buffer = new PacketByteBuf(Unpooled.buffer()); PacketByteBuf buffer = new PacketByteBuf(Unpooled.buffer());
// Write the entity's chat updated data // Write the entity's chat updated data
......
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