diff --git a/api/src/main/java/com/rappytv/globaltags/api/ApiHandler.java b/api/src/main/java/com/rappytv/globaltags/api/ApiHandler.java new file mode 100644 index 0000000..5d1369e --- /dev/null +++ b/api/src/main/java/com/rappytv/globaltags/api/ApiHandler.java @@ -0,0 +1,360 @@ +package com.rappytv.globaltags.api; + +import com.rappytv.globaltags.types.GlobalIcon; +import com.rappytv.globaltags.types.PlayerInfo; +import com.rappytv.globaltags.types.PlayerInfo.Suspension; +import com.rappytv.globaltags.util.TagCache; +import com.rappytv.globaltags.util.Util; +import net.labymod.api.Laby; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.component.format.NamedTextColor; +import net.labymod.api.client.entity.player.tag.PositionType; +import net.labymod.api.util.io.web.request.Request.Method; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; +import java.util.function.Consumer; + +@SuppressWarnings("unused") +public class ApiHandler { + + private static final Map emptyBody = Map.of("body", "placeholder body"); + + private ApiHandler() {} + + public static void getVersion(Consumer consumer) { + ApiRequest request = new ApiRequest( + Method.GET, + "/", + null + ) { + @Override + public Map getBody() { + return null; + } + }; + request.sendAsyncRequest((response) -> consumer.accept(request.responseBody.version)); + } + + public static void getInfo(Consumer consumer) { + getInfo(Laby.labyAPI().getUniqueId(), consumer); + } + + public static void getInfo(UUID uuid, Consumer consumer) { + ApiRequest request = new ApiRequest( + Method.GET, + "/players/" + uuid, + Util.getSessionToken() + ) { + @Override + public Map getBody() { + return null; + } + }; + request.sendAsyncRequest((response) -> { + if(!request.isSuccessful()) { + consumer.accept(null); + return; + } + consumer.accept(new PlayerInfo( + uuid, + request.responseBody.tag, + request.responseBody.position, + request.responseBody.icon, + request.responseBody.admin, + request.responseBody.ban + )); + }); + } + + public static void setTag(String tag, Consumer consumer) { + setTag(Laby.labyAPI().getUniqueId(), tag, consumer); + } + + public static void setTag(UUID uuid, String tag, Consumer consumer) { + ApiRequest request = new ApiRequest( + Method.POST, + "/players/" + uuid, + Util.getSessionToken() + ) { + @Override + public Map getBody() { + return Map.of("tag", tag); + } + }; + request.sendAsyncRequest((response -> { + if(!request.isSuccessful()) { + consumer.accept(new ApiResponse(false, request.getError())); + return; + } + TagCache.clear(); + TagCache.resolveSelf((info) -> consumer.accept(new ApiResponse(true, request.getMessage()))); + })); + } + + public static void setPosition(PositionType position, Consumer consumer) { + setPosition(Laby.labyAPI().getUniqueId(), position, consumer); + } + + public static void setPosition(UUID uuid, PositionType position, Consumer consumer) { + ApiRequest request = new ApiRequest( + Method.POST, + "/players/" + uuid + "/position", + Util.getSessionToken() + ) { + @Override + public Map getBody() { + return Map.of("position", position.name().split("_")[0]); + } + }; + request.sendAsyncRequest((response) -> { + if(!request.isSuccessful()) { + consumer.accept(new ApiResponse(false, request.getError())); + return; + } + TagCache.clear(); + TagCache.resolveSelf((info) -> consumer.accept(new ApiResponse(true, request.getMessage()))); + }); + } + + public static void setIcon(GlobalIcon icon, Consumer consumer) { + setIcon(Laby.labyAPI().getUniqueId(), icon, consumer); + } + + public static void setIcon(UUID uuid, GlobalIcon icon, Consumer consumer) { + ApiRequest request = new ApiRequest( + Method.POST, + "/players/" + uuid + "/icon", + Util.getSessionToken() + ) { + @Override + public Map getBody() { + return Map.of("icon", icon.name()); + } + }; + request.sendAsyncRequest((response) -> { + if(!request.isSuccessful()) { + consumer.accept(new ApiResponse(false, request.getError())); + return; + } + TagCache.clear(); + TagCache.resolveSelf((info) -> consumer.accept(new ApiResponse(true, request.getMessage()))); + }); + } + + public static void resetTag(Consumer consumer) { + resetTag(Laby.labyAPI().getUniqueId(), consumer); + } + + public static void resetTag(UUID uuid, Consumer consumer) { + ApiRequest request = new ApiRequest( + Method.DELETE, + "/players/" + uuid, + Util.getSessionToken() + ) { + @Override + public Map getBody() { + // https://github.com/elysiajs/elysia/issues/495 + return emptyBody; + } + }; + request.sendAsyncRequest((response) -> { + if(!request.isSuccessful()) { + consumer.accept(new ApiResponse(false, request.getError())); + return; + } + TagCache.clear(); + TagCache.resolveSelf((info) -> consumer.accept(new ApiResponse(true, request.getMessage()))); + }); + } + + public static void reportPlayer(UUID uuid, String reason, Consumer consumer) { + ApiRequest request = new ApiRequest( + Method.POST, + "/players/" + uuid + "/report", + Util.getSessionToken() + ) { + @Override + public Map getBody() { + return Map.of("reason", reason); + } + }; + request.sendAsyncRequest((response) -> { + if(!request.isSuccessful()) { + consumer.accept(new ApiResponse(false, request.getError())); + return; + } + consumer.accept(new ApiResponse(true, request.getMessage())); + }); + } + + public static void banPlayer(UUID uuid, String reason, Consumer consumer) { + ApiRequest request = new ApiRequest( + Method.POST, + "/players/" + uuid + "/ban", + Util.getSessionToken() + ) { + @Override + public Map getBody() { + return Map.of("reason", reason); + } + }; + request.sendAsyncRequest((response) -> { + if(!request.isSuccessful()) { + consumer.accept(new ApiResponse(false, request.getError())); + return; + } + TagCache.clear(); + TagCache.resolveSelf((info) -> consumer.accept(new ApiResponse(true, request.getMessage()))); + }); + } + + public static void unbanPlayer(UUID uuid, Consumer consumer) { + ApiRequest request = new ApiRequest( + Method.DELETE, + "/players/" + uuid + "/ban", + Util.getSessionToken() + ) { + @Override + public Map getBody() { + // https://github.com/elysiajs/elysia/issues/495 + return emptyBody; + } + }; + request.sendAsyncRequest((response) -> { + if(!request.isSuccessful()) { + consumer.accept(new ApiResponse(false, request.getError())); + return; + } + TagCache.clear(); + TagCache.resolveSelf((info) -> consumer.accept(new ApiResponse(true, request.getMessage()))); + }); + } + + public static void editBan(UUID uuid, Suspension suspension, Consumer consumer) { + ApiRequest request = new ApiRequest( + Method.PUT, + "/players/" + uuid + "/ban", + Util.getSessionToken() + ) { + @Override + public Map getBody() { + Objects.requireNonNull(suspension.getReason(), "Reason must not be null"); + return Map.of("reason", suspension.getReason(), "appealable", suspension.isAppealable()); + } + }; + request.sendAsyncRequest((response) -> { + if(!request.isSuccessful()) { + consumer.accept(new ApiResponse(false, request.getError())); + return; + } + TagCache.clear(); + TagCache.resolveSelf((info) -> consumer.accept(new ApiResponse(true, request.getMessage()))); + }); + } + + public static void appealBan(String reason, Consumer consumer) { + ApiRequest request = new ApiRequest( + Method.POST, + "/players/" + Laby.labyAPI().getUniqueId() + "/ban/appeal", + Util.getSessionToken() + ) { + @Override + public Map getBody() { + return Map.of("reason", reason); + } + }; + request.sendAsyncRequest((response) -> { + if(!request.isSuccessful()) { + consumer.accept(new ApiResponse(false, request.getError())); + return; + } + consumer.accept(new ApiResponse(true, request.getMessage())); + }); + } + + public static void toggleAdmin(UUID uuid, Consumer consumer) { + ApiRequest request = new ApiRequest( + Method.POST, + "/players/" + uuid + "/admin", + Util.getSessionToken() + ) { + @Override + public Map getBody() { + // https://github.com/elysiajs/elysia/issues/495 + return emptyBody; + } + }; + request.sendAsyncRequest((response) -> { + if(!request.isSuccessful()) { + consumer.accept(new ApiResponse(false, request.getError())); + return; + } + TagCache.clear(); + TagCache.resolveSelf((info) -> consumer.accept(new ApiResponse(true, request.getMessage()))); + }); + } + + public static void linkDiscord(Consumer consumer) { + ApiRequest request = new ApiRequest( + Method.POST, + "/players/" + Laby.labyAPI().getUniqueId() + "/connections/discord", + Util.getSessionToken() + ) { + @Override + public Map getBody() { + // https://github.com/elysiajs/elysia/issues/495 + return emptyBody; + } + }; + request.sendAsyncRequest((response) -> { + if(!request.isSuccessful()) { + consumer.accept(new ApiResponse(false, request.getError())); + return; + } + TagCache.clear(); + TagCache.resolveSelf((info) -> consumer.accept(new ApiResponse(true, request.responseBody.code))); + }); + } + + public static void unlinkDiscord(Consumer consumer) { + ApiRequest request = new ApiRequest( + Method.DELETE, + "/players/" + Laby.labyAPI().getUniqueId() + "/connections/discord", + Util.getSessionToken() + ) { + @Override + public Map getBody() { + // https://github.com/elysiajs/elysia/issues/495 + return emptyBody; + } + }; + request.sendAsyncRequest((response) -> { + if(!request.isSuccessful()) { + consumer.accept(new ApiResponse(false, request.getError())); + return; + } + TagCache.clear(); + TagCache.resolveSelf((info) -> consumer.accept(new ApiResponse(true, request.getMessage()))); + }); + } + + public static class ApiResponse { + + private final boolean successful; + private final Component message; + + public ApiResponse(boolean successful, String message) { + this.successful = successful; + this.message = Component.text(message, successful ? NamedTextColor.GREEN : NamedTextColor.RED); + } + + public boolean isSuccessful() { + return successful; + } + + public Component getMessage() { + return message; + } + } +} diff --git a/core/src/main/java/com/rappytv/globaltags/api/ApiRequest.java b/api/src/main/java/com/rappytv/globaltags/api/ApiRequest.java similarity index 76% rename from core/src/main/java/com/rappytv/globaltags/api/ApiRequest.java rename to api/src/main/java/com/rappytv/globaltags/api/ApiRequest.java index 26cb5e3..ba1d952 100644 --- a/core/src/main/java/com/rappytv/globaltags/api/ApiRequest.java +++ b/api/src/main/java/com/rappytv/globaltags/api/ApiRequest.java @@ -2,8 +2,6 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; -import com.rappytv.globaltags.GlobalTagAddon; -import com.rappytv.globaltags.config.GlobalTagConfig; import net.labymod.api.Laby; import net.labymod.api.util.io.web.request.Callback; import net.labymod.api.util.io.web.request.Request; @@ -13,6 +11,9 @@ public abstract class ApiRequest { + private static boolean localizedResponses; + private static String version; + private final Gson gson = new Gson(); private boolean successful; private String message; @@ -22,30 +23,28 @@ public abstract class ApiRequest { private final Method method; private final String path; private final String key; - private final boolean localized; public ApiRequest(Method method, String path, String key) { this.method = method; this.path = path; this.key = key; - this.localized = GlobalTagConfig.localizedResponses(); } public void sendAsyncRequest(Callback callback) { GsonRequest request = Request.ofGson(JsonObject.class) - .url("https://gt.rappytv.com" + path) + .url(getApiBase() + path) .method(method) .addHeader("Content-Type", "application/json") .addHeader("Authorization", key != null ? key : "") - .addHeader("X-Addon-Version", GlobalTagAddon.version) + .addHeader("X-Addon-Version", version) .handleErrorStream() .async(); - Map body = getBody(); + Map body = getBody(); if(body != null) request.json(body); - if(localized) + if(localizedResponses) request.addHeader("X-Minecraft-Language", Laby.labyAPI().minecraft().options().getCurrentLanguage()); request.execute((response) -> { @@ -53,6 +52,7 @@ public void sendAsyncRequest(Callback callback) { successful = false; error = response.exception().getMessage(); callback.accept(response); + response.exception().printStackTrace(); return; } responseBody = gson.fromJson(response.get(), ResponseBody.class); @@ -79,5 +79,18 @@ public String getMessage() { public String getError() { return error; } - public abstract Map getBody(); + public abstract Map getBody(); + + public static void useLocalizedResponses(boolean value) { + localizedResponses = value; + } + public static void addonVersion(String value) { + version = value; + } + public static String getVersion() { + return version; + } + private String getApiBase() { + return "https://gt.rappytv.com"; + } } diff --git a/core/src/main/java/com/rappytv/globaltags/api/ResponseBody.java b/api/src/main/java/com/rappytv/globaltags/api/ResponseBody.java similarity index 60% rename from core/src/main/java/com/rappytv/globaltags/api/ResponseBody.java rename to api/src/main/java/com/rappytv/globaltags/api/ResponseBody.java index 891a756..3313cfc 100644 --- a/core/src/main/java/com/rappytv/globaltags/api/ResponseBody.java +++ b/api/src/main/java/com/rappytv/globaltags/api/ResponseBody.java @@ -8,10 +8,18 @@ public class ResponseBody { public String icon; public boolean admin; public String message; + public Ban ban; // For errors public String error; - // Version + // Other public String version; + public String code; + + public static class Ban { + public boolean active; + public String reason; + public boolean appealable; + } } diff --git a/api/src/main/java/com/rappytv/globaltags/types/GlobalIcon.java b/api/src/main/java/com/rappytv/globaltags/types/GlobalIcon.java new file mode 100644 index 0000000..647ad09 --- /dev/null +++ b/api/src/main/java/com/rappytv/globaltags/types/GlobalIcon.java @@ -0,0 +1,45 @@ +package com.rappytv.globaltags.types; + +import net.labymod.api.client.gui.icon.Icon; +import net.labymod.api.client.resources.ResourceLocation; +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings("unused") +public enum GlobalIcon { + NONE, + BEREAL, + DISCORD, + EBIO, + EPICGAMES, + GITHUB, + GITLAB, + INSTAGRAM, + KICK, + PLAYSTATION, + SNAPCHAT, + STEAM, + THREADS, + TIKTOK, + TWITCH, + X, + XBOX, + YOUTUBE; + + private final Map iconCache = new HashMap<>(); + + public Icon getIcon() { + String name = name().toLowerCase(); + if(iconCache.containsKey(name)) + return iconCache.get(name); + ResourceLocation location = ResourceLocation.create( + "globaltags", + "textures/icons/" + name + ".png" + ); + iconCache.put( + name, + location.exists() ? Icon.texture(location) : null + ); + return getIcon(); + } +} diff --git a/api/src/main/java/com/rappytv/globaltags/types/PlayerInfo.java b/api/src/main/java/com/rappytv/globaltags/types/PlayerInfo.java new file mode 100644 index 0000000..53fb348 --- /dev/null +++ b/api/src/main/java/com/rappytv/globaltags/types/PlayerInfo.java @@ -0,0 +1,186 @@ +package com.rappytv.globaltags.types; + +import com.rappytv.globaltags.api.ResponseBody.Ban; +import com.rappytv.globaltags.util.Util; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.entity.player.tag.PositionType; +import net.labymod.api.client.gui.icon.Icon; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.util.Objects; +import java.util.UUID; + +public class PlayerInfo { + + private final UUID uuid; + private final Component tag; + private final String plainTag; + private final String position; + private final String icon; + private final boolean admin; + private final Suspension suspension; + + public PlayerInfo(UUID uuid, String tag, String position, String icon, boolean admin, Ban ban) { + this.uuid = uuid; + this.tag = Util.translateColorCodes(tag); + this.plainTag = tag != null ? tag : ""; + this.position = position; + this.icon = icon; + this.admin = admin; + this.suspension = ban != null ? new Suspension(ban) : new Suspension(); + } + + /** + * Returns the player's uuid + */ + @NotNull + public UUID getUUID() { + return uuid; + } + + /** + * Returns the player's GlobalTag as a colored component + */ + @Nullable + public Component getTag() { + return !plainTag.isEmpty() ? tag : null; + } + + /** + * Returns the player's GlobalTag as a plain string - with color codes + */ + @NotNull + public String getPlainTag() { + return plainTag; + } + + /** + * Returns the player's GlobalTag position + */ + @NotNull + public PositionType getPosition() { + if(position == null) return PositionType.ABOVE_NAME; + return switch(position) { + default -> PositionType.ABOVE_NAME; + case "BELOW" -> PositionType.BELOW_NAME; + case "RIGHT" -> PositionType.RIGHT_TO_NAME; + case "LEFT" -> PositionType.LEFT_TO_NAME; + }; + } + + /** + * Returns the {@link GlobalIcon} enum value which the player has selected + */ + @NotNull + public GlobalIcon getGlobalIcon() { + try { + return GlobalIcon.valueOf(icon); + } catch (Exception ignored) { + return GlobalIcon.NONE; + } + } + + /** + * Returns the global icon of the player + */ + public Icon getIcon() { + return getGlobalIcon().getIcon(); + } + + /** + * Returns if the player is a GlobalTag admin + */ + public boolean isAdmin() { + return admin; + } + + /** + * Use {@link PlayerInfo#isSuspended()} instead + */ + @Deprecated(forRemoval = true) + public boolean isBanned() { + return isSuspended(); + } + + /** + * Use {@link PlayerInfo#getSuspension()} instead + */ + @Deprecated(forRemoval = true) + @Nullable + public String getBanReason() { + return suspension.reason; + } + + /** + * Shortcut to check if the player suspension is active + */ + public boolean isSuspended() { + return suspension.active; + } + + /** + * Gets the suspension object from a player + */ + @NotNull + public Suspension getSuspension() { + return suspension; + } + + @SuppressWarnings("unused") + public static class Suspension { + + private final boolean active; + private final String reason; + private final boolean appealable; + + /** + * Creates a suspension from a {@link Ban} object + */ + public Suspension(Ban ban) { + Objects.requireNonNull(ban, "Ban must not be null"); + this.active = ban.active; + this.reason = ban.reason; + this.appealable = ban.appealable; + } + + /** + * Creates an inactive suspension + */ + public Suspension() { + this.active = false; + this.reason = null; + this.appealable = false; + } + + /** + * Creates an active suspension + */ + public Suspension(String reason, boolean appealable) { + this.active = true; + this.reason = reason; + this.appealable = appealable; + } + + /** + * Returns if the suspension is active or not + */ + public boolean isActive() { + return active; + } + + /** + * Returns the suspension reason + */ + @Nullable + public String getReason() { + return reason; + } + + /** + * Returns if the suspension can be appealed + */ + public boolean isAppealable() { + return appealable; + } + } +} diff --git a/api/src/main/java/com/rappytv/globaltags/util/TagCache.java b/api/src/main/java/com/rappytv/globaltags/util/TagCache.java new file mode 100644 index 0000000..6972bc9 --- /dev/null +++ b/api/src/main/java/com/rappytv/globaltags/util/TagCache.java @@ -0,0 +1,57 @@ +package com.rappytv.globaltags.util; + +import com.rappytv.globaltags.api.ApiHandler; +import com.rappytv.globaltags.types.PlayerInfo; +import net.labymod.api.Laby; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.function.Consumer; + +public class TagCache { + + private TagCache() {} + + private static final Map cache = new HashMap<>(); + private static final Set resolving = new HashSet<>(); + + public static void add(UUID uuid, PlayerInfo info) { + cache.put(uuid, info); + } + public static void remove(UUID uuid) { + cache.remove(uuid); + } + public static boolean has(UUID uuid) { + return cache.containsKey(uuid); + } + public static PlayerInfo get(UUID uuid) { + return cache.get(uuid); + } + public static void resolveSelf() { + resolveSelf((info) -> {}); + } + public static void resolveSelf(Consumer consumer) { + resolve(Laby.labyAPI().getUniqueId(), consumer); + } + public static void resolve(UUID uuid) { + resolve(uuid, (info) -> {}); + } + public static void resolve(UUID uuid, Consumer consumer) { + if(has(uuid)) { + consumer.accept(get(uuid)); + return; + } + if(resolving.contains(uuid)) return; + resolving.add(uuid); + ApiHandler.getInfo(uuid, (info) -> { + add(uuid, info); + resolving.remove(uuid); + resolve(uuid, consumer); + }); + } + public static void clear() { + cache.clear(); + } +} diff --git a/api/src/main/java/com/rappytv/globaltags/util/Util.java b/api/src/main/java/com/rappytv/globaltags/util/Util.java new file mode 100644 index 0000000..aeb6598 --- /dev/null +++ b/api/src/main/java/com/rappytv/globaltags/util/Util.java @@ -0,0 +1,96 @@ +package com.rappytv.globaltags.util; + +import net.labymod.api.Laby; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.component.format.NamedTextColor; +import net.labymod.api.client.component.serializer.legacy.LegacyComponentSerializer; +import net.labymod.api.client.gui.screen.widget.widgets.popup.SimpleAdvancedPopup; +import net.labymod.api.labyconnect.LabyConnectSession; +import net.labymod.api.labyconnect.TokenStorage.Purpose; +import net.labymod.api.labyconnect.TokenStorage.Token; +import net.labymod.api.notification.Notification; +import net.labymod.api.notification.Notification.Type; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class Util { + + public static final Component unchanged = Component.translatable( + "globaltags.settings.tags.updateSettings.unchanged", + NamedTextColor.DARK_GRAY + ); + private static Component tagResponse = null; + private static Component positionResponse = null; + private static Component iconResponse = null; + + public static void notify(String title, String text) { + notify( + Component.text(title), + Component.text(text) + ); + } + + public static void notify(Component title, Component description) { + Notification.builder() + .title(title) + .text(description) + .type(Type.SYSTEM) + .buildAndPush(); + } + + public static void update(ResultType type, Component component) { + switch (type) { + case TAG -> tagResponse = component; + case POSITION -> positionResponse = component; + case ICON -> iconResponse = component; + } + if(tagResponse == null || positionResponse == null || iconResponse == null) return; + SimpleAdvancedPopup popup = SimpleAdvancedPopup + .builder() + .title(Component.text("Update result", NamedTextColor.AQUA)) + .description(Component.translatable( + "globaltags.settings.tags.updateSettings.result", + tagResponse, + positionResponse, + iconResponse + )) + .build(); + + Laby.labyAPI().minecraft().executeOnRenderThread(() -> { + popup.displayInOverlay(); + TagCache.clear(); + TagCache.resolveSelf(); + tagResponse = null; + positionResponse = null; + iconResponse = null; + }); + } + + public enum ResultType { + TAG, + POSITION, + ICON + } + + @NotNull + public static Component translateColorCodes(String string) { + if(string == null) string = ""; + return LegacyComponentSerializer + .legacyAmpersand() + .deserialize(string); + } + + public static @Nullable String getSessionToken() { + LabyConnectSession session = Laby.labyAPI().labyConnect().getSession(); + if(session == null) return null; + + Token token = session.tokenStorage().getToken( + Purpose.JWT, + session.self().getUniqueId() + ); + + if(token == null || token.isExpired()) return null; + + return token.getToken(); + } +} diff --git a/build.gradle.kts b/build.gradle.kts index 65a66f9..5b0a50e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,7 +15,7 @@ labyMod { author = "RappyTV" description = "Get yourself a custom Globaltag that's publicly visible to anyone using this addon." minecraftVersion = "*" - version = System.getenv().getOrDefault("VERSION", "1.1.10") + version = System.getenv().getOrDefault("VERSION", "1.2.0") } minecraft { diff --git a/core/src/main/java/com/rappytv/globaltags/GlobalTagAddon.java b/core/src/main/java/com/rappytv/globaltags/GlobalTagAddon.java index cde9865..41d978e 100644 --- a/core/src/main/java/com/rappytv/globaltags/GlobalTagAddon.java +++ b/core/src/main/java/com/rappytv/globaltags/GlobalTagAddon.java @@ -1,14 +1,22 @@ package com.rappytv.globaltags; -import com.rappytv.globaltags.api.ApiHandler; +import com.rappytv.globaltags.api.ApiRequest; import com.rappytv.globaltags.command.GlobalTagCommand; import com.rappytv.globaltags.config.GlobalTagConfig; +import com.rappytv.globaltags.interaction.EditBanInfoBulletPoint; +import com.rappytv.globaltags.interaction.ToggleBanBulletPoint; +import com.rappytv.globaltags.interaction.ChangeTagBulletPoint; +import com.rappytv.globaltags.interaction.ClearTagBulletPoint; import com.rappytv.globaltags.interaction.ReportBulletPoint; +import com.rappytv.globaltags.interaction.ToggleAdminBulletPoint; import com.rappytv.globaltags.listener.ServerNavigationListener; import com.rappytv.globaltags.nametag.CustomTag; -import com.rappytv.globaltags.util.Util; +import com.rappytv.globaltags.util.TagCache; import net.labymod.api.Laby; import net.labymod.api.addon.LabyAddon; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.component.format.NamedTextColor; +import net.labymod.api.client.component.format.TextDecoration; import net.labymod.api.client.entity.player.tag.PositionType; import net.labymod.api.client.entity.player.tag.TagRegistry; import net.labymod.api.models.addon.annotation.AddonMain; @@ -20,24 +28,22 @@ @AddonMain public class GlobalTagAddon extends LabyAddon { - public static String prefix = "§1§lGlobalTags §8» §f"; - public static String version; - private static GlobalTagAddon addon; - private ApiHandler apiHandler; + public static Component prefix = Component.empty() + .append(Component.text("GlobalTags").color(NamedTextColor.BLUE).decorate(TextDecoration.BOLD)) + .append(Component.text(" » ", NamedTextColor.DARK_GRAY)); @Override protected void preConfigurationLoad() { Laby.references().revisionRegistry().register(new SimpleRevision("globaltags", new SemanticVersion("1.1.0"), "2023-11-24")); Laby.references().revisionRegistry().register(new SimpleRevision("globaltags", new SemanticVersion("1.1.7"), "2024-02-27")); Laby.references().revisionRegistry().register(new SimpleRevision("globaltags", new SemanticVersion("1.1.9"), "2024-06-01")); - this.apiHandler = new ApiHandler(); - addon = this; + Laby.references().revisionRegistry().register(new SimpleRevision("globaltags", new SemanticVersion("1.2.0"), "2024-07-06")); } @Override protected void enable() { registerSettingCategory(); - version = addon.addonInfo().getVersion(); + ApiRequest.addonVersion(addonInfo().getVersion()); TagRegistry tagRegistry = labyAPI().tagRegistry(); for (PositionType positionType : PositionType.values()) @@ -48,27 +54,26 @@ protected void enable() { new CustomTag(this, positionType) ); registerListener(new ServerNavigationListener()); - labyAPI().interactionMenuRegistry().register(new ReportBulletPoint(this)); + labyAPI().interactionMenuRegistry().register(new ChangeTagBulletPoint()); + labyAPI().interactionMenuRegistry().register(new ClearTagBulletPoint()); + labyAPI().interactionMenuRegistry().register(new EditBanInfoBulletPoint()); + labyAPI().interactionMenuRegistry().register(new ReportBulletPoint()); + labyAPI().interactionMenuRegistry().register(new ToggleAdminBulletPoint()); + labyAPI().interactionMenuRegistry().register(new ToggleBanBulletPoint()); registerCommand(new GlobalTagCommand()); // Clear cache every 5 minutes new Timer().scheduleAtFixedRate(new TimerTask() { @Override public void run() { - Util.clearCache(false); + TagCache.clear(); + TagCache.resolveSelf(); } - }, 0, 1000 * 60 * 5); + }, 1000 * 10, 1000 * 60 * 5); } @Override protected Class configurationClass() { return GlobalTagConfig.class; } - - public static GlobalTagAddon getAddon() { - return addon; - } - public ApiHandler getApiHandler() { - return apiHandler; - } } diff --git a/core/src/main/java/com/rappytv/globaltags/activities/BanActivity.java b/core/src/main/java/com/rappytv/globaltags/activities/BanActivity.java new file mode 100644 index 0000000..56f3a35 --- /dev/null +++ b/core/src/main/java/com/rappytv/globaltags/activities/BanActivity.java @@ -0,0 +1,74 @@ +package com.rappytv.globaltags.activities; + +import com.rappytv.globaltags.GlobalTagAddon; +import com.rappytv.globaltags.api.ApiHandler; +import net.labymod.api.Laby; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.component.format.NamedTextColor; +import net.labymod.api.client.gui.icon.Icon; +import net.labymod.api.client.gui.screen.Parent; +import net.labymod.api.client.gui.screen.ScreenInstance; +import net.labymod.api.client.gui.screen.activity.AutoActivity; +import net.labymod.api.client.gui.screen.activity.Link; +import net.labymod.api.client.gui.screen.activity.types.SimpleActivity; +import net.labymod.api.client.gui.screen.widget.Widget; +import net.labymod.api.client.gui.screen.widget.widgets.ComponentWidget; +import net.labymod.api.client.gui.screen.widget.widgets.input.ButtonWidget; +import net.labymod.api.client.gui.screen.widget.widgets.input.TextFieldWidget; +import net.labymod.api.client.gui.screen.widget.widgets.layout.FlexibleContentWidget; +import net.labymod.api.client.gui.screen.widget.widgets.layout.list.HorizontalListWidget; +import net.labymod.api.client.gui.screen.widget.widgets.layout.list.VerticalListWidget; +import net.labymod.api.client.gui.screen.widget.widgets.renderer.IconWidget; + +import java.util.UUID; + +@Link("input.lss") +@AutoActivity +public class BanActivity extends SimpleActivity { + + private final UUID uuid; + private final String username; + + public BanActivity(UUID uuid, String username) { + this.uuid = uuid; + this.username = username; + } + + @Override + public void initialize(Parent parent) { + super.initialize(parent); + FlexibleContentWidget windowWidget = new FlexibleContentWidget().addId("window"); + HorizontalListWidget profileWrapper = new HorizontalListWidget().addId("header"); + IconWidget headWidget = new IconWidget(Icon.head(this.uuid)).addId("head"); + ComponentWidget titleWidget = ComponentWidget.i18n("globaltags.context.ban.title", this.username).addId("username"); + VerticalListWidget content = new VerticalListWidget<>().addId("content"); + ComponentWidget labelWidget = ComponentWidget.i18n("globaltags.context.reason").addId("label"); + TextFieldWidget inputWidget = new TextFieldWidget() + .placeholder(Component.translatable("globaltags.context.placeholder", NamedTextColor.DARK_GRAY)) + .addId("input"); + ButtonWidget sendButton = new ButtonWidget() + .updateComponent(Component.translatable("globaltags.context.ban.send", NamedTextColor.RED)) + .addId("send-button"); + sendButton.setEnabled(false); + sendButton.setActionListener(() -> { + Laby.labyAPI().minecraft().minecraftWindow().displayScreen((ScreenInstance) null); + ApiHandler.banPlayer(uuid, inputWidget.getText(), (response) -> Laby.references().chatExecutor().displayClientMessage( + Component.empty() + .append(GlobalTagAddon.prefix) + .append(response.getMessage()) + )); + }); + inputWidget.updateListener((text) -> sendButton.setEnabled(!text.isBlank())); + + profileWrapper.addEntry(headWidget); + profileWrapper.addEntry(titleWidget); + + content.addChild(labelWidget); + content.addChild(inputWidget); + content.addChild(sendButton); + + windowWidget.addContent(profileWrapper); + windowWidget.addContent(content); + this.document.addChild(windowWidget); + } +} diff --git a/core/src/main/java/com/rappytv/globaltags/activities/ChangeTagActivity.java b/core/src/main/java/com/rappytv/globaltags/activities/ChangeTagActivity.java new file mode 100644 index 0000000..e3712c2 --- /dev/null +++ b/core/src/main/java/com/rappytv/globaltags/activities/ChangeTagActivity.java @@ -0,0 +1,78 @@ +package com.rappytv.globaltags.activities; + +import com.rappytv.globaltags.GlobalTagAddon; +import com.rappytv.globaltags.api.ApiHandler; +import java.util.UUID; +import com.rappytv.globaltags.util.TagCache; +import net.labymod.api.Laby; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.component.format.NamedTextColor; +import net.labymod.api.client.gui.icon.Icon; +import net.labymod.api.client.gui.screen.Parent; +import net.labymod.api.client.gui.screen.ScreenInstance; +import net.labymod.api.client.gui.screen.activity.AutoActivity; +import net.labymod.api.client.gui.screen.activity.Link; +import net.labymod.api.client.gui.screen.activity.types.SimpleActivity; +import net.labymod.api.client.gui.screen.widget.Widget; +import net.labymod.api.client.gui.screen.widget.widgets.ComponentWidget; +import net.labymod.api.client.gui.screen.widget.widgets.input.ButtonWidget; +import net.labymod.api.client.gui.screen.widget.widgets.input.TextFieldWidget; +import net.labymod.api.client.gui.screen.widget.widgets.layout.FlexibleContentWidget; +import net.labymod.api.client.gui.screen.widget.widgets.layout.list.HorizontalListWidget; +import net.labymod.api.client.gui.screen.widget.widgets.layout.list.VerticalListWidget; +import net.labymod.api.client.gui.screen.widget.widgets.renderer.IconWidget; + +@Link("input.lss") +@AutoActivity +public class ChangeTagActivity extends SimpleActivity { + + private final UUID uuid; + private final String username; + + public ChangeTagActivity(UUID uuid, String username) { + this.uuid = uuid; + this.username = username; + } + + @Override + public void initialize(Parent parent) { + super.initialize(parent); + TagCache.resolve(uuid, (info) -> { + FlexibleContentWidget windowWidget = new FlexibleContentWidget().addId("window"); + HorizontalListWidget profileWrapper = new HorizontalListWidget().addId("header"); + IconWidget headWidget = new IconWidget(Icon.head(this.uuid)).addId("head"); + ComponentWidget titleWidget = ComponentWidget.i18n("globaltags.context.changeTag.title", this.username).addId("username"); + VerticalListWidget content = new VerticalListWidget<>().addId("content"); + ComponentWidget labelWidget = ComponentWidget.i18n("globaltags.context.changeTag.label").addId("label"); + TextFieldWidget inputWidget = new TextFieldWidget() + .placeholder(Component.translatable("globaltags.context.changeTag.placeholder", NamedTextColor.DARK_GRAY)) + .addId("input"); + boolean hasTag = info.getPlainTag() != null; + inputWidget.setText(hasTag ? info.getPlainTag() : ""); + ButtonWidget sendButton = new ButtonWidget() + .updateComponent(Component.translatable("globaltags.context.changeTag.send", NamedTextColor.AQUA)) + .addId("send-button"); + sendButton.setEnabled(!inputWidget.getText().isBlank() && (!hasTag || !inputWidget.getText().equals(info.getPlainTag()))); + sendButton.setActionListener(() -> { + Laby.labyAPI().minecraft().minecraftWindow().displayScreen((ScreenInstance) null); + ApiHandler.setTag(uuid, inputWidget.getText(), (response) -> Laby.references().chatExecutor().displayClientMessage( + Component.empty() + .append(GlobalTagAddon.prefix) + .append(response.getMessage()) + )); + }); + inputWidget.updateListener((text) -> sendButton.setEnabled(!text.isBlank() && (!hasTag || !inputWidget.getText().equals(info.getPlainTag())))); + + profileWrapper.addEntry(headWidget); + profileWrapper.addEntry(titleWidget); + + content.addChild(labelWidget); + content.addChild(inputWidget); + content.addChild(sendButton); + + windowWidget.addContent(profileWrapper); + windowWidget.addContent(content); + this.document.addChild(windowWidget); + }); + } +} diff --git a/core/src/main/java/com/rappytv/globaltags/activities/EditBanActivity.java b/core/src/main/java/com/rappytv/globaltags/activities/EditBanActivity.java new file mode 100644 index 0000000..646dda3 --- /dev/null +++ b/core/src/main/java/com/rappytv/globaltags/activities/EditBanActivity.java @@ -0,0 +1,116 @@ +package com.rappytv.globaltags.activities; + +import com.rappytv.globaltags.GlobalTagAddon; +import com.rappytv.globaltags.api.ApiHandler; +import java.util.UUID; +import java.util.function.Consumer; +import com.rappytv.globaltags.types.PlayerInfo.Suspension; +import com.rappytv.globaltags.util.TagCache; +import net.labymod.api.Laby; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.component.format.NamedTextColor; +import net.labymod.api.client.gui.icon.Icon; +import net.labymod.api.client.gui.screen.Parent; +import net.labymod.api.client.gui.screen.ScreenInstance; +import net.labymod.api.client.gui.screen.activity.AutoActivity; +import net.labymod.api.client.gui.screen.activity.Link; +import net.labymod.api.client.gui.screen.activity.types.SimpleActivity; +import net.labymod.api.client.gui.screen.widget.Widget; +import net.labymod.api.client.gui.screen.widget.widgets.ComponentWidget; +import net.labymod.api.client.gui.screen.widget.widgets.input.ButtonWidget; +import net.labymod.api.client.gui.screen.widget.widgets.input.CheckBoxWidget; +import net.labymod.api.client.gui.screen.widget.widgets.input.CheckBoxWidget.State; +import net.labymod.api.client.gui.screen.widget.widgets.input.TextFieldWidget; +import net.labymod.api.client.gui.screen.widget.widgets.layout.FlexibleContentWidget; +import net.labymod.api.client.gui.screen.widget.widgets.layout.list.HorizontalListWidget; +import net.labymod.api.client.gui.screen.widget.widgets.layout.list.VerticalListWidget; +import net.labymod.api.client.gui.screen.widget.widgets.renderer.IconWidget; + +@Link("input.lss") +@AutoActivity +public class EditBanActivity extends SimpleActivity { + + private final UUID uuid; + private final String username; + + public EditBanActivity(UUID uuid, String username) { + this.uuid = uuid; + this.username = username; + } + + @Override + public void initialize(Parent parent) { + super.initialize(parent); + TagCache.resolve(uuid, (info) -> { + Suspension suspension = info.getSuspension(); + FlexibleContentWidget windowWidget = new FlexibleContentWidget().addId("window"); + HorizontalListWidget profileWrapper = new HorizontalListWidget().addId("header"); + IconWidget headWidget = new IconWidget(Icon.head(this.uuid)).addId("head"); + ComponentWidget titleWidget = ComponentWidget.i18n( + "globaltags.context.editBan.title", + this.username + ).addId("username"); + VerticalListWidget content = new VerticalListWidget<>().addId("content"); + ComponentWidget inputLabelWidget = ComponentWidget.i18n("globaltags.context.reason") + .addId("label"); + TextFieldWidget inputWidget = new TextFieldWidget() + .placeholder(Component.translatable( + "globaltags.context.placeholder", + NamedTextColor.DARK_GRAY + )) + .addId("input"); + String reason = suspension.getReason(); + if(reason != null) inputWidget.setText(reason, true); + ComponentWidget boxLabelWidget = ComponentWidget + .i18n("globaltags.context.editBan.appealable") + .addId("appealable-label"); + CheckBoxWidget checkBoxWidget = new CheckBoxWidget().addId("check-box"); + checkBoxWidget.setState(suspension.isAppealable() ? State.CHECKED : State.UNCHECKED); + ButtonWidget sendButton = new ButtonWidget() + .updateComponent(Component.translatable( + "globaltags.context.editBan.send", + NamedTextColor.AQUA + )) + .addId("send-button"); + sendButton.setEnabled(false); + sendButton.setActionListener(() -> { + Laby.labyAPI().minecraft().minecraftWindow().displayScreen((ScreenInstance) null); + Suspension editedSuspension = new Suspension( + inputWidget.getText(), + checkBoxWidget.state() == State.CHECKED + ); + ApiHandler.editBan(uuid, editedSuspension, (response) -> + Laby.references().chatExecutor().displayClientMessage( + Component.empty() + .append(GlobalTagAddon.prefix) + .append(response.getMessage()) + ) + ); + }); + Consumer updateButton = (text) -> { + boolean reasonNotEmpty = !text.isBlank(); + boolean updatedReason = !text.equals(suspension.getReason()); + boolean updatedCheckbox = + (checkBoxWidget.state() == State.CHECKED) != suspension.isAppealable(); + sendButton.setEnabled(reasonNotEmpty && (updatedReason || updatedCheckbox)); + }; + inputWidget.updateListener(updateButton); + checkBoxWidget.setActionListener(() -> + updateButton.accept(inputWidget.getText()) + ); + + profileWrapper.addEntry(headWidget); + profileWrapper.addEntry(titleWidget); + + content.addChild(inputLabelWidget); + content.addChild(inputWidget); + content.addChild(boxLabelWidget); + content.addChild(checkBoxWidget); + content.addChild(sendButton); + + windowWidget.addContent(profileWrapper); + windowWidget.addContent(content); + this.document.addChild(windowWidget); + }); + } +} diff --git a/core/src/main/java/com/rappytv/globaltags/activities/ReportUUIDActivity.java b/core/src/main/java/com/rappytv/globaltags/activities/ReportUUIDActivity.java index 4e66b95..cd5670c 100644 --- a/core/src/main/java/com/rappytv/globaltags/activities/ReportUUIDActivity.java +++ b/core/src/main/java/com/rappytv/globaltags/activities/ReportUUIDActivity.java @@ -1,6 +1,7 @@ package com.rappytv.globaltags.activities; import com.rappytv.globaltags.GlobalTagAddon; +import com.rappytv.globaltags.api.ApiHandler; import net.labymod.api.Laby; import net.labymod.api.client.component.Component; import net.labymod.api.client.component.format.NamedTextColor; @@ -20,16 +21,14 @@ import net.labymod.api.client.gui.screen.widget.widgets.renderer.IconWidget; import java.util.UUID; -@Link("report.lss") +@Link("input.lss") @AutoActivity public class ReportUUIDActivity extends SimpleActivity { - private final GlobalTagAddon addon; private final UUID uuid; private final String username; - public ReportUUIDActivity(GlobalTagAddon addon, UUID uuid, String username) { - this.addon = addon; + public ReportUUIDActivity(UUID uuid, String username) { this.uuid = uuid; this.username = username; } @@ -40,28 +39,32 @@ public void initialize(Parent parent) { FlexibleContentWidget windowWidget = new FlexibleContentWidget().addId("window"); HorizontalListWidget profileWrapper = new HorizontalListWidget().addId("header"); IconWidget headWidget = new IconWidget(Icon.head(this.uuid)).addId("head"); - ComponentWidget titleWidget = ComponentWidget.i18n("globaltags.report.title", this.username).addId("username"); + ComponentWidget titleWidget = ComponentWidget.i18n("globaltags.context.report.title", this.username).addId("username"); VerticalListWidget content = new VerticalListWidget<>().addId("content"); - ComponentWidget reasonWidget = ComponentWidget.i18n("globaltags.report.reason").addId("reason"); - TextFieldWidget textField = new TextFieldWidget() - .placeholder(Component.translatable("globaltags.report.placeholder", NamedTextColor.DARK_GRAY)) - .addId("text-field"); - ButtonWidget button = new ButtonWidget() - .updateComponent(Component.translatable("globaltags.report.send", NamedTextColor.RED)) - .addId("report-button"); - button.setEnabled(false); - button.setActionListener(() -> { + ComponentWidget labelWidget = ComponentWidget.i18n("globaltags.context.reason").addId("label"); + TextFieldWidget inputWidget = new TextFieldWidget() + .placeholder(Component.translatable("globaltags.context.placeholder", NamedTextColor.DARK_GRAY)) + .addId("input"); + ButtonWidget sendButton = new ButtonWidget() + .updateComponent(Component.translatable("globaltags.context.report.send", NamedTextColor.RED)) + .addId("send-button"); + sendButton.setEnabled(false); + sendButton.setActionListener(() -> { Laby.labyAPI().minecraft().minecraftWindow().displayScreen((ScreenInstance) null); - addon.getApiHandler().reportPlayer(uuid, textField.getText()); + ApiHandler.reportPlayer(uuid, inputWidget.getText(), (response) -> Laby.references().chatExecutor().displayClientMessage( + Component.empty() + .append(GlobalTagAddon.prefix) + .append(response.getMessage()) + )); }); - textField.updateListener((text) -> button.setEnabled(!text.isBlank())); + inputWidget.updateListener((text) -> sendButton.setEnabled(!text.isBlank())); profileWrapper.addEntry(headWidget); profileWrapper.addEntry(titleWidget); - content.addChild(reasonWidget); - content.addChild(textField); - content.addChild(button); + content.addChild(labelWidget); + content.addChild(inputWidget); + content.addChild(sendButton); windowWidget.addContent(profileWrapper); windowWidget.addContent(content); diff --git a/core/src/main/java/com/rappytv/globaltags/api/ApiHandler.java b/core/src/main/java/com/rappytv/globaltags/api/ApiHandler.java deleted file mode 100644 index 9413d41..0000000 --- a/core/src/main/java/com/rappytv/globaltags/api/ApiHandler.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.rappytv.globaltags.api; - -import com.rappytv.globaltags.api.requests.IconSetRequest; -import com.rappytv.globaltags.api.requests.PositionSetRequest; -import com.rappytv.globaltags.api.requests.TagSetRequest; -import com.rappytv.globaltags.util.GlobalIcon; -import com.rappytv.globaltags.util.Util; -import net.labymod.api.Laby; -import net.labymod.api.client.entity.player.tag.PositionType; -import net.labymod.api.util.I18n; -import net.labymod.api.util.io.web.request.Request.Method; -import javax.inject.Singleton; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -@Singleton -public class ApiHandler { - - public void setTag(String tag) { - TagSetRequest request = new TagSetRequest( - Util.getSessionToken(), - tag - ); - request.sendAsyncRequest((response -> { - if(!request.isSuccessful()) { - Util.notify(I18n.translate("globaltags.notifications.error"), request.getError()); - return; - } - Util.notify(I18n.translate("globaltags.notifications.success"), request.getMessage()); - Util.clearCache(false); - })); - } - - public void setPosition(PositionType position) { - PositionSetRequest request = new PositionSetRequest( - Util.getSessionToken(), - position - ); - request.sendAsyncRequest((response -> { - if(!request.isSuccessful()) { - Util.notify(I18n.translate("globaltags.notifications.error"), request.getError()); - return; - } - Util.notify(I18n.translate("globaltags.notifications.success"), request.getMessage()); - Util.clearCache(false); - })); - } - - public void setIcon(GlobalIcon icon) { - IconSetRequest request = new IconSetRequest( - Util.getSessionToken(), - icon - ); - request.sendAsyncRequest((response -> { - if(!request.isSuccessful()) { - Util.notify(I18n.translate("globaltags.notifications.error"), request.getError()); - return; - } - Util.notify(I18n.translate("globaltags.notifications.success"), request.getMessage()); - Util.clearCache(false); - })); - } - - public void resetTag() { - ApiRequest request = new ApiRequest( - Method.DELETE, - "/players/" + Laby.labyAPI().getUniqueId(), - Util.getSessionToken() - ) { - @Override - public Map getBody() { - return Map.of("placeholder", "body"); - } - }; - request.sendAsyncRequest((response)-> { - if(!request.isSuccessful()) { - Util.notify(I18n.translate("globaltags.notifications.error"), request.getError()); - return; - } - Util.notify(I18n.translate("globaltags.notifications.success"), request.getMessage()); - Util.clearCache(false); - }); - } - - public void reportPlayer(UUID uuid, String reason) { - ApiRequest request = new ApiRequest( - Method.POST, - "/players/" + uuid + "/report", - Util.getSessionToken() - ) { - @Override - public Map getBody() { - Map body = new HashMap<>(); - body.put("reason", reason); - return body; - } - }; - request.sendAsyncRequest((response) -> { - if(!request.isSuccessful()) { - Util.notify(I18n.translate("globaltags.notifications.error"), request.getError()); - return; - } - Util.notify(I18n.translate("globaltags.notifications.success"), request.getMessage()); - }); - } -} diff --git a/core/src/main/java/com/rappytv/globaltags/api/requests/IconSetRequest.java b/core/src/main/java/com/rappytv/globaltags/api/requests/IconSetRequest.java deleted file mode 100644 index 2024c0e..0000000 --- a/core/src/main/java/com/rappytv/globaltags/api/requests/IconSetRequest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.rappytv.globaltags.api.requests; - -import com.rappytv.globaltags.api.ApiRequest; -import com.rappytv.globaltags.util.GlobalIcon; -import net.labymod.api.Laby; -import net.labymod.api.util.io.web.request.Request.Method; -import java.util.HashMap; -import java.util.Map; - -public class IconSetRequest extends ApiRequest { - - private final GlobalIcon icon; - - public IconSetRequest(String key, GlobalIcon icon) { - super(Method.POST, "/players/" + Laby.labyAPI().getUniqueId() + "/icon", key); - this.icon = icon; - } - - @Override - public Map getBody() { - Map body = new HashMap<>(); - body.put("icon", icon.name()); - return body; - } -} diff --git a/core/src/main/java/com/rappytv/globaltags/api/requests/InfoGetRequest.java b/core/src/main/java/com/rappytv/globaltags/api/requests/InfoGetRequest.java deleted file mode 100644 index 3015c8b..0000000 --- a/core/src/main/java/com/rappytv/globaltags/api/requests/InfoGetRequest.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.rappytv.globaltags.api.requests; - -import com.google.gson.JsonObject; -import com.rappytv.globaltags.api.ApiRequest; -import net.labymod.api.util.io.web.request.Callback; -import net.labymod.api.util.io.web.request.Request.Method; -import java.util.Map; -import java.util.UUID; - -public class InfoGetRequest extends ApiRequest { - - private String tag; - private String position; - private String icon; - private boolean admin; - - public InfoGetRequest(UUID uuid, String key) { - super(Method.GET, "/players/" + uuid, key); - } - - @Override - public void sendAsyncRequest(Callback callback) { - super.sendAsyncRequest((response) -> { - if(isSuccessful()) { - this.tag = responseBody.tag; - this.position = responseBody.position; - this.icon = responseBody.icon; - this.admin = responseBody.admin; - } - callback.accept(response); - }); - } - - @Override - public Map getBody() { - return null; - } - - public String getTag() { - return tag; - } - public String getPosition() { - return position; - } - public String getIcon() { - return icon; - } - public boolean isAdmin() { - return admin; - } -} diff --git a/core/src/main/java/com/rappytv/globaltags/api/requests/PositionSetRequest.java b/core/src/main/java/com/rappytv/globaltags/api/requests/PositionSetRequest.java deleted file mode 100644 index 1ab1ab5..0000000 --- a/core/src/main/java/com/rappytv/globaltags/api/requests/PositionSetRequest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.rappytv.globaltags.api.requests; - -import com.rappytv.globaltags.api.ApiRequest; -import net.labymod.api.Laby; -import net.labymod.api.client.entity.player.tag.PositionType; -import net.labymod.api.util.io.web.request.Request.Method; -import java.util.HashMap; -import java.util.Map; - -public class PositionSetRequest extends ApiRequest { - - private final PositionType position; - - public PositionSetRequest(String key, PositionType type) { - super(Method.POST, "/players/" + Laby.labyAPI().getUniqueId() + "/position", key); - this.position = type; - } - - @Override - public Map getBody() { - Map body = new HashMap<>(); - body.put("position", position.name().split("_")[0]); - return body; - } -} diff --git a/core/src/main/java/com/rappytv/globaltags/api/requests/TagSetRequest.java b/core/src/main/java/com/rappytv/globaltags/api/requests/TagSetRequest.java deleted file mode 100644 index 0051d4d..0000000 --- a/core/src/main/java/com/rappytv/globaltags/api/requests/TagSetRequest.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.rappytv.globaltags.api.requests; - -import com.rappytv.globaltags.api.ApiRequest; -import net.labymod.api.Laby; -import net.labymod.api.util.io.web.request.Request.Method; -import java.util.HashMap; -import java.util.Map; - -public class TagSetRequest extends ApiRequest { - - private final String tag; - - public TagSetRequest(String token, String tag) { - super(Method.POST, "/players/" + Laby.labyAPI().getUniqueId(), token); - this.tag = tag; - } - - @Override - public Map getBody() { - Map body = new HashMap<>(); - body.put("tag", tag); - return body; - } -} diff --git a/core/src/main/java/com/rappytv/globaltags/api/requests/VersionGetRequest.java b/core/src/main/java/com/rappytv/globaltags/api/requests/VersionGetRequest.java deleted file mode 100644 index 5d68a96..0000000 --- a/core/src/main/java/com/rappytv/globaltags/api/requests/VersionGetRequest.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.rappytv.globaltags.api.requests; - -import com.google.gson.JsonObject; -import com.rappytv.globaltags.api.ApiRequest; -import net.labymod.api.util.io.web.request.Callback; -import net.labymod.api.util.io.web.request.Request.Method; -import java.util.Map; - -public class VersionGetRequest extends ApiRequest { - - private String version; - - public VersionGetRequest() { - super(Method.GET, "/", null); - } - - @Override - public void sendAsyncRequest(Callback callback) { - super.sendAsyncRequest((response) -> { - if(isSuccessful()) version = responseBody.version; - callback.accept(response); - }); - } - - @Override - public Map getBody() { - return null; - } - - public String getVersion() { - return version; - } -} diff --git a/core/src/main/java/com/rappytv/globaltags/command/GlobalTagCommand.java b/core/src/main/java/com/rappytv/globaltags/command/GlobalTagCommand.java index 39fd601..6f59867 100644 --- a/core/src/main/java/com/rappytv/globaltags/command/GlobalTagCommand.java +++ b/core/src/main/java/com/rappytv/globaltags/command/GlobalTagCommand.java @@ -1,8 +1,11 @@ package com.rappytv.globaltags.command; import com.rappytv.globaltags.GlobalTagAddon; -import com.rappytv.globaltags.api.requests.VersionGetRequest; +import com.rappytv.globaltags.api.ApiHandler; +import com.rappytv.globaltags.api.ApiRequest; import com.rappytv.globaltags.command.subcommands.ClearCacheCommand; +import com.rappytv.globaltags.command.subcommands.LinkDiscordSubcommand; +import com.rappytv.globaltags.command.subcommands.UnlinkDiscordSubcommand; import net.labymod.api.client.chat.command.Command; import net.labymod.api.client.component.Component; import net.labymod.api.client.component.TextComponent; @@ -18,17 +21,21 @@ public GlobalTagCommand() { super("globaltags", "globaltag", "gt"); withSubCommand(new ClearCacheCommand()); + withSubCommand(new LinkDiscordSubcommand()); + withSubCommand(new UnlinkDiscordSubcommand()); } @Override public boolean execute(String prefix, String[] arguments) { - VersionGetRequest request = new VersionGetRequest(); - request.sendAsyncRequest((response) -> { - String version = request.getVersion(); - + ApiHandler.getVersion((version) -> { TextComponent clearComponent = TextComponent.builder() - .append(GlobalTagAddon.prefix + "§aVersion: §b" + GlobalTagAddon.version + "\n") - .append(GlobalTagAddon.prefix + "§aAPI Version: " + (version != null ? "§b" + version : "§c" + I18n.translate("globaltags.messages.offline")) + "\n") + .append(GlobalTagAddon.prefix) + .append(Component.text("Version: ", NamedTextColor.GREEN)) + .append(Component.text(ApiRequest.getVersion() + "\n", NamedTextColor.AQUA)) + .append(GlobalTagAddon.prefix) + .append(Component.text("API Version: ", NamedTextColor.GREEN)) + .append(version != null ? Component.text(version, NamedTextColor.AQUA) : Component.translatable("globaltags.messages.offline", NamedTextColor.RED)) + .append("\n") .append(GlobalTagAddon.prefix) .append(Component .translatable("globaltags.messages.clearCache") diff --git a/core/src/main/java/com/rappytv/globaltags/command/subcommands/ClearCacheCommand.java b/core/src/main/java/com/rappytv/globaltags/command/subcommands/ClearCacheCommand.java index b39cb31..0661598 100644 --- a/core/src/main/java/com/rappytv/globaltags/command/subcommands/ClearCacheCommand.java +++ b/core/src/main/java/com/rappytv/globaltags/command/subcommands/ClearCacheCommand.java @@ -1,9 +1,10 @@ package com.rappytv.globaltags.command.subcommands; import com.rappytv.globaltags.GlobalTagAddon; -import com.rappytv.globaltags.util.Util; +import com.rappytv.globaltags.util.TagCache; import net.labymod.api.client.chat.command.SubCommand; -import net.labymod.api.util.I18n; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.component.format.NamedTextColor; public class ClearCacheCommand extends SubCommand { @@ -13,7 +14,13 @@ public ClearCacheCommand() { @Override public boolean execute(String prefix, String[] arguments) { - displayMessage(GlobalTagAddon.prefix + (Util.clearCache(false) ? "§a" + I18n.translate("globaltags.notifications.cacheCleared") : "§c" + I18n.translate("globaltags.notifications.cacheEmpty"))); + TagCache.clear(); + TagCache.resolveSelf(); + displayMessage( + Component.empty() + .append(GlobalTagAddon.prefix) + .append(Component.translatable("globaltags.notifications.cacheCleared", NamedTextColor.GREEN)) + ); return true; } } diff --git a/core/src/main/java/com/rappytv/globaltags/command/subcommands/LinkDiscordSubcommand.java b/core/src/main/java/com/rappytv/globaltags/command/subcommands/LinkDiscordSubcommand.java new file mode 100644 index 0000000..0c1ea9f --- /dev/null +++ b/core/src/main/java/com/rappytv/globaltags/command/subcommands/LinkDiscordSubcommand.java @@ -0,0 +1,32 @@ +package com.rappytv.globaltags.command.subcommands; + +import com.rappytv.globaltags.GlobalTagAddon; +import com.rappytv.globaltags.api.ApiHandler; +import net.labymod.api.Laby; +import net.labymod.api.client.chat.command.SubCommand; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.component.TextComponent; +import net.labymod.api.client.component.format.NamedTextColor; + +public class LinkDiscordSubcommand extends SubCommand { + + public LinkDiscordSubcommand() { + super("link"); + } + + @Override + public boolean execute(String s, String[] strings) { + ApiHandler.linkDiscord((info) -> { + if(info.isSuccessful()) { + String code = ((TextComponent) info.getMessage()).getText(); + Laby.references().chatExecutor().copyToClipboard(code); + displayMessage(GlobalTagAddon.prefix.copy().append( + Component.translatable("globaltags.messages.code", NamedTextColor.GREEN) + )); + } else displayMessage( + GlobalTagAddon.prefix.copy().append(info.getMessage()) + ); + }); + return true; + } +} diff --git a/core/src/main/java/com/rappytv/globaltags/command/subcommands/UnlinkDiscordSubcommand.java b/core/src/main/java/com/rappytv/globaltags/command/subcommands/UnlinkDiscordSubcommand.java new file mode 100644 index 0000000..d0351c7 --- /dev/null +++ b/core/src/main/java/com/rappytv/globaltags/command/subcommands/UnlinkDiscordSubcommand.java @@ -0,0 +1,20 @@ +package com.rappytv.globaltags.command.subcommands; + +import com.rappytv.globaltags.GlobalTagAddon; +import com.rappytv.globaltags.api.ApiHandler; +import net.labymod.api.client.chat.command.SubCommand; + +public class UnlinkDiscordSubcommand extends SubCommand { + + public UnlinkDiscordSubcommand() { + super("unlink"); + } + + @Override + public boolean execute(String s, String[] strings) { + ApiHandler.unlinkDiscord((response) -> displayMessage( + GlobalTagAddon.prefix.copy().append(response.getMessage())) + ); + return true; + } +} diff --git a/core/src/main/java/com/rappytv/globaltags/config/GlobalTagConfig.java b/core/src/main/java/com/rappytv/globaltags/config/GlobalTagConfig.java index ba7162e..fd4b51e 100644 --- a/core/src/main/java/com/rappytv/globaltags/config/GlobalTagConfig.java +++ b/core/src/main/java/com/rappytv/globaltags/config/GlobalTagConfig.java @@ -1,7 +1,12 @@ package com.rappytv.globaltags.config; +import com.rappytv.globaltags.api.ApiRequest; import com.rappytv.globaltags.config.subconfig.TagSubConfig; +import com.rappytv.globaltags.util.TagCache; +import com.rappytv.globaltags.util.Util; +import net.labymod.api.Laby; import net.labymod.api.addon.AddonConfig; +import net.labymod.api.client.gui.screen.widget.widgets.input.ButtonWidget.ButtonSetting; import net.labymod.api.client.gui.screen.widget.widgets.input.SliderWidget.SliderSetting; import net.labymod.api.client.gui.screen.widget.widgets.input.SwitchWidget.SwitchSetting; import net.labymod.api.configuration.loader.annotation.ConfigName; @@ -9,20 +14,36 @@ import net.labymod.api.configuration.loader.annotation.SpriteSlot; import net.labymod.api.configuration.loader.annotation.SpriteTexture; import net.labymod.api.configuration.loader.property.ConfigProperty; +import net.labymod.api.configuration.settings.Setting; +import net.labymod.api.configuration.settings.annotation.SettingSection; +import net.labymod.api.util.I18n; +import net.labymod.api.util.MethodOrder; @ConfigName("settings") @SpriteTexture("settings") public class GlobalTagConfig extends AddonConfig { - private static boolean localized; - public GlobalTagConfig() { - localizedResponses.addChangeListener((property, oldValue, newValue) -> localized = newValue); + localizedResponses.addChangeListener((property, oldValue, newValue) -> + ApiRequest.useLocalizedResponses(newValue) + ); } @SwitchSetting @SpriteSlot(size = 32) private final ConfigProperty enabled = new ConfigProperty<>(true); + @IntroducedIn(namespace = "globaltags", value = "1.1.9") + @SpriteSlot(size = 32, y = 2, x = 2) + @SwitchSetting + private final ConfigProperty localizedResponses = new ConfigProperty<>(true); + @MethodOrder(after = "localizedResponses") + @SpriteSlot(size = 32, y = 2, x = 3) + @ButtonSetting + public void joinDiscord(Setting setting) { + Laby.references().chatExecutor().openUrl("https://gt.rappytv.com/discord"); + } + + @SettingSection("display") @SwitchSetting @SpriteSlot(size = 32, x = 1) private final ConfigProperty showOwnTag = new ConfigProperty<>(false); @@ -33,13 +54,23 @@ public GlobalTagConfig() { @SpriteSlot(size = 32, y = 2, x = 1) @SwitchSetting private final ConfigProperty showBackground = new ConfigProperty<>(false); - @IntroducedIn(namespace = "globaltags", value = "1.1.9") - @SpriteSlot(size = 32, y = 2, x = 2) - @SwitchSetting - private final ConfigProperty localizedResponses = new ConfigProperty<>(true); - @SpriteSlot(size = 32, x = 1) + + @SettingSection("tags") + @SpriteSlot(size = 32, y = 1) private final TagSubConfig tags = new TagSubConfig(); + @MethodOrder(after = "tags") + @ButtonSetting + @SpriteSlot(size = 32, y = 2) + public void clearCache(Setting setting) { + TagCache.clear(); + TagCache.resolveSelf(); + Util.notify( + I18n.translate("globaltags.notifications.success"), + I18n.translate("globaltags.notifications.cacheCleared") + ); + } + @Override public ConfigProperty enabled() { return enabled; @@ -53,7 +84,4 @@ public ConfigProperty tagSize() { public ConfigProperty showBackground() { return showBackground; } - public static boolean localizedResponses() { - return localized; - } } diff --git a/core/src/main/java/com/rappytv/globaltags/config/subconfig/TagSubConfig.java b/core/src/main/java/com/rappytv/globaltags/config/subconfig/TagSubConfig.java index fb43e9d..3f40f6c 100644 --- a/core/src/main/java/com/rappytv/globaltags/config/subconfig/TagSubConfig.java +++ b/core/src/main/java/com/rappytv/globaltags/config/subconfig/TagSubConfig.java @@ -1,76 +1,116 @@ package com.rappytv.globaltags.config.subconfig; -import com.rappytv.globaltags.GlobalTagAddon; import com.rappytv.globaltags.api.ApiHandler; -import com.rappytv.globaltags.util.GlobalIcon; +import com.rappytv.globaltags.config.widget.TagPreviewWidget; +import com.rappytv.globaltags.config.widget.TagPreviewWidget.TagPreviewSetting; +import com.rappytv.globaltags.types.GlobalIcon; +import com.rappytv.globaltags.util.TagCache; import com.rappytv.globaltags.util.Util; -import net.labymod.api.Laby; +import com.rappytv.globaltags.util.Util.ResultType; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.component.format.NamedTextColor; import net.labymod.api.client.entity.player.tag.PositionType; import net.labymod.api.client.gui.screen.widget.widgets.input.ButtonWidget.ButtonSetting; import net.labymod.api.client.gui.screen.widget.widgets.input.TextFieldWidget.TextFieldSetting; import net.labymod.api.client.gui.screen.widget.widgets.input.dropdown.DropdownWidget.DropdownSetting; import net.labymod.api.configuration.loader.Config; -import net.labymod.api.configuration.loader.annotation.Exclude; +import net.labymod.api.configuration.loader.annotation.IntroducedIn; import net.labymod.api.configuration.loader.annotation.SpriteSlot; import net.labymod.api.configuration.loader.property.ConfigProperty; import net.labymod.api.configuration.settings.Setting; -import net.labymod.api.util.I18n; +import net.labymod.api.util.Debounce; import net.labymod.api.util.MethodOrder; public class TagSubConfig extends Config { - @Exclude - private final ApiHandler apiHandler; - public TagSubConfig() { - apiHandler = GlobalTagAddon.getAddon().getApiHandler(); - position.addChangeListener((property, oldValue, newValue) -> { - if(Laby.labyAPI().isFullyInitialized()) - apiHandler.setPosition(newValue); - }); - globalIcon.addChangeListener((property, oldValue, newValue) -> { - if(Laby.labyAPI().isFullyInitialized()) - apiHandler.setIcon(newValue); - }); + Runnable runnable = () -> Debounce.of( + "globaltags-config-update", + 1000, + TagPreviewWidget::change + ); + tag.addChangeListener(runnable); + position.addChangeListener(runnable); + globalIcon.addChangeListener(runnable); } + @SpriteSlot(size = 32, x = 1) + @IntroducedIn(namespace = "globaltags", value = "1.2.0") + @TagPreviewSetting + private final ConfigProperty tagPreview = new ConfigProperty<>(false); + @TextFieldSetting @SpriteSlot(size = 32, y = 1) private final ConfigProperty tag = new ConfigProperty<>(""); - @MethodOrder(after = "tag") - @ButtonSetting - @SpriteSlot(size = 32, y = 1, x = 1) - public void setTag(Setting setting) { - apiHandler.setTag(tag.get()); - tag.set(""); - Util.clearCache(false); - } - @DropdownSetting @SpriteSlot(size = 32, x = 3) private final ConfigProperty position = new ConfigProperty<>(PositionType.ABOVE_NAME); - @DropdownSetting @SpriteSlot(size = 32, y = 1, x = 2) private final ConfigProperty globalIcon = new ConfigProperty<>(GlobalIcon.NONE); @MethodOrder(after = "globalIcon") @ButtonSetting - @SpriteSlot(size = 32, y = 1, x = 3) - public void resetTag(Setting setting) { - apiHandler.resetTag(); + @SpriteSlot(size = 32, y = 1, x = 1) + @SuppressWarnings("ConstantConditions") + public void updateSettings(Setting setting) { + TagCache.resolveSelf((info) -> { + Component error = null; + if(Util.getSessionToken() == null) + error = Component.translatable("globaltags.settings.tags.tagPreview.labyConnect"); + else if(info == null) + error = Component.translatable("globaltags.settings.tags.tagPreview.noInfo"); + if(error != null) { + Util.notify( + Component.translatable("globaltags.notifications.error"), + error + ); + return; + } + if(!info.getPlainTag().equals(tag.get())) ApiHandler.setTag(tag.get(), (response) -> { + if(response.isSuccessful()) Util.update(ResultType.TAG, Component.text("✔", NamedTextColor.GREEN)); + else Util.update(ResultType.TAG, response.getMessage()); + }); + else Util.update(ResultType.TAG, Util.unchanged); + if(!info.getPosition().equals(position.get())) ApiHandler.setPosition(position.get(), (response) -> { + if(response.isSuccessful()) Util.update(ResultType.POSITION, Component.text("✔", NamedTextColor.GREEN)); + else Util.update(ResultType.POSITION, response.getMessage()); + }); + else Util.update(ResultType.POSITION, Util.unchanged); + if(!info.getGlobalIcon().equals(globalIcon.get())) ApiHandler.setIcon(globalIcon.get(), (response) -> { + if(response.isSuccessful()) Util.update(ResultType.ICON, Component.text("✔", NamedTextColor.GREEN)); + else Util.update(ResultType.ICON, response.getMessage()); + }); + else Util.update(ResultType.ICON, Util.unchanged); + }); } - @MethodOrder(after = "resetTag") + @MethodOrder(after = "updateSettings") @ButtonSetting - @SpriteSlot(size = 32, y = 2) - public void clearCache(Setting setting) { - if(Util.clearCache(true)) + @SpriteSlot(size = 32, y = 1, x = 3) + public void resetTag(Setting setting) { + ApiHandler.resetTag((info) -> { + if(info.isSuccessful()) TagPreviewWidget.refetch(); Util.notify( - I18n.translate("globaltags.notifications.success"), - I18n.translate("globaltags.notifications.cacheCleared") + Component.translatable(info.isSuccessful() + ? "globaltags.notifications.success" + : "globaltags.notifications.error" + ), + info.getMessage().color(NamedTextColor.WHITE) ); + }); + } + + public ConfigProperty tag() { + return tag; + } + public ConfigProperty position() { + return position; + } + + public ConfigProperty icon() { + return globalIcon; } } diff --git a/core/src/main/java/com/rappytv/globaltags/config/widget/AppealPopup.java b/core/src/main/java/com/rappytv/globaltags/config/widget/AppealPopup.java new file mode 100644 index 0000000..db99e9c --- /dev/null +++ b/core/src/main/java/com/rappytv/globaltags/config/widget/AppealPopup.java @@ -0,0 +1,55 @@ +package com.rappytv.globaltags.config.widget; + +import com.rappytv.globaltags.api.ApiHandler; +import com.rappytv.globaltags.util.Util; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.component.format.NamedTextColor; +import net.labymod.api.client.gui.screen.widget.Widget; +import net.labymod.api.client.gui.screen.widget.widgets.ComponentWidget; +import net.labymod.api.client.gui.screen.widget.widgets.input.ButtonWidget; +import net.labymod.api.client.gui.screen.widget.widgets.input.TextFieldWidget; +import net.labymod.api.client.gui.screen.widget.widgets.layout.list.VerticalListWidget; +import net.labymod.api.client.gui.screen.widget.widgets.popup.AdvancedPopup; +import org.jetbrains.annotations.Nullable; + +public class AppealPopup extends AdvancedPopup { + + @Override + public @Nullable Widget initialize() { + VerticalListWidget content = new VerticalListWidget<>().addId("content"); + ComponentWidget labelWidget = ComponentWidget.i18n( + "globaltags.settings.tags.tagPreview.appeal.popup.label" + ).addId("label", "popup-description"); + TextFieldWidget inputWidget = new TextFieldWidget() + .placeholder(Component.translatable( + "globaltags.settings.tags.tagPreview.appeal.popup.placeholder", + NamedTextColor.DARK_GRAY + )) + .addId("input", "popup-description"); + ButtonWidget sendButton = new ButtonWidget() + .updateComponent(Component.translatable( + "globaltags.settings.tags.tagPreview.appeal.popup.button", + NamedTextColor.RED + )) + .addId("send-button", "popup-description"); + sendButton.setEnabled(false); + sendButton.setActionListener(() -> + ApiHandler.appealBan(inputWidget.getText(), (response) -> + Util.notify( + Component.translatable(response.isSuccessful() + ? "globaltags.notifications.success" + : "globaltags.notifications.error" + ), + response.getMessage().color(NamedTextColor.WHITE) + ) + ) + ); + inputWidget.updateListener((text) -> sendButton.setEnabled(!text.isBlank())); + + content.addChild(labelWidget); + content.addChild(inputWidget); + content.addChild(sendButton); + + return content; + } +} diff --git a/core/src/main/java/com/rappytv/globaltags/config/widget/TagPreviewWidget.java b/core/src/main/java/com/rappytv/globaltags/config/widget/TagPreviewWidget.java new file mode 100644 index 0000000..9692397 --- /dev/null +++ b/core/src/main/java/com/rappytv/globaltags/config/widget/TagPreviewWidget.java @@ -0,0 +1,165 @@ +package com.rappytv.globaltags.config.widget; + +import com.rappytv.globaltags.config.subconfig.TagSubConfig; +import com.rappytv.globaltags.types.GlobalIcon; +import com.rappytv.globaltags.types.PlayerInfo; +import com.rappytv.globaltags.util.TagCache; +import com.rappytv.globaltags.util.Util; +import net.labymod.api.Laby; +import net.labymod.api.Textures.SpriteCommon; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.component.format.NamedTextColor; +import net.labymod.api.client.gui.icon.Icon; +import net.labymod.api.client.gui.lss.property.annotation.AutoWidget; +import net.labymod.api.client.gui.screen.Parent; +import net.labymod.api.client.gui.screen.activity.Link; +import net.labymod.api.client.gui.screen.widget.widgets.ComponentWidget; +import net.labymod.api.client.gui.screen.widget.widgets.input.ButtonWidget; +import net.labymod.api.client.gui.screen.widget.widgets.layout.list.HorizontalListWidget; +import net.labymod.api.client.gui.screen.widget.widgets.renderer.IconWidget; +import net.labymod.api.client.resources.ResourceLocation; +import net.labymod.api.configuration.settings.Setting; +import net.labymod.api.configuration.settings.accessor.SettingAccessor; +import net.labymod.api.configuration.settings.annotation.SettingElement; +import net.labymod.api.configuration.settings.annotation.SettingFactory; +import net.labymod.api.configuration.settings.annotation.SettingWidget; +import net.labymod.api.configuration.settings.widget.WidgetFactory; +import net.labymod.api.util.I18n; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Link("preview.lss") +@AutoWidget +@SettingWidget +public class TagPreviewWidget extends HorizontalListWidget { + + private final Icon adminIcon = Icon.texture(ResourceLocation.create( + "globaltags", + "textures/icons/staff.png" + )); + private static boolean refetch = true; + private static boolean changed = false; + private final TagSubConfig config; + + private TagPreviewWidget(TagSubConfig config) { + this.config = config; + } + + @Override + public void tick() { + super.tick(); + if(!refetch && !changed) return; + if(refetch) + TagCache.remove(Laby.labyAPI().getUniqueId()); + reInitialize(); + refetch = false; + changed = false; + } + + @Override + public void initialize(Parent parent) { + super.initialize(parent); + initialize(refetch); + } + + public void initialize(boolean refetched) { + TagCache.resolveSelf((info) -> + Laby.labyAPI().minecraft().executeOnRenderThread(() -> { + Component error = getError(info); + if (error != null) { + ComponentWidget errorComponent = ComponentWidget.component(error) + .addId("text", "error"); + this.addEntryInitialized(errorComponent); + } else { + if(refetched) { + config.tag().set(info.getPlainTag()); + config.position().set(info.getPosition()); + config.icon().set(info.getGlobalIcon()); + } + boolean updated = !config.tag().get().equals(info.getPlainTag()) + || !config.position().get().equals(info.getPosition()) + || !config.icon().get().equals(info.getGlobalIcon()); + if(changed && updated) { + Util.notify( + I18n.translate("globaltags.settings.tags.staged.title"), + I18n.translate("globaltags.settings.tags.staged.description") + ); + } + ComponentWidget tag = ComponentWidget.component( + config.tag().get().isBlank() + ? Component.translatable( + "globaltags.settings.tags.tagPreview.empty", + NamedTextColor.RED + ) + : Util.translateColorCodes(config.tag().get()) + ).addId("text"); + if (config.icon().get() != GlobalIcon.NONE) + this.addEntryInitialized(new IconWidget(config.icon().get().getIcon()).addId("icon")); + this.addEntryInitialized(tag); + if (info.isAdmin()) + this.addEntryInitialized(new IconWidget(adminIcon).addId("staff-icon")); + } + ButtonWidget refreshButton = ButtonWidget.icon(SpriteCommon.REFRESH, TagPreviewWidget::refetch) + .addId("refresh-button"); + addEntryInitialized(refreshButton); + if(info != null && info.isSuspended()) { + ButtonWidget appealButton = ButtonWidget.i18n( + "globaltags.settings.tags.tagPreview.appeal.name", + () -> new AppealPopup().displayInOverlay() + ).addId("appeal-button"); + appealButton.setHoverComponent(Component.translatable( + "globaltags.settings.tags.tagPreview.appeal.description", + NamedTextColor.GOLD + )); + appealButton.setEnabled(info.getSuspension().isAppealable()); + addEntryInitialized(appealButton); + } + })); + } + + public static void change() { + TagPreviewWidget.changed = true; + } + + public static void refetch() { + refetch = true; + } + + private Component getError(PlayerInfo info) { + String session = Util.getSessionToken(); + if(session == null) return Component.translatable("globaltags.settings.tags.tagPreview.labyConnect"); + else if(info == null) return Component.translatable("globaltags.settings.tags.tagPreview.noInfo"); + else if(info.isSuspended()) return Component.translatable( + "globaltags.settings.tags.tagPreview.banned", + Component.text( + info.getSuspension().getReason() != null + ? info.getSuspension().getReason() + : I18n.translate("globaltags.settings.tags.tagPreview.emptyReason") + ) + ); + return null; + } + + @SettingFactory + public static class Factory implements WidgetFactory { + + @Override + public TagPreviewWidget[] create(Setting setting, TagPreviewSetting annotation, SettingAccessor accessor) { + return new TagPreviewWidget[]{new TagPreviewWidget((TagSubConfig) accessor.config())}; + } + + @Override + public Class[] types() { + return new Class[0]; + } + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + @SettingElement(extended = true) + public @interface TagPreviewSetting { + + } +} diff --git a/core/src/main/java/com/rappytv/globaltags/interaction/ChangeTagBulletPoint.java b/core/src/main/java/com/rappytv/globaltags/interaction/ChangeTagBulletPoint.java new file mode 100644 index 0000000..c1f138c --- /dev/null +++ b/core/src/main/java/com/rappytv/globaltags/interaction/ChangeTagBulletPoint.java @@ -0,0 +1,37 @@ +package com.rappytv.globaltags.interaction; + +import com.rappytv.globaltags.activities.ChangeTagActivity; +import com.rappytv.globaltags.types.PlayerInfo; +import com.rappytv.globaltags.util.TagCache; +import net.labymod.api.Laby; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.entity.player.Player; +import net.labymod.api.client.entity.player.interaction.BulletPoint; +import net.labymod.api.client.gui.icon.Icon; + +public class ChangeTagBulletPoint implements BulletPoint { + + @Override + public Component getTitle() { + return Component.translatable("globaltags.context.changeTag.name"); + } + + @Override + public Icon getIcon() { + return null; + } + + @Override + public void execute(Player player) { + Laby.labyAPI().minecraft().executeNextTick(() -> + Laby.labyAPI().minecraft().minecraftWindow().displayScreen(new ChangeTagActivity(player.getUniqueId(), player.getName())) + ); + } + + @Override + public boolean isVisible(Player player) { + PlayerInfo executer = TagCache.get(Laby.labyAPI().getUniqueId()); + PlayerInfo target = TagCache.get(player.getUniqueId()); + return executer != null && executer.isAdmin() && target != null; + } +} diff --git a/core/src/main/java/com/rappytv/globaltags/interaction/ClearTagBulletPoint.java b/core/src/main/java/com/rappytv/globaltags/interaction/ClearTagBulletPoint.java new file mode 100644 index 0000000..859cc49 --- /dev/null +++ b/core/src/main/java/com/rappytv/globaltags/interaction/ClearTagBulletPoint.java @@ -0,0 +1,40 @@ +package com.rappytv.globaltags.interaction; + +import com.rappytv.globaltags.GlobalTagAddon; +import com.rappytv.globaltags.api.ApiHandler; +import com.rappytv.globaltags.types.PlayerInfo; +import com.rappytv.globaltags.util.TagCache; +import net.labymod.api.Laby; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.entity.player.Player; +import net.labymod.api.client.entity.player.interaction.BulletPoint; +import net.labymod.api.client.gui.icon.Icon; + +public class ClearTagBulletPoint implements BulletPoint { + + @Override + public Component getTitle() { + return Component.translatable("globaltags.context.clearTag.name"); + } + + @Override + public Icon getIcon() { + return null; + } + + @Override + public void execute(Player player) { + ApiHandler.resetTag(player.getUniqueId(), (response) -> Laby.references().chatExecutor().displayClientMessage( + Component.empty() + .append(GlobalTagAddon.prefix) + .append(response.getMessage()) + )); + } + + @Override + public boolean isVisible(Player player) { + PlayerInfo executer = TagCache.get(Laby.labyAPI().getUniqueId()); + PlayerInfo target = TagCache.get(player.getUniqueId()); + return executer != null && executer.isAdmin() && target != null && target.getTag() != null; + } +} diff --git a/core/src/main/java/com/rappytv/globaltags/interaction/EditBanInfoBulletPoint.java b/core/src/main/java/com/rappytv/globaltags/interaction/EditBanInfoBulletPoint.java new file mode 100644 index 0000000..4071182 --- /dev/null +++ b/core/src/main/java/com/rappytv/globaltags/interaction/EditBanInfoBulletPoint.java @@ -0,0 +1,45 @@ +package com.rappytv.globaltags.interaction; + +import com.rappytv.globaltags.GlobalTagAddon; +import com.rappytv.globaltags.activities.BanActivity; +import com.rappytv.globaltags.activities.EditBanActivity; +import com.rappytv.globaltags.api.ApiHandler; +import com.rappytv.globaltags.types.PlayerInfo; +import com.rappytv.globaltags.util.TagCache; +import net.labymod.api.Laby; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.entity.player.Player; +import net.labymod.api.client.entity.player.interaction.BulletPoint; +import net.labymod.api.client.gui.icon.Icon; + +public class EditBanInfoBulletPoint implements BulletPoint { + + private PlayerInfo target; + + @Override + public Component getTitle() { + return Component.translatable("globaltags.context.editBan.name"); + } + + @Override + public Icon getIcon() { + return null; + } + + @Override + public void execute(Player player) { + Laby.labyAPI().minecraft().executeNextTick(() -> + Laby.labyAPI().minecraft().minecraftWindow().displayScreen(new EditBanActivity( + player.getUniqueId(), + player.getName() + )) + ); + } + + @Override + public boolean isVisible(Player player) { + PlayerInfo executer = TagCache.get(Laby.labyAPI().getUniqueId()); + target = TagCache.get(player.getUniqueId()); + return executer != null && executer.isAdmin() && target != null && target.isSuspended(); + } +} diff --git a/core/src/main/java/com/rappytv/globaltags/interaction/ReportBulletPoint.java b/core/src/main/java/com/rappytv/globaltags/interaction/ReportBulletPoint.java index 8786598..dabfb39 100644 --- a/core/src/main/java/com/rappytv/globaltags/interaction/ReportBulletPoint.java +++ b/core/src/main/java/com/rappytv/globaltags/interaction/ReportBulletPoint.java @@ -1,8 +1,7 @@ package com.rappytv.globaltags.interaction; -import com.rappytv.globaltags.GlobalTagAddon; import com.rappytv.globaltags.activities.ReportUUIDActivity; -import com.rappytv.globaltags.util.PlayerInfo; +import com.rappytv.globaltags.types.PlayerInfo; import com.rappytv.globaltags.util.TagCache; import net.labymod.api.Laby; import net.labymod.api.client.component.Component; @@ -12,15 +11,9 @@ public class ReportBulletPoint implements BulletPoint { - private final GlobalTagAddon addon; - - public ReportBulletPoint(GlobalTagAddon addon) { - this.addon = addon; - } - @Override public Component getTitle() { - return Component.translatable("globaltags.context.report"); + return Component.translatable("globaltags.context.report.name"); } @Override @@ -31,7 +24,7 @@ public Icon getIcon() { @Override public void execute(Player player) { Laby.labyAPI().minecraft().executeNextTick(() -> - Laby.labyAPI().minecraft().minecraftWindow().displayScreen(new ReportUUIDActivity(addon, player.getUniqueId(), player.getName())) + Laby.labyAPI().minecraft().minecraftWindow().displayScreen(new ReportUUIDActivity(player.getUniqueId(), player.getName())) ); } diff --git a/core/src/main/java/com/rappytv/globaltags/interaction/ToggleAdminBulletPoint.java b/core/src/main/java/com/rappytv/globaltags/interaction/ToggleAdminBulletPoint.java new file mode 100644 index 0000000..c8742f7 --- /dev/null +++ b/core/src/main/java/com/rappytv/globaltags/interaction/ToggleAdminBulletPoint.java @@ -0,0 +1,42 @@ +package com.rappytv.globaltags.interaction; + +import com.rappytv.globaltags.GlobalTagAddon; +import com.rappytv.globaltags.api.ApiHandler; +import com.rappytv.globaltags.types.PlayerInfo; +import com.rappytv.globaltags.util.TagCache; +import net.labymod.api.Laby; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.entity.player.Player; +import net.labymod.api.client.entity.player.interaction.BulletPoint; +import net.labymod.api.client.gui.icon.Icon; + +public class ToggleAdminBulletPoint implements BulletPoint { + + private PlayerInfo target; + + @Override + public Component getTitle() { + return Component.translatable("globaltags.context.admin." + (target.isAdmin() ? "remove" : "set")); + } + + @Override + public Icon getIcon() { + return null; + } + + @Override + public void execute(Player player) { + ApiHandler.toggleAdmin(player.getUniqueId(), (response) -> Laby.references().chatExecutor().displayClientMessage( + Component.empty() + .append(GlobalTagAddon.prefix) + .append(response.getMessage()) + )); + } + + @Override + public boolean isVisible(Player player) { + PlayerInfo executer = TagCache.get(Laby.labyAPI().getUniqueId()); + target = TagCache.get(player.getUniqueId()); + return executer != null && executer.isAdmin() && target != null; + } +} diff --git a/core/src/main/java/com/rappytv/globaltags/interaction/ToggleBanBulletPoint.java b/core/src/main/java/com/rappytv/globaltags/interaction/ToggleBanBulletPoint.java new file mode 100644 index 0000000..61e5ed4 --- /dev/null +++ b/core/src/main/java/com/rappytv/globaltags/interaction/ToggleBanBulletPoint.java @@ -0,0 +1,52 @@ +package com.rappytv.globaltags.interaction; + +import com.rappytv.globaltags.GlobalTagAddon; +import com.rappytv.globaltags.activities.BanActivity; +import com.rappytv.globaltags.api.ApiHandler; +import com.rappytv.globaltags.types.PlayerInfo; +import com.rappytv.globaltags.util.TagCache; +import net.labymod.api.Laby; +import net.labymod.api.client.component.Component; +import net.labymod.api.client.entity.player.Player; +import net.labymod.api.client.entity.player.interaction.BulletPoint; +import net.labymod.api.client.gui.icon.Icon; + +public class ToggleBanBulletPoint implements BulletPoint { + + private PlayerInfo target; + + @Override + public Component getTitle() { + return Component.translatable("globaltags.context." + (target.isSuspended() ? "unban" : "ban") + ".name"); + } + + @Override + public Icon getIcon() { + return null; + } + + @Override + public void execute(Player player) { + if(target.isSuspended()) { + ApiHandler.unbanPlayer(target.getUUID(), (response) -> Laby.references().chatExecutor().displayClientMessage( + Component.empty() + .append(GlobalTagAddon.prefix) + .append(response.getMessage()) + )); + } else { + Laby.labyAPI().minecraft().executeNextTick(() -> + Laby.labyAPI().minecraft().minecraftWindow().displayScreen(new BanActivity( + player.getUniqueId(), + player.getName() + )) + ); + } + } + + @Override + public boolean isVisible(Player player) { + PlayerInfo executer = TagCache.get(Laby.labyAPI().getUniqueId()); + target = TagCache.get(player.getUniqueId()); + return executer != null && executer.isAdmin() && target != null; + } +} diff --git a/core/src/main/java/com/rappytv/globaltags/listener/ServerNavigationListener.java b/core/src/main/java/com/rappytv/globaltags/listener/ServerNavigationListener.java index b16837c..927c1ab 100644 --- a/core/src/main/java/com/rappytv/globaltags/listener/ServerNavigationListener.java +++ b/core/src/main/java/com/rappytv/globaltags/listener/ServerNavigationListener.java @@ -1,6 +1,6 @@ package com.rappytv.globaltags.listener; -import com.rappytv.globaltags.util.Util; +import com.rappytv.globaltags.util.TagCache; import net.labymod.api.event.Subscribe; import net.labymod.api.event.client.network.server.ServerDisconnectEvent; @@ -8,6 +8,7 @@ public class ServerNavigationListener { @Subscribe public void onLeave(ServerDisconnectEvent event) { - Util.clearCache(false); + TagCache.clear(); + TagCache.resolveSelf(); } } diff --git a/core/src/main/java/com/rappytv/globaltags/nametag/CustomTag.java b/core/src/main/java/com/rappytv/globaltags/nametag/CustomTag.java index 40c41e6..a987cd7 100644 --- a/core/src/main/java/com/rappytv/globaltags/nametag/CustomTag.java +++ b/core/src/main/java/com/rappytv/globaltags/nametag/CustomTag.java @@ -1,14 +1,10 @@ package com.rappytv.globaltags.nametag; import com.rappytv.globaltags.GlobalTagAddon; -import com.rappytv.globaltags.api.requests.InfoGetRequest; import com.rappytv.globaltags.config.GlobalTagConfig; -import com.rappytv.globaltags.util.PlayerInfo; +import com.rappytv.globaltags.types.PlayerInfo; import com.rappytv.globaltags.util.TagCache; -import com.rappytv.globaltags.util.Util; import net.labymod.api.Laby; -import net.labymod.api.client.component.Component; -import net.labymod.api.client.component.serializer.legacy.LegacyComponentSerializer; import net.labymod.api.client.entity.Entity; import net.labymod.api.client.entity.player.Player; import net.labymod.api.client.entity.player.tag.PositionType; @@ -20,8 +16,6 @@ import net.labymod.api.client.resources.ResourceLocation; import org.jetbrains.annotations.Nullable; import java.awt.*; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; @SuppressWarnings("deprecation") @@ -31,7 +25,6 @@ public class CustomTag extends NameTag { private final int black = new Color(0, 0, 0, 70).getRGB(); private final GlobalTagConfig config; private final PositionType position; - private final Set resolving = new HashSet<>(); private PlayerInfo info; public CustomTag(GlobalTagAddon addon, PositionType position) { @@ -60,23 +53,8 @@ public float getScale() { if(TagCache.has(uuid)) info = TagCache.get(uuid); else { - if(position == PositionType.ABOVE_NAME && !resolving.contains(uuid)) { - resolving.add(uuid); - InfoGetRequest request = new InfoGetRequest(uuid, Util.getSessionToken()); - request.sendAsyncRequest((response) -> { - if(!request.isSuccessful()) { - TagCache.add(uuid, null); - } else { - TagCache.add(uuid, new PlayerInfo( - translateColorCodes(request.getTag()), - request.getPosition(), - request.getIcon(), - request.isAdmin() - )); - } - resolving.remove(uuid); - }); - } + if(position == PositionType.ABOVE_NAME) + TagCache.resolve(uuid); } if(info == null || info.getTag() == null) return null; if(!position.equals(info.getPosition())) return null; @@ -112,11 +90,4 @@ protected NameTagBackground getCustomBackground() { public boolean isVisible() { return !this.entity.isCrouching() && super.isVisible(); } - - private Component translateColorCodes(String string) { - if(string == null) return null; - return LegacyComponentSerializer - .legacyAmpersand() - .deserialize(string); - } } diff --git a/core/src/main/java/com/rappytv/globaltags/util/GlobalIcon.java b/core/src/main/java/com/rappytv/globaltags/util/GlobalIcon.java deleted file mode 100644 index 6079609..0000000 --- a/core/src/main/java/com/rappytv/globaltags/util/GlobalIcon.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.rappytv.globaltags.util; - -@SuppressWarnings("unused") -public enum GlobalIcon { - NONE, - BEREAL, - DISCORD, - EBIO, - EPICGAMES, - GITHUB, - GITLAB, - INSTAGRAM, - KICK, - PLAYSTATION, - SNAPCHAT, - STEAM, - THREADS, - TIKTOK, - TWITCH, - X, - XBOX, - YOUTUBE -} diff --git a/core/src/main/java/com/rappytv/globaltags/util/PlayerInfo.java b/core/src/main/java/com/rappytv/globaltags/util/PlayerInfo.java deleted file mode 100644 index 86873eb..0000000 --- a/core/src/main/java/com/rappytv/globaltags/util/PlayerInfo.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.rappytv.globaltags.util; - -import net.labymod.api.client.component.Component; -import net.labymod.api.client.entity.player.tag.PositionType; -import net.labymod.api.client.gui.icon.Icon; -import net.labymod.api.client.resources.ResourceLocation; -import java.util.HashMap; -import java.util.Map; - -public class PlayerInfo { - - private final Component tag; - private final String position; - private final String icon; - private final boolean admin; - - public PlayerInfo(Component tag, String position, String icon, boolean admin) { - this.tag = tag; - this.position = position; - this.icon = icon; - this.admin = admin; - } - - public Component getTag() { - return tag; - } - - public PositionType getPosition() { - if(position == null) return PositionType.ABOVE_NAME; - return switch(position) { - default -> PositionType.ABOVE_NAME; - case "BELOW" -> PositionType.BELOW_NAME; - case "RIGHT" -> PositionType.RIGHT_TO_NAME; - case "LEFT" -> PositionType.LEFT_TO_NAME; - }; - } - - // To reduce object creation. Won't be cleared until restart - private final Map iconCache = new HashMap<>(); - - public Icon getIcon() { - if(iconCache.containsKey(this.icon.toLowerCase())) - return iconCache.get(this.icon.toLowerCase()); - ResourceLocation location = ResourceLocation.create( - "globaltags", - "textures/icons/" + this.icon.toLowerCase() + ".png" - ); - iconCache.put( - this.icon.toLowerCase(), - location.exists() ? Icon.texture(location) : null - ); - return getIcon(); - } - - public boolean isAdmin() { - return admin; - } -} diff --git a/core/src/main/java/com/rappytv/globaltags/util/TagCache.java b/core/src/main/java/com/rappytv/globaltags/util/TagCache.java deleted file mode 100644 index 82ebdc7..0000000 --- a/core/src/main/java/com/rappytv/globaltags/util/TagCache.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.rappytv.globaltags.util; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -public class TagCache { - - private static final Map cache = new HashMap<>(); - - public static void add(UUID uuid, PlayerInfo info) { - cache.put(uuid, info); - } - public static boolean has(UUID uuid) { - return cache.containsKey(uuid); - } - public static PlayerInfo get(UUID uuid) { - return cache.get(uuid); - } - public static boolean isEmpty() { - return cache.isEmpty(); - } - public static void clear() { - cache.clear(); - } -} diff --git a/core/src/main/java/com/rappytv/globaltags/util/Util.java b/core/src/main/java/com/rappytv/globaltags/util/Util.java deleted file mode 100644 index 9ac41e8..0000000 --- a/core/src/main/java/com/rappytv/globaltags/util/Util.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.rappytv.globaltags.util; - -import net.labymod.api.Laby; -import net.labymod.api.client.component.Component; -import net.labymod.api.labyconnect.LabyConnectSession; -import net.labymod.api.labyconnect.TokenStorage.Purpose; -import net.labymod.api.labyconnect.TokenStorage.Token; -import net.labymod.api.notification.Notification; -import net.labymod.api.notification.Notification.Type; -import net.labymod.api.util.I18n; -import org.jetbrains.annotations.Nullable; - -public class Util { - - public static void notify(String title, String text) { - Notification.Builder builder = Notification.builder() - .title(Component.text(title)) - .text(Component.text(text)) - .type(Type.SOCIAL); - Laby.labyAPI().notificationController().push(builder.build()); - } - - public static boolean clearCache(boolean notify) { - if(TagCache.isEmpty()) { - if(notify) Util.notify( - I18n.translate("globaltags.notifications.error"), - I18n.translate("globaltags.notifications.cacheEmpty") - ); - return false; - } - TagCache.clear(); - return true; - } - - public static @Nullable String getSessionToken() { - LabyConnectSession session = Laby.labyAPI().labyConnect().getSession(); - if(session == null) return null; - - Token token = session.tokenStorage().getToken( - Purpose.JWT, - session.self().getUniqueId() - ); - - if(token == null || token.isExpired()) return null; - - return token.getToken(); - } -} diff --git a/core/src/main/resources/assets/globaltags/i18n/en_us.json b/core/src/main/resources/assets/globaltags/i18n/en_us.json index a079e94..6180d05 100644 --- a/core/src/main/resources/assets/globaltags/i18n/en_us.json +++ b/core/src/main/resources/assets/globaltags/i18n/en_us.json @@ -2,9 +2,25 @@ "globaltags": { "settings": { "name": "Global Tags", + "header": { + "display": { + "name": "Display settings" + }, + "tags": { + "name": "Tag settings" + } + }, "enabled": { "name": "Enabled" }, + "localizedResponses": { + "name": "Localize API responses", + "description": "If this option is enabled, the addon also sends your minecraft language to the API. If the translations exist, you will receive localized responses. Your minecraft language will not be stored anywhere." + }, + "joinDiscord": { + "name": "Discord Server", + "text": "Join" + }, "showOwnTag": { "name": "Show own tag" }, @@ -12,21 +28,34 @@ "name": "Tag size" }, "showBackground": { - "name": "Show background" - }, - "localizedResponses": { - "name": "Localize API responses", - "description": "If this option is enabled, the addon also sends your minecraft language to the API. If the translations exist, you will receive localized responses. Your minecraft language will not be stored anywhere." + "name": "Show background", + "description": "When this option is enabled, you'll see the gray vanilla nametag background behind global tags." }, "tags": { - "name": "Tag settings", - "tag": { - "name": "Global tag", - "description": "This tag gets published as soon as you press the button below." + "name": "Global tag settings", + "staged": { + "title": "Staged changes.", + "description": "Click on the \"Publish settings\" button to publish changes!" + }, + "tagPreview": { + "name": "Tag Preview", + "banned": "Your account is suspended!\nReason: %s", + "noInfo": "Couldn't fetch account info!", + "labyConnect": "You're not connected to LabyConnect!", + "empty": "", + "emptyReason": "No reason provided", + "appeal": { + "name": "Appeal", + "description": "⚠ This button will only be clickable if your suspension is appealable.", + "popup": { + "label": "Why should we unban you?", + "placeholder": "Please enter a reason...", + "button": "Send appeal" + } + } }, - "setTag": { - "name": "Set tag you entered in the text field", - "text": "Click" + "tag": { + "name": "Global tag" }, "position": { "name": "Global position", @@ -39,7 +68,7 @@ } }, "globalIcon": { - "name": "Global Icon", + "name": "Global icon", "entries": { "none": "None", "discord": "Discord", @@ -62,39 +91,72 @@ "youtube": "YouTube" } }, + "updateSettings": { + "name": "Publish settings", + "text": "Update", + "result": "Tag: %s\nPosition: %s\nIcon: %s", + "unchanged": "Unchanged" + }, "resetTag": { "name": "Delete global tag", "text": "Delete" - }, - "clearCache": { - "name": "Clear cache", - "text": "Clear", - "description": "Clears the tag-cache manually.\nThe cache get's cleared automatically every §b5 minutes§f." } + }, + "clearCache": { + "name": "Clear cache", + "text": "Clear", + "description": "Clears the tag-cache manually.\nThe cache get's cleared automatically every §b5 minutes§f.\nYou can additionally clear the cache with §b/gt cc§f." } }, - "activity": { - "newtag": "New Tag" - }, "notifications": { "success": "Success!", "error": "An error ocurred", - "cacheCleared": "The cache was cleared!", - "cacheEmpty": "The cache is already empty!" + "cacheCleared": "The cache was cleared!" }, "messages": { "clearCache": "Clear cache", "hoverClearCache": "Click here to clear the tag cache!", - "offline": "Connection failed!" + "offline": "Connection failed!", + "code": "The code was copied to your clipboard!" }, "context": { - "report": "Report Globaltag" - }, - "report": { - "title": "Report %s", - "send": "Send report", "reason": "Reason", - "placeholder": "Please enter a reason..." + "placeholder": "Please enter a reason...", + "report": { + "name": "Report GlobalTag", + "title": "Report %s", + "send": "Send report" + }, + "ban": { + "name": "Ban GlobalTag player", + "title": "Ban %s", + "send": "Ban" + }, + "unban": { + "name": "Unban GlobalTag player", + "title": "Unban %s", + "send": "Unban" + }, + "editBan": { + "name": "Edit GlobalTag ban", + "title": "Edit %s's ban", + "send": "Submit changes", + "appealable": "Appealable" + }, + "changeTag": { + "name": "Change GlobalTag", + "title": "Change %s's Tag", + "label": "New GlobalTag", + "placeholder": "Enter the updated GlobalTag...", + "send": "Update Tag" + }, + "clearTag": { + "name": "Clear GlobalTag" + }, + "admin": { + "set": "Make GlobalTag Admin", + "remove": "Remove GlobalTag Admin" + } } } } \ No newline at end of file diff --git a/core/src/main/resources/assets/globaltags/themes/fancy/lss/report.lss b/core/src/main/resources/assets/globaltags/themes/fancy/lss/input.lss similarity index 79% rename from core/src/main/resources/assets/globaltags/themes/fancy/lss/report.lss rename to core/src/main/resources/assets/globaltags/themes/fancy/lss/input.lss index 9b89b24..1fe3651 100644 --- a/core/src/main/resources/assets/globaltags/themes/fancy/lss/report.lss +++ b/core/src/main/resources/assets/globaltags/themes/fancy/lss/input.lss @@ -34,20 +34,31 @@ alignment-y: center; overwrite-width: false; - .reason { + .label { margin-top: 40; alignment-x: center; alignment-y: center; } - .text-field { + .input { margin-top: 6; width: 200; alignment-x: center; alignment-y: center; } - .report-button { + .appealable-label { + margin-top: 8; + alignment-x: center; + alignment-y: center; + } + + .check-box { + margin-top: 5; + alignment-x: center; + } + + .send-button { margin-top: 5; width: 50; height: 20; diff --git a/core/src/main/resources/assets/globaltags/themes/fancy/lss/preview.lss b/core/src/main/resources/assets/globaltags/themes/fancy/lss/preview.lss new file mode 100644 index 0000000..183000c --- /dev/null +++ b/core/src/main/resources/assets/globaltags/themes/fancy/lss/preview.lss @@ -0,0 +1,44 @@ +TagPreview { + height: fit-content; + orientation: horizontal; + + .text { + margin-left: 2; + } + + .error { + text-color: red; + } + + .icon { + margin-left: 1; + margin-right: 1; + height: 16; + width: height; + } + + .staff-icon { + margin-left: 2; + height: 11; + width: height; + } + + .appeal-button { + height: 20; + width: fit-content; + # padding: 0; + alignment: right; + } + + .refresh-button { + height: 20; + width: height; + padding: 0; + alignment: right; + + .button-icon { + height: 8; + width: height; + } + } +} \ No newline at end of file diff --git a/core/src/main/resources/assets/globaltags/themes/vanilla/lss/report.lss b/core/src/main/resources/assets/globaltags/themes/vanilla/lss/input.lss similarity index 75% rename from core/src/main/resources/assets/globaltags/themes/vanilla/lss/report.lss rename to core/src/main/resources/assets/globaltags/themes/vanilla/lss/input.lss index 90d26aa..d70ab1e 100644 --- a/core/src/main/resources/assets/globaltags/themes/vanilla/lss/report.lss +++ b/core/src/main/resources/assets/globaltags/themes/vanilla/lss/input.lss @@ -34,22 +34,33 @@ alignment-y: center; overwrite-width: false; - .reason { - margin-top: 40; + .label { + margin-top: 30; alignment-x: center; alignment-y: center; } - .text-field { + .input { margin-top: 6; width: 200; alignment-x: center; alignment-y: center; } - .report-button { + .appealable-label { + margin-top: 8; + alignment-x: center; + alignment-y: center; + } + + .check-box { + margin-top: 5; + alignment-x: center; + } + + .send-button { margin-top: 5; - width: 70; + width: 80; height: 20; alignment-x: center; alignment-y: center; diff --git a/core/src/main/resources/assets/globaltags/themes/vanilla/lss/preview.lss b/core/src/main/resources/assets/globaltags/themes/vanilla/lss/preview.lss new file mode 100644 index 0000000..183000c --- /dev/null +++ b/core/src/main/resources/assets/globaltags/themes/vanilla/lss/preview.lss @@ -0,0 +1,44 @@ +TagPreview { + height: fit-content; + orientation: horizontal; + + .text { + margin-left: 2; + } + + .error { + text-color: red; + } + + .icon { + margin-left: 1; + margin-right: 1; + height: 16; + width: height; + } + + .staff-icon { + margin-left: 2; + height: 11; + width: height; + } + + .appeal-button { + height: 20; + width: fit-content; + # padding: 0; + alignment: right; + } + + .refresh-button { + height: 20; + width: height; + padding: 0; + alignment: right; + + .button-icon { + height: 8; + width: height; + } + } +} \ No newline at end of file diff --git a/core/src/main/resources/assets/globaltags/themes/vanilla/textures/settings.png b/core/src/main/resources/assets/globaltags/themes/vanilla/textures/settings.png index 7eb6afc..e5aaf2f 100644 Binary files a/core/src/main/resources/assets/globaltags/themes/vanilla/textures/settings.png and b/core/src/main/resources/assets/globaltags/themes/vanilla/textures/settings.png differ diff --git a/settings.gradle.kts b/settings.gradle.kts index 62d3fac..1c5ea34 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ rootProject.name = "GlobalTags" pluginManagement { - val labyGradlePluginVersion = "0.3.48" + val labyGradlePluginVersion = "0.4.1" plugins { id("net.labymod.gradle") version (labyGradlePluginVersion) }