Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-27 08:30:09 +01:00
Move dump creation to util class
Dieser Commit ist enthalten in:
Ursprung
17eb7b676a
Commit
08b2d78165
@ -63,7 +63,7 @@ public interface ViaAPI<T> {
|
|||||||
* @return API version incremented with meaningful API changes
|
* @return API version incremented with meaningful API changes
|
||||||
*/
|
*/
|
||||||
default int apiVersion() {
|
default int apiVersion() {
|
||||||
return 19;
|
return 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,32 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.viaversion.viaversion.commands.defaultsubs;
|
package com.viaversion.viaversion.commands.defaultsubs;
|
||||||
|
|
||||||
import com.google.common.io.CharStreams;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.viaversion.viaversion.api.Via;
|
|
||||||
import com.viaversion.viaversion.api.command.ViaCommandSender;
|
import com.viaversion.viaversion.api.command.ViaCommandSender;
|
||||||
import com.viaversion.viaversion.api.command.ViaSubCommand;
|
import com.viaversion.viaversion.api.command.ViaSubCommand;
|
||||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
import com.viaversion.viaversion.util.DumpUtil;
|
||||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
|
||||||
import com.viaversion.viaversion.dump.DumpTemplate;
|
|
||||||
import com.viaversion.viaversion.dump.VersionInfo;
|
|
||||||
import com.viaversion.viaversion.util.GsonUtil;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.InvalidObjectException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
public class DumpSubCmd extends ViaSubCommand {
|
public class DumpSubCmd extends ViaSubCommand {
|
||||||
|
|
||||||
@ -57,124 +34,15 @@ public class DumpSubCmd extends ViaSubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(ViaCommandSender sender, String[] args) {
|
public boolean execute(final ViaCommandSender sender, final String[] args) {
|
||||||
VersionInfo version = new VersionInfo(
|
DumpUtil.postDump(sender.getUUID()).whenComplete((url, e) -> {
|
||||||
System.getProperty("java.version"),
|
if (e != null) {
|
||||||
System.getProperty("os.name"),
|
sender.sendMessage("§4" + e.getMessage());
|
||||||
Via.getAPI().getServerVersion().lowestSupportedVersion(),
|
return;
|
||||||
Via.getManager().getProtocolManager().getSupportedVersions(),
|
|
||||||
Via.getPlatform().getPlatformName(),
|
|
||||||
Via.getPlatform().getPlatformVersion(),
|
|
||||||
Via.getPlatform().getPluginVersion(),
|
|
||||||
"$IMPL_VERSION",
|
|
||||||
Via.getManager().getSubPlatforms()
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, Object> configuration = Via.getPlatform().getConfigurationProvider().getValues();
|
|
||||||
DumpTemplate template = new DumpTemplate(version, configuration, Via.getPlatform().getDump(), Via.getManager().getInjector().getDump(), getPlayerSample(sender.getUUID()));
|
|
||||||
|
|
||||||
Via.getPlatform().runAsync(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
|
|
||||||
HttpURLConnection con;
|
|
||||||
try {
|
|
||||||
con = (HttpURLConnection) new URL("https://dump.viaversion.com/documents").openConnection();
|
|
||||||
} catch (IOException e) {
|
|
||||||
sender.sendMessage("§4Failed to dump, please check the console for more information");
|
|
||||||
Via.getPlatform().getLogger().log(Level.WARNING, "Could not paste ViaVersion dump to ViaVersion Dump", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
con.setRequestProperty("Content-Type", "application/json");
|
|
||||||
con.addRequestProperty("User-Agent", "ViaVersion/" + version.getPluginVersion());
|
|
||||||
con.setRequestMethod("POST");
|
|
||||||
con.setDoOutput(true);
|
|
||||||
|
|
||||||
OutputStream out = con.getOutputStream();
|
|
||||||
out.write(new GsonBuilder().setPrettyPrinting().create().toJson(template).getBytes(StandardCharsets.UTF_8));
|
|
||||||
out.close();
|
|
||||||
|
|
||||||
if (con.getResponseCode() == 429) {
|
|
||||||
sender.sendMessage("§4You can only paste once every minute to protect our systems.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String rawOutput = CharStreams.toString(new InputStreamReader(con.getInputStream()));
|
|
||||||
con.getInputStream().close();
|
|
||||||
|
|
||||||
JsonObject output = GsonUtil.getGson().fromJson(rawOutput, JsonObject.class);
|
|
||||||
|
|
||||||
if (!output.has("key"))
|
|
||||||
throw new InvalidObjectException("Key is not given in Hastebin output");
|
|
||||||
|
|
||||||
sender.sendMessage("§2We've made a dump with useful information, report your issue and provide this url: " + getUrl(output.get("key").getAsString()));
|
|
||||||
} catch (Exception e) {
|
|
||||||
sender.sendMessage("§4Failed to dump, please check the console for more information");
|
|
||||||
Via.getPlatform().getLogger().log(Level.WARNING, "Could not paste ViaVersion dump to Hastebin", e);
|
|
||||||
try {
|
|
||||||
if (con.getResponseCode() < 200 || con.getResponseCode() > 400) {
|
|
||||||
String rawOutput = CharStreams.toString(new InputStreamReader(con.getErrorStream()));
|
|
||||||
con.getErrorStream().close();
|
|
||||||
Via.getPlatform().getLogger().log(Level.WARNING, "Page returned: " + rawOutput);
|
|
||||||
}
|
|
||||||
} catch (IOException e1) {
|
|
||||||
Via.getPlatform().getLogger().log(Level.WARNING, "Failed to capture further info", e1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
|
sender.sendMessage("§2We've made a dump with useful information, report your issue and provide this url: " + url);
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUrl(String id) {
|
|
||||||
return String.format("https://dump.viaversion.com/%s", id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private JsonObject getPlayerSample(UUID senderUuid) {
|
|
||||||
JsonObject playerSample = new JsonObject();
|
|
||||||
// Player versions
|
|
||||||
JsonObject versions = new JsonObject();
|
|
||||||
playerSample.add("versions", versions);
|
|
||||||
Map<ProtocolVersion, Integer> playerVersions = new TreeMap<>((o1, o2) -> ProtocolVersion.getIndex(o2) - ProtocolVersion.getIndex(o1));
|
|
||||||
for (UserConnection connection : Via.getManager().getConnectionManager().getConnections()) {
|
|
||||||
ProtocolVersion protocolVersion = ProtocolVersion.getProtocol(connection.getProtocolInfo().getProtocolVersion());
|
|
||||||
playerVersions.compute(protocolVersion, (v, num) -> num != null ? num + 1 : 1);
|
|
||||||
}
|
|
||||||
for (Map.Entry<ProtocolVersion, Integer> entry : playerVersions.entrySet()) {
|
|
||||||
versions.addProperty(entry.getKey().getName(), entry.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pipeline of sender
|
|
||||||
Set<List<String>> pipelines = new HashSet<>();
|
|
||||||
UserConnection senderConnection = Via.getAPI().getConnection(senderUuid);
|
|
||||||
if (senderConnection != null && senderConnection.getChannel() != null) {
|
|
||||||
pipelines.add(senderConnection.getChannel().pipeline().names());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Other pipelines if different ones are found (3 max)
|
|
||||||
for (UserConnection connection : Via.getManager().getConnectionManager().getConnections()) {
|
|
||||||
if (connection.getChannel() == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> names = connection.getChannel().pipeline().names();
|
|
||||||
if (pipelines.add(names) && pipelines.size() == 3) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
for (List<String> pipeline : pipelines) {
|
|
||||||
JsonArray senderPipeline = new JsonArray(pipeline.size());
|
|
||||||
for (String name : pipeline) {
|
|
||||||
senderPipeline.add(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
playerSample.add("pipeline-" + i++, senderPipeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
return playerSample;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
215
common/src/main/java/com/viaversion/viaversion/util/DumpUtil.java
Normale Datei
215
common/src/main/java/com/viaversion/viaversion/util/DumpUtil.java
Normale Datei
@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||||
|
* Copyright (C) 2023 ViaVersion and 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 com.viaversion.viaversion.util;
|
||||||
|
|
||||||
|
import com.google.common.io.CharStreams;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.viaversion.viaversion.api.Via;
|
||||||
|
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||||
|
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||||
|
import com.viaversion.viaversion.dump.DumpTemplate;
|
||||||
|
import com.viaversion.viaversion.dump.VersionInfo;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.InvalidObjectException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
public final class DumpUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a platform dump and posts it to ViaVersion's dump server asychronously.
|
||||||
|
* May complete exceptionally with {@link DumpException}.
|
||||||
|
*
|
||||||
|
* @param playerToSample uuid of the player to include the pipeline of
|
||||||
|
* @return completable future that completes with the url of the dump
|
||||||
|
*/
|
||||||
|
public static CompletableFuture<String> postDump(@Nullable final UUID playerToSample) {
|
||||||
|
final VersionInfo version = new VersionInfo(
|
||||||
|
System.getProperty("java.version"),
|
||||||
|
System.getProperty("os.name"),
|
||||||
|
Via.getAPI().getServerVersion().lowestSupportedVersion(),
|
||||||
|
Via.getManager().getProtocolManager().getSupportedVersions(),
|
||||||
|
Via.getPlatform().getPlatformName(),
|
||||||
|
Via.getPlatform().getPlatformVersion(),
|
||||||
|
Via.getPlatform().getPluginVersion(),
|
||||||
|
"$IMPL_VERSION",
|
||||||
|
Via.getManager().getSubPlatforms()
|
||||||
|
);
|
||||||
|
final Map<String, Object> configuration = Via.getPlatform().getConfigurationProvider().getValues();
|
||||||
|
final DumpTemplate template = new DumpTemplate(version, configuration, Via.getPlatform().getDump(), Via.getManager().getInjector().getDump(), getPlayerSample(playerToSample));
|
||||||
|
final CompletableFuture<String> result = new CompletableFuture<>();
|
||||||
|
Via.getPlatform().runAsync(() -> {
|
||||||
|
final HttpURLConnection con;
|
||||||
|
try {
|
||||||
|
con = (HttpURLConnection) new URL("https://dump.viaversion.com/documents").openConnection();
|
||||||
|
} catch (final IOException e) {
|
||||||
|
Via.getPlatform().getLogger().log(Level.SEVERE, "Error when opening connection to ViaVersion dump service", e);
|
||||||
|
result.completeExceptionally(new DumpException(DumpErrorType.CONNECTION, e));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
con.setRequestProperty("Content-Type", "application/json");
|
||||||
|
con.addRequestProperty("User-Agent", "ViaVersion-" + Via.getPlatform().getPlatformName() + "/" + version.getPluginVersion());
|
||||||
|
con.setRequestMethod("POST");
|
||||||
|
con.setDoOutput(true);
|
||||||
|
|
||||||
|
try (final OutputStream out = con.getOutputStream()) {
|
||||||
|
out.write(new GsonBuilder().setPrettyPrinting().create().toJson(template).getBytes(StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (con.getResponseCode() == 429) {
|
||||||
|
result.completeExceptionally(new DumpException(DumpErrorType.RATE_LIMITED));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String rawOutput;
|
||||||
|
try (final InputStream inputStream = con.getInputStream()) {
|
||||||
|
rawOutput = CharStreams.toString(new InputStreamReader(inputStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
final JsonObject output = GsonUtil.getGson().fromJson(rawOutput, JsonObject.class);
|
||||||
|
if (!output.has("key")) {
|
||||||
|
throw new InvalidObjectException("Key is not given in Hastebin output");
|
||||||
|
}
|
||||||
|
|
||||||
|
result.complete(urlForId(output.get("key").getAsString()));
|
||||||
|
} catch (final Exception e) {
|
||||||
|
Via.getPlatform().getLogger().log(Level.SEVERE, "Error when posting ViaVersion dump", e);
|
||||||
|
result.completeExceptionally(new DumpException(DumpErrorType.POST, e));
|
||||||
|
printFailureInfo(con);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printFailureInfo(final HttpURLConnection connection) {
|
||||||
|
try {
|
||||||
|
if (connection.getResponseCode() < 200 || connection.getResponseCode() > 400) {
|
||||||
|
try (final InputStream errorStream = connection.getErrorStream()) {
|
||||||
|
final String rawOutput = CharStreams.toString(new InputStreamReader(errorStream));
|
||||||
|
Via.getPlatform().getLogger().log(Level.SEVERE, "Page returned: " + rawOutput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (final IOException e) {
|
||||||
|
Via.getPlatform().getLogger().log(Level.SEVERE, "Failed to capture further info", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String urlForId(final String id) {
|
||||||
|
return String.format("https://dump.viaversion.com/%s", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JsonObject getPlayerSample(@Nullable final UUID uuid) {
|
||||||
|
final JsonObject playerSample = new JsonObject();
|
||||||
|
// Player versions
|
||||||
|
final JsonObject versions = new JsonObject();
|
||||||
|
playerSample.add("versions", versions);
|
||||||
|
final Map<ProtocolVersion, Integer> playerVersions = new TreeMap<>((o1, o2) -> ProtocolVersion.getIndex(o2) - ProtocolVersion.getIndex(o1));
|
||||||
|
for (final UserConnection connection : Via.getManager().getConnectionManager().getConnections()) {
|
||||||
|
final ProtocolVersion protocolVersion = ProtocolVersion.getProtocol(connection.getProtocolInfo().getProtocolVersion());
|
||||||
|
playerVersions.compute(protocolVersion, (v, num) -> num != null ? num + 1 : 1);
|
||||||
|
}
|
||||||
|
for (final Map.Entry<ProtocolVersion, Integer> entry : playerVersions.entrySet()) {
|
||||||
|
versions.addProperty(entry.getKey().getName(), entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
final Set<List<String>> pipelines = new HashSet<>();
|
||||||
|
if (uuid != null) {
|
||||||
|
// Pipeline of sender
|
||||||
|
final UserConnection senderConnection = Via.getAPI().getConnection(uuid);
|
||||||
|
if (senderConnection != null && senderConnection.getChannel() != null) {
|
||||||
|
pipelines.add(senderConnection.getChannel().pipeline().names());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Other pipelines if different ones are found (3 max)
|
||||||
|
for (final UserConnection connection : Via.getManager().getConnectionManager().getConnections()) {
|
||||||
|
if (connection.getChannel() == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<String> names = connection.getChannel().pipeline().names();
|
||||||
|
if (pipelines.add(names) && pipelines.size() == 3) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (final List<String> pipeline : pipelines) {
|
||||||
|
final JsonArray senderPipeline = new JsonArray(pipeline.size());
|
||||||
|
for (final String name : pipeline) {
|
||||||
|
senderPipeline.add(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
playerSample.add("pipeline-" + i++, senderPipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
return playerSample;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class DumpException extends RuntimeException {
|
||||||
|
private final DumpErrorType errorType;
|
||||||
|
|
||||||
|
private DumpException(final DumpErrorType errorType, final Throwable cause) {
|
||||||
|
super(errorType.message(), cause);
|
||||||
|
this.errorType = errorType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DumpException(final DumpErrorType errorType) {
|
||||||
|
super(errorType.message());
|
||||||
|
this.errorType = errorType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DumpErrorType errorType() {
|
||||||
|
return errorType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum DumpErrorType {
|
||||||
|
|
||||||
|
CONNECTION("Failed to dump, please check the console for more information"),
|
||||||
|
RATE_LIMITED("Please wait before creating another dump"),
|
||||||
|
POST("Failed to dump, please check the console for more information");
|
||||||
|
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
DumpErrorType(final String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String message() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren