geforkt von Mirrors/Velocity
Resource pack API
Dieser Commit ist enthalten in:
Ursprung
280563ffa0
Commit
0ca0c2a297
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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),
|
||||||
|
@ -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 + '\''
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren