mirror of
https://github.com/GeyserMC/Floodgate.git
synced 2026-01-06 15:42:03 +00:00
Removed skin upload logic from Floodgate and some small changes
This commit is contained in:
@@ -23,7 +23,6 @@ val deployProjects = setOf(
|
||||
projects.api,
|
||||
// for future Floodgate integration + Fabric
|
||||
projects.core,
|
||||
// projects.database,
|
||||
projects.isolation,
|
||||
projects.bungee,
|
||||
projects.spigot,
|
||||
|
||||
@@ -18,7 +18,6 @@ dependencies {
|
||||
compileOnlyApi(libs.database.utils.sql)
|
||||
|
||||
api(libs.bundles.fastutil)
|
||||
api(libs.java.websocket)
|
||||
api(libs.cloud.core)
|
||||
api(libs.snakeyaml)
|
||||
api(libs.bstats)
|
||||
|
||||
@@ -99,6 +99,10 @@ public interface FloodgateConfig {
|
||||
@DefaultString("system")
|
||||
String defaultLocale();
|
||||
|
||||
@Hidden
|
||||
@DefaultBoolean
|
||||
boolean debug();
|
||||
|
||||
DisconnectMessages disconnect();
|
||||
|
||||
DatabaseConfig database();
|
||||
@@ -112,10 +116,6 @@ public interface FloodgateConfig {
|
||||
return Constants.CONFIG_VERSION;
|
||||
}
|
||||
|
||||
@Hidden
|
||||
@DefaultBoolean
|
||||
boolean debug();
|
||||
|
||||
@Field Key key();
|
||||
|
||||
@Field void key(Key key);
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.core.skin;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import org.geysermc.api.GeyserApiBase;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
|
||||
@Singleton
|
||||
public final class SkinUploadManager {
|
||||
private final Int2ObjectMap<SkinUploadSocket> connections =
|
||||
Int2ObjectMaps.synchronize(new Int2ObjectOpenHashMap<>());
|
||||
|
||||
@Inject GeyserApiBase api;
|
||||
@Inject SkinApplier applier;
|
||||
@Inject FloodgateLogger logger;
|
||||
|
||||
public void addConnectionIfNeeded(int id, String verifyCode) {
|
||||
connections.computeIfAbsent(id, (ignored) -> {
|
||||
SkinUploadSocket socket =
|
||||
new SkinUploadSocket(id, verifyCode, this, api, applier, logger);
|
||||
socket.connect();
|
||||
return socket;
|
||||
});
|
||||
}
|
||||
|
||||
public void removeConnection(int id, SkinUploadSocket socket) {
|
||||
connections.remove(id, socket);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
void closeAllSockets() {
|
||||
for (SkinUploadSocket socket : connections.values()) {
|
||||
socket.close();
|
||||
}
|
||||
connections.clear();
|
||||
}
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.core.skin;
|
||||
|
||||
import static org.geysermc.floodgate.core.util.Constants.WEBSOCKET_URL;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.URI;
|
||||
import javax.net.ssl.SSLException;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.api.GeyserApiBase;
|
||||
import org.geysermc.api.connection.Connection;
|
||||
import org.geysermc.floodgate.api.event.skin.SkinApplyEvent.SkinData;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.core.util.WebsocketEventType;
|
||||
import org.java_websocket.client.WebSocketClient;
|
||||
import org.java_websocket.handshake.ServerHandshake;
|
||||
|
||||
final class SkinUploadSocket extends WebSocketClient {
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
private final SkinUploadManager uploadManager;
|
||||
private final GeyserApiBase api;
|
||||
private final SkinApplier applier;
|
||||
private final FloodgateLogger logger;
|
||||
|
||||
@Getter private final int id;
|
||||
@Getter private final String verifyCode;
|
||||
@Getter private int subscribersCount;
|
||||
|
||||
public SkinUploadSocket(
|
||||
int id,
|
||||
String verifyCode,
|
||||
SkinUploadManager uploadManager,
|
||||
GeyserApiBase api,
|
||||
SkinApplier applier,
|
||||
FloodgateLogger logger
|
||||
) {
|
||||
super(getWebsocketUri(id, verifyCode));
|
||||
this.id = id;
|
||||
this.verifyCode = verifyCode;
|
||||
this.uploadManager = uploadManager;
|
||||
this.api = api;
|
||||
this.applier = applier;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
private static URI getWebsocketUri(int id, String verifyCode) {
|
||||
try {
|
||||
return new URI(WEBSOCKET_URL + "?subscribed_to=" + id + "&verify_code=" + verifyCode);
|
||||
} catch (Exception exception) {
|
||||
throw new RuntimeException(
|
||||
"Error while creating uri. Id = " + id + ", verify_code = " + verifyCode,
|
||||
exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(ServerHandshake ignored) {
|
||||
setConnectionLostTimeout(11);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(String data) {
|
||||
JsonObject message = gson.fromJson(data, JsonObject.class);
|
||||
if (message.has("error")) {
|
||||
logger.error("Skin uploader got an error: {}", message.get("error").getAsString());
|
||||
}
|
||||
|
||||
int typeId = message.get("event_id").getAsInt();
|
||||
WebsocketEventType type = WebsocketEventType.fromId(typeId);
|
||||
if (type == null) {
|
||||
logger.warn("Got unknown type {}. Ensure that Floodgate is up-to-date", typeId);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case SUBSCRIBER_COUNT:
|
||||
subscribersCount = message.get("subscribers_count").getAsInt();
|
||||
break;
|
||||
case SKIN_UPLOADED:
|
||||
String xuid = message.get("xuid").getAsString();
|
||||
Connection player = api.connectionByXuid(xuid);
|
||||
if (player != null) {
|
||||
if (!message.get("success").getAsBoolean()) {
|
||||
logger.info("Failed to upload skin for {} ({})", xuid,
|
||||
player.javaUsername());
|
||||
return;
|
||||
}
|
||||
|
||||
SkinData skinData = SkinDataImpl.from(message.getAsJsonObject("data"));
|
||||
applier.applySkin(player, skinData);
|
||||
}
|
||||
break;
|
||||
case LOG_MESSAGE:
|
||||
String logMessage = message.get("message").getAsString();
|
||||
switch (message.get("priority").getAsInt()) {
|
||||
case -1:
|
||||
logger.debug("Got a message from skin uploader: " + logMessage);
|
||||
break;
|
||||
case 0:
|
||||
logger.info("Got a message from skin uploader: " + logMessage);
|
||||
break;
|
||||
case 1:
|
||||
logger.error("Got a message from skin uploader: " + logMessage);
|
||||
break;
|
||||
default:
|
||||
logger.info(logMessage);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// we don't handle the remaining types
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(int code, String reason, boolean remote) {
|
||||
if (reason != null && !reason.isEmpty()) {
|
||||
JsonObject message = gson.fromJson(reason, JsonObject.class);
|
||||
|
||||
// info means that the uploader itself did nothing wrong
|
||||
if (message.has("info")) {
|
||||
String info = message.get("info").getAsString();
|
||||
logger.debug("Got disconnected from the skin uploader: {}", info);
|
||||
}
|
||||
|
||||
// error means that the uploader did something wrong
|
||||
if (message.has("error")) {
|
||||
String error = message.get("error").getAsString();
|
||||
logger.info("Got disconnected from the skin uploader: {}", error);
|
||||
}
|
||||
}
|
||||
|
||||
uploadManager.removeConnection(id, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception exception) {
|
||||
// skip can't connect exceptions and the syntax error in onClose that happens because of it.
|
||||
// they might however help during debugging so we'll log them when debug is enabled
|
||||
if (exception instanceof ConnectException || exception instanceof JsonSyntaxException ||
|
||||
exception instanceof SSLException) {
|
||||
if (logger.isDebug()) {
|
||||
logger.error("[debug] Got an error", exception);
|
||||
}
|
||||
return;
|
||||
}
|
||||
logger.error("Got an error", exception);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
plugins {
|
||||
id("floodgate.shadow-conventions")
|
||||
id("io.micronaut.library")
|
||||
id("floodgate.dependency-hash")
|
||||
}
|
||||
|
||||
configurations.runtimeClasspath.get()
|
||||
.exclude("org.slf4j", "slf4j-api")
|
||||
.exclude("jakarta.validation", "validation-api")
|
||||
.exclude("io.micronaut", "micronaut-aop")
|
||||
.exclude("io.micronaut", "micronaut-core")
|
||||
.exclude("io.micronaut", "micronaut-runtime")
|
||||
.exclude("io.micronaut", "micronaut-inject")
|
||||
.exclude("io.micronaut", "micronaut-context")
|
||||
|
||||
dependencies {
|
||||
api(libs.micronaut.hibernate)
|
||||
api(libs.micronaut.hikari)
|
||||
//runtimeOnly("com.h2database:h2")
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
org.gradle.configureondemand=true
|
||||
org.gradle.caching=true
|
||||
org.gradle.parallel=true
|
||||
systemProp.org.gradle.unsafe.kotlin.assignment=true
|
||||
|
||||
version=2.2.2-SNAPSHOT
|
||||
micronautVersion=4.3.1
|
||||
@@ -56,7 +56,6 @@ database-utils-mongo = { module = "org.geysermc.databaseutils:database-mongo", v
|
||||
database-utils-ap = { module = "org.geysermc.databaseutils:ap", version.ref = "database-utils" }
|
||||
fastutil-short-object-maps = { module = "com.nukkitx.fastutil:fastutil-short-object-maps", version.ref = "fastutil" }
|
||||
fastutil-int-object-maps = { module = "com.nukkitx.fastutil:fastutil-int-object-maps", version.ref = "fastutil" }
|
||||
java-websocket = { module = "org.java-websocket:Java-WebSocket", version.ref = "java-websocket" }
|
||||
cloud-core = { module = "cloud.commandframework:cloud-core", version.ref = "cloud" }
|
||||
snakeyaml = { module = "org.yaml:snakeyaml", version.ref = "snakeyaml" }
|
||||
bstats = { module = "org.bstats:bstats-base", version.ref = "bstats" }
|
||||
@@ -67,10 +66,6 @@ micronaut-context = { module = "io.micronaut:micronaut-context" }
|
||||
micronaut-http-client = { module = "io.micronaut:micronaut-http-client-jdk" }
|
||||
micronaut-validation = { module = "io.micronaut.validation:micronaut-validation" }
|
||||
micronaut-validation-processor = { module = "io.micronaut.validation:micronaut-validation-processor" }
|
||||
micronaut-data-processor = { module = "io.micronaut.data:micronaut-data-processor" }
|
||||
micronaut-data-jdbc = { module = "io.micronaut.data:micronaut-data-jdbc" }
|
||||
micronaut-hikari = { module = "io.micronaut.sql:micronaut-jdbc-hikari" }
|
||||
jakarta-persistence = { module = "jakarta.persistence:jakarta.persistence-api" }
|
||||
|
||||
micronaut-serde-jsonp = { module = "io.micronaut.serde:micronaut-serde-jsonp" }
|
||||
micronaut-serde-processor = { module = "io.micronaut.serde:micronaut-serde-processor" }
|
||||
@@ -81,9 +76,6 @@ netty-codec = { module = "io.netty:netty-codec", version.ref = "netty" }
|
||||
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter" }
|
||||
junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher" }
|
||||
|
||||
# database types
|
||||
h2 = { module = "com.h2database:h2" }
|
||||
|
||||
# bungee
|
||||
bungee = { module = "com.github.SpigotMC.BungeeCord:bungeecord-proxy", version.ref = "bungee" }
|
||||
cloud-bungee = { module = "cloud.commandframework:cloud-bungee", version.ref = "cloud" }
|
||||
|
||||
Reference in New Issue
Block a user