Commit 929305ad by Jonathan Thomas

New S2C packets to send whitelist / blacklist changes on login and after…

New S2C packets to send whitelist / blacklist changes on login and after commands are executed. Chat Bubble rendering & interacting is now dependent on whitelist / blacklist config.
parent 4073b524
Pipeline #12669 passed with stages
in 2 minutes 8 seconds
......@@ -7,19 +7,19 @@ All notable changes to **CreatureChat** are documented in this file. The format
## [Unreleased]
### Added
- New whitelist / blacklist Minecraft commands, to show and hide chat bubbles based on entity type
- New S2C packets to send whitelist / blacklist changes on login and after commands are executed
- Added UNFLEE behavior (to stop fleeing from a player)
- Added support for non path aware entities to FLEE (i.e. Ghast)
- Added new LLM tests for UNFLEE
### Added
- New whitelist and blacklist Minecraft commands, to show and hide chat bubbles based on entity type
### Changed
- Chat Bubble rendering & interacting is now dependent on whitelist / blacklist config
- Fixed a **crash with FLEE** when non-path aware entities (i.e. Ghast) attempted to flee.
- Fixed certain behaviors from colliding with others (i.e. mutual exclusive ones)
- Updated README.md with new video thumbnail, and simplified text, added spoiler to install instructions
- Fixed CurseForge deploy script to be much faster, and correctly lookup valid Type and Version IDs
- Large refactor of Minecraft commands (and how --config args are parsed)
- Fixed CurseForge deploy script to be much faster, and correctly lookup valid Type and Version IDs
## [1.0.7] - 2024-07-03
......
......@@ -3,6 +3,7 @@ package com.owlmaddie.network;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.owlmaddie.chat.ChatDataManager;
import com.owlmaddie.ui.BubbleRenderer;
import com.owlmaddie.ui.PlayerMessageManager;
import com.owlmaddie.utils.ClientEntityFinder;
import com.owlmaddie.utils.Decompression;
......@@ -19,7 +20,9 @@ import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
/**
......@@ -166,6 +169,28 @@ public class ClientPackets {
});
});
// Client-side packet handler, receive entire whitelist / blacklist, and update BubbleRenderer
ClientPlayNetworking.registerGlobalReceiver(ServerPackets.PACKET_S2C_WHITELIST, (client, handler, buffer, responseSender) -> {
// Read the whitelist data from the buffer
int whitelistSize = buffer.readInt();
List<String> whitelist = new ArrayList<>(whitelistSize);
for (int i = 0; i < whitelistSize; i++) {
whitelist.add(buffer.readString(32767));
}
// Read the blacklist data from the buffer
int blacklistSize = buffer.readInt();
List<String> blacklist = new ArrayList<>(blacklistSize);
for (int i = 0; i < blacklistSize; i++) {
blacklist.add(buffer.readString(32767));
}
client.execute(() -> {
BubbleRenderer.whitelist = whitelist;
BubbleRenderer.blacklist = blacklist;
});
});
// Client-side packet handler, player status sync
ClientPlayNetworking.registerGlobalReceiver(ServerPackets.PACKET_S2C_PLAYER_STATUS, (client, handler, buffer, responseSender) -> {
// Read the data from the server packet
......
......@@ -17,6 +17,7 @@ import net.minecraft.entity.boss.dragon.EnderDragonEntity;
import net.minecraft.entity.boss.dragon.EnderDragonPart;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.registry.Registries;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper;
......@@ -27,6 +28,7 @@ import org.joml.Quaternionf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
......@@ -43,6 +45,8 @@ public class BubbleRenderer {
public static long lastTick = 0;
public static int light = 15728880;
public static int overlay = OverlayTexture.DEFAULT_UV;
public static List<String> whitelist = new ArrayList<>();
public static List<String> blacklist = new ArrayList<>();
public static void drawTextBubbleBackground(String base_name, MatrixStack matrices, float x, float y, float width, float height, int friendship) {
// Set shader & texture
......@@ -356,6 +360,16 @@ public class BubbleRenderer {
.filter(entity -> !entity.hasPassengers())
.filter(entity -> !(entity.equals(cameraEntity) && !camera.isThirdPerson()))
.filter(entity -> !(entity.equals(cameraEntity) && entity.isSpectator()))
.filter(entity -> {
Identifier entityId = Registries.ENTITY_TYPE.getId(entity.getType());
String entityIdString = entityId.toString();
// Check blacklist first
if (blacklist.contains(entityIdString)) {
return false;
}
// If whitelist is not empty, only include entities in the whitelist
return whitelist.isEmpty() || whitelist.contains(entityIdString);
})
.collect(Collectors.toList());
for (Entity entity : relevantEntities) {
......
......@@ -7,6 +7,7 @@ import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.owlmaddie.network.ServerPackets;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.minecraft.command.CommandSource;
import net.minecraft.command.argument.IdentifierArgumentType;
......@@ -244,6 +245,9 @@ public class CreatureChatCommands {
if (configHandler.saveConfig(config, useServerConfig)) {
Text feedbackMessage = Text.literal("Successfully updated " + listName + " with " + action).formatted(Formatting.GREEN);
source.sendFeedback(() -> feedbackMessage, false);
// Send whitelist / blacklist to all players
ServerPackets.send_whitelist_blacklist(null);
return 1;
} else {
Text feedbackMessage = Text.literal("Failed to update " + listName).formatted(Formatting.RED);
......
......@@ -2,6 +2,7 @@ package com.owlmaddie.network;
import com.owlmaddie.chat.ChatDataManager;
import com.owlmaddie.chat.ChatDataSaverScheduler;
import com.owlmaddie.commands.ConfigurationHandler;
import com.owlmaddie.goals.EntityBehaviorManager;
import com.owlmaddie.goals.GoalPriority;
import com.owlmaddie.goals.TalkPlayerGoal;
......@@ -30,6 +31,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
......@@ -49,6 +51,7 @@ public class ServerPackets {
public static final Identifier PACKET_C2S_SEND_CHAT = new Identifier("creaturechat", "packet_c2s_send_chat");
public static final Identifier PACKET_S2C_MESSAGE = new Identifier("creaturechat", "packet_s2c_message");
public static final Identifier PACKET_S2C_LOGIN = new Identifier("creaturechat", "packet_s2c_login");
public static final Identifier PACKET_S2C_WHITELIST = new Identifier("creaturechat", "packet_s2c_whitelist");
public static final Identifier PACKET_S2C_PLAYER_STATUS = new Identifier("creaturechat", "packet_s2c_player_status");
public static void register() {
......@@ -160,8 +163,11 @@ public class ServerPackets {
// Data is sent in chunks, to prevent exceeding the 32767 limit per String.
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
ServerPlayerEntity player = handler.player;
LOGGER.info("Server send compressed, chunked login message packets to player: " + player.getName().getString());
// Send entire whitelist / blacklist to logged in player
send_whitelist_blacklist(player);
LOGGER.info("Server send compressed, chunked login message packets to player: " + player.getName().getString());
// Get lite JSON data & compress to byte array
String chatDataJSON = ChatDataManager.getServerInstance().GetLightChatData();
byte[] compressedData = Compression.compressString(chatDataJSON);
......@@ -232,6 +238,37 @@ public class ServerPackets {
}
public static void send_whitelist_blacklist(ServerPlayerEntity player) {
ConfigurationHandler.Config config = new ConfigurationHandler(ServerPackets.serverInstance).loadConfig();
PacketByteBuf buffer = new PacketByteBuf(Unpooled.buffer());
// Write the whitelist data to the buffer
List<String> whitelist = config.getWhitelist();
buffer.writeInt(whitelist.size());
for (String entry : whitelist) {
buffer.writeString(entry);
}
// Write the blacklist data to the buffer
List<String> blacklist = config.getBlacklist();
buffer.writeInt(blacklist.size());
for (String entry : blacklist) {
buffer.writeString(entry);
}
if (player != null) {
// Send packet to specific player
LOGGER.info("Sending whitelist / blacklist packet to player: " + player.getName().getString());
ServerPlayNetworking.send(player, PACKET_S2C_WHITELIST, buffer);
} else {
// Iterate over all players and send the packet
for (ServerPlayerEntity serverPlayer : serverInstance.getPlayerManager().getPlayerList()) {
LOGGER.info("Broadcast whitelist / blacklist packet to player: " + serverPlayer.getName().getString());
ServerPlayNetworking.send(serverPlayer, PACKET_S2C_WHITELIST, buffer);
}
}
}
public static void generate_character(String userLanguage, ChatDataManager.EntityChatData chatData, ServerPlayerEntity player, MobEntity entity) {
// Set talk to player goal (prevent entity from walking off)
TalkPlayerGoal talkGoal = new TalkPlayerGoal(player, entity, 3.5F);
......
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