-
-
Notifications
You must be signed in to change notification settings - Fork 104
/
PlayerReceivesTablistUpdateScriptEvent.java
197 lines (172 loc) · 7.54 KB
/
PlayerReceivesTablistUpdateScriptEvent.java
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
package com.denizenscript.denizen.events.player;
import com.denizenscript.denizen.events.BukkitScriptEvent;
import com.denizenscript.denizencore.utilities.debugging.Debug;
import com.denizenscript.denizen.utilities.implementation.BukkitScriptEntryData;
import com.denizenscript.denizen.utilities.packets.NetworkInterceptHelper;
import com.denizenscript.denizencore.objects.ObjectTag;
import com.denizenscript.denizencore.objects.core.ElementTag;
import com.denizenscript.denizencore.scripts.ScriptEntryData;
import com.denizenscript.denizencore.utilities.CoreConfiguration;
import com.denizenscript.denizencore.utilities.CoreUtilities;
import org.bukkit.entity.Player;
import java.util.UUID;
public class PlayerReceivesTablistUpdateScriptEvent extends BukkitScriptEvent {
// <--[event]
// @Events
// player receives tablist update
//
// @Switch mode:add/update/remove to only trigger if the tablist update is the specified mode.
//
// @Group Player
//
// @Triggers when a player receives a tablist update.
//
// @Location true
// @Cancellable true
//
// @Context
// <context.mode> returns the update mode: 'add', 'remove', 'update_gamemode', 'update_latency', 'update_listed', or 'update_display'. As of 1.19.3, you can also receive update combos like "update_gamemode|update_latency".
// <context.uuid> returns the packet's associated UUID.
// <context.name> returns the packet's associated name (if any).
// <context.display> returns the packet's associated display name (if any).
// <context.latency> returns the packet's associated latency (if any).
// <context.gamemode> returns the packet's associated gamemode (if any).
// <context.skin_blob> returns the packet's associated skin blob (if any).
//
// @Determine
// "LATENCY:" + ElementTag(Number) to change the latency.
// "NAME:" + ElementTag to change the name.
// "DISPLAY:" + ElementTag to change the display name. 'name', 'display' and 'cancelled' determinations require 'Allow restricted actions' in Denizen/config.yml
// "GAMEMODE:" + ElementTag to change the gamemode.
// "SKIN_BLOB:" + ElementTag to change the skin blob.
//
// @Player Always.
//
// -->
public PlayerReceivesTablistUpdateScriptEvent() {
instance = this;
registerCouldMatcher("player receives tablist update");
registerSwitches("mode");
}
public static PlayerReceivesTablistUpdateScriptEvent instance;
public static class TabPacketData {
public TabPacketData(String mode, UUID id, boolean isListed, String name, String display, String gamemode, String texture, String signature, int latency) {
this.mode = mode;
this.id = id;
this.name = name;
this.display = display;
this.gamemode = gamemode;
this.texture = texture;
this.signature = signature;
this.latency = latency;
this.isListed = isListed;
}
public UUID id;
public String mode, name, display, gamemode, texture, signature;
public int latency;
public boolean isListed;
public boolean cancelled = false;
public boolean modified = false;
}
public Player player;
public TabPacketData data;
public static boolean enabled = false;
@Override
public void init() {
NetworkInterceptHelper.enable();
enabled = true;
}
@Override
public void destroy() {
enabled = false;
}
@Override
public void cancellationChanged() {
if (cancelled && !CoreConfiguration.allowRestrictedActions) {
Debug.echoError("Cannot use 'receives tablist update' event to cancel a tablist packet: 'Allow restricted actions' is disabled in Denizen config.yml.");
return;
}
data.cancelled = cancelled;
data.modified = true;
}
@Override
public boolean matches(ScriptPath path) {
if (!runInCheck(path, player.getLocation())) {
return false;
}
if (!runGenericSwitchCheck(path, "mode", data.mode)) {
return false;
}
return super.matches(path);
}
@Override
public boolean applyDetermination(ScriptPath path, ObjectTag determinationObj) {
String determination = determinationObj.toString();
String determinationLow = CoreUtilities.toLowerCase(determination);
if (determinationLow.contains(":")) {
if (determinationLow.startsWith("latency:")) {
data.modified = true;
data.latency = Integer.parseInt(determination.substring("latency:".length()));
return true;
}
else if (determinationLow.startsWith("name:")) {
if (!CoreConfiguration.allowRestrictedActions) {
Debug.echoError("Cannot use 'receives tablist update' event to edit a display name: 'Allow restricted actions' is disabled in Denizen config.yml.");
return true;
}
data.modified = true;
data.name = determination.substring("name:".length());
return true;
}
else if (determinationLow.startsWith("display:")) {
if (!CoreConfiguration.allowRestrictedActions) {
Debug.echoError("Cannot use 'receives tablist update' event to edit a display name: 'Allow restricted actions' is disabled in Denizen config.yml.");
return true;
}
data.modified = true;
data.name = determination.substring("display:".length());
return true;
}
else if (determinationLow.startsWith("gamemode:")) {
data.modified = true;
data.gamemode = determination.substring("gamemode:".length());
return true;
}
else if (determinationLow.startsWith("skin_blob:")) {
String blob = determination.substring("skin_blob:".length());
int semicolon = blob.indexOf(';');
if (semicolon == -1) {
Debug.echoError("Invalid skin blob!");
return true;
}
data.modified = true;
data.texture = blob.substring(0, semicolon);
data.signature = blob.substring(semicolon + 1);
return true;
}
}
return super.applyDetermination(path, determinationObj);
}
@Override
public ScriptEntryData getScriptEntryData() {
return new BukkitScriptEntryData(player);
}
@Override
public ObjectTag getContext(String name) {
switch (name) {
case "name": return new ElementTag(data.name);
case "uuid": return new ElementTag(data.id.toString());
case "mode": return new ElementTag(data.mode);
case "display": return new ElementTag(data.display);
case "gamemode": return new ElementTag(data.gamemode);
case "skin_blob": return new ElementTag(data.texture + ";" + data.signature);
case "latency": return new ElementTag(data.latency);
}
return super.getContext(name);
}
public static void fire(Player player, TabPacketData data) {
instance.player = player;
instance.data = data;
instance.fire();
}
}