aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuck <git@lucko.me>2019-04-28 15:37:32 +0100
committerLuck <git@lucko.me>2019-05-04 23:22:32 +0100
commitc3ae37e88f967a21522af7d0cb79a571326cd7e9 (patch)
tree7ce46c61407dacdff3cabaeb1ffc8eb5e7cd614a
parent51fa2b3e64f021c3c0535f9f931d3fae27ca7adc (diff)
downloadspark-c3ae37e88f967a21522af7d0cb79a571326cd7e9.tar.gz
spark-c3ae37e88f967a21522af7d0cb79a571326cd7e9.tar.bz2
spark-c3ae37e88f967a21522af7d0cb79a571326cd7e9.zip
Start implementing activity log feature
-rw-r--r--spark-bukkit/build.gradle4
-rw-r--r--spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitCommandSender.java61
-rw-r--r--spark-bukkit/src/main/java/me/lucko/spark/bukkit/SparkBukkitPlugin.java39
-rw-r--r--spark-bungeecord/build.gradle4
-rw-r--r--spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/BungeeCordCommandSender.java61
-rw-r--r--spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/SparkBungeeCordPlugin.java42
-rw-r--r--spark-common/build.gradle11
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/ActivityLog.java195
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/CommandSender.java33
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java84
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/SparkPlugin.java7
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/Command.java45
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/CommandModule.java4
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/CommandResponseHandler.java22
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/modules/ActivityLogModule.java120
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/modules/HealthModule.java30
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/modules/MemoryModule.java11
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/modules/SamplerModule.java11
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/modules/TickMonitoringModule.java10
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/tick/TickMonitor.java12
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/tick/TpsCalculator.java2
-rw-r--r--spark-forge/build.gradle6
-rw-r--r--spark-forge/src/main/java/me/lucko/spark/forge/ForgeClientSparkPlugin.java16
-rw-r--r--spark-forge/src/main/java/me/lucko/spark/forge/ForgeCommandSender.java66
-rw-r--r--spark-forge/src/main/java/me/lucko/spark/forge/ForgeServerSparkPlugin.java20
-rw-r--r--spark-forge/src/main/java/me/lucko/spark/forge/ForgeSparkPlugin.java45
-rw-r--r--spark-sponge/build.gradle4
-rw-r--r--spark-sponge/src/main/java/me/lucko/spark/sponge/SparkSpongePlugin.java36
-rw-r--r--spark-sponge/src/main/java/me/lucko/spark/sponge/SpongeCommandSender.java62
-rw-r--r--spark-velocity/src/main/java/me/lucko/spark/velocity/SparkVelocityPlugin.java36
-rw-r--r--spark-velocity/src/main/java/me/lucko/spark/velocity/VelocityCommandSender.java69
31 files changed, 903 insertions, 265 deletions
diff --git a/spark-bukkit/build.gradle b/spark-bukkit/build.gradle
index e8c6721..836e389 100644
--- a/spark-bukkit/build.gradle
+++ b/spark-bukkit/build.gradle
@@ -1,6 +1,8 @@
dependencies {
compile project(':spark-common')
- compile 'net.kyori:text-adapter-bukkit:1.0.3'
+ compile('net.kyori:text-adapter-bukkit:1.0.3') {
+ exclude(module: 'text')
+ }
compileOnly 'org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT'
}
diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitCommandSender.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitCommandSender.java
new file mode 100644
index 0000000..dacea76
--- /dev/null
+++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitCommandSender.java
@@ -0,0 +1,61 @@
+/*
+ * This file is part of spark.
+ *
+ * Copyright (c) lucko (Luck) <luck@lucko.me>
+ * Copyright (c) contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package me.lucko.spark.bukkit;
+
+import me.lucko.spark.common.CommandSender;
+import net.kyori.text.Component;
+import net.kyori.text.adapter.bukkit.TextAdapter;
+
+public class BukkitCommandSender implements CommandSender {
+ private final org.bukkit.command.CommandSender sender;
+
+ public BukkitCommandSender(org.bukkit.command.CommandSender sender) {
+ this.sender = sender;
+ }
+
+ @Override
+ public String getName() {
+ return this.sender.getName();
+ }
+
+ @Override
+ public void sendMessage(Component message) {
+ TextAdapter.sendComponent(this.sender, message);
+ }
+
+ @Override
+ public boolean hasPermission(String permission) {
+ return this.sender.hasPermission(permission);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ BukkitCommandSender that = (BukkitCommandSender) o;
+ return this.sender.equals(that.sender);
+ }
+
+ @Override
+ public int hashCode() {
+ return this.sender.hashCode();
+ }
+}
diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/SparkBukkitPlugin.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/SparkBukkitPlugin.java
index 15c725d..ee85c70 100644
--- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/SparkBukkitPlugin.java
+++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/SparkBukkitPlugin.java
@@ -20,29 +20,27 @@
package me.lucko.spark.bukkit;
+import me.lucko.spark.common.CommandSender;
import me.lucko.spark.common.SparkPlatform;
import me.lucko.spark.common.SparkPlugin;
import me.lucko.spark.common.command.CommandResponseHandler;
import me.lucko.spark.common.monitor.tick.TpsCalculator;
import me.lucko.spark.common.sampler.ThreadDumper;
import me.lucko.spark.common.sampler.TickCounter;
-import net.kyori.text.Component;
import net.kyori.text.TextComponent;
-import net.kyori.text.adapter.bukkit.TextAdapter;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
-import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;
import java.nio.file.Path;
-import java.util.Collections;
-import java.util.HashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Set;
+import java.util.stream.Collectors;
-public class SparkBukkitPlugin extends JavaPlugin implements SparkPlugin<CommandSender> {
+public class SparkBukkitPlugin extends JavaPlugin implements SparkPlugin {
- private final SparkPlatform<CommandSender> platform = new SparkPlatform<>(this);
+ private final SparkPlatform platform = new SparkPlatform(this);
@Override
public void onEnable() {
@@ -56,7 +54,7 @@ public class SparkBukkitPlugin extends JavaPlugin implements SparkPlugin<Command
return true;
}
- CommandResponseHandler<CommandSender> resp = new CommandResponseHandler<>(this.platform, sender);
+ CommandResponseHandler resp = new CommandResponseHandler(this.platform, new BukkitCommandSender(sender));
TpsCalculator tpsCalculator = this.platform.getTpsCalculator();
resp.replyPrefixed(TextComponent.of("TPS from last 5s, 10s, 1m, 5m, 15m:"));
resp.replyPrefixed(TextComponent.builder(" ").append(tpsCalculator.toFormattedComponent()).build());
@@ -71,22 +69,14 @@ public class SparkBukkitPlugin extends JavaPlugin implements SparkPlugin<Command
}
@Override
- public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
- if (!sender.hasPermission("spark")) {
- sender.sendMessage(ChatColor.RED + "You do not have permission to use this command.");
- return true;
- }
-
- this.platform.executeCommand(sender, args);
+ public boolean onCommand(org.bukkit.command.CommandSender sender, Command command, String label, String[] args) {
+ this.platform.executeCommand(new BukkitCommandSender(sender), args);
return true;
}
@Override
- public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
- if (!sender.hasPermission("spark")) {
- return Collections.emptyList();
- }
- return this.platform.tabCompleteCommand(sender, args);
+ public List<String> onTabComplete(org.bukkit.command.CommandSender sender, Command command, String alias, String[] args) {
+ return this.platform.tabCompleteCommand(new BukkitCommandSender(sender), args);
}
@Override
@@ -106,15 +96,10 @@ public class SparkBukkitPlugin extends JavaPlugin implements SparkPlugin<Command
@Override
public Set<CommandSender> getSendersWithPermission(String permission) {
- Set<CommandSender> senders = new HashSet<>(getServer().getOnlinePlayers());
+ List<org.bukkit.command.CommandSender> senders = new LinkedList<>(getServer().getOnlinePlayers());
senders.removeIf(sender -> !sender.hasPermission(permission));
senders.add(getServer().getConsoleSender());
- return senders;
- }
-
- @Override
- public void sendMessage(CommandSender sender, Component message) {
- TextAdapter.sendComponent(sender, message);
+ return senders.stream().map(BukkitCommandSender::new).collect(Collectors.toSet());
}
@Override
diff --git a/spark-bungeecord/build.gradle b/spark-bungeecord/build.gradle
index 55dcb4e..5ee50d7 100644
--- a/spark-bungeecord/build.gradle
+++ b/spark-bungeecord/build.gradle
@@ -1,6 +1,8 @@
dependencies {
compile project(':spark-common')
- compile 'net.kyori:text-adapter-bungeecord:1.0.3'
+ compile('net.kyori:text-adapter-bungeecord:1.0.3') {
+ exclude(module: 'text')
+ }
compileOnly 'net.md-5:bungeecord-api:1.12-SNAPSHOT'
}
diff --git a/spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/BungeeCordCommandSender.java b/spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/BungeeCordCommandSender.java
new file mode 100644
index 0000000..d3a831c
--- /dev/null
+++ b/spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/BungeeCordCommandSender.java
@@ -0,0 +1,61 @@
+/*
+ * This file is part of spark.
+ *
+ * Copyright (c) lucko (Luck) <luck@lucko.me>
+ * Copyright (c) contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package me.lucko.spark.bungeecord;
+
+import me.lucko.spark.common.CommandSender;
+import net.kyori.text.Component;
+import net.kyori.text.adapter.bungeecord.TextAdapter;
+
+public class BungeeCordCommandSender implements CommandSender {
+ private final net.md_5.bungee.api.CommandSender sender;
+
+ public BungeeCordCommandSender(net.md_5.bungee.api.CommandSender sender) {
+ this.sender = sender;
+ }
+
+ @Override
+ public String getName() {
+ return this.sender.getName();
+ }
+
+ @Override
+ public void sendMessage(Component message) {
+ TextAdapter.sendComponent(this.sender, message);
+ }
+
+ @Override
+ public boolean hasPermission(String permission) {
+ return this.sender.hasPermission(permission);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ BungeeCordCommandSender that = (BungeeCordCommandSender) o;
+ return this.sender.equals(that.sender);
+ }
+
+ @Override
+ public int hashCode() {
+ return this.sender.hashCode();
+ }
+}
diff --git a/spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/SparkBungeeCordPlugin.java b/spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/SparkBungeeCordPlugin.java
index ba2ee99..193ae06 100644
--- a/spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/SparkBungeeCordPlugin.java
+++ b/spark-bungeecord/src/main/java/me/lucko/spark/bungeecord/SparkBungeeCordPlugin.java
@@ -20,27 +20,24 @@
package me.lucko.spark.bungeecord;
+import me.lucko.spark.common.CommandSender;
import me.lucko.spark.common.SparkPlatform;
import me.lucko.spark.common.SparkPlugin;
import me.lucko.spark.common.sampler.ThreadDumper;
import me.lucko.spark.common.sampler.TickCounter;
-import net.kyori.text.Component;
-import net.kyori.text.adapter.bungeecord.TextAdapter;
-import net.md_5.bungee.api.ChatColor;
-import net.md_5.bungee.api.CommandSender;
-import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.api.plugin.TabExecutor;
import java.nio.file.Path;
-import java.util.Collections;
-import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Set;
+import java.util.stream.Collectors;
-public class SparkBungeeCordPlugin extends Plugin implements SparkPlugin<CommandSender> {
+public class SparkBungeeCordPlugin extends Plugin implements SparkPlugin {
- private final SparkPlatform<CommandSender> platform = new SparkPlatform<>(this);
+ private final SparkPlatform platform = new SparkPlatform(this);
@Override
public void onEnable() {
@@ -70,15 +67,10 @@ public class SparkBungeeCordPlugin extends Plugin implements SparkPlugin<Command
@Override
public Set<CommandSender> getSendersWithPermission(String permission) {
- Set<CommandSender> senders = new HashSet<>(getProxy().getPlayers());
+ List<net.md_5.bungee.api.CommandSender> senders = new LinkedList<>(getProxy().getPlayers());
senders.removeIf(sender -> !sender.hasPermission(permission));
senders.add(getProxy().getConsole());
- return senders;
- }
-
- @Override
- public void sendMessage(CommandSender sender, Component message) {
- TextAdapter.sendComponent(sender, message);
+ return senders.stream().map(BungeeCordCommandSender::new).collect(Collectors.toSet());
}
@Override
@@ -105,23 +97,13 @@ public class SparkBungeeCordPlugin extends Plugin implements SparkPlugin<Command
}
@Override
- public void execute(CommandSender sender, String[] args) {
- if (!sender.hasPermission("spark")) {
- TextComponent msg = new TextComponent("You do not have permission to use this command.");
- msg.setColor(ChatColor.RED);
- sender.sendMessage(msg);
- return;
- }
-
- this.plugin.platform.executeCommand(sender, args);
+ public void execute(net.md_5.bungee.api.CommandSender sender, String[] args) {
+ this.plugin.platform.executeCommand(new BungeeCordCommandSender(sender), args);
}
@Override
- public Iterable<String> onTabComplete(CommandSender sender, String[] args) {
- if (!sender.hasPermission("spark")) {
- return Collections.emptyList();
- }
- return this.plugin.platform.tabCompleteCommand(sender, args);
+ public Iterable<String> onTabComplete(net.md_5.bungee.api.CommandSender sender, String[] args) {
+ return this.plugin.platform.tabCompleteCommand(new BungeeCordCommandSender(sender), args);
}
}
}
diff --git a/spark-common/build.gradle b/spark-common/build.gradle
index a8b95c6..8a9ee16 100644
--- a/spark-common/build.gradle
+++ b/spark-common/build.gradle
@@ -1,7 +1,16 @@
dependencies {
compile 'com.squareup.okhttp3:okhttp:3.14.1'
compile 'com.squareup.okio:okio:1.17.3'
- compile 'net.kyori:text-api:2.0.0'
+ compile('net.kyori:text-api:2.0.0') {
+ exclude(module: 'checker-qual')
+ }
+ compile('net.kyori:text-serializer-gson:2.0.0') {
+ exclude(module: 'text-api')
+ exclude(module: 'gson')
+ }
+ compile('net.kyori:text-serializer-legacy:2.0.0') {
+ exclude(module: 'text-api')
+ }
compileOnly 'com.google.code.gson:gson:2.7'
compileOnly 'com.google.guava:guava:19.0'
}
diff --git a/spark-common/src/main/java/me/lucko/spark/common/ActivityLog.java b/spark-common/src/main/java/me/lucko/spark/common/ActivityLog.java
new file mode 100644
index 0000000..4b5e942
--- /dev/null
+++ b/spark-common/src/main/java/me/lucko/spark/common/ActivityLog.java
@@ -0,0 +1,195 @@
+/*
+ * This file is part of spark.
+ *
+ * Copyright (c) lucko (Luck) <luck@lucko.me>
+ * Copyright (c) contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package me.lucko.spark.common;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.gson.JsonPrimitive;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+public class ActivityLog {
+
+ private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
+ private static final JsonParser PARSER = new JsonParser();
+
+ private final Path file;
+
+ private final List<Activity> log = new LinkedList<>();
+ private final Object[] mutex = new Object[0];
+
+ public ActivityLog(Path file) {
+ this.file = file;
+ }
+
+ public void addToLog(Activity activity) {
+ synchronized (this.mutex) {
+ this.log.add(activity);
+ }
+ save();
+ }
+
+ public List<Activity> getLog() {
+ synchronized (this.mutex) {
+ return new LinkedList<>(this.log);
+ }
+ }
+
+ public void save() {
+ JsonArray array = new JsonArray();
+ synchronized (this.mutex) {
+ for (Activity activity : this.log) {
+ if (!activity.shouldExpire()) {
+ array.add(activity.serialize());
+ }
+ }
+ }
+
+ try {
+ Files.createDirectories(this.file.getParent());
+ } catch (IOException e) {
+ // ignore
+ }
+
+ try (BufferedWriter writer = Files.newBufferedWriter(this.file, StandardCharsets.UTF_8)) {
+ GSON.toJson(array, writer);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void load() {
+ if (!Files.exists(this.file)) {
+ synchronized (this.mutex) {
+ this.log.clear();
+ return;
+ }
+ }
+
+ JsonArray array;
+ try (BufferedReader reader = Files.newBufferedReader(this.file, StandardCharsets.UTF_8)) {
+ array = PARSER.parse(reader).getAsJsonArray();
+ } catch (IOException e) {
+ e.printStackTrace();
+ return;
+ }
+
+ boolean save = false;
+
+ synchronized (this.mutex) {
+ this.log.clear();
+ for (JsonElement element : array) {
+ try {
+ Activity activity = Activity.deserialize(element);
+ if (activity.shouldExpire()) {
+ save = true;
+ }
+ this.log.add(activity);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ if (save) {
+ try {
+ save();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+
+ public static final class Activity {
+ private final String user;
+ private final long time;
+ private final String type;
+ private final String url;
+
+ public Activity(String user, long time, String type, String url) {
+ this.user = user;
+ this.time = time;
+ this.type = type;
+ this.url = url;
+ }
+
+ public String getUser() {
+ return this.user;
+ }
+
+ public long getTime() {
+ return this.time;
+ }
+
+ public String getType() {
+ return this.type;
+ }
+
+ public String getUrl() {
+ return this.url;
+ }
+
+ public boolean shouldExpire() {
+ return (System.currentTimeMillis() - this.time) > TimeUnit.DAYS.toMillis(7);
+ }
+
+ public JsonObject serialize() {
+ JsonObject object = new JsonObject();
+
+ JsonObject user = new JsonObject();
+ user.add("name", new JsonPrimitive(this.user));
+ object.add("user", user);
+
+ object.add("time", new JsonPrimitive(this.time));
+ object.add("type", new JsonPrimitive(this.type));
+
+ JsonObject data = new JsonObject();
+ data.add("url", new JsonPrimitive(this.url));
+ object.add("data", data);
+
+ return object;
+ }
+
+ public static Activity deserialize(JsonElement element) {
+ JsonObject object = element.getAsJsonObject();
+
+ String user = object.get("user").getAsJsonObject().get("name").getAsJsonPrimitive().getAsString();
+ long time = object.get("time").getAsJsonPrimitive().getAsLong();
+ String type = object.get("type").getAsJsonPrimitive().getAsString();
+ String url = object.get("data").getAsJsonObject().get("url").getAsJsonPrimitive().getAsString();
+
+ return new Activity(user, time, type, url);
+ }
+ }
+
+}
diff --git a/spark-common/src/main/java/me/lucko/spark/common/CommandSender.java b/spark-common/src/main/java/me/lucko/spark/common/CommandSender.java
new file mode 100644
index 0000000..9d2ecc0
--- /dev/null
+++ b/spark-common/src/main/java/me/lucko/spark/common/CommandSender.java
@@ -0,0 +1,33 @@
+/*
+ * This file is part of spark.
+ *
+ * Copyright (c) lucko (Luck) <luck@lucko.me>
+ * Copyright (c) contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package me.lucko.spark.common;
+
+import net.kyori.text.Component;
+
+public interface CommandSender {
+
+ String getName();
+
+ void sendMessage(Component message);
+
+ boolean hasPermission(String permission);
+
+}
diff --git a/spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java b/spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java
index 6b3eb21..d05d9e8 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java
@@ -24,6 +24,7 @@ import com.google.common.collect.ImmutableList;
import me.lucko.spark.common.command.Arguments;
import me.lucko.spark.common.command.Command;
import me.lucko.spark.common.command.CommandResponseHandler;
+import me.lucko.spark.common.command.modules.ActivityLogModule;
import me.lucko.spark.common.command.modules.HealthModule;
import me.lucko.spark.common.command.modules.MemoryModule;
import me.lucko.spark.common.command.modules.SamplerModule;
@@ -35,6 +36,7 @@ import me.lucko.spark.common.sampler.TickCounter;
import me.lucko.spark.common.util.BytebinClient;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
+import net.kyori.text.event.ClickEvent;
import net.kyori.text.format.TextColor;
import net.kyori.text.format.TextDecoration;
import okhttp3.OkHttpClient;
@@ -47,10 +49,8 @@ import java.util.stream.Collectors;
/**
* Abstract spark implementation used by all platforms.
- *
- * @param <S> the sender (e.g. CommandSender) type used by the platform
*/
-public class SparkPlatform<S> {
+public class SparkPlatform {
/** The URL of the viewer frontend */
public static final String VIEWER_URL = "https://sparkprofiler.github.io/#";
@@ -59,22 +59,26 @@ public class SparkPlatform<S> {
/** The bytebin instance used by the platform */
public static final BytebinClient BYTEBIN_CLIENT = new BytebinClient(OK_HTTP_CLIENT, "https://bytebin.lucko.me/", "spark-plugin");
- private final List<Command<S>> commands;
- private final SparkPlugin<S> plugin;
-
+ private final SparkPlugin plugin;
+ private final List<Command> commands;
+ private final ActivityLog activityLog;
private final TickCounter tickCounter;
private final TpsCalculator tpsCalculator;
- public SparkPlatform(SparkPlugin<S> plugin) {
+ public SparkPlatform(SparkPlugin plugin) {
this.plugin = plugin;
- ImmutableList.Builder<Command<S>> commandsBuilder = ImmutableList.builder();
- new SamplerModule<S>().registerCommands(commandsBuilder::add);
- new HealthModule<S>().registerCommands(commandsBuilder::add);
- new TickMonitoringModule<S>().registerCommands(commandsBuilder::add);
- new MemoryModule<S>().registerCommands(commandsBuilder::add);
+ ImmutableList.Builder<Command> commandsBuilder = ImmutableList.builder();
+ new SamplerModule().registerCommands(commandsBuilder::add);
+ new HealthModule().registerCommands(commandsBuilder::add);
+ new TickMonitoringModule().registerCommands(commandsBuilder::add);
+ new MemoryModule().registerCommands(commandsBuilder::add);
+ new ActivityLogModule().registerCommands(commandsBuilder::add);
this.commands = commandsBuilder.build();
+ this.activityLog = new ActivityLog(plugin.getPluginFolder().resolve("activity.json"));
+ this.activityLog.load();
+
this.tickCounter = plugin.createTickCounter();
this.tpsCalculator = this.tickCounter != null ? new TpsCalculator() : null;
}
@@ -92,10 +96,14 @@ public class SparkPlatform<S> {
}
}
- public SparkPlugin<S> getPlugin() {
+ public SparkPlugin getPlugin() {
return this.plugin;
}
+ public ActivityLog getActivityLog() {
+ return this.activityLog;
+ }
+
public TickCounter getTickCounter() {
return this.tickCounter;
}
@@ -104,17 +112,39 @@ public class SparkPlatform<S> {
return this.tpsCalculator;
}
- public void executeCommand(S sender, String[] args) {
- CommandResponseHandler<S> resp = new CommandResponseHandler<>(this, sender);
+ public void executeCommand(CommandSender sender, String[] args) {
+ CommandResponseHandler resp = new CommandResponseHandler(this, sender);
+
+ if (!sender.hasPermission("spark")) {
+ resp.replyPrefixed(TextComponent.of("You do not have permission to use this command.", TextColor.RED));
+ return;
+ }
+
if (args.length == 0) {
- sendUsage(resp);
+ resp.replyPrefixed(TextComponent.builder("")
+ .append(TextComponent.of("spark", TextColor.WHITE))
+ .append(Component.space())
+ .append(TextComponent.of("v" + getPlugin().getVersion(), TextColor.GRAY))
+ .build()
+ );
+ resp.replyPrefixed(TextComponent.builder("