metrics! (and placeholders)
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@ -33,3 +33,7 @@ build/
|
|||||||
|
|
||||||
### Mac OS ###
|
### Mac OS ###
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
### Aetheria ###
|
||||||
|
**/src/main/resources/git.properties
|
||||||
|
jars
|
1
.idea/misc.xml
generated
1
.idea/misc.xml
generated
@ -1,4 +1,3 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="EntryPointsManager">
|
<component name="EntryPointsManager">
|
||||||
<list size="1">
|
<list size="1">
|
||||||
|
114
pom.xml
114
pom.xml
@ -9,11 +9,96 @@
|
|||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>17</maven.compiler.source>
|
<java.version>17</java.version>
|
||||||
<maven.compiler.target>17</maven.compiler.target>
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
|
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<!-- Plugins -->
|
||||||
|
<plugins>
|
||||||
|
<!-- Used for compiling the source code with the proper Java version -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.12.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>${java.version}</source>
|
||||||
|
<target>${java.version}</target>
|
||||||
|
|
||||||
|
<!-- Enable incremental builds, this is reversed due to -->
|
||||||
|
<!-- a bug as seen in https://issues.apache.org/jira/browse/MCOMPILER-209 -->
|
||||||
|
<useIncrementalCompilation>false</useIncrementalCompilation>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- Used for generating a git properties file during build -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>pl.project13.maven</groupId>
|
||||||
|
<artifactId>git-commit-id-plugin</artifactId>
|
||||||
|
<version>4.9.10</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>revision</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<prefix>git</prefix>
|
||||||
|
<dotGitDirectory>$PROJECT.BASEDIR$/.git</dotGitDirectory>
|
||||||
|
<injectAllReactorProjects>true</injectAllReactorProjects>
|
||||||
|
<generateGitPropertiesFile>true</generateGitPropertiesFile>
|
||||||
|
<generateGitPropertiesFilename>src/main/resources/git.properties</generateGitPropertiesFilename>
|
||||||
|
<commitIdGenerationMode>full</commitIdGenerationMode>
|
||||||
|
<dateFormatTimeZone>$USER.TIMEZONE$</dateFormatTimeZone>
|
||||||
|
<dateFormat>MM-dd-yyyy@HH:mm:ss</dateFormat>
|
||||||
|
<includeOnlyProperties>
|
||||||
|
<includeOnlyProperty>^git.branch$</includeOnlyProperty>
|
||||||
|
<includeOnlyProperty>^git.build.(time|version)$</includeOnlyProperty>
|
||||||
|
<includeOnlyProperty>^git.commit.id.(abbrev|full)$</includeOnlyProperty>
|
||||||
|
<includeOnlyProperty>^git.build.user.name$</includeOnlyProperty>
|
||||||
|
</includeOnlyProperties>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- Handles shading of dependencies in the final output jar -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>3.6.0</version>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>./jars</outputDirectory>
|
||||||
|
<appendAssemblyId>false</appendAssemblyId>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
|
||||||
|
<!-- Filter the resources dir for placeholders -->
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
<includes>
|
||||||
|
<include>**/*.yml</include>
|
||||||
|
<include>**/*.properties</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<id>papermc</id>
|
<id>papermc</id>
|
||||||
@ -23,6 +108,10 @@
|
|||||||
<id>jitpack.io</id>
|
<id>jitpack.io</id>
|
||||||
<url>https://jitpack.io/</url>
|
<url>https://jitpack.io/</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>placeholderapi</id>
|
||||||
|
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||||
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -50,6 +139,27 @@
|
|||||||
<version>2.1.3</version>
|
<version>2.1.3</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>me.clip</groupId>
|
||||||
|
<artifactId>placeholderapi</artifactId>
|
||||||
|
<version>2.11.5</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.oshi</groupId>
|
||||||
|
<artifactId>oshi-core</artifactId>
|
||||||
|
<version>6.5.0</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.influxdb</groupId>
|
||||||
|
<artifactId>influxdb-client-java</artifactId>
|
||||||
|
<version>7.0.0</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -1,10 +1,16 @@
|
|||||||
package cc.fascinated;
|
package cc.fascinated;
|
||||||
|
|
||||||
import cc.fascinated.command.CommandManager;
|
import cc.fascinated.command.CommandManager;
|
||||||
|
import cc.fascinated.metrics.MetricManager;
|
||||||
|
import cc.fascinated.placeholder.PlaceholderManager;
|
||||||
import cc.fascinated.playercolors.ColorManager;
|
import cc.fascinated.playercolors.ColorManager;
|
||||||
import cc.fascinated.worldsize.WorldSizeManager;
|
import cc.fascinated.worldsize.WorldSizeManager;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class Aetheria extends JavaPlugin {
|
public class Aetheria extends JavaPlugin {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12,6 +18,9 @@ public class Aetheria extends JavaPlugin {
|
|||||||
*/
|
*/
|
||||||
public static Aetheria INSTANCE;
|
public static Aetheria INSTANCE;
|
||||||
|
|
||||||
|
public static ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(2, 8, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
|
||||||
|
|
||||||
|
// todo: move to config
|
||||||
public static final String PREFIX = "§6§lAetheria §7» §f";
|
public static final String PREFIX = "§6§lAetheria §7» §f";
|
||||||
|
|
||||||
public Aetheria() {
|
public Aetheria() {
|
||||||
@ -25,5 +34,7 @@ public class Aetheria extends JavaPlugin {
|
|||||||
new CommandManager();
|
new CommandManager();
|
||||||
new WorldSizeManager();
|
new WorldSizeManager();
|
||||||
new ColorManager();
|
new ColorManager();
|
||||||
|
new PlaceholderManager();
|
||||||
|
new MetricManager();
|
||||||
}
|
}
|
||||||
}
|
}
|
7
src/main/java/cc/fascinated/Oshi.java
Normal file
7
src/main/java/cc/fascinated/Oshi.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package cc.fascinated;
|
||||||
|
|
||||||
|
import oshi.SystemInfo;
|
||||||
|
|
||||||
|
public class Oshi {
|
||||||
|
public static final SystemInfo SYSTEM_INFO = new SystemInfo();
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package cc.fascinated.command;
|
package cc.fascinated.command;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -2,10 +2,8 @@ package cc.fascinated.command.impl;
|
|||||||
|
|
||||||
import cc.fascinated.Aetheria;
|
import cc.fascinated.Aetheria;
|
||||||
import cc.fascinated.command.Command;
|
import cc.fascinated.command.Command;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class HelpCommand extends Command {
|
public class HelpCommand extends Command {
|
||||||
|
22
src/main/java/cc/fascinated/metrics/Metric.java
Normal file
22
src/main/java/cc/fascinated/metrics/Metric.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package cc.fascinated.metrics;
|
||||||
|
|
||||||
|
import com.influxdb.client.write.Point;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public abstract class Metric {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the metric.
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collect and return the metric.
|
||||||
|
*
|
||||||
|
* @return the collected metric
|
||||||
|
*/
|
||||||
|
protected abstract Point toPoint();
|
||||||
|
}
|
113
src/main/java/cc/fascinated/metrics/MetricManager.java
Normal file
113
src/main/java/cc/fascinated/metrics/MetricManager.java
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
package cc.fascinated.metrics;
|
||||||
|
|
||||||
|
import cc.fascinated.Aetheria;
|
||||||
|
import cc.fascinated.metrics.impl.server.MemoryMetric;
|
||||||
|
import cc.fascinated.metrics.impl.server.PlayerCountMetric;
|
||||||
|
import cc.fascinated.metrics.impl.server.TotalJoinsMetric;
|
||||||
|
import cc.fascinated.metrics.impl.server.TpsMetric;
|
||||||
|
import cc.fascinated.metrics.impl.system.CpuUsageMetric;
|
||||||
|
import cc.fascinated.metrics.impl.world.WorldSizeMetric;
|
||||||
|
import com.influxdb.client.InfluxDBClient;
|
||||||
|
import com.influxdb.client.InfluxDBClientFactory;
|
||||||
|
import com.influxdb.client.InfluxDBClientOptions;
|
||||||
|
import com.influxdb.client.WriteApiBlocking;
|
||||||
|
import com.influxdb.client.domain.WriteConsistency;
|
||||||
|
import com.influxdb.client.domain.WritePrecision;
|
||||||
|
import com.influxdb.client.write.Point;
|
||||||
|
import com.influxdb.client.write.WriteParameters;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.server.PluginDisableEvent;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Log4j2
|
||||||
|
public class MetricManager implements Listener {
|
||||||
|
|
||||||
|
private InfluxDBClient influxDB;
|
||||||
|
private WriteApiBlocking writeApi;
|
||||||
|
private static final List<Metric> metrics = new ArrayList<>();
|
||||||
|
|
||||||
|
public MetricManager() {
|
||||||
|
FileConfiguration config = Aetheria.INSTANCE.getConfig();
|
||||||
|
String url = config.getString("influxdb.url");
|
||||||
|
String token = config.getString("influxdb.token");
|
||||||
|
String org = config.getString("influxdb.org");
|
||||||
|
String bucket = config.getString("influxdb.bucket");
|
||||||
|
|
||||||
|
if (url == null || token == null || org == null || bucket == null) {
|
||||||
|
log.error("InfluxDB configuration is missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
InfluxDBClientOptions options = InfluxDBClientOptions.builder()
|
||||||
|
.url(url)
|
||||||
|
.authenticateToken(token.toCharArray())
|
||||||
|
.org(org)
|
||||||
|
.bucket(bucket)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try {
|
||||||
|
influxDB = InfluxDBClientFactory.create(options);
|
||||||
|
influxDB.ping(); // test the connection
|
||||||
|
writeApi = influxDB.getWriteApiBlocking();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to connect to influx", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// system metrics
|
||||||
|
registerMetric(new CpuUsageMetric());
|
||||||
|
|
||||||
|
// world metrics
|
||||||
|
registerMetric(new WorldSizeMetric());
|
||||||
|
|
||||||
|
// server metrics
|
||||||
|
registerMetric(new TpsMetric());
|
||||||
|
registerMetric(new MemoryMetric());
|
||||||
|
registerMetric(new PlayerCountMetric());
|
||||||
|
registerMetric(new TotalJoinsMetric());
|
||||||
|
|
||||||
|
Bukkit.getAsyncScheduler().runAtFixedRate(Aetheria.INSTANCE, (task) -> this.collectMetrics(), 30, 30, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collect all metrics and write them to influx
|
||||||
|
*/
|
||||||
|
public void collectMetrics() {
|
||||||
|
log.info("Collecting metrics");
|
||||||
|
long before = System.currentTimeMillis();
|
||||||
|
List<Point> points = new ArrayList<>();
|
||||||
|
for (Metric metric : metrics) {
|
||||||
|
points.add(metric.toPoint());
|
||||||
|
}
|
||||||
|
// write the points async
|
||||||
|
Aetheria.EXECUTOR.execute(() -> {
|
||||||
|
writeApi.writePoints(points, new WriteParameters(WritePrecision.MS, WriteConsistency.ONE));
|
||||||
|
|
||||||
|
log.info("Wrote {} points to influx ({}ms)", points.size(), System.currentTimeMillis() - before);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new metric
|
||||||
|
*
|
||||||
|
* @param metric the metric to register
|
||||||
|
*/
|
||||||
|
public static void registerMetric(Metric metric) {
|
||||||
|
metrics.add(metric);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPluginDisable(PluginDisableEvent event) {
|
||||||
|
if (event.getPlugin() != Aetheria.INSTANCE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
influxDB.close(); // close the connection
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package cc.fascinated.metrics.impl.server;
|
||||||
|
|
||||||
|
import cc.fascinated.metrics.Metric;
|
||||||
|
import com.influxdb.client.write.Point;
|
||||||
|
|
||||||
|
public class MemoryMetric extends Metric {
|
||||||
|
|
||||||
|
public MemoryMetric() {
|
||||||
|
super("memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Point toPoint() {
|
||||||
|
Runtime runtime = Runtime.getRuntime();
|
||||||
|
|
||||||
|
return Point.measurement(getName())
|
||||||
|
.addField("total", runtime.totalMemory())
|
||||||
|
.addField("available", runtime.freeMemory())
|
||||||
|
.addField("used", runtime.totalMemory() - runtime.freeMemory());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package cc.fascinated.metrics.impl.server;
|
||||||
|
|
||||||
|
import cc.fascinated.metrics.Metric;
|
||||||
|
import com.influxdb.client.write.Point;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
|
public class PlayerCountMetric extends Metric {
|
||||||
|
|
||||||
|
public PlayerCountMetric() {
|
||||||
|
super("player_count");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Point toPoint() {
|
||||||
|
return Point.measurement(getName())
|
||||||
|
.addField("value", Bukkit.getServer().getOnlinePlayers().size());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package cc.fascinated.metrics.impl.server;
|
||||||
|
|
||||||
|
import cc.fascinated.metrics.Metric;
|
||||||
|
import com.influxdb.client.write.Point;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
|
public class TotalJoinsMetric extends Metric {
|
||||||
|
|
||||||
|
public TotalJoinsMetric() {
|
||||||
|
super("total_joins");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Point toPoint() {
|
||||||
|
return Point.measurement(getName())
|
||||||
|
.addField("value", Bukkit.getServer().getOfflinePlayers().length);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package cc.fascinated.metrics.impl.server;
|
||||||
|
|
||||||
|
import cc.fascinated.metrics.Metric;
|
||||||
|
import com.influxdb.client.write.Point;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
|
public class TpsMetric extends Metric {
|
||||||
|
|
||||||
|
public TpsMetric() {
|
||||||
|
super("tps");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Point toPoint() {
|
||||||
|
return Point.measurement("tps")
|
||||||
|
.addTag("server", "server")
|
||||||
|
.addField("tps", Bukkit.getServer().getTPS()[0]);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package cc.fascinated.metrics.impl.system;
|
||||||
|
|
||||||
|
import cc.fascinated.Oshi;
|
||||||
|
import cc.fascinated.metrics.Metric;
|
||||||
|
import com.influxdb.client.write.Point;
|
||||||
|
import oshi.hardware.HardwareAbstractionLayer;
|
||||||
|
|
||||||
|
public class CpuUsageMetric extends Metric {
|
||||||
|
|
||||||
|
public CpuUsageMetric() {
|
||||||
|
super("cpu_usage");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Point toPoint() {
|
||||||
|
HardwareAbstractionLayer hardware = Oshi.SYSTEM_INFO.getHardware();
|
||||||
|
double cpuLoad = hardware.getProcessor().getSystemCpuLoad(500) * 100; // get the CPU load in percentage
|
||||||
|
|
||||||
|
return Point.measurement(getName())
|
||||||
|
.addField("value", cpuLoad);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package cc.fascinated.metrics.impl.world;
|
||||||
|
|
||||||
|
import cc.fascinated.metrics.Metric;
|
||||||
|
import cc.fascinated.worldsize.WorldSizeManager;
|
||||||
|
import com.influxdb.client.write.Point;
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class WorldSizeMetric extends Metric {
|
||||||
|
|
||||||
|
public WorldSizeMetric() {
|
||||||
|
super("world_size");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Point toPoint() {
|
||||||
|
Map<World, Long> worldSizes = WorldSizeManager.getWorldSizes();
|
||||||
|
if (worldSizes.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point point = Point.measurement(getName());
|
||||||
|
for (Map.Entry<World, Long> entry : worldSizes.entrySet()) {
|
||||||
|
point.addField(entry.getKey().getName(), entry.getValue());
|
||||||
|
}
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package cc.fascinated.placeholder;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public interface AetheriaPlaceholder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the identifier for this placeholder
|
||||||
|
*/
|
||||||
|
String getIdentifier();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse this placeholder and return the value for the provided player
|
||||||
|
*
|
||||||
|
* @param player the player to parse the placeholder for, null if offline
|
||||||
|
* @param params the parameters for the placeholder
|
||||||
|
* @return the placeholder string
|
||||||
|
*/
|
||||||
|
String parse(@Nullable Player player, String[] params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the required amount of parameters for this placeholder
|
||||||
|
* Does not include the expansion identifier or the placeholder identifier
|
||||||
|
*
|
||||||
|
* @return the required amount of parameters
|
||||||
|
*/
|
||||||
|
int getRequiredParameterCount();
|
||||||
|
|
||||||
|
}
|
106
src/main/java/cc/fascinated/placeholder/PlaceholderManager.java
Normal file
106
src/main/java/cc/fascinated/placeholder/PlaceholderManager.java
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
package cc.fascinated.placeholder;
|
||||||
|
|
||||||
|
import cc.fascinated.Aetheria;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import me.clip.placeholderapi.PlaceholderAPI;
|
||||||
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@Log4j2
|
||||||
|
public class PlaceholderManager {
|
||||||
|
|
||||||
|
private static final Map<String, AetheriaPlaceholder> PLACEHOLDERS = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public PlaceholderManager() {
|
||||||
|
new PlaceholderAdapter().register();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the provided placeholder
|
||||||
|
*
|
||||||
|
* @param placeholder the placeholder to register
|
||||||
|
*/
|
||||||
|
public static void registerPlaceholder(AetheriaPlaceholder placeholder) {
|
||||||
|
PLACEHOLDERS.put(placeholder.getIdentifier(), placeholder);
|
||||||
|
log.info("Registered placeholder " + placeholder.getIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister the provided placeholder
|
||||||
|
*
|
||||||
|
* @param placeholder the placeholder to unregister
|
||||||
|
*/
|
||||||
|
public static void unregisterPlaceholder(AetheriaPlaceholder placeholder) {
|
||||||
|
PLACEHOLDERS.remove(placeholder.getIdentifier());
|
||||||
|
log.info("Unregistered placeholder " + placeholder.getIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace PAPI placeholders in the given content.
|
||||||
|
*
|
||||||
|
* @param player the player to replace the placeholders for, null if offline
|
||||||
|
* @param content the content to replace the placeholders in
|
||||||
|
* @return the content with the placeholders replaced
|
||||||
|
*/
|
||||||
|
public static String replace(@Nullable Player player, String content) {
|
||||||
|
return PlaceholderAPI.setPlaceholders(player != null && (player.isOnline()) ? player : null, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class PlaceholderAdapter extends PlaceholderExpansion {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getIdentifier() {
|
||||||
|
return "aetheria";
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("UnstableApiUsage")
|
||||||
|
@Override
|
||||||
|
public @NotNull String getAuthor() {
|
||||||
|
return String.join(", ", Aetheria.INSTANCE.getPluginMeta().getAuthors());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("UnstableApiUsage")
|
||||||
|
@Override
|
||||||
|
public @NotNull String getVersion() {
|
||||||
|
return Aetheria.INSTANCE.getPluginMeta().getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* From PlaceholderAPI:
|
||||||
|
* <p>
|
||||||
|
* Expansions that do not use the e-cloud and instead register from the dependency should set this to true
|
||||||
|
* to ensure that your placeholder expansion is not unregistered when the papi reload command is used
|
||||||
|
*/
|
||||||
|
public boolean persist() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String onRequest(@Nullable OfflinePlayer player, @NotNull String params) {
|
||||||
|
String[] parameters = params.split("_");
|
||||||
|
AetheriaPlaceholder placeholder = PLACEHOLDERS.get(parameters[0]);
|
||||||
|
// Attempt to fetch the placeholder with the provided id
|
||||||
|
if (placeholder == null) {
|
||||||
|
log.error("Tried to fetch an unregistered placeholder: " + parameters[0]);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Ensure the correct amount of parameters is provided
|
||||||
|
if (parameters.length - 1 < placeholder.getRequiredParameterCount()) {
|
||||||
|
log.error("Invalid placeholders provided for {}, provided = {}, required = {}",
|
||||||
|
placeholder.getIdentifier(),
|
||||||
|
parameters.length - 1,
|
||||||
|
placeholder.getRequiredParameterCount());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Trim the placeholder identifier from the parameters before parsing
|
||||||
|
return placeholder.parse((Player) player, parameters.length > 1 ? Arrays.copyOfRange(parameters, 1, parameters.length) : parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ package cc.fascinated.worldsize;
|
|||||||
|
|
||||||
import cc.fascinated.Aetheria;
|
import cc.fascinated.Aetheria;
|
||||||
import cc.fascinated.command.CommandManager;
|
import cc.fascinated.command.CommandManager;
|
||||||
|
import cc.fascinated.placeholder.PlaceholderManager;
|
||||||
import cc.fascinated.worldsize.impl.WorldSizeCommand;
|
import cc.fascinated.worldsize.impl.WorldSizeCommand;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -31,6 +32,7 @@ public class WorldSizeManager {
|
|||||||
|
|
||||||
public WorldSizeManager() {
|
public WorldSizeManager() {
|
||||||
CommandManager.registerCommand(new WorldSizeCommand());
|
CommandManager.registerCommand(new WorldSizeCommand());
|
||||||
|
PlaceholderManager.registerPlaceholder(new WorldSizePlaceholder());
|
||||||
|
|
||||||
Aetheria.INSTANCE.getServer().getAsyncScheduler().runAtFixedRate(Aetheria.INSTANCE, (task) -> {
|
Aetheria.INSTANCE.getServer().getAsyncScheduler().runAtFixedRate(Aetheria.INSTANCE, (task) -> {
|
||||||
calculateTotalWorldSize();
|
calculateTotalWorldSize();
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package cc.fascinated.worldsize;
|
||||||
|
|
||||||
|
import cc.fascinated.placeholder.AetheriaPlaceholder;
|
||||||
|
import cc.fascinated.utils.FormatterUtils;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class WorldSizePlaceholder implements AetheriaPlaceholder {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return "worldsize";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String parse(@Nullable Player player, String[] params) {
|
||||||
|
World world = Bukkit.getWorld(params[0].replaceAll("-", "_"));
|
||||||
|
if (world == null) {
|
||||||
|
return "-1";
|
||||||
|
}
|
||||||
|
long size = WorldSizeManager.getWorldSizes().get(world);
|
||||||
|
return FormatterUtils.formatBytes(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRequiredParameterCount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,9 @@
|
|||||||
|
influxdb:
|
||||||
|
url: "http://localhost:8086"
|
||||||
|
token: "aetheria"
|
||||||
|
org: "aetheria"
|
||||||
|
bucket: "aetheria"
|
||||||
|
|
||||||
help-command:
|
help-command:
|
||||||
- "&e/help &7- &fShows this help message"
|
- "&e/help &7- &fShows this help message"
|
||||||
- "&e/kill &7- &fKills you"
|
- "&e/kill &7- &fKills you"
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
name: Aetheria
|
name: Aetheria
|
||||||
main: cc.fascinated.Aetheria
|
main: cc.fascinated.Aetheria
|
||||||
version: 1.0
|
version: 1.0
|
||||||
|
author: Fascinated
|
||||||
|
depend:
|
||||||
|
- PlaceholderAPI
|
||||||
commands:
|
commands:
|
||||||
totaljoins:
|
totaljoins:
|
||||||
description: "Shows the total amount of joins"
|
description: "Shows the total amount of joins"
|
||||||
|
Reference in New Issue
Block a user