aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0381-Implement-Player-Client-Options-API.patch
blob: 2fe03d3c1b4703c1e1c39a135d6f71d270daefcf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
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

== AT ==
public net.minecraft.world.entity.player.Player DATA_PLAYER_MODE_CUSTOMISATION

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 71fac1a579b375759462b843d9ef7c8a2a463db5..2d54f2abae82521fbd34aa046f26ec8e72df8362 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1902,9 +1902,24 @@ public class ServerPlayer extends Player {
         }
     }
 
+    // Paper start - Client option API
+    private java.util.Map<com.destroystokyo.paper.ClientOption<?>, ?> getClientOptionMap(String locale, int viewDistance, com.destroystokyo.paper.ClientOption.ChatVisibility chatVisibility, boolean chatColors, com.destroystokyo.paper.PaperSkinParts skinParts, org.bukkit.inventory.MainHand mainHand, boolean allowsServerListing, boolean textFilteringEnabled) {
+        java.util.Map<com.destroystokyo.paper.ClientOption<?>, Object> map = new java.util.HashMap<>();
+        map.put(com.destroystokyo.paper.ClientOption.LOCALE, locale);
+        map.put(com.destroystokyo.paper.ClientOption.VIEW_DISTANCE, viewDistance);
+        map.put(com.destroystokyo.paper.ClientOption.CHAT_VISIBILITY, chatVisibility);
+        map.put(com.destroystokyo.paper.ClientOption.CHAT_COLORS_ENABLED, chatColors);
+        map.put(com.destroystokyo.paper.ClientOption.SKIN_PARTS, skinParts);
+        map.put(com.destroystokyo.paper.ClientOption.MAIN_HAND, mainHand);
+        map.put(com.destroystokyo.paper.ClientOption.ALLOW_SERVER_LISTINGS, allowsServerListing);
+        map.put(com.destroystokyo.paper.ClientOption.TEXT_FILTERING_ENABLED, textFilteringEnabled);
+        return map;
+    }
+    // Paper end
     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(), getClientOptionMap(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, packet.allowsListing(), packet.textFilteringEnabled())).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 f21bbbc7ff8aee29e0eb35e779bf02dbba703950..16cc7cfd39158cfb4045375d8be664b91d4a57d4 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -622,6 +622,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
             connection.disconnect(message == null ? net.kyori.adventure.text.Component.empty() : message);
         }
     }
+
+    @Override
+    public <T> T getClientOption(com.destroystokyo.paper.ClientOption<T> type) {
+        if (com.destroystokyo.paper.ClientOption.SKIN_PARTS == 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 == type) {
+            return type.getType().cast(getHandle().canChatInColor());
+        } else if (com.destroystokyo.paper.ClientOption.CHAT_VISIBILITY == 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 == type) {
+            return type.getType().cast(getLocale());
+        } else if (com.destroystokyo.paper.ClientOption.MAIN_HAND == type) {
+            return type.getType().cast(getMainHand());
+        } else if (com.destroystokyo.paper.ClientOption.VIEW_DISTANCE == type) {
+            return type.getType().cast(getClientViewDistance());
+        } else if (com.destroystokyo.paper.ClientOption.ALLOW_SERVER_LISTINGS == type) {
+            return type.getType().cast(getHandle().allowsListing());
+        } else if (com.destroystokyo.paper.ClientOption.TEXT_FILTERING_ENABLED == type) {
+            return type.getType().cast(getHandle().isTextFilteringEnabled());
+        }
+        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..fab3063fffa959ac7f0eb5937f2fae94d11b6591
--- /dev/null
+++ b/src/test/java/io/papermc/paper/world/TranslationKeyTest.java
@@ -0,0 +1,18 @@
+package io.papermc.paper.world;
+
+import com.destroystokyo.paper.ClientOption;
+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());
+        }
+    }
+}