9
0
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:
Harvels X
2021-12-31 21:49:56 +03:00
parent cff00742ce
commit 5bbb4a8547
3 changed files with 50 additions and 32 deletions

View File

@@ -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,

View File

@@ -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;

View File

@@ -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);
}