Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into gh-pages
Browse files Browse the repository at this point in the history
  • Loading branch information
tomwmth committed Aug 22, 2024
2 parents 3e1014c + 1a293df commit e72f527
Show file tree
Hide file tree
Showing 17 changed files with 268 additions and 106 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This plugin does the following by default:
- `/acnotify [player] [content]` - Sends a notification to the given player containing the given content. Requires the `alpineapi.notify` permission.
- `/aclist` - Displays a list of all online Alpine Client users. Requires the `alpineapi.list` permission.

The plugin should work on any server running on at least `1.8.8` and Java 8.
The plugin should work on any server running on at least `1.8.8`, Spigot and Java 8.

Much more is possible with this API, however it would require your development team to implement it with your plugins manually. This is what is available by default with no extra development work.

Expand All @@ -21,7 +21,6 @@ This plugin exposes an API that can be leveraged to add Alpine Client integratio
- Accessing certain user data:
- Minecraft version
- Mod platform
- Loaded mod IDs
- Sending custom notifications to the client
- Sending temporary waypoints to the client
- Sending cooldown information to the client
Expand Down
6 changes: 3 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
id("java-library")
id("maven-publish")
id("net.kyori.blossom") version "1.3.1"
id("com.github.johnrengelman.shadow") version "8.1.1"
id("com.gradleup.shadow") version "8.3.0"
}

group = this.compileGroup()
Expand Down Expand Up @@ -38,7 +38,7 @@ dependencies {
depend(this, "dev.rollczi:litecommands-adventure-platform:${liteCommands}")

val adventure = "4.17.0"
depend(this, "net.kyori:adventure-platform-bukkit:4.3.2")
depend(this, "net.kyori:adventure-platform-bukkit:4.3.4")
depend(this, "net.kyori:adventure-api:${adventure}")
depend(this, "net.kyori:adventure-text-minimessage:${adventure}")
depend(this, "net.kyori:adventure-text-serializer-legacy:${adventure}")
Expand Down Expand Up @@ -201,7 +201,7 @@ fun compileVersion(): String {
val minor = project.properties["version_minor"]
val patch = project.properties["version_patch"]
val preRelease = project.properties["version_pre_release"]
return "${major}.${minor}.${patch}${if (preRelease == "none") "" else preRelease}"
return "${major}.${minor}.${patch}${if (preRelease == "none") "" else "-${preRelease}"}"
}

fun depend(scope: DependencyHandlerScope, dependency: String, api: Boolean = false) {
Expand Down
2 changes: 2 additions & 0 deletions example/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ repositories {
mavenCentral()
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
maven("https://oss.sonatype.org/content/repositories/snapshots")
maven("https://lib.alpn.cloud/alpine-public/")
maven("https://repo.panda-lang.org/releases")
}

dependencies {
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ plugin_id=alpineclientapi

version_major=1
version_minor=3
version_patch=0
version_patch=1
version_pre_release=none
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Fri Jun 02 18:20:52 EDT 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,17 @@ public final class AlpinePlayer {
private final Player bukkitPlayer;
private final String platform;
private final String version;
private final List<String> mods;

@ApiStatus.Internal
public AlpinePlayer(@NotNull Player bukkitPlayer, @NotNull HandshakeData data) {
this(bukkitPlayer, data.getPlatform(), data.getVersion(), data.getMods());
this(bukkitPlayer, data.getPlatform(), data.getVersion());
}

@ApiStatus.Internal
public AlpinePlayer(@NotNull Player bukkitPlayer, @NotNull String platform, @NotNull String version, @NotNull List<String> mods) {
public AlpinePlayer(@NotNull Player bukkitPlayer, @NotNull String platform, @NotNull String version) {
this.bukkitPlayer = bukkitPlayer;
this.platform = platform;
this.version = version;
this.mods = mods;
}

/**
Expand Down Expand Up @@ -84,16 +82,19 @@ public AlpinePlayer(@NotNull Player bukkitPlayer, @NotNull String platform, @Not
* e.g. {@code ["sodium", "lithium", "alpineclient"]}
*
* @return a list containing mod IDs
* @deprecated functionality removed; no replacement
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "1.4.0")
public @NotNull List<String> getMods() {
return Collections.unmodifiableList(this.mods);
return Collections.emptyList();
}

/**
* Get the full client brand consisting of their version
* and platform.
* <p>
* e.g. {@code 1.20-fabric}
* e.g. {@code 1.18.2-fabric}
*
* @return the client brand
*/
Expand Down
12 changes: 1 addition & 11 deletions src/main/java/com/alpineclient/plugin/config/AbstractConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@
package com.alpineclient.plugin.config;

import de.exlll.configlib.Configuration;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import net.kyori.adventure.text.format.TextColor;
import org.jetbrains.annotations.NotNull;

import java.nio.file.Path;

/**
* @author BestBearr
Expand All @@ -29,11 +26,4 @@ public class AbstractConfig {
public static final TextColor DIVIDER_COLOR = TextColor.color(0x777777);
public static final TextColor TEXT_COLOR = TextColor.color(0xdbfce9);
public static final TextColor ERROR_TEXT_COLOR = TextColor.color(0xfcd5cc);

@Getter @Setter
private transient Path configPath;

public AbstractConfig(@NotNull Path configPath) {
this.configPath = configPath;
}
}
79 changes: 33 additions & 46 deletions src/main/java/com/alpineclient/plugin/config/ConfigManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@
import com.alpineclient.plugin.Reference;
import com.alpineclient.plugin.config.impl.GeneralConfig;
import com.alpineclient.plugin.config.impl.MessageConfig;
import com.google.common.collect.ImmutableMap;
import de.exlll.configlib.ConfigLib;
import de.exlll.configlib.YamlConfigurationProperties;
import de.exlll.configlib.YamlConfigurations;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

Expand All @@ -26,74 +30,57 @@
* Created on 02/06/23
*/
public final class ConfigManager {
@Getter
private static ConfigManager instance;
private static final Map<Class<? extends AbstractConfig>, Path> CONFIGURATIONS = ImmutableMap.of(
GeneralConfig.class, Paths.get("config.yml"),
MessageConfig.class, Paths.get("messages.yml")
);

public static final YamlConfigurationProperties PROPERTIES = ConfigLib.BUKKIT_DEFAULT_PROPERTIES.toBuilder()
private static final YamlConfigurationProperties PROPERTIES = ConfigLib.BUKKIT_DEFAULT_PROPERTIES.toBuilder()
.header(String.join("\n",
Reference.NAME + " (" + Reference.VERSION + ")",
"Copyright (c) 2023, Crystal Development, LLC. All rights reserved.",
"",
"Messages are deserialized by the Adventure library",
" - https://webui.advntr.dev/",
""))
.inputNulls(true).outputNulls(true)
.charset(StandardCharsets.UTF_8)
.build();

@Getter
private final Map<Class<? extends AbstractConfig>, AbstractConfig> registeredConfigurations = new HashMap<>();
private static ConfigManager instance;

public ConfigManager() {
instance = this;
PluginMain main = PluginMain.getInstance();
private final Path directory;

File path = main.getDataFolder();
if (!path.exists() && !path.mkdirs())
throw new IllegalStateException("Unable to generate configuration directory");
private final Map<Class<? extends AbstractConfig>, AbstractConfig> loadedConfigs = new HashMap<>(CONFIGURATIONS.size());

File dataFolder = main.getDataFolder();
this.registeredConfigurations.put(GeneralConfig.class, new GeneralConfig(new File(dataFolder, "config.yml").toPath()));
this.registeredConfigurations.put(MessageConfig.class, new MessageConfig(new File(dataFolder, "messages.yml").toPath()));
public ConfigManager() {
instance = this;
this.directory = PluginMain.getInstance().getDataFolder().toPath();

// Load/save the config
for (Map.Entry<Class<? extends AbstractConfig>, AbstractConfig> abstractConfigEntry : this.registeredConfigurations.entrySet()) {
AbstractConfig config = abstractConfigEntry.getValue();
if (Files.exists(config.getConfigPath())) {
AbstractConfig newConfig = YamlConfigurations.load(config.getConfigPath(), config.getClass(), PROPERTIES);
newConfig.setConfigPath(config.getConfigPath());
this.registeredConfigurations.put(config.getClass(), newConfig);
YamlConfigurations.save(config.getConfigPath(), (Class<? super AbstractConfig>) config.getClass(), newConfig, PROPERTIES);
if (!Files.exists(this.directory)) {
try {
Files.createDirectories(this.directory);
}
else {
YamlConfigurations.save(config.getConfigPath(), (Class<? super AbstractConfig>) config.getClass(), config, PROPERTIES);
catch (IOException ex) {
Reference.LOGGER.error("Unable to create config directory at \"{}\"", this.directory, ex);
}
}
}

public void loadConfigs() {
for (Map.Entry<Class<? extends AbstractConfig>, AbstractConfig> abstractConfigEntry : this.registeredConfigurations.entrySet()) {
AbstractConfig config = abstractConfigEntry.getValue();
if (!Files.exists(config.getConfigPath()))
YamlConfigurations.save(config.getConfigPath(), (Class<? super AbstractConfig>) config.getClass(), config, PROPERTIES);
else {
AbstractConfig newConfig = YamlConfigurations.load(config.getConfigPath(), config.getClass(), PROPERTIES);
newConfig.setConfigPath(config.getConfigPath());
this.registeredConfigurations.put(config.getClass(), newConfig);
CONFIGURATIONS.forEach((key, val) -> {
try {
AbstractConfig loadedConfig = YamlConfigurations.update(this.directory.resolve(val), key, PROPERTIES);
this.loadedConfigs.put(key, loadedConfig);
}
}
}

public void saveConfigs() {
for (Map.Entry<Class<? extends AbstractConfig>, AbstractConfig> abstractConfigEntry : this.registeredConfigurations.entrySet()) {
AbstractConfig config = abstractConfigEntry.getValue();
YamlConfigurations.save(config.getConfigPath(), (Class<? super AbstractConfig>) config.getClass(), config, PROPERTIES);
}
catch (RuntimeException ex) {
Reference.LOGGER.error("Unable to load config file \"{}\"", val, ex);
}
});
}

public <T extends AbstractConfig> @NotNull T getConfig(@NotNull Class<T> configClass) {
AbstractConfig config = this.registeredConfigurations.get(configClass);
public <T extends AbstractConfig> @NotNull T getConfig(@NotNull Class<T> clazz) {
AbstractConfig config = this.loadedConfigs.get(clazz);
if (config != null)
return (T) config;
throw new IllegalStateException("config was not registered");
throw new IllegalStateException("No config was loaded for " + clazz.getSimpleName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
import com.google.common.collect.ImmutableMap;
import de.exlll.configlib.Comment;
import lombok.NoArgsConstructor;
import org.jetbrains.annotations.NotNull;

import java.nio.file.Path;
import java.util.Map;

/**
Expand All @@ -34,8 +32,4 @@ public final class GeneralConfig extends AbstractConfig {
" A list of all module IDs can be found in the GitHub repository under \"MODULES.md\"."
})
public Map<String, Boolean> modules = ImmutableMap.of("cannon_view", false);

public GeneralConfig(@NotNull Path configPath) {
super(configPath);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
import lombok.NoArgsConstructor;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextDecoration;
import org.jetbrains.annotations.NotNull;

import java.nio.file.Path;

/**
* @author BestBearr
Expand Down Expand Up @@ -102,8 +99,4 @@ public final class MessageConfig extends AbstractConfig {
Component.text(" * ").color(DIVIDER_COLOR),
Component.text("%syntax%").color(SECONDARY_ERROR_COLOR)
);

public MessageConfig(@NotNull Path configPath) {
super(configPath);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
public final class HandshakeListener extends PluginListener {
public static final String CHANNEL_ID = "ac:handshake";

private static final byte[] MAGIC_NUMBER = new byte[] { 0x3A, 0x3D };
private static final byte[] MAGIC_BYTES = new byte[] { 0x41, 0x4C, 0x50, 0x4E };

public HandshakeListener() {
super(CHANNEL_ID);
Expand All @@ -36,11 +36,11 @@ public void onMessage(@NotNull Player player, byte[] message) {
boolean success = this.main.getPlayerHandler().addConnectedPlayer(player, data);
if (success) {
player.setMetadata("IsOnAlpineClient", new FixedMetadataValue(this.main, true));
player.sendPluginMessage(this.main, this.getChannelId(), MAGIC_NUMBER);
player.sendPluginMessage(this.main, this.getChannelId(), MAGIC_BYTES);
}
}
catch (JsonSyntaxException ex) {
Reference.LOGGER.warn("Invalid handshake payload received from {}", player.getName());
Reference.LOGGER.warn("Invalid handshake payload received from {}", player.getName(), ex);
}
}
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

package com.alpineclient.plugin.network.packet;

import com.alpineclient.plugin.api.objects.ClientResource;
import com.alpineclient.plugin.api.objects.Cooldown;
import com.alpineclient.plugin.network.Packet;
import com.alpineclient.plugin.network.WriteOnly;
Expand Down Expand Up @@ -36,10 +35,7 @@ public void write(@NotNull MessagePacker packer) throws IOException {
packer.packString(this.cooldown.getName());
packer.packInt(this.cooldown.getColor());
packer.packLong(this.cooldown.getDuration());

ClientResource texture = this.cooldown.getTexture();
packer.packBoolean(texture.getType() == ClientResource.Type.INTERNAL);
packer.packString(texture.getValue());
MsgPackUtils.packClientResource(packer, this.cooldown.getTexture());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

package com.alpineclient.plugin.network.packet;

import com.alpineclient.plugin.api.objects.ClientResource;
import com.alpineclient.plugin.api.objects.Notification;
import com.alpineclient.plugin.network.Packet;
import com.alpineclient.plugin.network.WriteOnly;
import com.alpineclient.plugin.util.MsgPackUtils;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.msgpack.core.MessagePacker;
Expand All @@ -32,15 +32,11 @@ public PacketNotificationAdd(@NotNull Notification notification) {
@Override
public void write(@NotNull MessagePacker packer) throws IOException {
String title = this.notification.getTitle() == null ? "" : this.notification.getTitle();

packer.packString(title);
packer.packString(this.notification.getDescription());
packer.packInt(this.notification.getColor());
packer.packLong(this.notification.getDuration());

ClientResource texture = this.notification.getTexture();
packer.packBoolean(texture.getType() == ClientResource.Type.INTERNAL);
packer.packString(texture.getValue());
MsgPackUtils.packClientResource(packer, this.notification.getTexture());
}

@Override
Expand Down
Loading

0 comments on commit e72f527

Please sign in to comment.