Skip to content

Commit 3332528

Browse files
committed
Only queue skins if we've ever made a successful connection
Some people deliberately or unknowingly block access to the global api
1 parent 27fc2d5 commit 3332528

File tree

2 files changed

+48
-19
lines changed

2 files changed

+48
-19
lines changed

core/src/main/java/org/geysermc/geyser/skin/FloodgateSkinUploader.java

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,18 @@
2828
import com.google.gson.JsonArray;
2929
import com.google.gson.JsonObject;
3030
import com.google.gson.JsonSyntaxException;
31+
import java.net.ConnectException;
32+
import java.net.UnknownHostException;
33+
import java.nio.charset.StandardCharsets;
34+
import java.util.Deque;
35+
import java.util.Iterator;
36+
import java.util.LinkedList;
37+
import java.util.List;
38+
import java.util.concurrent.ThreadLocalRandom;
39+
import java.util.concurrent.TimeUnit;
40+
import javax.net.ssl.SSLException;
3141
import lombok.Getter;
42+
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
3243
import org.geysermc.floodgate.pluginmessage.PluginMessageChannels;
3344
import org.geysermc.floodgate.util.WebsocketEventType;
3445
import org.geysermc.geyser.Constants;
@@ -40,23 +51,23 @@
4051
import org.java_websocket.client.WebSocketClient;
4152
import org.java_websocket.handshake.ServerHandshake;
4253

43-
import javax.net.ssl.SSLException;
44-
import java.net.ConnectException;
45-
import java.net.UnknownHostException;
46-
import java.nio.charset.StandardCharsets;
47-
import java.util.ArrayList;
48-
import java.util.Iterator;
49-
import java.util.List;
50-
import java.util.concurrent.ThreadLocalRandom;
51-
import java.util.concurrent.TimeUnit;
52-
5354
public final class FloodgateSkinUploader {
54-
private final List<String> skinQueue = new ArrayList<>();
55+
private static final int MAX_QUEUED_ENTRIES = 500;
5556

5657
private final GeyserLogger logger;
5758
private final WebSocketClient client;
5859
private volatile boolean closed;
5960

61+
/**
62+
* Queue skins in case the global api is temporarily unavailable, so that players will have their skin when the
63+
* global api comes back online.
64+
* However, we only start queueing skins if the websocket has been opened before, which is why this is nullable.
65+
* Some servers block access to external sites such as our global api, in which case the skin upload queue would
66+
* grow without the skins having a chance to be actually uploaded.
67+
* We'll lose player skins if the server started while the global api was offline, but that's worth the trade-off.
68+
*/
69+
private @MonotonicNonNull Deque<String> skinQueue = null;
70+
6071
@Getter private int id;
6172
@Getter private String verifyCode;
6273
@Getter private int subscribersCount;
@@ -68,10 +79,19 @@ public FloodgateSkinUploader(GeyserImpl geyser) {
6879
public void onOpen(ServerHandshake handshake) {
6980
setConnectionLostTimeout(11);
7081

71-
Iterator<String> queueIterator = skinQueue.iterator();
72-
while (isOpen() && queueIterator.hasNext()) {
73-
send(queueIterator.next());
74-
queueIterator.remove();
82+
boolean hasSkinQueue = skinQueue != null;
83+
84+
if (!hasSkinQueue) {
85+
skinQueue = new LinkedList<>();
86+
return;
87+
}
88+
89+
synchronized (skinQueue) {
90+
Iterator<String> queueIterator = skinQueue.iterator();
91+
while (isOpen() && queueIterator.hasNext()) {
92+
send(queueIterator.next());
93+
queueIterator.remove();
94+
}
7595
}
7696
}
7797

@@ -210,7 +230,16 @@ public void uploadSkin(GeyserSession session) {
210230
client.send(jsonString);
211231
return;
212232
}
213-
skinQueue.add(jsonString);
233+
234+
if (skinQueue != null) {
235+
synchronized (skinQueue) {
236+
// Only keep the most recent skins if we hit the limit, as it's more likely that they're still online
237+
if (skinQueue.size() >= MAX_QUEUED_ENTRIES) {
238+
skinQueue.removeFirst();
239+
}
240+
skinQueue.addLast(jsonString);
241+
}
242+
}
214243
}
215244

216245
private void reconnectLater(GeyserImpl geyser) {

gradle/libs.versions.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ guava = "29.0-jre"
1313
gson = "2.3.1" # Provided by Spigot 1.8.8 TODO bump to 2.8.1 or similar (Spigot 1.16.5 version) after Merge
1414
gson-runtime = "2.10.1"
1515
websocket = "1.5.1"
16-
protocol-connection = "3.0.0.Beta11-20251210.195537-15"
17-
protocol-common = "3.0.0.Beta11-20251210.195537-14"
18-
protocol-codec = "3.0.0.Beta11-20251210.195537-15"
16+
protocol-connection = "3.0.0.Beta11-20251212.150341-16"
17+
protocol-common = "3.0.0.Beta11-20251212.150341-15"
18+
protocol-codec = "3.0.0.Beta11-20251212.150341-16"
1919
raknet = "1.0.0.CR3-20251208.214317-23"
2020
minecraftauth = "5.0.0"
2121
mcprotocollib = "1.21.11-20251210.192611-9"

0 commit comments

Comments
 (0)