3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-09-29 14:40:21 +02:00

Resource pack API

Dieser Commit ist enthalten in:
Andrew Steinborn 2018-12-29 15:21:47 -05:00
Ursprung 280563ffa0
Commit 0ca0c2a297
8 geänderte Dateien mit 230 neuen und 1 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,49 @@
package com.velocitypowered.api.event.player;
import com.google.common.base.Preconditions;
import com.velocitypowered.api.proxy.Player;
public class PlayerResourcePackStatusEvent {
private final Player player;
private final Status result;
public PlayerResourcePackStatusEvent(Player player, Status result) {
this.player = Preconditions.checkNotNull(player, "player");
this.result = Preconditions.checkNotNull(result, "result");
}
public Player getPlayer() {
return player;
}
public Status getResult() {
return result;
}
@Override
public String toString() {
return "PlayerResourcePackStatusEvent{"
+ "player=" + player
+ ", result=" + result
+ '}';
}
public enum Status {
/**
* The resource pack was applied successfully.
*/
SUCCESSFUL,
/**
* The player declined to download the resource pack.
*/
DECLINED,
/**
* The player could not download the resource pack.
*/
FAILED_DOWNLOAD,
/**
* The player has accepted the resource pack and is now downloading it.
*/
ACCEPTED
}
}

Datei anzeigen

@ -151,4 +151,20 @@ public interface Player extends CommandSource, InboundConnection, ChannelMessage
* @param input the chat input to send * @param input the chat input to send
*/ */
void spoofChatInput(String input); void spoofChatInput(String input);
/**
* Sends the specified resource pack from {@code url} to the user. If at all possible, send the
* resource pack using {@link #sendResourcePack(String, byte[])}.
*
* @param url the URL for the resource pack
*/
void sendResourcePack(String url);
/**
* Sends the specified resource pack from {@code url} to the user.
*
* @param url the URL for the resource pack
* @param hash the SHA-1 hash value for the resource pack
*/
void sendResourcePack(String url, byte[] hash);
} }

Datei anzeigen

@ -18,6 +18,8 @@ import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse; import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
import com.velocitypowered.proxy.protocol.packet.PlayerListItem; import com.velocitypowered.proxy.protocol.packet.PlayerListItem;
import com.velocitypowered.proxy.protocol.packet.PluginMessage; import com.velocitypowered.proxy.protocol.packet.PluginMessage;
import com.velocitypowered.proxy.protocol.packet.ResourcePackRequest;
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponse;
import com.velocitypowered.proxy.protocol.packet.Respawn; import com.velocitypowered.proxy.protocol.packet.Respawn;
import com.velocitypowered.proxy.protocol.packet.ServerLogin; import com.velocitypowered.proxy.protocol.packet.ServerLogin;
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess; import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
@ -175,4 +177,12 @@ public interface MinecraftSessionHandler {
default boolean handle(PlayerListItem packet) { default boolean handle(PlayerListItem packet) {
return false; return false;
} }
default boolean handle(ResourcePackRequest packet) {
return false;
}
default boolean handle(ResourcePackResponse packet) {
return false;
}
} }

Datei anzeigen

@ -4,6 +4,7 @@ import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_13;
import com.velocitypowered.api.event.connection.PluginMessageEvent; import com.velocitypowered.api.event.connection.PluginMessageEvent;
import com.velocitypowered.api.event.player.PlayerChatEvent; import com.velocitypowered.api.event.player.PlayerChatEvent;
import com.velocitypowered.api.event.player.PlayerResourcePackStatusEvent;
import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.messages.ChannelIdentifier; import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
import com.velocitypowered.proxy.VelocityServer; import com.velocitypowered.proxy.VelocityServer;
@ -18,6 +19,7 @@ import com.velocitypowered.proxy.protocol.packet.ClientSettings;
import com.velocitypowered.proxy.protocol.packet.JoinGame; import com.velocitypowered.proxy.protocol.packet.JoinGame;
import com.velocitypowered.proxy.protocol.packet.KeepAlive; import com.velocitypowered.proxy.protocol.packet.KeepAlive;
import com.velocitypowered.proxy.protocol.packet.PluginMessage; import com.velocitypowered.proxy.protocol.packet.PluginMessage;
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponse;
import com.velocitypowered.proxy.protocol.packet.Respawn; import com.velocitypowered.proxy.protocol.packet.Respawn;
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequest; import com.velocitypowered.proxy.protocol.packet.TabCompleteRequest;
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponse; import com.velocitypowered.proxy.protocol.packet.TabCompleteResponse;
@ -235,6 +237,13 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
return true; return true;
} }
@Override
public boolean handle(ResourcePackResponse packet) {
server.getEventManager().fireAndForget(new PlayerResourcePackStatusEvent(player,
packet.getStatus()));
return false;
}
@Override @Override
public void handleGeneric(MinecraftPacket packet) { public void handleGeneric(MinecraftPacket packet) {
VelocityServerConnection serverConnection = player.getConnectedServer(); VelocityServerConnection serverConnection = player.getConnectedServer();

Datei anzeigen

@ -38,9 +38,11 @@ import com.velocitypowered.proxy.protocol.packet.ClientSettings;
import com.velocitypowered.proxy.protocol.packet.Disconnect; import com.velocitypowered.proxy.protocol.packet.Disconnect;
import com.velocitypowered.proxy.protocol.packet.KeepAlive; import com.velocitypowered.proxy.protocol.packet.KeepAlive;
import com.velocitypowered.proxy.protocol.packet.PluginMessage; import com.velocitypowered.proxy.protocol.packet.PluginMessage;
import com.velocitypowered.proxy.protocol.packet.ResourcePackRequest;
import com.velocitypowered.proxy.protocol.packet.TitlePacket; import com.velocitypowered.proxy.protocol.packet.TitlePacket;
import com.velocitypowered.proxy.server.VelocityRegisteredServer; import com.velocitypowered.proxy.server.VelocityRegisteredServer;
import com.velocitypowered.proxy.tablist.VelocityTabList; import com.velocitypowered.proxy.tablist.VelocityTabList;
import io.netty.buffer.ByteBufUtil;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -467,6 +469,28 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
ensureBackendConnection().write(Chat.createServerbound(input)); ensureBackendConnection().write(Chat.createServerbound(input));
} }
@Override
public void sendResourcePack(String url) {
Preconditions.checkNotNull(url, "url");
ResourcePackRequest request = new ResourcePackRequest();
request.setUrl(url);
request.setHash("");
connection.write(request);
}
@Override
public void sendResourcePack(String url, byte[] hash) {
Preconditions.checkNotNull(url, "url");
Preconditions.checkNotNull(hash, "hash");
Preconditions.checkArgument(hash.length == 20, "Hash length is not 20");
ResourcePackRequest request = new ResourcePackRequest();
request.setUrl(url);
request.setHash(ByteBufUtil.hexDump(hash));
connection.write(request);
}
/** /**
* Sends a {@link KeepAlive} packet to the player with a random ID. * Sends a {@link KeepAlive} packet to the player with a random ID.
* The response will be ignored by Velocity as it will not match the * The response will be ignored by Velocity as it will not match the

Datei anzeigen

@ -17,7 +17,6 @@ import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_9_4;
import static com.velocitypowered.api.network.ProtocolVersion.MINIMUM_VERSION; import static com.velocitypowered.api.network.ProtocolVersion.MINIMUM_VERSION;
import static com.velocitypowered.proxy.protocol.ProtocolUtils.Direction; import static com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
import com.google.common.collect.ImmutableList;
import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.protocol.packet.AvailableCommands; import com.velocitypowered.proxy.protocol.packet.AvailableCommands;
import com.velocitypowered.proxy.protocol.packet.BossBar; import com.velocitypowered.proxy.protocol.packet.BossBar;
@ -34,6 +33,8 @@ import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse; import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
import com.velocitypowered.proxy.protocol.packet.PlayerListItem; import com.velocitypowered.proxy.protocol.packet.PlayerListItem;
import com.velocitypowered.proxy.protocol.packet.PluginMessage; import com.velocitypowered.proxy.protocol.packet.PluginMessage;
import com.velocitypowered.proxy.protocol.packet.ResourcePackRequest;
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponse;
import com.velocitypowered.proxy.protocol.packet.Respawn; import com.velocitypowered.proxy.protocol.packet.Respawn;
import com.velocitypowered.proxy.protocol.packet.ServerLogin; import com.velocitypowered.proxy.protocol.packet.ServerLogin;
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess; import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
@ -110,6 +111,11 @@ public enum StateRegistry {
map(0x0C, MINECRAFT_1_12, false), map(0x0C, MINECRAFT_1_12, false),
map(0x0B, MINECRAFT_1_12_1, false), map(0x0B, MINECRAFT_1_12_1, false),
map(0x0E, MINECRAFT_1_13, false)); map(0x0E, MINECRAFT_1_13, false));
serverbound.register(ResourcePackResponse.class, ResourcePackResponse::new,
map(0x19, MINECRAFT_1_8, false),
map(0x16, MINECRAFT_1_9, false),
map(0x18, MINECRAFT_1_12, false),
map(0x1D, MINECRAFT_1_13, false));
clientbound.register(BossBar.class, BossBar::new, clientbound.register(BossBar.class, BossBar::new,
map(0x0C, MINECRAFT_1_9, false), map(0x0C, MINECRAFT_1_9, false),
@ -153,6 +159,12 @@ public enum StateRegistry {
map(0x34, MINECRAFT_1_12, true), map(0x34, MINECRAFT_1_12, true),
map(0x35, MINECRAFT_1_12_2, true), map(0x35, MINECRAFT_1_12_2, true),
map(0x38, MINECRAFT_1_13, true)); map(0x38, MINECRAFT_1_13, true));
clientbound.register(ResourcePackRequest.class, ResourcePackRequest::new,
map(0x48, MINECRAFT_1_8, true),
map(0x32, MINECRAFT_1_9, true),
map(0x33, MINECRAFT_1_12, true),
map(0x34, MINECRAFT_1_12_1, true),
map(0x37, MINECRAFT_1_13, true));
clientbound.register(HeaderAndFooter.class, HeaderAndFooter::new, clientbound.register(HeaderAndFooter.class, HeaderAndFooter::new,
map(0x47, MINECRAFT_1_8, true), map(0x47, MINECRAFT_1_8, true),
map(0x48, MINECRAFT_1_9, true), map(0x48, MINECRAFT_1_9, true),

Datei anzeigen

@ -0,0 +1,64 @@
package com.velocitypowered.proxy.protocol.packet;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
public class ResourcePackRequest implements MinecraftPacket {
@MonotonicNonNull
private String url;
@MonotonicNonNull
private String hash;
@Nullable
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Nullable
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
@Override
public void decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
this.url = ProtocolUtils.readString(buf);
this.hash = ProtocolUtils.readString(buf);
}
@Override
public void encode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
if (url == null || hash == null) {
throw new IllegalStateException("Packet not fully filled in yet!");
}
ProtocolUtils.writeString(buf, url);
ProtocolUtils.writeString(buf, hash);
}
@Override
public boolean handle(MinecraftSessionHandler handler) {
return handler.handle(this);
}
@Override
public String toString() {
return "ResourcePackRequest{"
+ "url='" + url + '\''
+ ", hash='" + hash + '\''
+ '}';
}
}

Datei anzeigen

@ -0,0 +1,45 @@
package com.velocitypowered.proxy.protocol.packet;
import com.velocitypowered.api.event.player.PlayerResourcePackStatusEvent.Status;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public class ResourcePackResponse implements MinecraftPacket {
@MonotonicNonNull
private Status status;
public Status getStatus() {
if (status == null) {
throw new IllegalStateException("Packet not yet deserialized");
}
return status;
}
@Override
public void decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
this.status = Status.values()[ProtocolUtils.readVarInt(buf)];
}
@Override
public void encode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
ProtocolUtils.writeVarInt(buf, status.ordinal());
}
@Override
public boolean handle(MinecraftSessionHandler handler) {
return handler.handle(this);
}
@Override
public String toString() {
return "ResourcePackResponse{"
+ "status=" + status
+ '}';
}
}