feat: implemented player context management
This commit is contained in:
parent
5253b89779
commit
c6b6217588
@ -5,9 +5,13 @@ import lombok.experimental.UtilityClass;
|
|||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
|
||||||
import net.minestom.server.event.player.PlayerDisconnectEvent;
|
import net.minestom.server.event.player.PlayerDisconnectEvent;
|
||||||
import ru.dragonestia.msb3.api.entity.PickableItem;
|
import ru.dragonestia.msb3.api.entity.PickableItem;
|
||||||
import ru.dragonestia.msb3.api.item.ItemUtil;
|
import ru.dragonestia.msb3.api.item.ItemUtil;
|
||||||
|
import ru.dragonestia.msb3.api.player.MsbPlayer;
|
||||||
|
import ru.dragonestia.msb3.api.player.PlayerContextManager;
|
||||||
|
import ru.dragonestia.msb3.api.player.defaults.KeyedBossBarContext;
|
||||||
import ru.dragonestia.msb3.api.resource.DialogueResources;
|
import ru.dragonestia.msb3.api.resource.DialogueResources;
|
||||||
import ru.dragonestia.msb3.api.resource.MonologueResources;
|
import ru.dragonestia.msb3.api.resource.MonologueResources;
|
||||||
import ru.dragonestia.msb3.api.ui.BlackScreen;
|
import ru.dragonestia.msb3.api.ui.BlackScreen;
|
||||||
@ -78,11 +82,7 @@ public final class ServerBootstrap {
|
|||||||
compileResourcePack();
|
compileResourcePack();
|
||||||
initializer.onResourcePackCompiled(Resources.getResourcePack());
|
initializer.onResourcePackCompiled(Resources.getResourcePack());
|
||||||
|
|
||||||
MinecraftServer.getGlobalEventHandler().addListener(PlayerDisconnectEvent.class, event -> {
|
initPlayerContextManager();
|
||||||
var player = event.getPlayer();
|
|
||||||
|
|
||||||
KeyedBossBars.hideAll(player);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initDefaultModules() {
|
private void initDefaultModules() {
|
||||||
@ -153,4 +153,23 @@ public final class ServerBootstrap {
|
|||||||
Resources.getResourcePack().language(Language.language(Key.key("minecraft", lang), locales));
|
Resources.getResourcePack().language(Language.language(Key.key("minecraft", lang), locales));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initPlayerContextManager() {
|
||||||
|
MinecraftServer.getConnectionManager().setPlayerProvider(PlayerContextManager::create);
|
||||||
|
|
||||||
|
MinecraftServer.getGlobalEventHandler().addListener(AsyncPlayerConfigurationEvent.class, event -> {
|
||||||
|
var player = (MsbPlayer) event.getPlayer();
|
||||||
|
|
||||||
|
log.info("Connected player {} (uuid: {}, address: {})", player.getUsername(), player.getUuid(), player.getPlayerConnection().getRemoteAddress());
|
||||||
|
player.initContexts();
|
||||||
|
}).addListener(PlayerDisconnectEvent.class, event -> {
|
||||||
|
var player = (MsbPlayer) event.getPlayer();
|
||||||
|
|
||||||
|
log.info("Disconnected player {} (uuid: {}, address: {})", player.getUsername(), player.getUuid(), player.getPlayerConnection().getRemoteAddress());
|
||||||
|
player.disposeContexts();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Default contexts
|
||||||
|
PlayerContextManager.registerContext(KeyedBossBarContext.class, KeyedBossBarContext::new);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,45 @@
|
|||||||
|
package ru.dragonestia.msb3.api.player;
|
||||||
|
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.network.player.GameProfile;
|
||||||
|
import net.minestom.server.network.player.PlayerConnection;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class MsbPlayer extends Player {
|
||||||
|
|
||||||
|
private final Map<String, PlayerContext> contexts = new HashMap<>();
|
||||||
|
|
||||||
|
public MsbPlayer(@NotNull PlayerConnection playerConnection, @NotNull GameProfile gameProfile) {
|
||||||
|
super(playerConnection, gameProfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void putContext(PlayerContext ctx) {
|
||||||
|
contexts.put(ctx.getClass().getName(), ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T extends PlayerContext> T getContext(Class<T> clazz) {
|
||||||
|
return (T) contexts.get(clazz.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initContexts() {
|
||||||
|
for (var entry: contexts.entrySet()) {
|
||||||
|
var ctxKey = entry.getKey();
|
||||||
|
var ctx = entry.getValue();
|
||||||
|
|
||||||
|
ctx.init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disposeContexts() {
|
||||||
|
for (var entry: contexts.entrySet()) {
|
||||||
|
var ctxKey = entry.getKey();
|
||||||
|
var ctx = entry.getValue();
|
||||||
|
|
||||||
|
ctx.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package ru.dragonestia.msb3.api.player;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public abstract class PlayerContext {
|
||||||
|
|
||||||
|
private final MsbPlayer player;
|
||||||
|
|
||||||
|
public PlayerContext(MsbPlayer player) {
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void init();
|
||||||
|
|
||||||
|
public abstract void dispose();
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package ru.dragonestia.msb3.api.player;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.network.player.GameProfile;
|
||||||
|
import net.minestom.server.network.player.PlayerConnection;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
@Log4j2
|
||||||
|
@UtilityClass
|
||||||
|
public class PlayerContextManager {
|
||||||
|
|
||||||
|
private final Map<String, Function<MsbPlayer, ? extends PlayerContext>> contexts = new HashMap<>();
|
||||||
|
|
||||||
|
public MsbPlayer create(@NotNull PlayerConnection playerConnection, @NotNull GameProfile gameProfile) {
|
||||||
|
var player = new MsbPlayer(playerConnection, gameProfile);
|
||||||
|
|
||||||
|
for (var entry: contexts.entrySet()) {
|
||||||
|
var ctxKey = entry.getKey();
|
||||||
|
var ctx = entry.getValue().apply(player);
|
||||||
|
|
||||||
|
player.putContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerContext(Class<? extends PlayerContext> clazz, Function<MsbPlayer, ? extends PlayerContext> ctxProvider) {
|
||||||
|
var key = clazz.getName();
|
||||||
|
var prev = contexts.put(key, ctxProvider);
|
||||||
|
|
||||||
|
if (prev != null) {
|
||||||
|
log.warn("Duplicate context registration for {}", key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends PlayerContext> T getContext(Player player, Class<T> clazz) {
|
||||||
|
return ((MsbPlayer) player).getContext(clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package ru.dragonestia.msb3.api.player.defaults;
|
||||||
|
|
||||||
|
import net.kyori.adventure.bossbar.BossBar;
|
||||||
|
import ru.dragonestia.msb3.api.player.MsbPlayer;
|
||||||
|
import ru.dragonestia.msb3.api.player.PlayerContext;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class KeyedBossBarContext extends PlayerContext {
|
||||||
|
|
||||||
|
private final Map<String, BossBar> bossBars = new HashMap<>();
|
||||||
|
|
||||||
|
public KeyedBossBarContext(MsbPlayer player) {
|
||||||
|
super(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
hideAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hideAll() {
|
||||||
|
bossBars.forEach((barId, bossBar) -> getPlayer().hideBossBar(bossBar));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hide(String bossBarId) {
|
||||||
|
var bossBar = bossBars.remove(bossBarId);
|
||||||
|
if (bossBar == null) return;
|
||||||
|
|
||||||
|
getPlayer().hideBossBar(bossBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BossBar show(String bossBarId, BossBar bossBar) {
|
||||||
|
var prev = bossBars.put(bossBarId, bossBar);
|
||||||
|
if (prev != null) getPlayer().hideBossBar(prev);
|
||||||
|
getPlayer().showBossBar(bossBar);
|
||||||
|
return bossBar;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,13 +5,11 @@ import net.kyori.adventure.bossbar.BossBar;
|
|||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
|
import ru.dragonestia.msb3.api.player.PlayerContextManager;
|
||||||
|
import ru.dragonestia.msb3.api.player.defaults.KeyedBossBarContext;
|
||||||
import ru.dragonestia.msb3.api.util.ResourceFromJar;
|
import ru.dragonestia.msb3.api.util.ResourceFromJar;
|
||||||
import ru.dragonestia.msb3.resource.Resources;
|
import ru.dragonestia.msb3.resource.Resources;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class KeyedBossBars {
|
public class KeyedBossBars {
|
||||||
|
|
||||||
@ -24,34 +22,23 @@ public class KeyedBossBars {
|
|||||||
ResourceFromJar.of("glyphs/navigator/notched_20_progress.png"));
|
ResourceFromJar.of("glyphs/navigator/notched_20_progress.png"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<UUID, Map<String, BossBar>> bars = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public void hideAll(Player player) {
|
public void hideAll(Player player) {
|
||||||
var map = bars.remove(player.getUuid());
|
contextOf(player).hideAll();
|
||||||
if (map == null) return;
|
|
||||||
|
|
||||||
map.forEach((barId, bossBar) -> player.hideBossBar(bossBar));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hide(Player player, String bossBarId) {
|
public void hide(Player player, String bossBarId) {
|
||||||
var map = bars.get(player.getUuid());
|
contextOf(player).hide(bossBarId);
|
||||||
if (map == null) return;
|
|
||||||
|
|
||||||
var bossBar = map.remove(bossBarId);
|
|
||||||
if (bossBar == null) return;
|
|
||||||
|
|
||||||
player.hideBossBar(bossBar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BossBar show(Player player, String bossBarId, BossBar bossBar) {
|
public BossBar show(Player player, String bossBarId, BossBar bossBar) {
|
||||||
var playerBars = bars.computeIfAbsent(player.getUuid(), uuid -> new ConcurrentHashMap<>());
|
return contextOf(player).show(bossBarId, bossBar);
|
||||||
var prev = playerBars.put(bossBarId, bossBar);
|
|
||||||
if (prev != null) player.hideBossBar(prev);
|
|
||||||
player.showBossBar(bossBar);
|
|
||||||
return bossBar;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BossBar showText(Player player, String bossBarId, Component text) {
|
public BossBar showText(Player player, String bossBarId, Component text) {
|
||||||
return show(player, bossBarId, BossBar.bossBar(text, 1, BossBar.Color.WHITE, BossBar.Overlay.PROGRESS));
|
return show(player, bossBarId, BossBar.bossBar(text, 1, BossBar.Color.WHITE, BossBar.Overlay.PROGRESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private KeyedBossBarContext contextOf(Player player) {
|
||||||
|
return PlayerContextManager.getContext(player, KeyedBossBarContext.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user