Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions battle/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Battle
1 change: 1 addition & 0 deletions blocksumo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Block Sumo
73 changes: 73 additions & 0 deletions core/src/main/java/dev/emortal/minestom/core/utils/Menu.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package dev.emortal.minestom.core.utils;

import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import net.minestom.server.entity.Player;
import net.minestom.server.event.EventListener;
import net.minestom.server.event.inventory.InventoryPreClickEvent;
import net.minestom.server.event.trait.InventoryEvent;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.item.ItemStack;

import java.util.function.Consumer;

public abstract class Menu {
protected final Player player;
protected final Inventory inventory;
protected final Int2ObjectMap<EventListener<? extends InventoryEvent>> listeners;

protected Menu(Player player, InventoryType type, String title) {
this.player = player;
this.inventory = new Inventory(type, title);
this.listeners = new Int2ObjectArrayMap<>();
}

public final Player getPlayer() {
return this.player;
}

public final Inventory getInventory() {
return this.inventory;
}

protected final void set(int slot, ItemStack itemStack, Consumer<Click> handler) {
// clean up old listeners when replacing an item
for (var listener : this.listeners.int2ObjectEntrySet()) {
if (listener.getIntKey() != slot) continue;
this.inventory.eventNode().removeListener(listener.getValue());
}

this.listeners.remove(slot);

// add new listeners
this.inventory.setItemStack(slot, itemStack);
var listener = this.eventListener(slot, handler);
this.inventory.eventNode().addListener(listener);
this.listeners.put(slot, listener);
}

protected final void set(int slot, ItemStack itemStack) {
this.set(slot, itemStack, _ -> {});
}

protected final void add(ItemStack itemStack) {
this.inventory.addItemStack(itemStack);
}

protected final void clear() {
this.inventory.clear();
this.listeners.forEach((_, listener) -> this.inventory.eventNode().removeListener(listener));
this.listeners.clear();
}

private EventListener<InventoryPreClickEvent> eventListener(int slot, Consumer<Click> handler) {
return EventListener.of(InventoryPreClickEvent.class, event -> {
if (event.getSlot() == slot) {
event.setCancelled(true);
handler.accept(event.getClick());
}
});
}
}
1 change: 1 addition & 0 deletions lazertag/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# LazerTag
Empty file added lobby/README.md
Empty file.
35 changes: 19 additions & 16 deletions lobby/src/main/java/dev/emortal/minestom/lobby/LobbyEvents.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package dev.emortal.minestom.lobby;

import dev.emortal.api.modules.ModuleManager;
import dev.emortal.minestom.core.module.core.playerprovider.EmortalPlayer;
import dev.emortal.minestom.lobby.emote.Emote;
import dev.emortal.minestom.lobby.emote.EmoteMenu;
import dev.emortal.minestom.lobby.gadget.Fireball;
import dev.emortal.minestom.lobby.gadget.Gadget;
import dev.emortal.minestom.lobby.gadget.LightningRod;
import dev.emortal.minestom.lobby.gadget.Trumpet;
import dev.emortal.minestom.lobby.gadget.blaster.InkBlaster;
import dev.emortal.minestom.lobby.gadget.lobber.BlockLobber;
import dev.emortal.minestom.lobby.game.ServerSelectorMenu;
import dev.emortal.minestom.lobby.util.CustomModels;
import dev.emortal.minestom.lobby.util.MusicPlayerInventory;
import dev.emortal.minestom.lobby.util.MusicPlayerMenu;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
Expand All @@ -31,21 +34,17 @@
import java.util.List;

public final class LobbyEvents {
public static final Tag<@NotNull Boolean> SERVER_SELECTOR_TAG = Tag.Boolean("serverSelector");
public static final ItemStack SERVER_SELECTOR_ITEM = ItemStack.builder(Material.COMPASS)
.set(DataComponents.ITEM_NAME, Component.text("Server Selector", NamedTextColor.GOLD).decoration(TextDecoration.ITALIC, false))
.set(SERVER_SELECTOR_TAG, true)
.build();
public static final Tag<@NotNull Boolean> MUSIC_PLAYER_TAG = Tag.Boolean("musicPlayer");

public static final ItemStack MUSIC_PLAYER_ITEM = ItemStack.builder(Material.JUKEBOX)
.set(DataComponents.ITEM_NAME, Component.text("Music Player", NamedTextColor.LIGHT_PURPLE).decoration(TextDecoration.ITALIC, false))
.set(MUSIC_PLAYER_TAG, true)
.build();
public static final Tag<@NotNull Boolean> EMOTES_TAG = Tag.Boolean("emotes");

public static final ItemStack EMOTES_ITEM = ItemStack.builder(Material.PHANTOM_MEMBRANE)
.itemModel(CustomModels.EMOTES.getModelId())
.set(DataComponents.ITEM_NAME, Component.text("Emotes", NamedTextColor.AQUA).decoration(TextDecoration.ITALIC, false))
.set(EMOTES_TAG, true)
.build();

private static final String EMORTAL_UUID = "7bd5b459-1e6b-4753-8274-1fbd2fe9a4d5";
Expand All @@ -59,9 +58,9 @@ public final class LobbyEvents {
// new BubbleBlower()
);

public static void registerGeneric(@NotNull EventNode<@NotNull Event> eventNode, @NotNull Instance instance) {
public static void registerGeneric(LobbyModule lobbyModule, @NotNull EventNode<@NotNull Event> eventNode, @NotNull Instance instance) {
eventNode.addListener(PlayerSpawnEvent.class, event -> onSpawn(event.getPlayer(), event.getInstance(), instance));
eventNode.addListener(PlayerUseItemEvent.class, LobbyEvents::onItemUse);
eventNode.addListener(PlayerUseItemEvent.class, event -> onItemUse(lobbyModule, event));

for (Gadget gadget : GADGETS) {
gadget.registerListeners(eventNode);
Expand Down Expand Up @@ -96,23 +95,27 @@ public static void onSpawn(@NotNull Player player, @NotNull Instance spawnInstan
player.setTag(LobbyTags.LOBBABLE, true);
}

private static void onItemUse(@NotNull PlayerUseItemEvent event) {
private static void onItemUse(LobbyModule lobbyModule, @NotNull PlayerUseItemEvent event) {
if (event.getHand() != PlayerHand.MAIN) return;

Player player = event.getPlayer();
ItemStack mainHandItem = player.getItemInMainHand();
if (mainHandItem.hasTag(MUSIC_PLAYER_TAG)) {

if (SERVER_SELECTOR_ITEM.equals(mainHandItem)) {
cancel(event);
player.openInventory(MusicPlayerInventory.getInventory());
ServerSelectorMenu menu = new ServerSelectorMenu(player, lobbyModule.matchmaker, lobbyModule.playerTracker, lobbyModule.configProvider);
player.openInventory(menu.getInventory());
}

if (mainHandItem.hasTag(EMOTES_TAG)) {
if (MUSIC_PLAYER_ITEM.equals(mainHandItem)) {
cancel(event);
Emote.openInventory(player);
player.openInventory(new MusicPlayerMenu(player).getInventory());
}



if (EMOTES_ITEM.equals(mainHandItem)) {
cancel(event);
player.openInventory(new EmoteMenu(player).getInventory());
}
}

public static void registerProtectionEvents(@NotNull EventNode<@NotNull Event> eventNode, @NotNull Instance spawnInstance) {
Expand Down
41 changes: 22 additions & 19 deletions lobby/src/main/java/dev/emortal/minestom/lobby/LobbyModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import dev.emortal.api.modules.annotation.ModuleData;
import dev.emortal.api.modules.env.ModuleEnvironment;
import dev.emortal.api.service.matchmaker.MatchmakerService;
import dev.emortal.api.service.playertracker.PlayerTrackerService;
import dev.emortal.api.utils.GrpcStubCollection;
import dev.emortal.minestom.core.module.MinestomModule;
import dev.emortal.minestom.core.module.kubernetes.KubernetesModule;
Expand All @@ -17,7 +18,6 @@
import dev.emortal.minestom.lobby.emote.Emote;
import dev.emortal.minestom.lobby.events.EventManager;
import dev.emortal.minestom.lobby.features.*;
import dev.emortal.minestom.lobby.game.ServerSelector;
import dev.emortal.minestom.lobby.util.PolarConvertingLoader;
import net.hollowcube.polar.ChunkSelector;
import net.minestom.server.MinecraftServer;
Expand All @@ -31,6 +31,7 @@
import net.minestom.server.instance.block.BlockManager;
import net.minestom.server.network.packet.server.play.TeamsPacket;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -44,6 +45,10 @@ public final class LobbyModule extends MinestomModule {
public static final Pos SPAWN_POINT = new Pos(0.5, 66, 0.5, 180f, 0f);
private static final int SPAWN_CHUNK_RADIUS = 5;

@Nullable MatchmakerService matchmaker;
@Nullable PlayerTrackerService playerTracker;
ConfigProvider<GameModeConfig> configProvider;

LobbyModule(@NotNull ModuleEnvironment environment) {
super(environment);
}
Expand Down Expand Up @@ -71,16 +76,30 @@ public boolean onLoad() {
this.spawnFeatures(instance);

LiveConfigModule liveConfigModule = this.environment.moduleProvider().getModule(LiveConfigModule.class);
if (liveConfigModule != null) this.loadSelectorAndNpcs(liveConfigModule, instance);

if (liveConfigModule != null) {
this.configProvider = liveConfigModule.getGameModes();

if (this.configProvider == null) {
LOGGER.warn("GameModeCollection is not present in LiveConfigModule");
} else {
Collection<GameModeConfig> allConfigs = this.configProvider.allConfigs();
LOGGER.info("Loaded modes ({}): {}", allConfigs.size(), allConfigs.stream().map(GameModeConfig::friendlyName).collect(Collectors.joining(", ")));
LOGGER.debug("Game modes: {}", allConfigs);
this.matchmaker = GrpcStubCollection.getMatchmakerService().orElse(null);
this.playerTracker = GrpcStubCollection.getPlayerTrackerService().orElse(null);
}
}

MessagingModule messagingModule = this.environment.moduleProvider().getModule(MessagingModule.class);

if (messagingModule != null) GrpcStubCollection.getPartyService().ifPresent(partyService -> {
EventNode<@NotNull PlayerEvent> eventManagerNode = EventNode.type("event-manager", EventFilter.PLAYER);
MinecraftServer.getGlobalEventHandler().addChild(eventManagerNode);
new EventManager(messagingModule, partyService, eventManagerNode, instance);
});

LobbyEvents.registerGeneric(this.eventNode, instance);
LobbyEvents.registerGeneric(this, this.eventNode, instance);
LobbyEvents.registerProtectionEvents(this.eventNode, instance);

CommandManager commandManager = MinecraftServer.getCommandManager();
Expand Down Expand Up @@ -114,22 +133,6 @@ private void spawnFeatures(@NotNull Instance instance) {
new ModelDecorationFeature().register(instance);
}

private void loadSelectorAndNpcs(@NotNull LiveConfigModule module, @NotNull Instance instance) {
ConfigProvider<GameModeConfig> gameModes = module.getGameModes();
if (gameModes == null) {
LOGGER.warn("GameModeCollection is not present in LiveConfigModule");
return;
}

Collection<GameModeConfig> allConfigs = gameModes.allConfigs();

LOGGER.info("Loaded modes ({}): {}", allConfigs.size(), allConfigs.stream().map(GameModeConfig::friendlyName).collect(Collectors.joining(", ")));
LOGGER.debug("Game modes: {}", allConfigs);

MatchmakerService matchmaker = GrpcStubCollection.getMatchmakerService().orElse(null);
new ServerSelector(instance, matchmaker, GrpcStubCollection.getPlayerTrackerService().orElse(null), this.eventNode, gameModes);
}

private void loadKubernetesFeatures() {
KubernetesModule kubernetes = this.getOptionalModule(KubernetesModule.class);
if (kubernetes == null || kubernetes.getAgonesSdk() == null) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ public class Emote {
private static final Path MODEL_PATH = Path.of("emotes.bbmodel");
public static BBModel MODEL;

private static final EmoteInventory INVENTORY = new EmoteInventory();
private static final Tag<@NotNull EmoteTask> TASK_TAG = Tag.Transient("emoteTask");

public static void init(EventNode<@NotNull Event> eventNode) {
Expand Down Expand Up @@ -59,11 +58,6 @@ public static void play(Player player, Type emote) {
player.setTag(TASK_TAG, emoteTask);
}

public static void openInventory(Player player) {
player.openInventory(INVENTORY);
}


public static class EmoteTask implements Supplier<TaskSchedule> {
private final Pos originalPos;
private int ticks = 0;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package dev.emortal.minestom.lobby.emote;

import dev.emortal.minestom.core.utils.Menu;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import net.minestom.server.component.DataComponents;
import net.minestom.server.entity.Player;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;

public class EmoteMenu extends Menu {
public EmoteMenu(Player player) {
super(player, InventoryType.CHEST_1_ROW, "Emotes");

int slotI = 0;

for (Emote.Type emote : Emote.Type.values()) {
Component itemName = Component.text(emote.getFriendlyName(), NamedTextColor.WHITE).decoration(TextDecoration.ITALIC, false);

this.set(slotI, ItemStack.of(Material.DIAMOND).with(DataComponents.ITEM_NAME, itemName), _ -> {
Emote.stop(player);

player.scheduleNextTick(_ -> {
Emote.play(player, emote);
player.setHeldItemSlot((byte) 2);
});

player.closeInventory();
});

slotI++;
}

ItemStack stopItem = ItemStack.of(Material.BARRIER)
.with(DataComponents.ITEM_NAME, Component.text("Stop", NamedTextColor.RED));

this.set(8, stopItem, _ -> Emote.stop(this.player));
}
}
Loading