Skip to content

Commit

Permalink
We're going on an Adventure! (EssentialsX#4717)
Browse files Browse the repository at this point in the history
https://user-images.githubusercontent.com/10731363/147530817-f9adc58e-18a5-49ed-84c6-106e51d6948f.mp4
Add support for chat components throughout EssentialsX using the Adventure library.
Translations have been converted to the MiniMessage format, and custom message files will be migrated on startup.
This also introduces new options to allow players to see messages in their own language and for server owners to change the main message colours without editing message files.

Closes EssentialsX#2029
Closes EssentialsX#2391

---------

Co-authored-by: MD <[email protected]>
Co-authored-by: pop4959 <[email protected]>
  • Loading branch information
3 people authored and HarvelsX committed Jun 2, 2024
1 parent 77cce45 commit d399007
Show file tree
Hide file tree
Showing 324 changed files with 25,755 additions and 25,163 deletions.
37 changes: 31 additions & 6 deletions Essentials/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,21 @@ dependencies {
compileOnly('com.github.milkbowl:VaultAPI:1.7') {
exclude group: "org.bukkit", module: "bukkit"
}
compileOnly 'net.luckperms:api:5.0'
compileOnly 'net.luckperms:api:5.3'

api 'io.papermc:paperlib:1.0.6'

api 'org.bstats:bstats-bukkit:2.2.1'

implementation 'org.spongepowered:configurate-yaml:4.1.2'
implementation 'org.checkerframework:checker-qual:3.14.0'
implementation 'org.checkerframework:checker-qual:3.21.0'
implementation 'nu.studer:java-ordered-properties:1.0.4'

implementation 'net.kyori:adventure-api:4.15.0'
implementation 'net.kyori:adventure-text-minimessage:4.15.0'
implementation 'net.kyori:adventure-platform-bukkit:4.3.1'

// Providers
api project(':providers:BaseProviders')
api project(':providers:PaperProvider')
api project(path: ':providers:PaperProvider', configuration: 'shadow')
api project(':providers:FoliaProvider')
api(project(':providers:NMSReflectionProvider')) {
exclude group: "org.bukkit", module: "bukkit"
Expand All @@ -44,8 +47,25 @@ shadowJar {
include (dependency('org.yaml:snakeyaml'))
include (dependency('io.leangen.geantyref:geantyref'))
include (dependency('org.checkerframework:checker-qual'))
include (dependency('nu.studer:java-ordered-properties'))
include (dependency('net.kyori:adventure-api'))
include (dependency('net.kyori:adventure-key'))
include (dependency('net.kyori:examination-api'))
include (dependency('net.kyori:examination-string'))
include (dependency('net.kyori:option'))
include (dependency('net.kyori:adventure-platform-bukkit'))
include (dependency('net.kyori:adventure-platform-api'))
include (dependency('net.kyori:adventure-platform-facet'))
include (dependency('net.kyori:adventure-nbt'))
include (dependency('net.kyori:adventure-text-serializer-bungeecord'))
include (dependency('net.kyori:adventure-text-serializer-gson'))
include (dependency('net.kyori:adventure-text-serializer-gson-legacy-impl'))
include (dependency('net.kyori:adventure-text-serializer-json'))
include (dependency('net.kyori:adventure-text-serializer-json-legacy-impl'))
include (dependency('net.kyori:adventure-text-serializer-legacy'))
include (dependency('net.kyori:adventure-text-minimessage'))
include (project(':providers:BaseProviders'))
include (project(':providers:PaperProvider'))
include (project(path: ':providers:PaperProvider', configuration: 'shadow'))
include (project(':providers:FoliaProvider'))
include (project(':providers:NMSReflectionProvider'))
include (project(':providers:1_8Provider'))
Expand All @@ -57,8 +77,13 @@ shadowJar {
relocate 'org.yaml.snakeyaml', 'com.earth2me.essentials.libs.snakeyaml'
relocate 'io.leangen.geantyref', 'com.earth2me.essentials.libs.geantyref'
relocate 'org.checkerframework', 'com.earth2me.essentials.libs.checkerframework'
relocate 'net.kyori', 'com.earth2me.essentials.libs.kyori'
relocate 'net.essentialsx.temp.adventure', 'net.kyori.adventure'

minimize {
include(dependency('org.checkerframework:checker-qual'))
include(dependency('net.kyori:adventure-api'))
include(dependency('net.kyori:adventure-platform-bukkit'))
include(dependency('net.kyori:adventure-text-minimessage'))
}
}
25 changes: 12 additions & 13 deletions Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import net.ess3.api.IEssentials;
import net.ess3.api.IUser;
import net.ess3.api.InvalidWorldException;
import net.ess3.api.TranslatableException;
import net.ess3.api.events.UserWarpEvent;
import net.ess3.api.events.teleport.PreTeleportEvent;
import net.ess3.api.events.teleport.TeleportWarmupEvent;
Expand All @@ -23,8 +24,6 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import static com.earth2me.essentials.I18n.tl;

public class AsyncTeleport implements IAsyncTeleport {
private final IUser teleportOwner;
private final IEssentials ess;
Expand Down Expand Up @@ -73,7 +72,7 @@ && cooldownApplies()) {
time.setTimeInMillis(lastTime);
time.add(Calendar.SECOND, (int) cooldown);
time.add(Calendar.MILLISECOND, (int) ((cooldown * 1000.0) % 1000.0));
future.completeExceptionally(new Exception(tl("timeBeforeTeleport", DateUtil.formatDateDiff(time.getTimeInMillis()))));
future.completeExceptionally(new TranslatableException("timeBeforeTeleport", DateUtil.formatDateDiff(time.getTimeInMillis())));
return true;
}
}
Expand Down Expand Up @@ -107,7 +106,7 @@ private void warnUser(final IUser user, final double delay) {
final Calendar c = new GregorianCalendar();
c.add(Calendar.SECOND, (int) delay);
c.add(Calendar.MILLISECOND, (int) ((delay * 1000.0) % 1000.0));
user.sendMessage(tl("dontMoveMessage", DateUtil.formatDateDiff(c.getTimeInMillis())));
user.sendTl("dontMoveMessage", DateUtil.formatDateDiff(c.getTimeInMillis()));
}

@Override
Expand All @@ -129,7 +128,7 @@ public void now(final Player entity, final boolean cooldown, final TeleportCause
nowAsync(teleportOwner, target, cause, future);
future.thenAccept(success -> {
if (success) {
teleportOwner.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
teleportOwner.sendTl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ());
}
});
}
Expand All @@ -153,7 +152,7 @@ protected void nowAsync(final IUser teleportee, final ITarget target, final Tele

if (!ess.getSettings().isForcePassengerTeleport() && !teleportee.getBase().isEmpty()) {
if (!ess.getSettings().isTeleportPassengerDismount()) {
future.completeExceptionally(new Exception(tl("passengerTeleportFail")));
future.completeExceptionally(new TranslatableException("passengerTeleportFail"));
return;
}

Expand Down Expand Up @@ -190,7 +189,7 @@ protected void nowAsync(final IUser teleportee, final ITarget target, final Tele
}
}
} else {
future.completeExceptionally(new Exception(tl("unsafeTeleportDestination", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())));
future.completeExceptionally(new TranslatableException("unsafeTeleportDestination", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
return;
}
} else {
Expand Down Expand Up @@ -218,7 +217,7 @@ public void teleport(final Location loc, final Trade chargeFor, final TeleportCa

@Override
public void teleport(final Player entity, final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
teleportOwner.sendMessage(tl("teleportToPlayer", entity.getDisplayName()));
teleportOwner.sendTl("teleportToPlayer", entity.getDisplayName());
teleport(teleportOwner, new PlayerTarget(entity), chargeFor, cause, future);
}

Expand All @@ -233,8 +232,8 @@ public void teleportPlayer(final IUser otherUser, final Player entity, final Tra
teleport(otherUser, target, chargeFor, cause, future);
future.thenAccept(success -> {
if (success) {
otherUser.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
teleportOwner.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
otherUser.sendTl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ());
teleportOwner.sendTl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ());
}
});
}
Expand Down Expand Up @@ -417,9 +416,9 @@ public void warp(final IUser otherUser, String warp, final Trade chargeFor, fina
final String finalWarp = warp;
future.thenAccept(success -> {
if (success) {
otherUser.sendMessage(tl("warpingTo", finalWarp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
otherUser.sendTl("warpingTo", finalWarp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if (!otherUser.equals(teleportOwner)) {
teleportOwner.sendMessage(tl("warpingTo", finalWarp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
teleportOwner.sendTl("warpingTo", finalWarp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
}
}
});
Expand All @@ -435,7 +434,7 @@ public void back(final Trade chargeFor, final CompletableFuture<Boolean> future)
public void back(final IUser teleporter, final Trade chargeFor, final CompletableFuture<Boolean> future) {
tpType = TeleportType.BACK;
final Location loc = teleportOwner.getLastLocation();
teleportOwner.sendMessage(tl("backUsageMsg", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
teleportOwner.sendTl("backUsageMsg", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
teleportOther(teleporter, teleportOwner, new LocationTarget(loc), chargeFor, TeleportCause.COMMAND, future);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

import static com.earth2me.essentials.I18n.tl;

public class AsyncTimedTeleport implements Runnable {
private static final double MOVE_CONSTANT = 0.3;
private final IUser teleportOwner;
Expand Down Expand Up @@ -107,14 +105,14 @@ public void run() {
try {
teleport.cooldown(false);
} catch (final Throwable ex) {
teleportOwner.sendMessage(tl("cooldownWithMessage", ex.getMessage()));
teleportOwner.sendTl("cooldownWithMessage", ex.getMessage());
if (teleportOwner != teleportUser) {
teleportUser.sendMessage(tl("cooldownWithMessage", ex.getMessage()));
teleportUser.sendTl("cooldownWithMessage", ex.getMessage());
}
}
try {
cancelTimer(false);
teleportUser.sendMessage(tl("teleportationCommencing"));
teleportUser.sendTl("teleportationCommencing");

if (timer_chargeFor != null) {
timer_chargeFor.isAffordableFor(teleportOwner);
Expand Down Expand Up @@ -153,9 +151,9 @@ void cancelTimer(final boolean notifyUser) {
try {
timer_task.cancel();
if (notifyUser) {
teleportOwner.sendMessage(tl("pendingTeleportCancelled"));
teleportOwner.sendTl("pendingTeleportCancelled");
if (timer_teleportee != null && !timer_teleportee.equals(teleportOwner.getBase().getUniqueId())) {
ess.getUser(timer_teleportee).sendMessage(tl("pendingTeleportCancelled"));
ess.getUser(timer_teleportee).sendTl("pendingTeleportCancelled");
}
}
} finally {
Expand Down
6 changes: 3 additions & 3 deletions Essentials/src/main/java/com/earth2me/essentials/Backup.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;

import static com.earth2me.essentials.I18n.tl;
import static com.earth2me.essentials.I18n.tlLiteral;

public class Backup implements Runnable {
private transient final Server server;
Expand Down Expand Up @@ -80,7 +80,7 @@ public void run() {
taskLock.complete(new Object());
return;
}
ess.getLogger().log(Level.INFO, tl("backupStarted"));
ess.getLogger().log(Level.INFO, tlLiteral("backupStarted"));
final CommandSender cs = server.getConsoleSender();
server.dispatchCommand(cs, "save-all");
server.dispatchCommand(cs, "save-off");
Expand Down Expand Up @@ -119,7 +119,7 @@ public void run() {
}
active = false;
taskLock.complete(new Object());
ess.getLogger().log(Level.INFO, tl("backupFinished"));
ess.getLogger().log(Level.INFO, tlLiteral("backupFinished"));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package com.earth2me.essentials;

import com.earth2me.essentials.utils.AdventureUtil;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import static com.earth2me.essentials.I18n.tlLiteral;

public class CommandSource {
protected Essentials ess;
protected CommandSender sender;

public CommandSource(final CommandSender base) {
public CommandSource(final Essentials ess, final CommandSender base) {
this.ess = ess;
this.sender = base;
}

Expand All @@ -21,7 +28,40 @@ public final Player getPlayer() {
return null;
}

public final net.ess3.api.IUser getUser(final IEssentials ess) {
public void sendTl(final String tlKey, final Object... args) {
if (isPlayer()) {
//noinspection ConstantConditions
getUser().sendTl(tlKey, args);
return;
}

final String translation = tlLiteral(tlKey, args);
sendComponent(AdventureUtil.miniMessage().deserialize(translation));
}

public String tl(final String tlKey, final Object... args) {
if (isPlayer()) {
//noinspection ConstantConditions
return getUser().playerTl(tlKey, args);
}
return tlLiteral(tlKey, args);
}

public Component tlComponent(final String tlKey, final Object... args) {
if (isPlayer()) {
//noinspection ConstantConditions
return getUser().tlComponent(tlKey, args);
}
final String translation = tlLiteral(tlKey, args);
return AdventureUtil.miniMessage().deserialize(translation);
}

public void sendComponent(final Component component) {
final BukkitAudiences audiences = ess.getBukkitAudience();
audiences.sender(sender).sendMessage(component);
}

public final net.ess3.api.IUser getUser() {
if (sender instanceof Player) {
return ess.getUser((Player) sender);
}
Expand All @@ -42,15 +82,18 @@ public void sendMessage(final String message) {
}
}

public boolean isAuthorized(final String permission, final IEssentials ess) {
return !(sender instanceof Player) || getUser(ess).isAuthorized(permission);
public boolean isAuthorized(final String permission) {
//noinspection ConstantConditions
return !(sender instanceof Player) || getUser().isAuthorized(permission);
}

public String getSelfSelector() {
//noinspection ConstantConditions
return sender instanceof Player ? getPlayer().getName() : "*";
}

public String getDisplayName() {
//noinspection ConstantConditions
return sender instanceof Player ? getPlayer().getDisplayName() : getSender().getName();
}
}
22 changes: 20 additions & 2 deletions Essentials/src/main/java/com/earth2me/essentials/Console.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@

import com.earth2me.essentials.messaging.IMessageRecipient;
import com.earth2me.essentials.messaging.SimpleMessageRecipient;
import com.earth2me.essentials.utils.AdventureUtil;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import java.util.UUID;

import static com.earth2me.essentials.I18n.tl;
import static com.earth2me.essentials.I18n.tlLiteral;

public final class Console implements IMessageRecipient {
public static final String NAME = "Console";
public static final String DISPLAY_NAME = tl("consoleName");
public static final String DISPLAY_NAME = tlLiteral("consoleName");
private static Console instance; // Set in essentials

private final IEssentials ess;
Expand Down Expand Up @@ -63,6 +66,21 @@ public void sendMessage(final String message) {
getCommandSender().sendMessage(message);
}

@Override
public void sendTl(String tlKey, Object... args) {
final String translation = tlLiteral(tlKey, args);

final Audience consoleAudience = ((Essentials) ess).getBukkitAudience().sender(getCommandSender());
final Component component = AdventureUtil.miniMessage()
.deserialize(translation);
consoleAudience.sendMessage(component);
}

@Override
public String tlSender(String tlKey, Object... args) {
return tlLiteral(tlKey, args);
}

@Override
public boolean isReachable() {
return true;
Expand Down
Loading

0 comments on commit d399007

Please sign in to comment.