Skip to content

Commit 2f09e41

Browse files
committed
Remove zstd dependency and switch to GZIP in SimpleMetrics
1 parent 393baed commit 2f09e41

5 files changed

Lines changed: 37 additions & 28 deletions

File tree

bukkit/src/main/java/dev/faststats/bukkit/BukkitMetricsImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ static final class Factory extends SimpleMetrics.Factory<Plugin> {
105105
@Override
106106
public Metrics create(Plugin plugin) throws IOException, IllegalStateException {
107107
var dataFolder = plugin.getServer().getPluginsFolder().toPath().resolve("faststats");
108-
var config = dataFolder.resolve("config.json");
108+
var config = dataFolder.resolve("config.properties");
109109
return new BukkitMetricsImpl(this, plugin, config);
110110
}
111111
}

core/build.gradle.kts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
dependencies {
2-
api("com.github.luben:zstd-jni:1.5.7-6")
3-
42
compileOnlyApi("com.google.code.gson:gson:2.13.2")
53
compileOnlyApi("org.jetbrains:annotations:26.0.2-1")
64
compileOnlyApi("org.jspecify:jspecify:1.0.0")

core/src/main/java/dev/faststats/core/SimpleMetrics.java

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
package dev.faststats.core;
22

3-
import com.github.luben.zstd.Zstd;
4-
import com.google.gson.FormattingStyle;
53
import com.google.gson.JsonObject;
6-
import com.google.gson.JsonParser;
7-
import com.google.gson.stream.JsonReader;
8-
import com.google.gson.stream.JsonWriter;
94
import dev.faststats.core.chart.Chart;
105
import org.jetbrains.annotations.Async;
116
import org.jetbrains.annotations.Contract;
127
import org.jetbrains.annotations.MustBeInvokedByOverriders;
138
import org.jetbrains.annotations.VisibleForTesting;
149
import org.jspecify.annotations.Nullable;
1510

11+
import java.io.ByteArrayInputStream;
1612
import java.io.IOException;
1713
import java.io.OutputStreamWriter;
1814
import java.net.ConnectException;
@@ -28,11 +24,13 @@
2824
import java.time.Duration;
2925
import java.util.HashSet;
3026
import java.util.Optional;
27+
import java.util.Properties;
3128
import java.util.Set;
3229
import java.util.UUID;
3330
import java.util.concurrent.Executors;
3431
import java.util.concurrent.ScheduledExecutorService;
3532
import java.util.concurrent.TimeUnit;
33+
import java.util.zip.GZIPInputStream;
3634

3735
public abstract class SimpleMetrics implements Metrics {
3836
private final HttpClient httpClient = HttpClient.newBuilder()
@@ -95,9 +93,10 @@ protected boolean isSubmitting() {
9593
}
9694

9795
protected void submitData() {
98-
try {
99-
var data = createData().toString();
100-
var compressed = Zstd.compress(data.getBytes(StandardCharsets.UTF_8), 6);
96+
var data = createData().toString();
97+
try (var bytes = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
98+
var input = new GZIPInputStream(bytes)) {
99+
var compressed = input.readAllBytes();
101100
var request = HttpRequest.newBuilder()
102101
.POST(HttpRequest.BodyPublishers.ofByteArray(compressed))
103102
.header("Content-Encoding", "zstd")
@@ -154,7 +153,7 @@ protected JsonObject createData() {
154153
error("Failed to build chart data: " + chart.getId(), e);
155154
}
156155
});
157-
156+
158157
appendDefaultData(charts);
159158

160159
data.addProperty("server_id", config.serverId().toString());
@@ -235,9 +234,9 @@ protected static final class Config implements Metrics.Config {
235234
protected Config(Path file) throws IOException {
236235
var json = readOrEmpty(file);
237236

238-
this.serverId = json.map(object -> UUID.fromString(object.get("serverId").getAsString())).orElseGet(UUID::randomUUID);
239-
this.enabled = json.map(object -> object.get("enabled").getAsBoolean()).orElse(true);
240-
this.debug = json.map(object -> object.get("debug").getAsBoolean()).orElse(false);
237+
this.serverId = json.map(object -> UUID.fromString(object.getProperty("serverId"))).orElseGet(UUID::randomUUID);
238+
this.enabled = json.map(object -> object.getProperty("enabled")).map(Boolean::parseBoolean).orElse(true);
239+
this.debug = json.map(object -> object.getProperty("debug")).map(Boolean::parseBoolean).orElse(false);
241240

242241
if (json.isEmpty()) create(file, serverId);
243242
}
@@ -264,7 +263,7 @@ public boolean debug() {
264263
return debug;
265264
}
266265

267-
private static Optional<JsonObject> readOrEmpty(Path file) throws IOException {
266+
private static Optional<Properties> readOrEmpty(Path file) throws IOException {
268267
if (Files.isRegularFile(file)) {
269268
return Optional.of(read(file));
270269
} else {
@@ -275,19 +274,32 @@ private static Optional<JsonObject> readOrEmpty(Path file) throws IOException {
275274
private static void create(Path file, UUID serverId) throws IOException {
276275
Files.createDirectories(file.getParent());
277276
try (var out = Files.newOutputStream(file, StandardOpenOption.CREATE_NEW);
278-
var writer = new JsonWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8))) {
279-
writer.setFormattingStyle(FormattingStyle.PRETTY);
280-
writer.beginObject();
281-
writer.name("serverId").value(serverId.toString());
282-
writer.name("enabled").value(true);
283-
writer.name("debug").value(false);
284-
writer.endObject();
277+
var writer = new OutputStreamWriter(out, StandardCharsets.UTF_8)) {
278+
var properties = new Properties();
279+
280+
properties.setProperty("serverId", serverId.toString());
281+
properties.setProperty("enabled", Boolean.toString(true));
282+
properties.setProperty("debug", Boolean.toString(false));
283+
284+
var comment = """
285+
FastStats (https://faststats.dev) collects some basic information for plugin authors, like
286+
# how many people use their plugin and their total player count. It's recommended to keep
287+
# metrics enabled, but if you're not comfortable with this, you can turn this setting off.
288+
# There is no performance penalty associated with having metrics enabled, and data sent to
289+
# FastStats is fully anonymous.
290+
291+
# If you suspect a plugin is collecting personal data or bypassing the "enabled" option,
292+
# please report it to the FastStats team (https://faststats.dev/abuse).
293+
""";
294+
properties.store(writer, comment);
285295
}
286296
}
287297

288-
private static JsonObject read(Path file) throws IOException {
289-
try (var reader = new JsonReader(Files.newBufferedReader(file, StandardCharsets.UTF_8))) {
290-
return JsonParser.parseReader(reader).getAsJsonObject();
298+
private static Properties read(Path file) throws IOException {
299+
try (var reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) {
300+
var properties = new Properties();
301+
properties.load(reader);
302+
return properties;
291303
}
292304
}
293305
}

core/src/main/java/module-info.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
exports dev.faststats.core.chart;
66
exports dev.faststats.core;
77

8-
requires com.github.luben.zstd_jni;
98
requires com.google.gson;
109
requires java.net.http;
1110

velocity/src/main/java/dev/faststats/velocity/VelocityMetricsImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public Factory(ProxyServer server, Logger logger, @DataDirectory Path dataDirect
100100
public Metrics create(Object plugin) throws IOException, IllegalStateException, IllegalArgumentException {
101101
var faststats = dataDirectory.resolveSibling("faststats");
102102
var container = server.getPluginManager().ensurePluginContainer(plugin);
103-
return new VelocityMetricsImpl(this, logger, server, faststats.resolve("config.json"), container);
103+
return new VelocityMetricsImpl(this, logger, server, faststats.resolve("config.properties"), container);
104104
}
105105
}
106106
}

0 commit comments

Comments
 (0)