diff --git a/src/main/java/cc/aabss/eventutils/EventUtils.java b/src/main/java/cc/aabss/eventutils/EventUtils.java index 54df067..c4ce5d5 100644 --- a/src/main/java/cc/aabss/eventutils/EventUtils.java +++ b/src/main/java/cc/aabss/eventutils/EventUtils.java @@ -3,11 +3,11 @@ import cc.aabss.eventutils.commands.CommandRegister; import cc.aabss.eventutils.config.EUConfig; import cc.aabss.eventutils.config.EventType; -import cc.aabss.eventutils.config.Group; import cc.aabss.eventutils.config.migrations.*; import cc.aabss.eventutils.config.serdes.EntityTypeSerializer; import cc.aabss.eventutils.config.serdes.EventSettingsSerializer; import cc.aabss.eventutils.config.serdes.GroupSerializer; +import cc.aabss.eventutils.config.serdes.GroupsSerializer; import cc.aabss.eventutils.discordrpc.DiscordRPC; import cc.aabss.eventutils.manager.AuthManager; import cc.aabss.eventutils.manager.DiscordLinkManager; @@ -120,7 +120,8 @@ public EventUtils() { // Custom serdes new EntityTypeSerializer(), new EventSettingsSerializer(), - new GroupSerializer()); + new GroupSerializer(), + new GroupsSerializer()); opt.bindFile(new File(FabricLoader.getInstance().getConfigDir().toFile(), "eventutils.json")); opt.removeOrphans(true); @@ -137,18 +138,6 @@ public EventUtils() { // Clamp event_server_display_minutes config.setEventServerDisplayMinutes(config.event_server_display_minutes); - // Add UUIDs to Groups - for (final Map.Entry entry : config.groups.entrySet()) entry.getValue().setUuid(entry.getKey()); - // Validate groups (unique names) - boolean updated = false; - final Set groupNames = new HashSet<>(); - for (final Group group : new HashSet<>(config.groups.values())) { - if (groupNames.add(group.getName().toLowerCase())) continue; - EventUtils.LOGGER.error("Removing duplicate group: {}", group); - config.groups.remove(group.getUuid()); - updated = true; - } - if (updated) config.save(); // Save if a group was removed // Need to wait for config to be loaded updateLogLevel(); diff --git a/src/main/java/cc/aabss/eventutils/config/EUConfig.java b/src/main/java/cc/aabss/eventutils/config/EUConfig.java index e83fd4d..c0db467 100644 --- a/src/main/java/cc/aabss/eventutils/config/EUConfig.java +++ b/src/main/java/cc/aabss/eventutils/config/EUConfig.java @@ -5,7 +5,6 @@ import org.apache.logging.log4j.Level; import org.apache.logging.log4j.spi.StandardLevel; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Range; import java.util.*; @@ -42,7 +41,7 @@ public class EUConfig extends OkaeriConfig { public int event_server_display_minutes = Defaults.EVENT_SERVER_DISPLAY_MINUTES; @Stat - @NotNull public Map groups = Defaults.groups(); + @NotNull public Groups groups = Defaults.groups(); @Stat @NotNull public Map event_settings = Defaults.eventSettings(); @@ -54,29 +53,6 @@ public class EUConfig extends OkaeriConfig { @NotNull public StandardLevel log_level = Defaults.LOG_LEVEL; - @NotNull - public List getGroupNames() { - return groups.values().stream() - .map(Group::getName) - .toList(); - } - - @Nullable - public Group getGroupByName(@NotNull String name) { - return groups.values().stream() - .filter(group -> group.getName().equalsIgnoreCase(name)) - .findFirst() - .orElse(null); - } - - /** - * If a group with the same UUID already exists, it will be replaced - */ - public void upsertGroup(@NotNull Group group) { - groups.put(group.getUuid(), group); - save(); - } - @NotNull public EventSettings getEventSettings(@NotNull EventType type) { return event_settings.getOrDefault(type, new EventSettings()); @@ -106,7 +82,7 @@ public static class Defaults { @NotNull public static final String DEFAULT_FAMOUS_IP = "play.invadedlands.net"; public static final boolean BEE_ICONS = true; public static final int EVENT_SERVER_DISPLAY_MINUTES = 5; - @NotNull private static final Map GROUPS = Map.of(UUID.randomUUID(), new Group().setName("Hide All Players")); + @NotNull private static final Groups GROUPS = new Groups(new Group().setName("Hide All Players")); @NotNull private static final Map EVENT_SETTINGS = Arrays.stream(EventType.values()) .collect(Collectors.toMap(type -> type, type -> new EventSettings(), (a, b) -> a, () -> new EnumMap<>(EventType.class))); @@ -115,8 +91,8 @@ public static class Defaults { @NotNull public static final StandardLevel LOG_LEVEL = Level.INFO.getStandardLevel(); @NotNull - public static Map groups() { - return new HashMap<>(GROUPS); + public static Groups groups() { + return new Groups(GROUPS); } @NotNull public static Map eventSettings() { diff --git a/src/main/java/cc/aabss/eventutils/config/Group.java b/src/main/java/cc/aabss/eventutils/config/Group.java index 19706f6..ee2f3f4 100644 --- a/src/main/java/cc/aabss/eventutils/config/Group.java +++ b/src/main/java/cc/aabss/eventutils/config/Group.java @@ -37,6 +37,18 @@ public Group() { this.uuid = UUID.randomUUID(); } + @Override + public int hashCode() { + return uuid.hashCode(); + } + + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) return true; + if (!(obj instanceof Group group)) return false; + return uuid.equals(group.uuid); + } + @NotNull public UUID getUuid() { return uuid; diff --git a/src/main/java/cc/aabss/eventutils/config/Groups.java b/src/main/java/cc/aabss/eventutils/config/Groups.java new file mode 100644 index 0000000..d52c10f --- /dev/null +++ b/src/main/java/cc/aabss/eventutils/config/Groups.java @@ -0,0 +1,54 @@ +package cc.aabss.eventutils.config; + +import cc.aabss.eventutils.stats.Statable; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; + + +public class Groups implements Statable { + @NotNull public final List groups; + + public Groups(@NotNull Map groups) { + this.groups = new ArrayList<>(groups.values()); + } + + public Groups(@NotNull Group @NotNull ... groups) { + this.groups = new ArrayList<>(List.of(groups)); + } + + public Groups(@NotNull Groups groups) { + this.groups = new ArrayList<>(groups.groups); + } + + @NotNull + public Map toMap() { + return groups.stream().collect(Collectors.toMap(Group::getUuid, group -> group)); + } + + @Nullable + public Group getByName(@NotNull String name) { + return groups.stream() + .filter(group -> group.getName().equalsIgnoreCase(name)) + .findFirst() + .orElse(null); + } + + public void remove(@NotNull UUID uuid) { + groups.removeIf(group -> group.getUuid().equals(uuid)); + } + + @Override @NotNull + public JsonElement toStat() { + final JsonArray array = new JsonArray(); + for (final Group group : groups) array.add(group.toStat()); + return array; + } +} diff --git a/src/main/java/cc/aabss/eventutils/config/serdes/GroupsSerializer.java b/src/main/java/cc/aabss/eventutils/config/serdes/GroupsSerializer.java new file mode 100644 index 0000000..1ee54f9 --- /dev/null +++ b/src/main/java/cc/aabss/eventutils/config/serdes/GroupsSerializer.java @@ -0,0 +1,47 @@ +package cc.aabss.eventutils.config.serdes; + +import cc.aabss.eventutils.EventUtils; +import cc.aabss.eventutils.config.Group; +import cc.aabss.eventutils.config.Groups; +import eu.okaeri.configs.schema.GenericsDeclaration; +import eu.okaeri.configs.serdes.DeserializationData; +import eu.okaeri.configs.serdes.ObjectSerializer; +import eu.okaeri.configs.serdes.SerializationData; +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + + +public class GroupsSerializer implements ObjectSerializer { + @Override + public boolean supports(@NotNull Class type) { + return Groups.class.isAssignableFrom(type); + } + + @Override + public void serialize(@NotNull Groups object, @NotNull SerializationData data, @NotNull GenericsDeclaration generics) { + data.setValue(object.toMap(), GenericsDeclaration.of(Map.class, List.of(UUID.class, Group.class))); + } + + @Override @NotNull + public Groups deserialize(@NotNull DeserializationData data, @NotNull GenericsDeclaration generics) { + final Map map = data.getValueDirect(GenericsDeclaration.of(Map.class, List.of(UUID.class, Group.class))); + + // Add UUIDs to Groups + for (final Map.Entry entry : map.entrySet()) entry.getValue().setUuid(entry.getKey()); + + // Validate (unique names) + final Set groupNames = new HashSet<>(); + for (final Group group : map.values()) { + if (groupNames.add(group.getName().toLowerCase())) continue; + EventUtils.LOGGER.error("Removing duplicate group: {}", group); + map.remove(group.getUuid()); + } + + return new Groups(map); + } +} diff --git a/src/main/java/cc/aabss/eventutils/manager/GroupManager.java b/src/main/java/cc/aabss/eventutils/manager/GroupManager.java index d585885..5eada5e 100644 --- a/src/main/java/cc/aabss/eventutils/manager/GroupManager.java +++ b/src/main/java/cc/aabss/eventutils/manager/GroupManager.java @@ -10,45 +10,22 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Iterator; -import java.util.UUID; - public class GroupManager { @NotNull private final EventUtils mod; - @Nullable public UUID selectedGroup; - @NotNull public Iterator groupIterator; + @Nullable public Group selectedGroup; public GroupManager(@NotNull EventUtils mod) { this.mod = mod; - resetIterator(); - } - - public boolean isAllPlayersRevealed() { - return selectedGroup == null; - } - - @Nullable - public Group getSelectedGroup() { - return selectedGroup != null ? mod.config.groups.get(selectedGroup) : null; - } - - private void resetIterator() { - groupIterator = mod.config.groups.keySet().iterator(); } /** * Revealed -> group 1 -> group 2 -> revealed -> repeat */ public void cycle() { - if (selectedGroup == null) resetIterator(); - - if (groupIterator.hasNext()) { - selectedGroup = groupIterator.next(); - } else { - selectedGroup = null; - } + final int nextIndex = selectedGroup == null ? 0 : mod.config.groups.groups.indexOf(selectedGroup) + 1; + selectedGroup = nextIndex < mod.config.groups.groups.size() ? mod.config.groups.groups.get(nextIndex) : null; } private boolean isSelf(@NotNull String name) { @@ -58,41 +35,38 @@ private boolean isSelf(@NotNull String name) { public boolean isPlayerVisible(@NotNull GameProfile profile, @Nullable Vec3 position) { // All visible - final Group group = getSelectedGroup(); - if (group == null) return true; + if (selectedGroup == null) return true; // Always show self final VersionedGameProfile versionedProfile = new VersionedGameProfile(profile); if (isSelf(versionedProfile.getName())) return true; // NPC - if (EventUtils.isNpc(versionedProfile.getId())) return group.isNpcVisible(position); + if (EventUtils.isNpc(versionedProfile.getId())) return selectedGroup.isNpcVisible(position); // Delegate to Group - return group.isPlayerVisible(versionedProfile.getName(), position); + return selectedGroup.isPlayerVisible(versionedProfile.getName(), position); } public boolean isPlayerVisible(@Nullable String name, @Nullable Vec3 position) { // All visible - final Group group = getSelectedGroup(); - if (group == null) return true; + if (selectedGroup == null) return true; // Always show self if (name != null && isSelf(name)) return true; // NPC - if (EventUtils.isNpc(name)) return group.isNpcVisible(position); + if (EventUtils.isNpc(name)) return selectedGroup.isNpcVisible(position); // Delegate to Group - return group.isPlayerVisible(name, position); + return selectedGroup.isPlayerVisible(name, position); } public boolean isEntityVisible(@NotNull EntityType entityType, @Nullable Vec3 position) { // All visible - final Group group = getSelectedGroup(); - if (group == null) return true; + if (selectedGroup == null) return true; // Delegate to Group - return group.isEntityVisible(entityType, position); + return selectedGroup.isEntityVisible(entityType, position); } } diff --git a/src/main/java/cc/aabss/eventutils/manager/KeybindManager.java b/src/main/java/cc/aabss/eventutils/manager/KeybindManager.java index 47463a9..e06ff56 100644 --- a/src/main/java/cc/aabss/eventutils/manager/KeybindManager.java +++ b/src/main/java/cc/aabss/eventutils/manager/KeybindManager.java @@ -1,7 +1,6 @@ package cc.aabss.eventutils.manager; import cc.aabss.eventutils.EventUtils; -import cc.aabss.eventutils.config.Group; import cc.aabss.eventutils.mixin.KeyMappingAccessor; import cc.aabss.eventutils.screen.EventInfoScreen; import cc.aabss.eventutils.sdk.EventWrapper; @@ -135,9 +134,8 @@ public KeybindManager(@NotNull EventUtils mod) { // Action bar final MutableComponent message; - final Group group = mod.groupManager.getSelectedGroup(); - if (group != null) { - message = literal(group.getName()); + if (mod.groupManager.selectedGroup != null) { + message = literal(mod.groupManager.selectedGroup.getName()); } else { message = translatable("eventutils.hideplayers.view_revealed"); } diff --git a/src/main/java/cc/aabss/eventutils/screen/config/group/EditGroupScreen.java b/src/main/java/cc/aabss/eventutils/screen/config/group/EditGroupScreen.java index 6943ea4..6c41d9b 100644 --- a/src/main/java/cc/aabss/eventutils/screen/config/group/EditGroupScreen.java +++ b/src/main/java/cc/aabss/eventutils/screen/config/group/EditGroupScreen.java @@ -39,10 +39,10 @@ public static Screen getScreen(@NotNull EventUtils mod, @NotNull Screen parent, .name(translatable("eventutils.config.groups.name.label")) .binding(group.getUuid().toString(), group::getName, newValue -> { // Check if group with NEW name already exists - if (!newValue.equals(group.getName()) && mod.config.getGroupByName(newValue) != null) return; + if (!newValue.equals(group.getName()) && mod.config.groups.getByName(newValue) != null) return; group.setName(newValue); - mod.config.upsertGroup(group); + mod.config.save(); }) .controller(StringControllerBuilder::create) .build()) @@ -55,7 +55,7 @@ public static Screen getScreen(@NotNull EventUtils mod, @NotNull Screen parent, if (newValue > Group.MAX_RADIUS) newValue = null; group.setRadius(newValue); - mod.config.upsertGroup(group); + mod.config.save(); }) .controller(opt -> IntegerSliderControllerBuilder.create(opt) .range(1, Group.MAX_RADIUS + 1) @@ -71,7 +71,7 @@ public static Screen getScreen(@NotNull EventUtils mod, @NotNull Screen parent, .name(translatable("eventutils.config.groups.player_mode.label")) .binding(Group.Defaults.PLAYER_MODE, group::getPlayerMode, newValue -> { group.setPlayerMode(newValue); - mod.config.upsertGroup(group); + mod.config.save(); }) .controller(EditGroupScreen::getModeController) .build()) @@ -79,7 +79,7 @@ public static Screen getScreen(@NotNull EventUtils mod, @NotNull Screen parent, .name(translatable("eventutils.config.groups.entity_mode.label")) .binding(Group.Defaults.ENTITY_MODE, group::getEntityMode, newValue -> { group.setEntityMode(newValue); - mod.config.upsertGroup(group); + mod.config.save(); }) .controller(EditGroupScreen::getModeController) .build()) @@ -87,7 +87,7 @@ public static Screen getScreen(@NotNull EventUtils mod, @NotNull Screen parent, .name(translatable("eventutils.config.groups.npc_mode.label")) .binding(Group.Defaults.NPC_MODE, group::getNpcMode, newValue -> { group.setNpcMode(newValue); - mod.config.upsertGroup(group); + mod.config.save(); }) .controller(EditGroupScreen::getModeController) .build()) @@ -95,7 +95,7 @@ public static Screen getScreen(@NotNull EventUtils mod, @NotNull Screen parent, .name(translatable("eventutils.config.groups.players.label")) .binding(new ArrayList<>(Group.Defaults.players()), () -> new ArrayList<>(group.getPlayers()), newValue -> { group.setPlayers(newValue); - mod.config.upsertGroup(group); + mod.config.save(); }) .initial(new VersionedGameProfile(Minecraft.getInstance().getGameProfile()).getName()) .controller(StringControllerBuilder::create) @@ -104,7 +104,7 @@ public static Screen getScreen(@NotNull EventUtils mod, @NotNull Screen parent, .name(translatable("eventutils.config.groups.entities.label")) .binding(new ArrayList<>(Group.Defaults.entityIds()), () -> new ArrayList<>(group.getEntityIds()), newValue -> { group.setEntitiesByIds(newValue); - mod.config.upsertGroup(group); + mod.config.save(); }) .initial("minecraft:bee") .controller(option -> DropdownStringControllerBuilder.create(option).values(ENTITY_TYPES)) diff --git a/src/main/java/cc/aabss/eventutils/screen/config/group/GroupManagerScreen.java b/src/main/java/cc/aabss/eventutils/screen/config/group/GroupManagerScreen.java index eb78617..7004c3c 100644 --- a/src/main/java/cc/aabss/eventutils/screen/config/group/GroupManagerScreen.java +++ b/src/main/java/cc/aabss/eventutils/screen/config/group/GroupManagerScreen.java @@ -38,28 +38,28 @@ protected void init() { final int listTop = 40; int i = 0; - for (final Group group : mod.config.groups.values()) { + for (final Group group : mod.config.groups.groups) { final int y = listTop + i * ROW_HEIGHT; if (y >= height - 60) break; i++; final Button editBtn = Button.builder(literal(group.getName()).withStyle(Style.EMPTY.withColor(TextColor.fromRgb(0xE0E0E0))), button -> { - if (minecraft != null) vClient.setScreen(EditGroupScreen.getScreen(mod, this, group)); + vClient.setScreen(EditGroupScreen.getScreen(mod, this, group)); }).bounds(PADDING, y, width - PADDING * 2 - REMOVE_WIDTH - 4, 20).build(); addRenderableWidget(editBtn); addRenderableWidget(Button.builder(literal("X").withStyle(ChatFormatting.RED), button -> { - if (mod.groupManager.selectedGroup == group.getUuid()) mod.groupManager.selectedGroup = null; + if (mod.groupManager.selectedGroup == group) mod.groupManager.selectedGroup = null; mod.config.groups.remove(group.getUuid()); mod.config.save(); - if (minecraft != null) vClient.setScreen(new GroupManagerScreen(mod, parent)); + vClient.setScreen(new GroupManagerScreen(mod, parent)); }).bounds(width - PADDING - REMOVE_WIDTH, y, REMOVE_WIDTH, 20).build()); } final Button addBtn = Button.builder(translatable("eventutils.config.groups.add"), button -> { - mod.config.upsertGroup(new Group()); - if (minecraft != null) vClient.setScreen(new GroupManagerScreen(mod, parent)); + mod.config.groups.groups.add(new Group()); + vClient.setScreen(new GroupManagerScreen(mod, parent)); }).bounds(width / 2 - BUTTON_WIDTH - 4, height - 32, BUTTON_WIDTH, 20).build(); addRenderableWidget(addBtn); diff --git a/src/main/java/cc/aabss/eventutils/versioning/VersionedClient.java b/src/main/java/cc/aabss/eventutils/versioning/VersionedClient.java index 073d922..e925a61 100644 --- a/src/main/java/cc/aabss/eventutils/versioning/VersionedClient.java +++ b/src/main/java/cc/aabss/eventutils/versioning/VersionedClient.java @@ -2,19 +2,20 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class VersionedClient { - @NotNull private final Minecraft client; + @Nullable private final Minecraft client; - public VersionedClient(@NotNull Minecraft client) { + public VersionedClient(@Nullable Minecraft client) { this.client = client; } @Nullable public Screen screen() { + if (client == null) return null; + //? if >=26.2 { /*return client.gui.screen(); *///?} else { @@ -23,6 +24,8 @@ public Screen screen() { } public void setScreen(@Nullable Screen screen) { + if (client == null) return; + //? if >=26.2 { /*client.gui.setScreen(screen); *///?} else {