feat(onboarding): welcome eligible new players
This commit is contained in:
@@ -2,6 +2,7 @@ package games.dmg.leaf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.Server;
|
||||
@@ -51,6 +52,11 @@ public final class LeafRuntime {
|
||||
);
|
||||
stateManager.saveIfDirty();
|
||||
reconcile(player);
|
||||
LeafSettings settings = settingsProvider.current();
|
||||
Instant onboardingEnd = state.firstJoin().plus(settings.onboardingDays(), ChronoUnit.DAYS);
|
||||
if (settings.enabled() && observedAt.isBefore(onboardingEnd)) {
|
||||
player.sendMessage(LeafText.color(settings.welcomeMessage()));
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.contains;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -43,6 +44,49 @@ final class LeafRuntimeTest {
|
||||
verify(protection, org.mockito.Mockito.times(2)).apply(player, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void welcomesPlayersOnEachJoinOnlyDuringTheConfiguredWindow() throws Exception {
|
||||
UUID playerId = UUID.randomUUID();
|
||||
Player player = player(playerId, "Alex");
|
||||
Server server = mock(Server.class);
|
||||
when(server.getPlayer(playerId)).thenReturn(player);
|
||||
LeafRuntime runtime = runtime(
|
||||
server,
|
||||
mock(LeafProtection.class),
|
||||
temporaryDirectory.resolve("welcome.yml")
|
||||
);
|
||||
Instant firstJoin = Instant.parse("2026-08-01T00:00:00Z");
|
||||
|
||||
runtime.observe(player, firstJoin);
|
||||
runtime.observe(player, firstJoin.plusSeconds(6 * 86_400L));
|
||||
runtime.observe(player, firstJoin.plusSeconds(7 * 86_400L));
|
||||
|
||||
verify(player, times(2)).sendMessage(contains("/leaf on, /leaf off, or /leaf status"));
|
||||
verify(player, times(2)).sendMessage(contains("Attacking another player opts you out"));
|
||||
assertEquals(firstJoin, runtime.status(playerId).firstJoin());
|
||||
}
|
||||
|
||||
@Test
|
||||
void suppressesWelcomeWhileLeafIsGloballyDisabled() throws Exception {
|
||||
UUID playerId = UUID.randomUUID();
|
||||
Player player = player(playerId, "Alex");
|
||||
Server server = mock(Server.class);
|
||||
when(server.getPlayer(playerId)).thenReturn(player);
|
||||
LeafRuntime runtime = new LeafRuntime(
|
||||
server,
|
||||
new LeafSettingsProvider(LeafSettings.from(Map.of("enabled", false))),
|
||||
new LeafStateManager(new YamlLeafStateRepository(
|
||||
temporaryDirectory.resolve("disabled-welcome.yml")
|
||||
)),
|
||||
mock(LeafProtection.class),
|
||||
mock(LeafIdentity.class)
|
||||
);
|
||||
|
||||
runtime.observe(player, Instant.parse("2026-08-01T00:00:00Z"));
|
||||
|
||||
verify(player, never()).sendMessage(contains("Leaf protection is available"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void lockedPlayerCannotChangeTheirChoice() throws Exception {
|
||||
UUID playerId = UUID.randomUUID();
|
||||
|
||||
Reference in New Issue
Block a user