Skip to content

Commit

Permalink
fix: Resolve issues around syncing PlayerSkills registry when reloadi…
Browse files Browse the repository at this point in the history
…ng resources
  • Loading branch information
impleri committed Nov 30, 2022
1 parent e9993f2 commit 45b6689
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import dev.architectury.event.events.common.PlayerEvent;
import dev.architectury.registry.ReloadListenerRegistry;
import dev.architectury.registry.registries.DeferredRegister;
import net.impleri.playerskills.api.Skill;
import net.impleri.playerskills.api.SkillType;
import net.impleri.playerskills.basic.BasicSkillType;
import net.impleri.playerskills.integration.kubejs.PlayerSkillsPlugin;
Expand All @@ -25,6 +24,9 @@
import net.minecraft.server.packs.resources.ResourceManagerReloadListener;
import org.jetbrains.annotations.NotNull;

import java.util.List;
import java.util.UUID;

public class PlayerSkillsCore implements ResourceManagerReloadListener {
public static final String MOD_ID = "playerskills";

Expand Down Expand Up @@ -85,12 +87,12 @@ private void registerCoreTypes() {

@Override
public void onResourceManagerReload(@NotNull ResourceManager resourceManager) {
var players = PlayerSkills.closeAllPlayers();
List<UUID> players = PlayerSkills.closeAllPlayers();

Skills.resync();
PlayerSkillsPlugin.registerSkills();

PlayerSkills.resyncPlayers(players, Skill.all());
PlayerSkills.openPlayers(players);
}

// Server lifecycle events
Expand All @@ -106,8 +108,7 @@ private void savePlayers(MinecraftServer server) {
// Events while server running

private void addPlayer(ServerPlayer player) {
LOGGER.info("Player {} joined, ensuring skills are synced", player.getName().getString());
PlayerSkills.openPlayer(player.getUUID(), Skill.all());
PlayerSkills.openPlayer(player.getUUID());
}

private void removePlayer(ServerPlayer player) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,6 @@ public void debug(String message) {
}

public void debug(String message, Object... params) {
instance.info(addPrefix(message), Arrays.stream(params).toArray());
instance.debug(addPrefix(message), Arrays.stream(params).toArray());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public abstract class PlayerSkills {
Expand Down Expand Up @@ -47,7 +49,6 @@ private static List<Skill<?>> getFor(UUID playerUuid) {
var cachedSkills = players.get(playerUuid);

if (cachedSkills == null) {
PlayerSkillsCore.LOGGER.info("Pulling {}'s skills from the freezer", playerUuid);
return readFromStorage(playerUuid);
}

Expand All @@ -61,11 +62,10 @@ public static List<Skill<?>> getAllForPlayer(UUID playerUuid) {
return getFor(playerUuid);
}

/**
* Instantiates the in-memory cache for a player. Note that this will automatically prune saved skills that do not
* match the skill type in the Skills Registry as well as those which no longer exist at all in the Skills Registery
*/
public static void openPlayer(UUID playerUuid, List<Skill<?>> registeredSkills) {
public static List<Skill<?>> handleOpenFor(UUID playerUuid) {
PlayerSkillsCore.LOGGER.info("Opening player {}, ensuring skills are synced", playerUuid);

var registeredSkills = Skills.entries();
// Get all the names of the registered skills
List<ResourceLocation> registeredSkillNames = registeredSkills.stream()
.map(Skill::getName)
Expand All @@ -91,12 +91,27 @@ public static void openPlayer(UUID playerUuid, List<Skill<?>> registeredSkills)

Skill.logSkills(newSkills, "Appending registerd skills for player");

List<Skill<?>> skills = Stream.concat(savedSkills.stream(), newSkills.stream()).toList();
return Stream.concat(savedSkills.stream(), newSkills.stream()).toList();
}

/**
* Instantiates the in-memory cache for a player. Note that this will automatically prune saved skills that do not
* match the skill type in the Skills Registry as well as those which no longer exist at all in the Skills Registery
*/
public static void openPlayer(UUID playerUuid) {
var skills = handleOpenFor(playerUuid);

// Immediately sync in-memory cache AND persistent storage with updated skills set
save(playerUuid, skills);
}

public static void openPlayers(List<UUID> playerUuids) {
Map<UUID, List<Skill<?>>> skillsList = playerUuids.stream()
.collect(Collectors.toMap(Function.identity(), PlayerSkills::handleOpenFor));

players.putAll(skillsList);
}

/**
* Helper function to upsert a skill for a player in memory only
*/
Expand Down Expand Up @@ -158,31 +173,34 @@ public static List<Skill<?>> remove(UUID playerUuid, ResourceLocation name) {
return newSkills;
}

private static void handleCloseFor(UUID playerUuid) {
PlayerSkillsCore.LOGGER.info("Closing player {}, ensuring skills are saved", playerUuid);
List<Skill<?>> skills = getFor(playerUuid);
writeToStorage(playerUuid, skills);
}

/**
* Save a player's skills to persistent storage then remove player from in-memory cache
*/
public static void closePlayer(UUID playerUuid) {
List<Skill<?>> skills = getFor(playerUuid);
save(playerUuid, skills);
handleCloseFor(playerUuid);

players.remove(playerUuid);
}

/**
* Save multiple players' skills to persistent storage then remove them from in-memory cache
*/
public static Set<UUID> closeAllPlayers() {
Set<UUID> playerIds = players.keySet();
playerIds.forEach(PlayerSkills::closePlayer);
public static List<UUID> closeAllPlayers() {
List<UUID> playerIds = players.keySet().stream().toList();
playerIds.stream().sequential().forEach(PlayerSkills::handleCloseFor);
players.clear();

return playerIds;
}

public static void resyncPlayers(Set<UUID> players, List<Skill<?>> registeredSkills) {
players.forEach(player -> openPlayer(player, registeredSkills));
}

private static List<Skill<?>> readFromStorage(UUID playerUuid) {
PlayerSkillsCore.LOGGER.debug("Restoring saved skills for {}", playerUuid);
return SkillStorage.read(playerUuid).stream()
.<Skill<?>>map(PlayerSkills::transformFromStorage)
.filter(Objects::nonNull)
Expand Down Expand Up @@ -223,6 +241,7 @@ private static List<Skill<?>> readFromStorage(UUID playerUuid) {
}

private static void writeToStorage(UUID playerUuid, List<Skill<?>> skills) {
PlayerSkillsCore.LOGGER.debug("Saving skills for {}", playerUuid);
List<String> rawSkills = skills.stream().map(skill -> {
try {
return serializeSkill(skill);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public List<String> read(File file) {
}

if (!tag.contains(SKILLS_TAG)) {
PlayerSkillsCore.LOGGER.warn("Player data file {} does not match the expected format", file.getPath());
PlayerSkillsCore.LOGGER.error("Player data file {} does not match the expected format", file.getPath());
return skills;
}

Expand All @@ -45,7 +45,7 @@ public void write(File file, List<String> data) {
try {
NbtIo.writeCompressed(storage, file);
} catch (IOException e) {
PlayerSkillsCore.LOGGER.debug("Failed to write to {}", file.getPath());
PlayerSkillsCore.LOGGER.error("Failed to write to {}", file.getPath());
}
}
}
1 change: 0 additions & 1 deletion common/src/main/resources/kubejs.classfilter.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
scala.*
net.impleri.playerskills.*

0 comments on commit 45b6689

Please sign in to comment.