diff --git a/core/src/main/java/org/phantazm/core/hologram/BasicPaginatedHologram.java b/core/src/main/java/org/phantazm/core/hologram/BasicPaginatedHologram.java index ef59a76b0..807669894 100644 --- a/core/src/main/java/org/phantazm/core/hologram/BasicPaginatedHologram.java +++ b/core/src/main/java/org/phantazm/core/hologram/BasicPaginatedHologram.java @@ -113,7 +113,10 @@ public void addPage(@NotNull Collection contents, Holog viewableHologram.addAll(contents); this.pages.add(viewableHologram); - viewableHologram.setInstance(instance); + + if (instance != null) { + viewableHologram.setInstance(instance); + } } } @@ -178,4 +181,16 @@ public void clear() { pages.clear(); } } + + @Override + public void destroy() { + synchronized (sync) { + for (ViewableHologram hologram : pages) { + hologram.destroy(); + } + + pages.clear(); + this.instance = null; + } + } } diff --git a/core/src/main/java/org/phantazm/core/hologram/Hologram.java b/core/src/main/java/org/phantazm/core/hologram/Hologram.java index b109c8b8a..fdf0b2e87 100644 --- a/core/src/main/java/org/phantazm/core/hologram/Hologram.java +++ b/core/src/main/java/org/phantazm/core/hologram/Hologram.java @@ -237,6 +237,8 @@ default boolean addAllFormats(@NotNull Collection formatString @NotNull Component getComponent(int index); + void destroy(); + /** * Ways that holograms may be aligned. */ diff --git a/core/src/main/java/org/phantazm/core/hologram/InstanceHologram.java b/core/src/main/java/org/phantazm/core/hologram/InstanceHologram.java index e4256d756..46e4994d2 100644 --- a/core/src/main/java/org/phantazm/core/hologram/InstanceHologram.java +++ b/core/src/main/java/org/phantazm/core/hologram/InstanceHologram.java @@ -177,6 +177,14 @@ public boolean addAllFormats(@NotNull Collection formatStrings } } + @Override + public void destroy() { + synchronized (sync) { + clear0(); + this.instance = null; + } + } + @Override public @NotNull Line get(int index) { synchronized (sync) { @@ -222,14 +230,18 @@ public void add(int index, @NotNull Line line) { } } + private void clear0() { + for (Entry entry : entries) { + entry.entity.remove(); + } + entries.clear(); + updateArmorStands(); + } + @Override public void clear() { synchronized (sync) { - for (Entry entry : entries) { - entry.entity.remove(); - } - entries.clear(); - updateArmorStands(); + clear0(); } } diff --git a/core/src/main/java/org/phantazm/core/hologram/PaginatedHologram.java b/core/src/main/java/org/phantazm/core/hologram/PaginatedHologram.java index eac81238f..caa24dd79 100644 --- a/core/src/main/java/org/phantazm/core/hologram/PaginatedHologram.java +++ b/core/src/main/java/org/phantazm/core/hologram/PaginatedHologram.java @@ -36,4 +36,6 @@ public interface PaginatedHologram { @NotNull Point location(); void clear(); + + void destroy(); } diff --git a/core/src/main/java/org/phantazm/core/hologram/ViewableHologram.java b/core/src/main/java/org/phantazm/core/hologram/ViewableHologram.java index 363ce32e7..770e19833 100644 --- a/core/src/main/java/org/phantazm/core/hologram/ViewableHologram.java +++ b/core/src/main/java/org/phantazm/core/hologram/ViewableHologram.java @@ -15,7 +15,6 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.CompletableFuture; -import java.util.function.BiConsumer; import java.util.function.Predicate; /** @@ -110,7 +109,6 @@ public void updateNewViewer(@NotNull Player player) { * alignment, and only to players who satisfy the given predicate. * * @param location the location of the instance - * @param gap the distance between separate hologram messages * @param alignment the alignment method * @param canRender the predicate used to determine if this hologram should be visible */ @@ -125,7 +123,6 @@ public ViewableHologram(@NotNull Point location, @NotNull Alignment alignment, * alignment {@link Alignment#UPPER}, and only to players who satisfy the given predicate. * * @param location the location to render holograms - * @param gap the distance between separate hologram messages * @param canRender the predicate used to determine if this hologram should be visible */ public ViewableHologram(@NotNull Point location, @NotNull Predicate canRender) { diff --git a/core/src/main/java/org/phantazm/core/leaderboard/Leaderboard.java b/core/src/main/java/org/phantazm/core/leaderboard/Leaderboard.java index fbdc8d774..21aac3624 100644 --- a/core/src/main/java/org/phantazm/core/leaderboard/Leaderboard.java +++ b/core/src/main/java/org/phantazm/core/leaderboard/Leaderboard.java @@ -1,7 +1,10 @@ package org.phantazm.core.leaderboard; +import net.minestom.server.instance.Instance; +import org.jetbrains.annotations.NotNull; + public interface Leaderboard { - void show(); + void show(@NotNull Instance instance); void hide(); } diff --git a/core/src/main/java/org/phantazm/core/leaderboard/ZombiesBestTimeLeaderboard.java b/core/src/main/java/org/phantazm/core/leaderboard/ZombiesBestTimeLeaderboard.java index 275311725..992b6b358 100644 --- a/core/src/main/java/org/phantazm/core/leaderboard/ZombiesBestTimeLeaderboard.java +++ b/core/src/main/java/org/phantazm/core/leaderboard/ZombiesBestTimeLeaderboard.java @@ -57,7 +57,6 @@ public class ZombiesBestTimeLeaderboard implements MonoComponent { public record Args( @NotNull Point worldOrigin, @NotNull Executor executor, - @NotNull Instance instance, @NotNull ZombiesLeaderboardDatabase database, @NotNull RoleStore roleStore, @NotNull Function, ? extends @NotNull String> descriptorFunction, @@ -73,7 +72,7 @@ public ZombiesBestTimeLeaderboard(@NotNull Data data, @NotNull @Child("tick_form @Override public @NotNull Leaderboard apply(@NotNull InjectionStore injectionStore) { Args args = injectionStore.get(ARGS_KEY); - return new Impl(data, args.worldOrigin, args.executor, args.instance, args.database, args.roleStore, args.identitySource, + return new Impl(data, args.worldOrigin, args.executor, args.database, args.roleStore, args.identitySource, args.descriptorFunction, tickFormatter); } @@ -100,7 +99,6 @@ private static class Impl implements Leaderboard { private final Data data; private final Point worldOrigin; private final Executor executor; - private final Instance instance; private final ZombiesLeaderboardDatabase database; private final RoleStore roleStore; private final IdentitySource identitySource; @@ -115,13 +113,12 @@ private static class Impl implements Leaderboard { private Entity interactionPoint; private boolean shown; - private Impl(Data data, Point worldOrigin, Executor executor, Instance instance, - ZombiesLeaderboardDatabase database, RoleStore roleStore, IdentitySource identitySource, + private Impl(Data data, Point worldOrigin, Executor executor, ZombiesLeaderboardDatabase database, + RoleStore roleStore, IdentitySource identitySource, Function, ? extends String> descriptorFunction, TickFormatter tickFormatter) { this.data = data; this.worldOrigin = worldOrigin; this.executor = executor; - this.instance = instance; this.database = database; this.roleStore = roleStore; this.identitySource = identitySource; @@ -135,7 +132,6 @@ private Impl(Data data, Point worldOrigin, Executor executor, Instance instance, data.teamSizeToEntryCountMappings.defaultReturnValue(12); - hologram.setInstance(instance); initPageMap(); } @@ -160,7 +156,7 @@ private void removeArmorStand() { } @Override - public void show() { + public void show(@NotNull Instance instance) { if (data.teamSizes.isEmpty() || data.modifiers.isEmpty() || shown) { return; } @@ -170,6 +166,8 @@ public void show() { return; } + hologram.setInstance(instance); + shown = true; initPages(); @@ -187,6 +185,25 @@ public void show() { } } + @Override + public void hide() { + if (data.teamSizes.isEmpty() || data.modifiers.isEmpty() || !shown) { + return; + } + + synchronized (sync) { + if (!shown) { + return; + } + + shown = false; + removeArmorStand(); + + hologram.destroy(); + pageRenderTimes.clear(); + } + } + private Entity makeInteractionEntity() { Entity armorStand = new Entity(EntityType.ARMOR_STAND) { @Override @@ -212,25 +229,6 @@ public void attacked(@NotNull Player player) { return armorStand; } - @Override - public void hide() { - if (data.teamSizes.isEmpty() || data.modifiers.isEmpty() || !shown) { - return; - } - - synchronized (sync) { - if (!shown) { - return; - } - - shown = false; - removeArmorStand(); - - hologram.clear(); - pageRenderTimes.clear(); - } - } - private void interact(@NotNull Player player, @NotNull Point relativePosition, @NotNull Entity armorStand) { double midpoint = armorStand.getPosition().y() + (armorStand.getBoundingBox().height() / 2); int sizeIndex; diff --git a/core/src/main/java/org/phantazm/core/npc/LeaderboardNPC.java b/core/src/main/java/org/phantazm/core/npc/LeaderboardNPC.java new file mode 100644 index 000000000..f77ae791c --- /dev/null +++ b/core/src/main/java/org/phantazm/core/npc/LeaderboardNPC.java @@ -0,0 +1,59 @@ +package org.phantazm.core.npc; + +import com.github.steanky.element.core.annotation.*; +import net.minestom.server.entity.Player; +import net.minestom.server.instance.Instance; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.phantazm.commons.InjectionStore; +import org.phantazm.commons.MonoComponent; +import org.phantazm.core.leaderboard.Leaderboard; + +import java.util.UUID; + +@Model("npc.leaderboard") +@Cache +public class LeaderboardNPC implements MonoComponent { + private final MonoComponent leaderboard; + + @FactoryMethod + public LeaderboardNPC(@NotNull @Child("leaderboard") MonoComponent leaderboard) { + this.leaderboard = leaderboard; + } + + @Override + public @NotNull NPC apply(@NotNull InjectionStore injectionStore) { + return new Impl(leaderboard.apply(injectionStore)); + } + + @DataObject + public record Data(@NotNull @ChildPath("leaderboard") String leaderboard) { + } + + private record Impl(Leaderboard leaderboard) implements NPC { + @Override + public void handleInteraction(@NotNull Player interactor) { + + } + + @Override + public void spawn(@NotNull Instance instance) { + leaderboard.show(instance); + } + + @Override + public void despawn() { + leaderboard.hide(); + } + + @Override + public @Nullable UUID uuid() { + return null; + } + + @Override + public void tick(long time) { + + } + } +} diff --git a/core/src/main/java/org/phantazm/core/scene2/SceneManager.java b/core/src/main/java/org/phantazm/core/scene2/SceneManager.java index e856785ad..12702b578 100644 --- a/core/src/main/java/org/phantazm/core/scene2/SceneManager.java +++ b/core/src/main/java/org/phantazm/core/scene2/SceneManager.java @@ -21,6 +21,7 @@ import org.phantazm.core.event.scene.SceneCreationEvent; import org.phantazm.core.event.scene.SceneJoinEvent; import org.phantazm.core.event.scene.SceneShutdownEvent; +import org.phantazm.stats.Databases; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -484,6 +485,7 @@ private void handleLogin(@NotNull PlayerLoginEvent loginEvent) { joinRequestMap.put(player.getUuid(), LoginEntry.of(loginJoin, result)); loginEvent.setSpawningInstance(result.scene().instance()); + Databases.usernames().submitUsername(player.getUuid(), player.getUsername()); } private void handleTablist(@NotNull PlayerTablistShowEvent tablistEvent) { diff --git a/server/src/main/java/org/phantazm/server/LobbyFeature.java b/server/src/main/java/org/phantazm/server/LobbyFeature.java index ec3e575c5..7e6805558 100644 --- a/server/src/main/java/org/phantazm/server/LobbyFeature.java +++ b/server/src/main/java/org/phantazm/server/LobbyFeature.java @@ -8,6 +8,7 @@ import com.github.steanky.ethylene.mapper.MappingProcessorSource; import com.github.steanky.ethylene.mapper.type.Token; import net.minestom.server.MinecraftServer; +import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.Player; import net.minestom.server.instance.DynamicChunk; import org.jetbrains.annotations.NotNull; @@ -16,6 +17,7 @@ import org.phantazm.commons.FileUtils; import org.phantazm.core.instance.AnvilFileSystemInstanceLoader; import org.phantazm.core.instance.InstanceLoader; +import org.phantazm.core.leaderboard.ZombiesBestTimeLeaderboard; import org.phantazm.core.npc.NPC; import org.phantazm.core.scene2.SceneCreator; import org.phantazm.core.scene2.lobby.Lobby; @@ -81,6 +83,7 @@ public int hashCode() { static void initialize(@NotNull DatabaseContext databaseContext, @NotNull EthyleneContext ethyleneContext, @NotNull DataLoadingContext dataLoadingContext, + @NotNull DatabaseAccessContext databaseAccessContext, @NotNull PlayerContext playerContext, @NotNull ZombiesContext zombiesContext) { MappingProcessorSource mappingProcessorSource = ethyleneContext.mappingProcessorSource(); RoleStore roleStore = playerContext.roles(); @@ -106,8 +109,13 @@ static void initialize(@NotNull DatabaseContext databaseContext, }); }); + ZombiesBestTimeLeaderboard.Args args = new ZombiesBestTimeLeaderboard.Args(Vec.ZERO, + databaseContext.databaseExecutor(), databaseAccessContext.zombiesLeaderboardDatabase(), roleStore, + names -> zombiesContext.modifierHandlerLoader().first().descriptor(names), playerContext.identitySource()); + InjectionStore lobbyStore = InjectionStore.of(InjectionKeys.MODIFIER_LOADER_KEY, - new InjectionKeys.ModifierHandlerLoader(zombiesContext.modifierHandlerLoader())); + new InjectionKeys.ModifierHandlerLoader(zombiesContext.modifierHandlerLoader()), + ZombiesBestTimeLeaderboard.ARGS_KEY, args); lobbyLoader = Loader.loader(() -> { return composite(path -> { diff --git a/server/src/main/java/org/phantazm/server/PhantazmServer.java b/server/src/main/java/org/phantazm/server/PhantazmServer.java index d4dc450cf..a0969f97d 100644 --- a/server/src/main/java/org/phantazm/server/PhantazmServer.java +++ b/server/src/main/java/org/phantazm/server/PhantazmServer.java @@ -290,7 +290,7 @@ private static void initializeFeatures(ConfigContext configContext, EthyleneCont PlayerContext playerContext = new PlayerContext(LoginValidatorFeature.loginValidator(), PermissionFeature.permissionHandler(), viewProvider, PermissionFeature.roleStore(), - PartyFeature.getPartyHolder().uuidToGuild()); + PartyFeature.getPartyHolder().uuidToGuild(), IdentitySource.MOJANG); ChatFeature.initialize(configContext, playerContext); @@ -308,8 +308,8 @@ private static void initializeFeatures(ConfigContext configContext, EthyleneCont ZombiesContext zombiesContext = new ZombiesContext(ZombiesFeature.modifierHandlerLoader()); - LobbyFeature.initialize(databaseContext, ethyleneContext, dataLoadingContext, playerContext, - zombiesContext); + LobbyFeature.initialize(databaseContext, ethyleneContext, dataLoadingContext, databaseAccessContext, + playerContext, zombiesContext); ServerCommandFeature.initialize(configContext, playerContext); ValidationFeature.initialize(playerContext); @@ -412,7 +412,7 @@ private static void syncDb(DatabaseAccessContext databaseAccessContext) { generalDatabase.updateJoin(uuid, firstJoin, lastJoin).join(); } } - } catch (IOException e) { + } catch (IOException ignored) { } } diff --git a/server/src/main/java/org/phantazm/server/context/PlayerContext.java b/server/src/main/java/org/phantazm/server/context/PlayerContext.java index 12bad7945..706fe6001 100644 --- a/server/src/main/java/org/phantazm/server/context/PlayerContext.java +++ b/server/src/main/java/org/phantazm/server/context/PlayerContext.java @@ -2,6 +2,7 @@ import org.jetbrains.annotations.NotNull; import org.phantazm.core.guild.party.Party; +import org.phantazm.core.player.IdentitySource; import org.phantazm.core.player.PlayerViewProvider; import org.phantazm.core.role.RoleStore; import org.phantazm.server.permission.PermissionHandler; @@ -14,5 +15,6 @@ public record PlayerContext(@NotNull LoginValidator loginValiator, @NotNull PermissionHandler permissionHandler, @NotNull PlayerViewProvider playerViewProvider, @NotNull RoleStore roles, - @NotNull Map parties) { + @NotNull Map parties, + @NotNull IdentitySource identitySource) { } diff --git a/stats/src/main/java/org/phantazm/stats/general/JDBCUsernameDatabase.java b/stats/src/main/java/org/phantazm/stats/general/JDBCUsernameDatabase.java index 96621a5ff..ee14b7cf4 100644 --- a/stats/src/main/java/org/phantazm/stats/general/JDBCUsernameDatabase.java +++ b/stats/src/main/java/org/phantazm/stats/general/JDBCUsernameDatabase.java @@ -73,7 +73,7 @@ username VARCHAR(16) NOT NULL, CREATE OR REPLACE EVENT clean_expired_entries ON SCHEDULE EVERY 12 HOUR DO DELETE FROM phantazm_db.username_cache - WHERE (SELECT ROUND(UNIX_TIMESTAMP(CURTIME(4)))) - last_updated > ? + WHERE (SELECT UNIX_TIMESTAMP()) - last_updated > ? """)) { preparedStatement.setLong(1, expireTime.toSeconds()); preparedStatement.execute(); diff --git a/zombies/src/main/java/org/phantazm/zombies/scene2/ZombiesSceneCreator.java b/zombies/src/main/java/org/phantazm/zombies/scene2/ZombiesSceneCreator.java index c691df249..1d043845b 100644 --- a/zombies/src/main/java/org/phantazm/zombies/scene2/ZombiesSceneCreator.java +++ b/zombies/src/main/java/org/phantazm/zombies/scene2/ZombiesSceneCreator.java @@ -190,7 +190,7 @@ public ZombiesSceneCreator(int sceneCap, InjectionStore store = InjectionStore.of(ZombiesBestTimeLeaderboard.ARGS_KEY, new ZombiesBestTimeLeaderboard.Args(VecUtils.toPoint(mapInfo.settings().origin()).add(0.5, 0, 0.5), - leaderboardContext.executor(), instance, leaderboardContext.database(), roleStore, + leaderboardContext.executor(), leaderboardContext.database(), roleStore, modifierHandler::descriptor, identitySource)); Leaderboard bestTimeLeaderboard = leaderboardContext.bestTimeLeaderboard().apply(store); diff --git a/zombies/src/main/java/org/phantazm/zombies/stage/IdleStage.java b/zombies/src/main/java/org/phantazm/zombies/stage/IdleStage.java index 0320caa2e..a942f9dd4 100644 --- a/zombies/src/main/java/org/phantazm/zombies/stage/IdleStage.java +++ b/zombies/src/main/java/org/phantazm/zombies/stage/IdleStage.java @@ -84,7 +84,7 @@ public void onLeave(@NotNull ZombiesPlayer zombiesPlayer) { @Override public void start() { - bestTimeLeaderboard.show(); + bestTimeLeaderboard.show(instance); emptyTicks = 0L; }