mirror of
https://github.com/WiIIiam278/HuskSync.git
synced 2025-12-28 19:19:13 +00:00
Add support for save & set the date of advancement;
This commit is contained in:
@@ -16,6 +16,7 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
|
||||
public class DataSerializer {
|
||||
@@ -207,17 +208,23 @@ public class DataSerializer {
|
||||
playerLocation.getYaw(), playerLocation.getPitch(), player.getWorld().getName(), player.getWorld().getEnvironment()));
|
||||
}
|
||||
|
||||
public record PlayerLocation(double x, double y, double z, float yaw, float pitch,
|
||||
String worldName, World.Environment environment) implements Serializable {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // Ignore the unchecked cast here
|
||||
public static ArrayList<DataSerializer.AdvancementRecord> deserializeAdvancementData(String serializedAdvancementData) throws IOException {
|
||||
public static List<DataSerializer.AdvancementRecordDate> deserializeAdvancementData(String serializedAdvancementData) throws IOException {
|
||||
if (serializedAdvancementData.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
try {
|
||||
return (ArrayList<DataSerializer.AdvancementRecord>) RedisMessage.deserialize(serializedAdvancementData);
|
||||
List<?> deserialize = (List<?>) RedisMessage.deserialize(serializedAdvancementData);
|
||||
|
||||
if (!deserialize.isEmpty() && deserialize.get(0) instanceof AdvancementRecord) {
|
||||
deserialize = ((List<AdvancementRecord>) deserialize).stream()
|
||||
.map(o -> new AdvancementRecordDate(
|
||||
o.advancementKey,
|
||||
o.awardedAdvancementCriteria
|
||||
)).toList();
|
||||
}
|
||||
|
||||
return (List<AdvancementRecordDate>) deserialize;
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IOException("Unable to decode class type.", e);
|
||||
}
|
||||
@@ -225,22 +232,21 @@ public class DataSerializer {
|
||||
|
||||
public static String getSerializedAdvancements(Player player) throws IOException {
|
||||
Iterator<Advancement> serverAdvancements = Bukkit.getServer().advancementIterator();
|
||||
ArrayList<DataSerializer.AdvancementRecord> advancementData = new ArrayList<>();
|
||||
ArrayList<DataSerializer.AdvancementRecordDate> advancementData = new ArrayList<>();
|
||||
|
||||
while (serverAdvancements.hasNext()) {
|
||||
final AdvancementProgress progress = player.getAdvancementProgress(serverAdvancements.next());
|
||||
final NamespacedKey advancementKey = progress.getAdvancement().getKey();
|
||||
final ArrayList<String> awardedCriteria = new ArrayList<>(progress.getAwardedCriteria());
|
||||
advancementData.add(new DataSerializer.AdvancementRecord(advancementKey.getNamespace() + ":" + advancementKey.getKey(), awardedCriteria));
|
||||
|
||||
final Map<String, Date> awardedCriteria = new HashMap<>();
|
||||
progress.getAwardedCriteria().forEach(s -> awardedCriteria.put(s, progress.getDateAwarded(s)));
|
||||
|
||||
advancementData.add(new DataSerializer.AdvancementRecordDate(advancementKey.getNamespace() + ":" + advancementKey.getKey(), awardedCriteria));
|
||||
}
|
||||
|
||||
return RedisMessage.serialize(advancementData);
|
||||
}
|
||||
|
||||
public record AdvancementRecord(String advancementKey,
|
||||
ArrayList<String> awardedAdvancementCriteria) implements Serializable {
|
||||
}
|
||||
|
||||
public static DataSerializer.StatisticData deserializeStatisticData(String serializedStatisticData) throws IOException {
|
||||
if (serializedStatisticData.isEmpty()) {
|
||||
return new DataSerializer.StatisticData(new HashMap<>(), new HashMap<>(), new HashMap<>(), new HashMap<>());
|
||||
@@ -288,6 +294,22 @@ public class DataSerializer {
|
||||
return RedisMessage.serialize(statisticData);
|
||||
}
|
||||
|
||||
public record PlayerLocation(double x, double y, double z, float yaw, float pitch,
|
||||
String worldName, World.Environment environment) implements Serializable {
|
||||
}
|
||||
|
||||
public record AdvancementRecord(String advancementKey,
|
||||
ArrayList<String> awardedAdvancementCriteria) implements Serializable {
|
||||
}
|
||||
|
||||
public record AdvancementRecordDate(String key, Map<String, Date> criteriaMap) implements Serializable {
|
||||
AdvancementRecordDate(String key, List<String> criteriaList) {
|
||||
this(key, new HashMap<>() {{
|
||||
criteriaList.forEach(s -> put(s, Date.from(Instant.EPOCH)));
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
public record StatisticData(HashMap<Statistic, Integer> untypedStatisticValues,
|
||||
HashMap<Statistic, HashMap<Material, Integer>> blockStatisticValues,
|
||||
HashMap<Statistic, HashMap<Material, Integer>> itemStatisticValues,
|
||||
|
||||
@@ -160,7 +160,7 @@ public class PlayerSetter {
|
||||
// Set the player's data from the PlayerData
|
||||
try {
|
||||
if (Settings.syncAdvancements) {
|
||||
ArrayList<DataSerializer.AdvancementRecord> advancementRecords
|
||||
List<DataSerializer.AdvancementRecordDate> advancementRecords
|
||||
= DataSerializer.deserializeAdvancementData(data.getSerializedAdvancements());
|
||||
|
||||
if (Settings.useNativeImplementation) {
|
||||
@@ -280,7 +280,7 @@ public class PlayerSetter {
|
||||
}
|
||||
}
|
||||
|
||||
private static void nativeSyncPlayerAdvancements(final Player player, final List<DataSerializer.AdvancementRecord> advancementRecords) {
|
||||
private static void nativeSyncPlayerAdvancements(final Player player, final List<DataSerializer.AdvancementRecordDate> advancementRecords) {
|
||||
final Object playerAdvancements = AdvancementUtils.getPlayerAdvancements(player);
|
||||
|
||||
// Clear
|
||||
@@ -288,8 +288,8 @@ public class PlayerSetter {
|
||||
|
||||
advancementRecords.forEach(advancementRecord -> {
|
||||
NamespacedKey namespacedKey = Objects.requireNonNull(
|
||||
NamespacedKey.fromString(advancementRecord.advancementKey()),
|
||||
"Invalid Namespaced key of " + advancementRecord.advancementKey()
|
||||
NamespacedKey.fromString(advancementRecord.key()),
|
||||
"Invalid Namespaced key of " + advancementRecord.key()
|
||||
);
|
||||
|
||||
Advancement bukkitAdvancement = Bukkit.getAdvancement(namespacedKey);
|
||||
@@ -298,20 +298,16 @@ public class PlayerSetter {
|
||||
return;
|
||||
}
|
||||
|
||||
// todo: sync date of get advancement
|
||||
Date date = Date.from(Instant.now().minus(Period.ofWeeks(1)));
|
||||
|
||||
Object advancement = AdvancementUtils.getHandle(bukkitAdvancement);
|
||||
List<String> criteriaList = advancementRecord.awardedAdvancementCriteria();
|
||||
Map<String, Date> criteriaList = advancementRecord.criteriaMap();
|
||||
{
|
||||
Map<String, Object> nativeCriteriaMap = new HashMap<>();
|
||||
criteriaList.forEach(criteria ->
|
||||
criteriaList.forEach((criteria, date) ->
|
||||
nativeCriteriaMap.put(criteria, AdvancementUtils.newCriterionProgress(date))
|
||||
);
|
||||
Object nativeAdvancementProgress = AdvancementUtils.newAdvancementProgress(nativeCriteriaMap);
|
||||
|
||||
AdvancementUtils.startProgress(playerAdvancements, advancement, nativeAdvancementProgress);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
@@ -327,7 +323,7 @@ public class PlayerSetter {
|
||||
* @param player The player to set the advancements of
|
||||
* @param advancementData The ArrayList of {@link DataSerializer.AdvancementRecord}s to set
|
||||
*/
|
||||
private static void setPlayerAdvancements(Player player, ArrayList<DataSerializer.AdvancementRecord> advancementData, PlayerData data) {
|
||||
private static void setPlayerAdvancements(Player player, List<DataSerializer.AdvancementRecordDate> advancementData, PlayerData data) {
|
||||
// Temporarily disable advancement announcing if needed
|
||||
boolean announceAdvancementUpdate = false;
|
||||
if (Boolean.TRUE.equals(player.getWorld().getGameRuleValue(GameRule.ANNOUNCE_ADVANCEMENTS))) {
|
||||
@@ -345,13 +341,13 @@ public class PlayerSetter {
|
||||
boolean correctExperienceCheck = false; // Determines whether the experience might have changed warranting an update
|
||||
Advancement advancement = serverAdvancements.next();
|
||||
AdvancementProgress playerProgress = player.getAdvancementProgress(advancement);
|
||||
for (DataSerializer.AdvancementRecord record : advancementData) {
|
||||
for (DataSerializer.AdvancementRecordDate record : advancementData) {
|
||||
// If the advancement is one on the data
|
||||
if (record.advancementKey().equals(advancement.getKey().getNamespace() + ":" + advancement.getKey().getKey())) {
|
||||
if (record.key().equals(advancement.getKey().getNamespace() + ":" + advancement.getKey().getKey())) {
|
||||
|
||||
// Award all criteria that the player does not have that they do on the cache
|
||||
ArrayList<String> currentlyAwardedCriteria = new ArrayList<>(playerProgress.getAwardedCriteria());
|
||||
for (String awardCriteria : record.awardedAdvancementCriteria()) {
|
||||
for (String awardCriteria : record.criteriaMap().keySet()) {
|
||||
if (!playerProgress.getAwardedCriteria().contains(awardCriteria)) {
|
||||
Bukkit.getScheduler().runTask(plugin, () -> player.getAdvancementProgress(advancement).awardCriteria(awardCriteria));
|
||||
correctExperienceCheck = true;
|
||||
|
||||
@@ -43,17 +43,17 @@ public class AdvancementUtils {
|
||||
|
||||
Class<?> ADVANCEMENT = ThrowSupplier.get(() -> Class.forName("net.minecraft.advancements.Advancement"));
|
||||
|
||||
Class<?> PLAYER_ADVANCEMENTS = MinecraftVersionUtils.getMinecraftClass("AdvancementDataPlayer");
|
||||
PLAYER_ADVANCEMENTS_MAP = ThrowSupplier.get(() -> PLAYER_ADVANCEMENTS.getDeclaredField("h"));
|
||||
Class<?> PLAYER_ADVANCEMENT = MinecraftVersionUtils.getMinecraftClass("AdvancementDataPlayer");
|
||||
PLAYER_ADVANCEMENTS_MAP = ThrowSupplier.get(() -> PLAYER_ADVANCEMENT.getDeclaredField("h"));
|
||||
PLAYER_ADVANCEMENTS_MAP.setAccessible(true);
|
||||
|
||||
START_PROGRESS = ThrowSupplier.get(() -> PLAYER_ADVANCEMENTS.getDeclaredMethod("a", ADVANCEMENT, ADVANCEMENT_PROGRESS));
|
||||
START_PROGRESS = ThrowSupplier.get(() -> PLAYER_ADVANCEMENT.getDeclaredMethod("a", ADVANCEMENT, ADVANCEMENT_PROGRESS));
|
||||
START_PROGRESS.setAccessible(true);
|
||||
|
||||
ENSURE_ALL_VISIBLE = ThrowSupplier.get(() -> PLAYER_ADVANCEMENTS.getDeclaredMethod("c"));
|
||||
ENSURE_ALL_VISIBLE = ThrowSupplier.get(() -> PLAYER_ADVANCEMENT.getDeclaredMethod("c"));
|
||||
ENSURE_ALL_VISIBLE.setAccessible(true);
|
||||
|
||||
IS_FIRST_PACKET = ThrowSupplier.get(() -> PLAYER_ADVANCEMENTS.getDeclaredField("n"));
|
||||
IS_FIRST_PACKET = ThrowSupplier.get(() -> PLAYER_ADVANCEMENT.getDeclaredField("n"));
|
||||
IS_FIRST_PACKET.setAccessible(true);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user