Compare commits

...

6 Commits

Author SHA1 Message Date
rtm516 e45922a630
Merge 46f19dd6f7 into 42a9ba617b 2024-04-26 23:07:56 +00:00
rtm516 46f19dd6f7
Add originalSkin method to event 2024-04-27 00:07:49 +01:00
rtm516 92e4439075
Get rid of array and preserve original skin data 2024-04-27 00:00:41 +01:00
rtm516 d2a9ee53e8
Ajust for review and bump version to 2.2.4 2024-04-26 22:29:01 +01:00
RK_01 42a9ba617b
Update ViaProxy platform (#4607)
* Update ViaProxy API usage

* Don't reference ViaProxy API in dummy application
2024-04-26 20:06:37 +02:00
chris a57e7b54dc
Update ViaVersion api usage to be compatible with ViaVersion 4.10 (#4606) 2024-04-26 16:36:47 +02:00
13 changed files with 64 additions and 73 deletions

View File

@ -1,5 +1,6 @@
<component name="CopyrightManager"> <component name="CopyrightManager">
<copyright> <copyright>
<option name="allowReplaceRegexp" value="Copyright" />
<option name="notice" value="Copyright (c) &amp;#36;originalComment.match(&quot;Copyright \(c\) (\d+)&quot;, 1, &quot;-&quot;)&amp;#36;today.year GeyserMC. http://geysermc.org&#10;&#10;Permission is hereby granted, free of charge, to any person obtaining a copy&#10;of this software and associated documentation files (the &quot;Software&quot;), to deal&#10;in the Software without restriction, including without limitation the rights&#10;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell&#10;copies of the Software, and to permit persons to whom the Software is&#10;furnished to do so, subject to the following conditions:&#10;&#10;The above copyright notice and this permission notice shall be included in&#10;all copies or substantial portions of the Software.&#10;&#10;THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR&#10;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,&#10;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE&#10;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER&#10;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,&#10;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN&#10;THE SOFTWARE.&#10;&#10;@author GeyserMC&#10;@link https://github.com/GeyserMC/Geyser" /> <option name="notice" value="Copyright (c) &amp;#36;originalComment.match(&quot;Copyright \(c\) (\d+)&quot;, 1, &quot;-&quot;)&amp;#36;today.year GeyserMC. http://geysermc.org&#10;&#10;Permission is hereby granted, free of charge, to any person obtaining a copy&#10;of this software and associated documentation files (the &quot;Software&quot;), to deal&#10;in the Software without restriction, including without limitation the rights&#10;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell&#10;copies of the Software, and to permit persons to whom the Software is&#10;furnished to do so, subject to the following conditions:&#10;&#10;The above copyright notice and this permission notice shall be included in&#10;all copies or substantial portions of the Software.&#10;&#10;THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR&#10;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,&#10;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE&#10;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER&#10;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,&#10;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN&#10;THE SOFTWARE.&#10;&#10;@author GeyserMC&#10;@link https://github.com/GeyserMC/Geyser" />
<option name="myName" value="Geyser" /> <option name="myName" value="Geyser" />
</copyright> </copyright>

View File

@ -46,7 +46,7 @@ public abstract class SessionSkinApplyEvent extends ConnectionEvent {
private final UUID uuid; private final UUID uuid;
private final boolean slim; private final boolean slim;
private final boolean bedrock; private final boolean bedrock;
private final SkinData skinData; private final SkinData originalSkinData;
public SessionSkinApplyEvent(@NonNull GeyserConnection connection, String username, UUID uuid, boolean slim, boolean bedrock, SkinData skinData) { public SessionSkinApplyEvent(@NonNull GeyserConnection connection, String username, UUID uuid, boolean slim, boolean bedrock, SkinData skinData) {
super(connection); super(connection);
@ -54,7 +54,7 @@ public abstract class SessionSkinApplyEvent extends ConnectionEvent {
this.uuid = uuid; this.uuid = uuid;
this.slim = slim; this.slim = slim;
this.bedrock = bedrock; this.bedrock = bedrock;
this.skinData = skinData; this.originalSkinData = skinData;
} }
/** /**
@ -93,14 +93,21 @@ public abstract class SessionSkinApplyEvent extends ConnectionEvent {
return bedrock; return bedrock;
} }
/**
* The original skin data of the player.
*
* @return the original skin data of the player
*/
public SkinData originalSkin() {
return originalSkinData;
}
/** /**
* The skin data of the player. * The skin data of the player.
* *
* @return the skin data of the player * @return the skin data of the player
*/ */
public SkinData skinData() { public abstract SkinData skinData();
return skinData;
}
/** /**
* Change the skin of the player. * Change the skin of the player.

View File

@ -58,7 +58,7 @@ public class GeyserSpigotLegacyNativeWorldManager extends GeyserSpigotNativeWorl
int newBlockId = oldBlockId; int newBlockId = oldBlockId;
// protocolList should *not* be null; we checked for that before initializing this class // protocolList should *not* be null; we checked for that before initializing this class
for (int i = protocolList.size() - 1; i >= 0; i--) { for (int i = protocolList.size() - 1; i >= 0; i--) {
MappingData mappingData = protocolList.get(i).getProtocol().getMappingData(); MappingData mappingData = protocolList.get(i).protocol().getMappingData();
if (mappingData != null) { if (mappingData != null) {
newBlockId = mappingData.getNewBlockStateId(newBlockId); newBlockId = mappingData.getNewBlockStateId(newBlockId);
} }

View File

@ -26,7 +26,7 @@ package org.geysermc.geyser.platform.viaproxy;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import net.raphimc.vialegacy.api.LegacyProtocolVersion; import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.viaproxy.cli.options.Options; import net.raphimc.viaproxy.ViaProxy;
import org.geysermc.geyser.configuration.GeyserJacksonConfiguration; import org.geysermc.geyser.configuration.GeyserJacksonConfiguration;
import java.io.File; import java.io.File;
@ -43,7 +43,7 @@ public class GeyserViaProxyConfiguration extends GeyserJacksonConfiguration {
@Override @Override
public int getPingPassthroughInterval() { public int getPingPassthroughInterval() {
int interval = super.getPingPassthroughInterval(); int interval = super.getPingPassthroughInterval();
if (interval < 15 && Options.PROTOCOL_VERSION != null && Options.PROTOCOL_VERSION.olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) { if (interval < 15 && ViaProxy.getConfig().getTargetVersion() != null && ViaProxy.getConfig().getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) {
// <= 1.6.4 servers sometimes block incoming connections from an IP address if too many connections are made // <= 1.6.4 servers sometimes block incoming connections from an IP address if too many connections are made
interval = 15; interval = 15;
} }

View File

@ -26,7 +26,6 @@ package org.geysermc.geyser.platform.viaproxy;
import lombok.Getter; import lombok.Getter;
import net.raphimc.viaproxy.ViaProxy; import net.raphimc.viaproxy.ViaProxy;
import net.raphimc.viaproxy.cli.options.Options;
import net.raphimc.viaproxy.plugins.ViaProxyPlugin; import net.raphimc.viaproxy.plugins.ViaProxyPlugin;
import org.geysermc.geyser.dump.BootstrapDumpInfo; import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.text.AsteriskSerializer; import org.geysermc.geyser.text.AsteriskSerializer;
@ -49,8 +48,8 @@ public class GeyserViaProxyDumpInfo extends BootstrapDumpInfo {
public GeyserViaProxyDumpInfo() { public GeyserViaProxyDumpInfo() {
this.platformVersion = ViaProxy.VERSION; this.platformVersion = ViaProxy.VERSION;
this.onlineMode = Options.ONLINE_MODE; this.onlineMode = ViaProxy.getConfig().isProxyOnlineMode();
if (Options.BIND_ADDRESS instanceof InetSocketAddress inetSocketAddress) { if (ViaProxy.getConfig().getBindAddress() instanceof InetSocketAddress inetSocketAddress) {
this.serverIP = inetSocketAddress.getHostString(); this.serverIP = inetSocketAddress.getHostString();
this.serverPort = inetSocketAddress.getPort(); this.serverPort = inetSocketAddress.getPort();
} else { } else {

View File

@ -25,7 +25,6 @@
package org.geysermc.geyser.platform.viaproxy; package org.geysermc.geyser.platform.viaproxy;
import net.raphimc.viaproxy.plugins.PluginManager;
import org.geysermc.geyser.GeyserMain; import org.geysermc.geyser.GeyserMain;
public class GeyserViaProxyMain extends GeyserMain { public class GeyserViaProxyMain extends GeyserMain {
@ -39,7 +38,7 @@ public class GeyserViaProxyMain extends GeyserMain {
} }
public String getPluginFolder() { public String getPluginFolder() {
return PluginManager.PLUGINS_DIR.getName(); return "plugins";
} }
} }

View File

@ -27,7 +27,6 @@ package org.geysermc.geyser.platform.viaproxy;
import net.lenni0451.lambdaevents.EventHandler; import net.lenni0451.lambdaevents.EventHandler;
import net.raphimc.vialegacy.api.LegacyProtocolVersion; import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.viaproxy.ViaProxy; import net.raphimc.viaproxy.ViaProxy;
import net.raphimc.viaproxy.cli.options.Options;
import net.raphimc.viaproxy.plugins.PluginManager; import net.raphimc.viaproxy.plugins.PluginManager;
import net.raphimc.viaproxy.plugins.ViaProxyPlugin; import net.raphimc.viaproxy.plugins.ViaProxyPlugin;
import net.raphimc.viaproxy.plugins.events.ConsoleCommandEvent; import net.raphimc.viaproxy.plugins.events.ConsoleCommandEvent;
@ -137,7 +136,7 @@ public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootst
GeyserImpl.start(); GeyserImpl.start();
if (Options.PROTOCOL_VERSION != null && Options.PROTOCOL_VERSION.newerThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) { if (ViaProxy.getConfig().getTargetVersion() != null && ViaProxy.getConfig().getTargetVersion().newerThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) {
// Only initialize the ping passthrough if the protocol version is above beta 1.7.3, as that's when the status protocol was added // Only initialize the ping passthrough if the protocol version is above beta 1.7.3, as that's when the status protocol was added
this.pingPassthrough = GeyserLegacyPingPassthrough.init(this.geyser); this.pingPassthrough = GeyserLegacyPingPassthrough.init(this.geyser);
} }
@ -186,19 +185,19 @@ public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootst
@NotNull @NotNull
@Override @Override
public String getServerBindAddress() { public String getServerBindAddress() {
if (Options.BIND_ADDRESS instanceof InetSocketAddress socketAddress) { if (ViaProxy.getConfig().getBindAddress() instanceof InetSocketAddress socketAddress) {
return socketAddress.getHostString(); return socketAddress.getHostString();
} else { } else {
throw new IllegalStateException("Unsupported bind address type: " + Options.BIND_ADDRESS.getClass().getName()); throw new IllegalStateException("Unsupported bind address type: " + ViaProxy.getConfig().getBindAddress().getClass().getName());
} }
} }
@Override @Override
public int getServerPort() { public int getServerPort() {
if (Options.BIND_ADDRESS instanceof InetSocketAddress socketAddress) { if (ViaProxy.getConfig().getBindAddress() instanceof InetSocketAddress socketAddress) {
return socketAddress.getPort(); return socketAddress.getPort();
} else { } else {
throw new IllegalStateException("Unsupported bind address type: " + Options.BIND_ADDRESS.getClass().getName()); throw new IllegalStateException("Unsupported bind address type: " + ViaProxy.getConfig().getBindAddress().getClass().getName());
} }
} }

View File

@ -2,4 +2,4 @@ name: "${name}-ViaProxy"
version: "${version}" version: "${version}"
author: "${author}" author: "${author}"
main: "org.geysermc.geyser.platform.viaproxy.GeyserViaProxyPlugin" main: "org.geysermc.geyser.platform.viaproxy.GeyserViaProxyPlugin"
min-version: "3.2.0" min-version: "3.2.1"

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -116,7 +116,7 @@ public class SkullResourcePackManager {
return; return;
} }
BufferedImage image = SkinProvider.requestImage(skinUrl, null); BufferedImage image = SkinProvider.requestImage(skinUrl, false);
// Resize skins to 48x16 to save on space and memory // Resize skins to 48x16 to save on space and memory
BufferedImage skullTexture = new BufferedImage(48, 16, image.getType()); BufferedImage skullTexture = new BufferedImage(48, 16, image.getType());
// Reorder skin parts to fit into the space // Reorder skin parts to fit into the space

View File

@ -94,6 +94,7 @@ public class FakeHeadProvider {
// Avoiding memory leak // Avoiding memory leak
fakeHeadEntry.setEntity(null); fakeHeadEntry.setEntity(null);
fakeHeadEntry.setSession(null);
return new SkinData(mergedSkin, cape, geometry); return new SkinData(mergedSkin, cape, geometry);
} }

View File

@ -261,25 +261,31 @@ public class SkinProvider {
// Call event to allow extensions to modify the skin, cape and geo // Call event to allow extensions to modify the skin, cape and geo
boolean isBedrock = GeyserImpl.getInstance().connectionByUuid(entity.getUuid()) != null; boolean isBedrock = GeyserImpl.getInstance().connectionByUuid(entity.getUuid()) != null;
final SkinData[] skinData = {new SkinData(skin, cape, geometry)}; SkinData skinData = new SkinData(skin, cape, geometry);
GeyserImpl.getInstance().eventBus().fire(new SessionSkinApplyEvent(session, entity.getUsername(), entity.getUuid(), data.isAlex(), isBedrock, skinData[0]) { final EventSkinData eventSkinData = new EventSkinData(skinData);
GeyserImpl.getInstance().eventBus().fire(new SessionSkinApplyEvent(session, entity.getUsername(), entity.getUuid(), data.isAlex(), isBedrock, skinData) {
@Override
public SkinData skinData() {
return eventSkinData.skinData();
}
@Override @Override
public void skin(@NonNull Skin newSkin) { public void skin(@NonNull Skin newSkin) {
skinData[0] = new SkinData(newSkin, skinData[0].cape(), skinData[0].geometry()); eventSkinData.skinData(new SkinData(newSkin, skinData.cape(), skinData.geometry()));
} }
@Override @Override
public void cape(@NonNull Cape newCape) { public void cape(@NonNull Cape newCape) {
skinData[0] = new SkinData(skinData[0].skin(), newCape, skinData[0].geometry()); eventSkinData.skinData(new SkinData(skinData.skin(), newCape, skinData.geometry()));
} }
@Override @Override
public void geometry(@NonNull SkinGeometry newGeometry) { public void geometry(@NonNull SkinGeometry newGeometry) {
skinData[0] = new SkinData(skinData[0].skin(), skinData[0].cape(), newGeometry); eventSkinData.skinData(new SkinData(skinData.skin(), skinData.cape(), newGeometry));
} }
}); });
return skinData[0]; return eventSkinData.skinData();
} catch (Exception e) { } catch (Exception e) {
GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.skin.fail", entity.getUuid()), e); GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.skin.fail", entity.getUuid()), e);
} }
@ -292,10 +298,9 @@ public class SkinProvider {
return CompletableFuture.supplyAsync(() -> { return CompletableFuture.supplyAsync(() -> {
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
CapeProvider provider = capeUrl != null ? CapeProvider.MINECRAFT : null;
SkinAndCape skinAndCape = new SkinAndCape( SkinAndCape skinAndCape = new SkinAndCape(
getOrDefault(requestSkin(playerId, skinUrl, false), EMPTY_SKIN, 5), getOrDefault(requestSkin(playerId, skinUrl, false), EMPTY_SKIN, 5),
getOrDefault(requestCape(capeUrl, provider, false), EMPTY_CAPE, 5) getOrDefault(requestCape(capeUrl, false), EMPTY_CAPE, 5)
); );
GeyserImpl.getInstance().getLogger().debug("Took " + (System.currentTimeMillis() - time) + "ms for " + playerId); GeyserImpl.getInstance().getLogger().debug("Took " + (System.currentTimeMillis() - time) + "ms for " + playerId);
@ -332,7 +337,7 @@ public class SkinProvider {
return future; return future;
} }
private static CompletableFuture<Cape> requestCape(String capeUrl, CapeProvider provider, boolean newThread) { private static CompletableFuture<Cape> requestCape(String capeUrl, boolean newThread) {
if (capeUrl == null || capeUrl.isEmpty()) return CompletableFuture.completedFuture(EMPTY_CAPE); if (capeUrl == null || capeUrl.isEmpty()) return CompletableFuture.completedFuture(EMPTY_CAPE);
CompletableFuture<Cape> requestedCape = requestedCapes.get(capeUrl); CompletableFuture<Cape> requestedCape = requestedCapes.get(capeUrl);
if (requestedCape != null) { if (requestedCape != null) {
@ -346,14 +351,14 @@ public class SkinProvider {
CompletableFuture<Cape> future; CompletableFuture<Cape> future;
if (newThread) { if (newThread) {
future = CompletableFuture.supplyAsync(() -> supplyCape(capeUrl, provider), getExecutorService()) future = CompletableFuture.supplyAsync(() -> supplyCape(capeUrl), getExecutorService())
.whenCompleteAsync((cape, throwable) -> { .whenCompleteAsync((cape, throwable) -> {
CACHED_JAVA_CAPES.put(capeUrl, cape); CACHED_JAVA_CAPES.put(capeUrl, cape);
requestedCapes.remove(capeUrl); requestedCapes.remove(capeUrl);
}); });
requestedCapes.put(capeUrl, future); requestedCapes.put(capeUrl, future);
} else { } else {
Cape cape = supplyCape(capeUrl, provider); // blocking Cape cape = supplyCape(capeUrl); // blocking
future = CompletableFuture.completedFuture(cape); future = CompletableFuture.completedFuture(cape);
CACHED_JAVA_CAPES.put(capeUrl, cape); CACHED_JAVA_CAPES.put(capeUrl, cape);
} }
@ -377,17 +382,17 @@ public class SkinProvider {
private static Skin supplySkin(UUID uuid, String textureUrl) { private static Skin supplySkin(UUID uuid, String textureUrl) {
try { try {
byte[] skin = requestImageData(textureUrl, null); byte[] skin = requestImageData(textureUrl, false);
return new Skin(textureUrl, skin); return new Skin(textureUrl, skin);
} catch (Exception ignored) {} // just ignore I guess } catch (Exception ignored) {} // just ignore I guess
return new Skin("empty", EMPTY_SKIN.skinData(), true); return new Skin("empty", EMPTY_SKIN.skinData(), true);
} }
private static Cape supplyCape(String capeUrl, CapeProvider provider) { private static Cape supplyCape(String capeUrl) {
byte[] cape = EMPTY_CAPE.capeData(); byte[] cape = EMPTY_CAPE.capeData();
try { try {
cape = requestImageData(capeUrl, provider); cape = requestImageData(capeUrl, true);
} catch (Exception ignored) { } catch (Exception ignored) {
} // just ignore I guess } // just ignore I guess
@ -402,7 +407,7 @@ public class SkinProvider {
} }
@SuppressWarnings("ResultOfMethodCallIgnored") @SuppressWarnings("ResultOfMethodCallIgnored")
public static BufferedImage requestImage(String imageUrl, CapeProvider provider) throws IOException { public static BufferedImage requestImage(String imageUrl, boolean isCape) throws IOException {
BufferedImage image = null; BufferedImage image = null;
// First see if we have a cached file. We also update the modification stamp so we know when the file was last used // First see if we have a cached file. We also update the modification stamp so we know when the file was last used
@ -417,7 +422,7 @@ public class SkinProvider {
// If no image we download it // If no image we download it
if (image == null) { if (image == null) {
image = downloadImage(imageUrl, provider); image = downloadImage(imageUrl);
GeyserImpl.getInstance().getLogger().debug("Downloaded " + imageUrl); GeyserImpl.getInstance().getLogger().debug("Downloaded " + imageUrl);
// Write to cache if we are allowed // Write to cache if we are allowed
@ -433,7 +438,7 @@ public class SkinProvider {
} }
// if the requested image is a cape // if the requested image is a cape
if (provider != null) { if (isCape) {
if (image.getWidth() > 64 || image.getHeight() > 32) { if (image.getWidth() > 64 || image.getHeight() > 32) {
// Prevent weirdly-scaled capes from being cut off // Prevent weirdly-scaled capes from being cut off
BufferedImage newImage = new BufferedImage(128, 64, BufferedImage.TYPE_INT_ARGB); BufferedImage newImage = new BufferedImage(128, 64, BufferedImage.TYPE_INT_ARGB);
@ -465,8 +470,8 @@ public class SkinProvider {
return image; return image;
} }
private static byte[] requestImageData(String imageUrl, CapeProvider provider) throws Exception { private static byte[] requestImageData(String imageUrl, boolean isCape) throws Exception {
BufferedImage image = requestImage(imageUrl, provider); BufferedImage image = requestImage(imageUrl, isCape);
byte[] data = bufferedImageToImageData(image); byte[] data = bufferedImageToImageData(image);
image.flush(); image.flush();
return data; return data;
@ -529,7 +534,7 @@ public class SkinProvider {
}); });
} }
private static BufferedImage downloadImage(String imageUrl, CapeProvider provider) throws IOException { private static BufferedImage downloadImage(String imageUrl) throws IOException {
HttpURLConnection con = (HttpURLConnection) new URL(imageUrl).openConnection(); HttpURLConnection con = (HttpURLConnection) new URL(imageUrl).openConnection();
con.setRequestProperty("User-Agent", WebUtils.getUserAgent()); con.setRequestProperty("User-Agent", WebUtils.getUserAgent());
con.setConnectTimeout(10000); con.setConnectTimeout(10000);
@ -538,7 +543,7 @@ public class SkinProvider {
BufferedImage image = ImageIO.read(con.getInputStream()); BufferedImage image = ImageIO.read(con.getInputStream());
if (image == null) { if (image == null) {
throw new IllegalArgumentException("Failed to read image from: %s (cape provider=%s)".formatted(imageUrl, provider)); throw new IllegalArgumentException("Failed to read image from: %s".formatted(imageUrl));
} }
return image; return image;
} }
@ -616,39 +621,19 @@ public class SkinProvider {
public record SkinAndCape(Skin skin, Cape cape) { public record SkinAndCape(Skin skin, Cape cape) {
} }
/* public static class EventSkinData {
* Sorted by 'priority' private SkinData skinData;
*/
@AllArgsConstructor
@NoArgsConstructor
@Getter
public enum CapeProvider {
MINECRAFT;
public static final CapeProvider[] VALUES = Arrays.copyOfRange(values(), 1, 5); public EventSkinData(SkinData skinData) {
private String url; this.skinData = skinData;
private CapeUrlType type;
public String getUrlFor(String type) {
return String.format(url, type);
} }
public String getUrlFor(UUID uuid, String username) { public SkinData skinData() {
return getUrlFor(toRequestedType(type, uuid, username)); return skinData;
} }
public static String toRequestedType(CapeUrlType type, UUID uuid, String username) { public void skinData(SkinData skinData) {
return switch (type) { this.skinData = skinData;
case UUID -> uuid.toString().replace("-", "");
case UUID_DASHED -> uuid.toString();
default -> username;
};
} }
} }
public enum CapeUrlType {
USERNAME,
UUID,
UUID_DASHED
}
} }

View File

@ -7,5 +7,5 @@ org.gradle.vfs.watch=false
group=org.geysermc group=org.geysermc
id=geyser id=geyser
version=2.2.3-SNAPSHOT version=2.2.4-SNAPSHOT
description=Allows for players from Minecraft: Bedrock Edition to join Minecraft: Java Edition servers. description=Allows for players from Minecraft: Bedrock Edition to join Minecraft: Java Edition servers.

View File

@ -29,7 +29,7 @@ adapters = "1.11-SNAPSHOT"
commodore = "2.2" commodore = "2.2"
bungeecord = "a7c6ede" bungeecord = "a7c6ede"
velocity = "3.1.1" velocity = "3.1.1"
viaproxy = "3.2.0-SNAPSHOT" viaproxy = "3.2.1"
fabric-minecraft = "1.20.4" fabric-minecraft = "1.20.4"
fabric-loader = "0.15.2" fabric-loader = "0.15.2"
fabric-api = "0.91.2+1.20.4" fabric-api = "0.91.2+1.20.4"