-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use json for storing player data, reapply displays on join
- Loading branch information
1 parent
5645a11
commit 6376d80
Showing
3 changed files
with
83 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 11 additions & 3 deletions
14
src/main/java/com/triassic/geyserdebuginfo/listener/PlayerJoinListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,42 @@ | ||
package com.triassic.geyserdebuginfo.listener; | ||
|
||
import com.triassic.geyserdebuginfo.GeyserDebugInfo; | ||
import com.triassic.geyserdebuginfo.display.DisplayManager; | ||
import com.triassic.geyserdebuginfo.display.DisplayType; | ||
import com.triassic.geyserdebuginfo.manager.PlayerDataManager; | ||
import org.geysermc.event.subscribe.Subscribe; | ||
import org.geysermc.geyser.api.event.bedrock.SessionDisconnectEvent; | ||
import org.geysermc.geyser.api.event.bedrock.SessionJoinEvent; | ||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity; | ||
import org.geysermc.geyser.session.GeyserSession; | ||
|
||
import java.util.Set; | ||
|
||
public class PlayerJoinListener { | ||
|
||
private final DisplayManager displayManager; | ||
private final PlayerDataManager playerDataManager; | ||
|
||
public PlayerJoinListener( | ||
final GeyserDebugInfo instance | ||
) { | ||
this.displayManager = instance.getDisplayManager(); | ||
this.playerDataManager = instance.getPlayerDataManager(); | ||
} | ||
|
||
@Subscribe | ||
public void onJoin(final SessionJoinEvent event) { | ||
final GeyserSession session = (GeyserSession) event.connection(); | ||
final SessionPlayerEntity player = session.getPlayerEntity(); | ||
final Set<DisplayType> enabledDisplays = playerDataManager.getEnabledDisplays(session.playerUuid()); | ||
|
||
// TODO: Re-implement this. | ||
for (DisplayType displayType : enabledDisplays) { | ||
displayManager.subscribePlayer(session, displayType); | ||
} | ||
} | ||
|
||
@Subscribe | ||
public void onDisconnect(final SessionDisconnectEvent event) { | ||
final GeyserSession session = (GeyserSession) event.connection(); | ||
// TODO: Remove Bossbar | ||
// TODO: Clean-up. | ||
} | ||
} |
136 changes: 70 additions & 66 deletions
136
src/main/java/com/triassic/geyserdebuginfo/manager/PlayerDataManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,100 +1,104 @@ | ||
package com.triassic.geyserdebuginfo.manager; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.fasterxml.jackson.databind.SerializationFeature; | ||
import com.triassic.geyserdebuginfo.display.DisplayType; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
import org.geysermc.geyser.api.extension.ExtensionLogger; | ||
import org.yaml.snakeyaml.DumperOptions; | ||
import org.yaml.snakeyaml.Yaml; | ||
|
||
import java.io.File; | ||
import java.io.FileReader; | ||
import java.io.FileWriter; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.UUID; | ||
import java.io.IOException; | ||
import java.util.*; | ||
|
||
public class PlayerDataManager { | ||
|
||
private final File playerDataFile; | ||
private final File playerDataFolder; | ||
private final ExtensionLogger logger; | ||
private final Yaml yaml; | ||
private final Map<UUID, Map<DisplayType, Boolean>> playerDisplayStates; | ||
private final boolean defaultEnabled; | ||
|
||
public PlayerDataManager( | ||
final File dataFolder, | ||
final ExtensionLogger logger, | ||
final boolean defaultEnabled | ||
) { | ||
this.playerDataFile = new File(dataFolder, "playerdata.yml"); | ||
private final ObjectMapper objectMapper; | ||
private final Map<UUID, Set<DisplayType>> playerDisplayStates; | ||
|
||
public PlayerDataManager(File dataFolder, ExtensionLogger logger) { | ||
this.playerDataFolder = new File(dataFolder, "playerdata"); | ||
this.logger = logger; | ||
this.yaml = new Yaml(createDumperOptions()); | ||
this.objectMapper = new ObjectMapper() | ||
.enable(SerializationFeature.INDENT_OUTPUT); | ||
this.playerDisplayStates = new HashMap<>(); | ||
this.defaultEnabled = defaultEnabled; | ||
|
||
load(); | ||
} | ||
if (!playerDataFolder.exists() && !playerDataFolder.mkdirs()) { | ||
logger.error("Failed to create player data folder at " + playerDataFolder.getAbsolutePath()); | ||
} | ||
|
||
private DumperOptions createDumperOptions() { | ||
DumperOptions options = new DumperOptions(); | ||
options.setIndent(2); | ||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); | ||
return options; | ||
loadAll(); | ||
} | ||
|
||
private void load() { | ||
if (!playerDataFile.exists()) return; | ||
|
||
try (FileReader reader = new FileReader(playerDataFile)) { | ||
Map<String, Map<String, Boolean>> data = yaml.load(reader); | ||
if (data != null) { | ||
for (Map.Entry<String, Map<String, Boolean>> entry : data.entrySet()) { | ||
UUID playerUuid = UUID.fromString(entry.getKey()); | ||
Map<DisplayType, Boolean> displayStates = new HashMap<>(); | ||
for (Map.Entry<String, Boolean> stateEntry : entry.getValue().entrySet()) { | ||
displayStates.put(DisplayType.valueOf(stateEntry.getKey()), stateEntry.getValue()); | ||
} | ||
playerDisplayStates.put(playerUuid, displayStates); | ||
private void loadAll() { | ||
File[] files = playerDataFolder.listFiles((dir, name) -> name.endsWith(".json")); | ||
if (files == null) return; | ||
|
||
for (File file : files) { | ||
try { | ||
UUID playerUuid = UUID.fromString(file.getName().replace(".json", "")); | ||
PlayerData data = objectMapper.readValue(file, PlayerData.class); | ||
Set<DisplayType> enabledDisplays = new HashSet<>(); | ||
for (String display : data.getEnabledDisplays()) { | ||
enabledDisplays.add(DisplayType.valueOf(display)); | ||
} | ||
playerDisplayStates.put(playerUuid, enabledDisplays); | ||
} catch (IOException | IllegalArgumentException e) { | ||
logger.error("Failed to load player data from file: " + file.getName(), e); | ||
} | ||
} catch (Throwable error) { | ||
logger.error("Failed to load player data file", error); | ||
} | ||
} | ||
|
||
public void save() { | ||
try (FileWriter writer = new FileWriter(playerDataFile)) { | ||
Map<String, Map<String, Boolean>> data = new HashMap<>(); | ||
for (Map.Entry<UUID, Map<DisplayType, Boolean>> entry : playerDisplayStates.entrySet()) { | ||
UUID playerUuid = entry.getKey(); | ||
Map<String, Boolean> stateMap = new HashMap<>(); | ||
for (Map.Entry<DisplayType, Boolean> stateEntry : entry.getValue().entrySet()) { | ||
Boolean enabled = stateEntry.getValue(); | ||
if (enabled != defaultEnabled) { | ||
stateMap.put(stateEntry.getKey().name(), enabled); | ||
} | ||
} | ||
if (!stateMap.isEmpty()) { | ||
data.put(playerUuid.toString(), stateMap); | ||
} | ||
} | ||
yaml.dump(data, writer); | ||
} catch (Throwable error) { | ||
logger.error("Failed to save player data to file", error); | ||
public void save(UUID playerUuid) { | ||
Set<DisplayType> enabledDisplays = playerDisplayStates.get(playerUuid); | ||
if (enabledDisplays == null) return; | ||
|
||
File playerFile = new File(playerDataFolder, playerUuid + ".json"); | ||
try { | ||
PlayerData data = new PlayerData(); | ||
data.setEnabledDisplays( | ||
enabledDisplays.stream() | ||
.map(DisplayType::name) | ||
.toList() | ||
); | ||
objectMapper.writeValue(playerFile, data); | ||
} catch (IOException e) { | ||
logger.error("Failed to save player data for " + playerUuid, e); | ||
} | ||
} | ||
|
||
public void setDisplayEnabled(UUID playerUuid, DisplayType displayType, boolean enabled) { | ||
playerDisplayStates | ||
.computeIfAbsent(playerUuid, k -> new HashMap<>()) | ||
.put(displayType, enabled); | ||
.computeIfAbsent(playerUuid, k -> new HashSet<>()); | ||
|
||
save(); | ||
if (enabled) { | ||
playerDisplayStates.get(playerUuid).add(displayType); | ||
} else { | ||
playerDisplayStates.get(playerUuid).remove(displayType); | ||
} | ||
|
||
save(playerUuid); | ||
} | ||
|
||
public boolean isDisplayEnabled(UUID playerUuid, DisplayType displayType) { | ||
return playerDisplayStates | ||
.getOrDefault(playerUuid, new HashMap<>()) | ||
.getOrDefault(displayType, defaultEnabled); | ||
.getOrDefault(playerUuid, Collections.emptySet()) | ||
.contains(displayType); | ||
} | ||
|
||
public Set<DisplayType> getEnabledDisplays(UUID playerUuid) { | ||
return Collections.unmodifiableSet( | ||
playerDisplayStates.getOrDefault(playerUuid, Collections.emptySet()) | ||
); | ||
} | ||
|
||
@Setter | ||
@Getter | ||
private static class PlayerData { | ||
private List<String> enabledDisplays = new ArrayList<>(); | ||
|
||
} | ||
} | ||
|