diff --git a/common/src/main/java/dev/ftb/mods/ftbquests/client/ClientQuestFile.java b/common/src/main/java/dev/ftb/mods/ftbquests/client/ClientQuestFile.java index e27757b9..84b18bb9 100644 --- a/common/src/main/java/dev/ftb/mods/ftbquests/client/ClientQuestFile.java +++ b/common/src/main/java/dev/ftb/mods/ftbquests/client/ClientQuestFile.java @@ -178,6 +178,7 @@ public static boolean isQuestPinned(long id) { @Override public boolean isPlayerOnTeam(Player player, TeamData teamData) { + if (!isShareProgressWithTeam()) return player.getUUID().equals(teamData.getTeamId()); return FTBTeamsAPI.api().getClientManager().getKnownPlayer(player.getUUID()) .map(kcp -> kcp.teamId().equals(teamData.getTeamId())) .orElse(false); diff --git a/common/src/main/java/dev/ftb/mods/ftbquests/quest/BaseQuestFile.java b/common/src/main/java/dev/ftb/mods/ftbquests/quest/BaseQuestFile.java index 9e892a47..5e2751ac 100644 --- a/common/src/main/java/dev/ftb/mods/ftbquests/quest/BaseQuestFile.java +++ b/common/src/main/java/dev/ftb/mods/ftbquests/quest/BaseQuestFile.java @@ -1,5 +1,6 @@ package dev.ftb.mods.ftbquests.quest; +import dev.architectury.networking.NetworkManager; import dev.architectury.utils.Env; import dev.ftb.mods.ftblibrary.config.ConfigGroup; import dev.ftb.mods.ftblibrary.config.ItemStackConfig; @@ -15,6 +16,7 @@ import dev.ftb.mods.ftbquests.events.*; import dev.ftb.mods.ftbquests.integration.RecipeModHelper; import dev.ftb.mods.ftbquests.net.DeleteObjectResponseMessage; +import dev.ftb.mods.ftbquests.net.SyncTeamDataMessage; import dev.ftb.mods.ftbquests.quest.loot.EntityWeight; import dev.ftb.mods.ftbquests.quest.loot.LootCrate; import dev.ftb.mods.ftbquests.quest.loot.RewardTable; @@ -42,6 +44,8 @@ import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.RandomSource; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; @@ -108,6 +112,7 @@ public void encode(RegistryFriendlyByteBuf buf, BaseQuestFile file) { private boolean dropBookOnDeath; private String fallbackLocale; private boolean verifyOnLoad; + private boolean shareProgressWithTeam; private List allTasks; private List submitTasks; @@ -149,6 +154,7 @@ public BaseQuestFile() { dropBookOnDeath = false; hideExcludedQuests = false; verifyOnLoad = false; + shareProgressWithTeam = true; allTasks = null; @@ -454,6 +460,7 @@ public final void writeData(CompoundTag nbt, HolderLookup.Provider provider) { nbt.putBoolean("hide_excluded_quests", hideExcludedQuests); nbt.putString("fallback_locale", fallbackLocale); nbt.putBoolean("verify_on_load", verifyOnLoad); + nbt.putBoolean("share_progress_with_team", shareProgressWithTeam); } @Override @@ -497,6 +504,7 @@ public final void readData(CompoundTag nbt, HolderLookup.Provider provider) { hideExcludedQuests = nbt.getBoolean("hide_excluded_quests"); fallbackLocale = nbt.getString("fallback_locale"); verifyOnLoad = nbt.getBoolean("verify_on_load"); + shareProgressWithTeam = !nbt.contains("share_progress_with_team") || nbt.getBoolean("share_progress_with_team"); } public final void writeDataFull(Path folder, HolderLookup.Provider provider) { @@ -868,6 +876,7 @@ public final void writeNetData(RegistryFriendlyByteBuf buffer) { buffer.writeBoolean(dropBookOnDeath); buffer.writeBoolean(hideExcludedQuests); buffer.writeUtf(fallbackLocale); + buffer.writeBoolean(shareProgressWithTeam); } @Override @@ -894,6 +903,7 @@ public final void readNetData(RegistryFriendlyByteBuf buffer) { dropBookOnDeath = buffer.readBoolean(); hideExcludedQuests = buffer.readBoolean(); fallbackLocale = buffer.readUtf(); + shareProgressWithTeam = buffer.readBoolean(); } public final void writeNetDataFull(RegistryFriendlyByteBuf buffer) { @@ -1123,6 +1133,22 @@ public TeamData getOrCreateTeamData(Team team) { @Override public TeamData getOrCreateTeamData(Entity player) { + if (!shareProgressWithTeam) { + UUID pid = player.getUUID(); + boolean isNew = !teamDataMap.containsKey(pid); + TeamData data = getOrCreateTeamData(pid); + + if (player instanceof Player p && data.getName().isEmpty()) { data.setName(String.valueOf(p.getDisplayName())); } + + if (isNew && isServerSide()) { + FTBTeamsAPI.api().getManager().getTeamForPlayerID(pid).ifPresent(team -> { + TeamData shared = getOrCreateTeamData(team); + data.copyData(shared); + }); + } + + return data; + } return FTBTeamsAPI.api().getManager().getTeamForPlayerID(player.getUUID()) .map(this::getOrCreateTeamData) .orElse(null); @@ -1130,6 +1156,7 @@ public TeamData getOrCreateTeamData(Entity player) { @Override public Optional getTeamData(Player player) { + if (!shareProgressWithTeam) { return Optional.of(getOrCreateTeamData(player.getUUID())); } return player.level().isClientSide ? getClientTeamData(player) : FTBTeamsAPI.api().getManager().getTeamForPlayerID(player.getUUID()) @@ -1173,6 +1200,7 @@ public void fillConfigGroup(ConfigGroup config) { config.addDouble("grid_scale", gridScale, v -> gridScale = v, 0.5D, 1D / 32D, 8D); config.addString("lock_message", lockMessage, v -> lockMessage = v, ""); config.addEnum("progression_mode", progressionMode, v -> progressionMode = v, ProgressionMode.NAME_MAP_NO_DEFAULT); + config.addBool("share_progress_with_team", shareProgressWithTeam, v -> shareProgressWithTeam = v, true); config.addInt("detection_delay", detectionDelay, v -> detectionDelay = v, 20, 0, 200); config.addBool("pause_game", pauseGame, v -> pauseGame = v, false); config.addBool("show_lock_icons", showLockIcons, v -> showLockIcons = v, true).setNameKey("ftbquests.ui.show_lock_icon"); @@ -1214,6 +1242,16 @@ public void clearCachedProgress() { getAllTeamData().forEach(TeamData::clearCachedProgress); } + @Override + public void editedFromGUIOnServer() { + if (this instanceof ServerQuestFile sqf) { + MinecraftServer server = sqf.server; + for (ServerPlayer p : server.getPlayerList().getPlayers()) { + sqf.getTeamData(p).ifPresent(td -> NetworkManager.sendToPlayer(p, new SyncTeamDataMessage(td))); + } + } + } + public long newID() { return readID(0L); } @@ -1464,6 +1502,10 @@ public boolean isDefaultTeamConsumeItems() { return defaultTeamConsumeItems; } + public boolean isShareProgressWithTeam() { + return shareProgressWithTeam; + } + public RewardAutoClaim getDefaultRewardAutoClaim() { return defaultRewardAutoClaim; } diff --git a/common/src/main/java/dev/ftb/mods/ftbquests/quest/ServerQuestFile.java b/common/src/main/java/dev/ftb/mods/ftbquests/quest/ServerQuestFile.java index 9fe3effc..ec7007fe 100644 --- a/common/src/main/java/dev/ftb/mods/ftbquests/quest/ServerQuestFile.java +++ b/common/src/main/java/dev/ftb/mods/ftbquests/quest/ServerQuestFile.java @@ -185,7 +185,7 @@ public void withPlayerContext(ServerPlayer player, Runnable toDo) { public void playerLoggedIn(PlayerLoggedInAfterTeamEvent event) { ServerPlayer player = event.getPlayer(); - TeamData data = getOrCreateTeamData(event.getTeam()); + TeamData data = getTeamData(player).orElseGet(() -> getOrCreateTeamData(player.getUUID())); // Sync the quest book data // - client will respond to this with a RequestTeamData message @@ -240,7 +240,7 @@ public void teamCreated(TeamCreatedEvent event) { addData(data, false); - if (event.getTeam() instanceof PartyTeam) { + if (isShareProgressWithTeam() && event.getTeam() instanceof PartyTeam) { FTBTeamsAPI.api().getManager().getPlayerTeamForPlayerID(event.getCreator().getUUID()).ifPresent(playerTeam -> { TeamData oldTeamData = getOrCreateTeamData(playerTeam); data.copyData(oldTeamData); @@ -251,6 +251,13 @@ public void teamCreated(TeamCreatedEvent event) { } public void playerChangedTeam(PlayerChangedTeamEvent event) { + if (!isShareProgressWithTeam()) { + ServerPlayer player = event.getPlayer(); + TeamData personal = getOrCreateTeamData(player); + if (personal.getName().isEmpty()) personal.setName(player.getScoreboardName()); + NetworkManager.sendToPlayer(player, new SyncTeamDataMessage(personal)); + return; + } event.getPreviousTeam().ifPresent(prevTeam -> { Team curTeam = event.getTeam(); TeamData oldTeamData = getOrCreateTeamData(prevTeam); @@ -274,6 +281,7 @@ public void playerChangedTeam(PlayerChangedTeamEvent event) { @Override public boolean isPlayerOnTeam(Player player, TeamData teamData) { + if (!isShareProgressWithTeam()) return player.getUUID().equals(teamData.getTeamId()); return FTBTeamsAPI.api().getManager().getTeamForPlayerID(player.getUUID()) .map(team -> team.getTeamId().equals(teamData.getTeamId())) .orElse(false); diff --git a/common/src/main/java/dev/ftb/mods/ftbquests/quest/TeamData.java b/common/src/main/java/dev/ftb/mods/ftbquests/quest/TeamData.java index c00556dc..37895d6d 100644 --- a/common/src/main/java/dev/ftb/mods/ftbquests/quest/TeamData.java +++ b/common/src/main/java/dev/ftb/mods/ftbquests/quest/TeamData.java @@ -623,7 +623,13 @@ public void claimReward(ServerPlayer player, Reward reward, boolean notify) { public Collection getOnlineMembers() { return FTBTeamsAPI.api().getManager().getTeamByID(teamId) .map(Team::getOnlineMembers) - .orElse(List.of()); + .orElseGet(() -> { + if (file instanceof ServerQuestFile sqf) { + ServerPlayer p = sqf.server.getPlayerList().getPlayer(teamId); + return p != null ? List.of(p) : List.of(); + } + return List.of(); + }); } public void checkAutoCompletion(Quest quest) {