Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;

import java.util.List;

/**
* @author theEvilReaper
* @version 1.1.0
* @version 1.2.0
* @since 1.0.0
**/
public final class Messages {
Expand All @@ -34,6 +36,7 @@ public final class Messages {
private static final Component SURVIVOR_JOIN_PART_UPPER;
private static final Component SURVIVOR_JOIN_LOWER_PART;
public static final Component SLENDER_JOIN_PART;
private static final int MAP_ANNOUNCEMENT_MIN_WIDTH = 20;

static {
int forceStartTime = GameConfig.FORCE_START_TIME - 1;
Expand Down Expand Up @@ -171,4 +174,38 @@ public static Component getSurvivorJoinMessage(String pageCount) {
.append(Component.newline())
.append(SURVIVOR_JOIN_LOWER_PART);
}

/**
* Returns a {@link Component} which contains information about which map is used for the game.
*
* @param mapName of the map
* @param builders of the map
* @return the created {@link Component} reference
*/
@Contract(value = "_, _ -> new", pure = true)
public static Component getMapAnnouncementMessage(String mapName, @Nullable List<String> builders) {
boolean hasBuilders = builders != null && !builders.isEmpty();
String joinedBuilders = hasBuilders ? String.join(", ", builders) : "";

int width = Math.max(MAP_ANNOUNCEMENT_MIN_WIDTH, ("Now playing: " + mapName).length());
if (hasBuilders) {
width = Math.max(width, ("Built by: " + joinedBuilders).length());
}
Component separator = Component.text("─".repeat(width), NamedTextColor.DARK_GRAY);

Component message = Component.newline().append(separator)
.append(Component.newline())
.append(Component.text("Now playing: ", NamedTextColor.GRAY))
.append(Component.text(mapName, NamedTextColor.GOLD))
.append(Component.newline());

if (hasBuilders) {
message = message
.append(Component.text("Built by: ", NamedTextColor.GRAY))
.append(Component.text(joinedBuilders, NamedTextColor.AQUA))
.append(Component.newline());
}

return message.append(separator).append(Component.newline());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package net.onelitefeather.cygnus.common;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;

class MessagesTest {

@Test
void testMapAnnouncementWithBuilders() {
Component message = Messages.getMapAnnouncementMessage("Granskoga", List.of("Alice", "Bob"));

assertEquals(
"\n──────────────────────\nNow playing: Granskoga\nBuilt by: Alice, Bob\n──────────────────────\n",
PlainTextComponentSerializer.plainText().serialize(message)
);
}

@Test
void testMapAnnouncementWithNullBuilders() {
Component message = Messages.getMapAnnouncementMessage("Granskoga", null);

assertEquals(
"\n──────────────────────\nNow playing: Granskoga\n──────────────────────\n",
PlainTextComponentSerializer.plainText().serialize(message)
);
}

@Test
void testMapAnnouncementWithEmptyBuilders() {
Component message = Messages.getMapAnnouncementMessage("Granskoga", List.of());

assertEquals(
"\n──────────────────────\nNow playing: Granskoga\n──────────────────────\n",
PlainTextComponentSerializer.plainText().serialize(message)
);
}

@Test
void testMapAnnouncementWidthScalesWithLongestLine() {
Component message = Messages.getMapAnnouncementMessage(
"Very Long Map Name Example",
List.of("Alice", "Bob", "Charlie", "Dave")
);

assertEquals(
"\n───────────────────────────────────────\nNow playing: Very Long Map Name Example\nBuilt by: Alice, Bob, Charlie, Dave\n───────────────────────────────────────\n",
PlainTextComponentSerializer.plainText().serialize(message)
);
}
}
2 changes: 2 additions & 0 deletions game/src/main/java/net/onelitefeather/cygnus/Cygnus.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import net.onelitefeather.cygnus.event.GameStartEvent;
import net.onelitefeather.cygnus.common.page.event.PageSpawnEvent;
import net.onelitefeather.cygnus.listener.game.GameStartListener;
import net.onelitefeather.cygnus.listener.map.GameMapLoadedListener;
import net.onelitefeather.cygnus.listener.page.PageSpawnListener;
import net.onelitefeather.cygnus.listener.view.ViewUpdateListener;
import net.onelitefeather.cygnus.listener.page.PageDiscoveryCompleteListener;
Expand Down Expand Up @@ -144,6 +145,7 @@ private void initListener() {
manager.addListener(GameMapLoadedEvent.class, event ->
this.pageProvider.loadPageData(event.gameMap().getPageFaces())
);
manager.addListener(GameMapLoadedEvent.class, new GameMapLoadedListener());
manager.addListener(PlayerSpawnEvent.class, new PlayerSpawnListener(player -> this.mapProvider.teleportToSpawn(player, false), phaseSupplier));
PlayerQuitListener quitListener = new PlayerQuitListener(phaseSupplier, teamService, this.staminaService, this.gameConfig.minPlayers());
manager.addListener(PlayerDisconnectEvent.class, quitListener);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package net.onelitefeather.cygnus.listener.map;

import net.onelitefeather.cygnus.common.Messages;
import net.onelitefeather.cygnus.common.map.GameMap;
import net.onelitefeather.cygnus.map.event.GameMapLoadedEvent;
import net.theevilreaper.aves.util.Broadcaster;

import java.util.function.Consumer;

public final class GameMapLoadedListener implements Consumer<GameMapLoadedEvent> {

@Override
public void accept(GameMapLoadedEvent event) {
GameMap gameMap = event.gameMap();
Broadcaster.broadcast(Messages.getMapAnnouncementMessage(gameMap.name(), gameMap.builders()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@NotNullByDefault
package net.onelitefeather.cygnus.listener.map;

import org.jetbrains.annotations.NotNullByDefault;
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package net.onelitefeather.cygnus.listener.map;

import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.InstanceContainer;
import net.minestom.server.network.packet.server.play.SystemChatPacket;
import net.minestom.testing.Collector;
import net.minestom.testing.Env;
import net.minestom.testing.TestConnection;
import net.onelitefeather.cygnus.CygnusPlayerTestBase;
import net.onelitefeather.cygnus.common.map.GameMap;
import net.onelitefeather.cygnus.map.event.GameMapLoadedEvent;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Set;

import static org.junit.jupiter.api.Assertions.assertEquals;

class GameMapLoadedListenerTest extends CygnusPlayerTestBase {

@Test
void testBroadcastsMapAnnouncementToOnlinePlayers(@NotNull Env env) {
Instance instance = env.createFlatInstance();
InstanceContainer gameInstance = (InstanceContainer) env.createFlatInstance();

TestConnection connection = env.createConnection();
connection.connect(instance);
Collector<SystemChatPacket> packets = connection.trackIncoming(SystemChatPacket.class);

GameMap gameMap = new GameMap(
"Granskoga",
Pos.ZERO,
Pos.ZERO,
Set.of(),
Set.of(),
List.of("Alice", "Bob")
);

new GameMapLoadedListener().accept(new GameMapLoadedEvent(gameMap, gameInstance));

List<SystemChatPacket> received = packets.collect();
assertEquals(1, received.size(), "Player should have received exactly one map announcement message.");
assertEquals(
"\n──────────────────────\nNow playing: Granskoga\nBuilt by: Alice, Bob\n──────────────────────\n",
PlainTextComponentSerializer.plainText().serialize(received.getFirst().message())
);

env.destroyInstance(instance, true);
env.destroyInstance(gameInstance, true);
}

@Test
void testOmitsBuilderLineWhenMapHasNoBuilders(@NotNull Env env) {
Instance instance = env.createFlatInstance();
InstanceContainer gameInstance = (InstanceContainer) env.createFlatInstance();

TestConnection connection = env.createConnection();
connection.connect(instance);
Collector<SystemChatPacket> packets = connection.trackIncoming(SystemChatPacket.class);

GameMap gameMap = new GameMap(
"Granskoga",
Pos.ZERO,
Pos.ZERO,
Set.of(),
Set.of(),
List.of()
);

new GameMapLoadedListener().accept(new GameMapLoadedEvent(gameMap, gameInstance));

List<SystemChatPacket> received = packets.collect();
assertEquals(1, received.size(), "Player should have received exactly one map announcement message.");
assertEquals(
"\n──────────────────────\nNow playing: Granskoga\n──────────────────────\n",
PlainTextComponentSerializer.plainText().serialize(received.getFirst().message())
);

env.destroyInstance(instance, true);
env.destroyInstance(gameInstance, true);
}
}
Loading