mirror of
https://github.com/GeyserMC/Floodgate.git
synced 2025-12-19 14:59:20 +00:00
Reduce session server lookups (#509)
* fix: add default skin to gameprofiles * fix: add signatures by default to prevent issues * cleanup * no longer apply empty textures * revert formatting change * fix(spigot): linked player textures * fix(velocity): linked player textures * fix(bungeecord): apply linked textures * Made the MojangUtils class instance based, removed some unneeded code * Don't block Velocity event threads, made the Bungee variant work * Add some comments --------- Co-authored-by: bridge <haha@haha.com> Co-authored-by: Tim203 <mctim203@gmail.com>
This commit is contained in:
@@ -29,8 +29,14 @@ import com.google.gson.JsonObject;
|
||||
import java.util.Objects;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.floodgate.api.event.skin.SkinApplyEvent.SkinData;
|
||||
import org.geysermc.floodgate.util.Constants;
|
||||
|
||||
public class SkinDataImpl implements SkinData {
|
||||
public static final SkinData DEFAULT_SKIN = new SkinDataImpl(
|
||||
Constants.DEFAULT_MINECRAFT_JAVA_SKIN_TEXTURE,
|
||||
Constants.DEFAULT_MINECRAFT_JAVA_SKIN_SIGNATURE
|
||||
);
|
||||
|
||||
private final String value;
|
||||
private final String signature;
|
||||
|
||||
|
||||
110
core/src/main/java/org/geysermc/floodgate/util/MojangUtils.java
Normal file
110
core/src/main/java/org/geysermc/floodgate/util/MojangUtils.java
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2024 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.util;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.name.Named;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.NonNull;
|
||||
import org.geysermc.floodgate.api.event.skin.SkinApplyEvent.SkinData;
|
||||
import org.geysermc.floodgate.skin.SkinDataImpl;
|
||||
import org.geysermc.floodgate.util.HttpClient.HttpResponse;
|
||||
|
||||
@Singleton
|
||||
public class MojangUtils {
|
||||
private final Cache<UUID, SkinData> SKIN_CACHE = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(5, TimeUnit.MINUTES)
|
||||
.maximumSize(500)
|
||||
.build();
|
||||
|
||||
@Inject private HttpClient httpClient;
|
||||
@Inject
|
||||
@Named("commonPool")
|
||||
private ExecutorService commonPool;
|
||||
|
||||
public CompletableFuture<@NonNull SkinData> skinFor(UUID playerId) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
return SKIN_CACHE.get(playerId, () -> fetchSkinFor(playerId));
|
||||
} catch (ExecutionException exception) {
|
||||
throw new RuntimeException(exception.getCause());
|
||||
}
|
||||
}, commonPool);
|
||||
}
|
||||
|
||||
private @NonNull SkinData fetchSkinFor(UUID playerId) {
|
||||
HttpResponse<JsonObject> httpResponse = httpClient.get(
|
||||
String.format(Constants.PROFILE_WITH_PROPERTIES_URL, playerId.toString()));
|
||||
|
||||
if (httpResponse.getHttpCode() != 200) {
|
||||
return SkinDataImpl.DEFAULT_SKIN;
|
||||
}
|
||||
|
||||
JsonObject response = httpResponse.getResponse();
|
||||
|
||||
if (response == null) {
|
||||
return SkinDataImpl.DEFAULT_SKIN;
|
||||
}
|
||||
|
||||
JsonArray properties = response.getAsJsonArray("properties");
|
||||
|
||||
if (properties.size() == 0) {
|
||||
return SkinDataImpl.DEFAULT_SKIN;
|
||||
}
|
||||
|
||||
for (JsonElement property : properties) {
|
||||
if (!property.isJsonObject()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
JsonObject propertyObject = property.getAsJsonObject();
|
||||
|
||||
if (!propertyObject.has("name")
|
||||
|| !propertyObject.has("value")
|
||||
|| !propertyObject.has("signature")
|
||||
|| !propertyObject.get("name").getAsString().equals("textures")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return new SkinDataImpl(
|
||||
propertyObject.get("value").getAsString(),
|
||||
propertyObject.get("signature").getAsString()
|
||||
);
|
||||
}
|
||||
|
||||
return SkinDataImpl.DEFAULT_SKIN;
|
||||
}
|
||||
}
|
||||
@@ -56,6 +56,9 @@ public final class Constants {
|
||||
public static final String LATEST_VERSION_URL =
|
||||
"https://download.geysermc.org/v2/projects/%s/versions/latest/builds/latest";
|
||||
|
||||
public static final String PROFILE_WITH_PROPERTIES_URL =
|
||||
"https://sessionserver.mojang.com/session/minecraft/profile/%s?unsigned=false";
|
||||
|
||||
|
||||
public static final String NTP_SERVER = "time.cloudflare.com";
|
||||
public static final String INTERNAL_ERROR_MESSAGE =
|
||||
@@ -70,4 +73,7 @@ public final class Constants {
|
||||
public static final int HANDSHAKE_PACKET_ID = 0;
|
||||
public static final int LOGIN_SUCCESS_PACKET_ID = 2;
|
||||
public static final int SET_COMPRESSION_PACKET_ID = 3;
|
||||
|
||||
public static final String DEFAULT_MINECRAFT_JAVA_SKIN_TEXTURE = "ewogICJ0aW1lc3RhbXAiIDogMTcxNTcxNzM1NTI2MywKICAicHJvZmlsZUlkIiA6ICIyMWUzNjdkNzI1Y2Y0ZTNiYjI2OTJjNGEzMDBhNGRlYiIsCiAgInByb2ZpbGVOYW1lIiA6ICJHZXlzZXJNQyIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS8zMWY0NzdlYjFhN2JlZWU2MzFjMmNhNjRkMDZmOGY2OGZhOTNhMzM4NmQwNDQ1MmFiMjdmNDNhY2RmMWI2MGNiIgogICAgfQogIH0KfQ";
|
||||
public static final String DEFAULT_MINECRAFT_JAVA_SKIN_SIGNATURE = "dFKIZ5d6vNqCSe1IFGiVLjt3cnW8qh4qNP2umg9zqkX9bvAQawuR1iuO1kCD/+ye8A6GQFv2wRCdxdrjp5+Vrr0SsWqMnsYDN8cEg6CD18mAnaKI1TYDuGbdJaqLyGqN5wqSMdHxchs9iovFkde5ir4aYdvHkA11vOTi11L4kUzETGzJ4iKVuZOv4dq+B7wFAWqp4n8QZfhixyvemFazQHlLmxnuhU+jhpZMvYY9MAaRAJonfy/wJe9LymbTe0EJ8N+NwZQDrEUzgfBFo4OIGDqRZwvydInCqkjhPMtHCSL25VOKwcFocYpRYbk4eIKM4CLjYlBiQGki+XKsPaljwjVhnT0jUupSf7yraGb3T0CsVBjhDbIIIp9nytlbO0GvxHu0TzYjkr4Iji0do5jlCKQ/OasXcL21wd6ozw0t1QZnnzxi9ewSuyYVY9ErmWdkww1OtCIgJilceEBwNAB8+mhJ062WFaYPgJQAmOREM8InW33dbbeENMFhQi4LIO5P7p9ye3B4Lrwm20xtd9wJk3lewzcs8ezh0LUF6jPSDQDivgSKU49mLCTmOi+WZh8zKjjxfVEtNZON2W+3nct0LiWBVsQ55HzlvF0FFxuRVm6pxi6MQK2ernv3DQl0hUqyQ1+RV9nfZXTQOAUzwLjKx3t2zKqyZIiNEKLE+iAXrsE=";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user