PaperMC/patches/server/0395-Implement-Player-Client-Options-API.patch
Jake Potrebic 1c5f8b0fce
Updated Upstream (Bukkit/CraftBukkit) (#7604)
Upstream has released updates that appear to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
33a2b476 PR-734: Make PlayerInventory#getItem Nullable

CraftBukkit Changes:
953d3ddc SPIGOT-3034: PlayerKickEvent.setLeaveMessage(String) doesn't actually do anything
2c47af0c SPIGOT-6963: CraftMetaBlockState#getBlockState applied TileEntity ids without the minecraft namespace prefix.
2022-03-16 16:57:51 +01:00

152 lines
6.8 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MiniDigger <admin@benndorf.dev>
Date: Mon, 20 Jan 2020 21:38:15 +0100
Subject: [PATCH] Implement Player Client Options API
diff --git a/src/main/java/com/destroystokyo/paper/PaperSkinParts.java b/src/main/java/com/destroystokyo/paper/PaperSkinParts.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6f4400df3d8ec7e06a996de54f8cabba57885e1
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/PaperSkinParts.java
@@ -0,0 +1,74 @@
+package com.destroystokyo.paper;
+
+import com.google.common.base.Objects;
+
+import java.util.StringJoiner;
+
+public class PaperSkinParts implements SkinParts {
+
+ private final int raw;
+
+ public PaperSkinParts(int raw) {
+ this.raw = raw;
+ }
+
+ public boolean hasCapeEnabled() {
+ return (raw & 1) == 1;
+ }
+
+ public boolean hasJacketEnabled() {
+ return (raw >> 1 & 1) == 1;
+ }
+
+ public boolean hasLeftSleeveEnabled() {
+ return (raw >> 2 & 1) == 1;
+ }
+
+ public boolean hasRightSleeveEnabled() {
+ return (raw >> 3 & 1) == 1;
+ }
+
+ public boolean hasLeftPantsEnabled() {
+ return (raw >> 4 & 1) == 1;
+ }
+
+ public boolean hasRightPantsEnabled() {
+ return (raw >> 5 & 1) == 1;
+ }
+
+ public boolean hasHatsEnabled() {
+ return (raw >> 6 & 1) == 1;
+ }
+
+ @Override
+ public int getRaw() {
+ return raw;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ PaperSkinParts that = (PaperSkinParts) o;
+ return raw == that.raw;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(raw);
+ }
+
+ @Override
+ public String toString() {
+ return new StringJoiner(", ", PaperSkinParts.class.getSimpleName() + "[", "]")
+ .add("raw=" + raw)
+ .add("cape=" + hasCapeEnabled())
+ .add("jacket=" + hasJacketEnabled())
+ .add("leftSleeve=" + hasLeftSleeveEnabled())
+ .add("rightSleeve=" + hasRightSleeveEnabled())
+ .add("leftPants=" + hasLeftPantsEnabled())
+ .add("rightPants=" + hasRightPantsEnabled())
+ .add("hats=" + hasHatsEnabled())
+ .toString();
+ }
+}
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 97d7237060f2a9a03180b5d15bcec54246b1645b..36753bedf0be050f0bdf2baf26bdeba833967323 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1829,6 +1829,7 @@ public class ServerPlayer extends Player {
public String locale = null; // CraftBukkit - add, lowercase // Paper - default to null
public java.util.Locale adventure$locale = java.util.Locale.US; // Paper
public void updateOptions(ServerboundClientInformationPacket packet) {
+ new com.destroystokyo.paper.event.player.PlayerClientOptionsChangeEvent(getBukkitEntity(), packet.language, packet.viewDistance, com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(packet.chatVisibility().name()), packet.chatColors(), new com.destroystokyo.paper.PaperSkinParts(packet.modelCustomisation()), packet.mainHand() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT).callEvent(); // Paper - settings event
// CraftBukkit start
if (getMainArm() != packet.mainHand()) {
PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(this.getBukkitEntity(), getMainArm() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 3412f03fae9857243ae51905218818c4ad64beec..f4643f7ca1468bd7bd60637bf6096a828d1c0a40 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -561,6 +561,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
public void setSendViewDistance(int viewDistance) {
throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement (There are per world view distances though!)"); // TODO
}
+
+ @Override
+ public <T> T getClientOption(com.destroystokyo.paper.ClientOption<T> type) {
+ if(com.destroystokyo.paper.ClientOption.SKIN_PARTS.equals(type)) {
+ return type.getType().cast(new com.destroystokyo.paper.PaperSkinParts(getHandle().getEntityData().get(net.minecraft.world.entity.player.Player.DATA_PLAYER_MODE_CUSTOMISATION)));
+ } else if(com.destroystokyo.paper.ClientOption.CHAT_COLORS_ENABLED.equals(type)) {
+ return type.getType().cast(getHandle().canChatInColor());
+ } else if(com.destroystokyo.paper.ClientOption.CHAT_VISIBILITY.equals(type)) {
+ return type.getType().cast(getHandle().getChatVisibility() == null ? com.destroystokyo.paper.ClientOption.ChatVisibility.UNKNOWN : com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(getHandle().getChatVisibility().name()));
+ } else if(com.destroystokyo.paper.ClientOption.LOCALE.equals(type)) {
+ return type.getType().cast(getLocale());
+ } else if(com.destroystokyo.paper.ClientOption.MAIN_HAND.equals(type)) {
+ return type.getType().cast(getMainHand());
+ } else if(com.destroystokyo.paper.ClientOption.VIEW_DISTANCE.equals(type)) {
+ return type.getType().cast(getClientViewDistance());
+ }
+ throw new RuntimeException("Unknown settings type");
+ }
// Paper end
@Override
diff --git a/src/test/java/io/papermc/paper/world/TranslationKeyTest.java b/src/test/java/io/papermc/paper/world/TranslationKeyTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6cd015dc5a2e012ac827c2b2d9aa5542b0591afb
--- /dev/null
+++ b/src/test/java/io/papermc/paper/world/TranslationKeyTest.java
@@ -0,0 +1,19 @@
+package io.papermc.paper.world;
+
+import com.destroystokyo.paper.ClientOption;
+import net.minecraft.network.chat.TranslatableComponent;
+import net.minecraft.world.entity.player.ChatVisiblity;
+import org.bukkit.Difficulty;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TranslationKeyTest {
+
+ @Test
+ public void testChatVisibilityKeys() {
+ for (ClientOption.ChatVisibility chatVisibility : ClientOption.ChatVisibility.values()) {
+ if (chatVisibility == ClientOption.ChatVisibility.UNKNOWN) continue;
+ Assert.assertEquals(chatVisibility + "'s translation key doesn't match", ChatVisiblity.valueOf(chatVisibility.name()).getKey(), chatVisibility.translationKey());
+ }
+ }
+}