Skip to content

Commit 443e731

Browse files
committed
Add UpdateTeam packet support for legacy servers
1 parent ea9bcc8 commit 443e731

File tree

5 files changed

+169
-63
lines changed

5 files changed

+169
-63
lines changed

src/main/java/me/rothes/protocolstringreplacer/packetlisteners/PacketListenerManager.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import me.rothes.protocolstringreplacer.packetlisteners.server.combat.PlayerCombatKill;
2424
import me.rothes.protocolstringreplacer.packetlisteners.server.itemstack.MerchantTradeList;
2525
import me.rothes.protocolstringreplacer.packetlisteners.server.scoreboard.UpdateTeam;
26+
import me.rothes.protocolstringreplacer.packetlisteners.server.scoreboard.UpdateTeamPost13;
27+
import me.rothes.protocolstringreplacer.packetlisteners.server.scoreboard.UpdateTeamPost17;
2628
import me.rothes.protocolstringreplacer.packetlisteners.server.sign.MapChunkUpper18;
2729
import me.rothes.protocolstringreplacer.packetlisteners.server.sign.TileEntityDataUpper18;
2830
import me.rothes.protocolstringreplacer.packetlisteners.server.title.SetSubtitleText;
@@ -122,7 +124,13 @@ public void addListeners() {
122124
protocolManager.addPacketListener(new OpenWindow().packetAdapter);
123125
protocolManager.addPacketListener(new EntityMetadata().packetAdapter);
124126
protocolManager.addPacketListener(new UpdateScore().packetAdapter);
125-
protocolManager.addPacketListener(new UpdateTeam().packetAdapter);
127+
if (ProtocolStringReplacer.getInstance().getServerMajorVersion() >= 17) {
128+
protocolManager.addPacketListener(new UpdateTeamPost17().packetAdapter);
129+
} else if (ProtocolStringReplacer.getInstance().getServerMajorVersion() >= 13) {
130+
protocolManager.addPacketListener(new UpdateTeamPost13().packetAdapter);
131+
} else {
132+
protocolManager.addPacketListener(new UpdateTeam().packetAdapter);
133+
}
126134
protocolManager.addPacketListener(new ScoreBoardObjective().packetAdapter);
127135
protocolManager.addPacketListener(new KickDisconnect().packetAdapter);
128136

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package me.rothes.protocolstringreplacer.packetlisteners.server.scoreboard;
2+
3+
import com.comphenix.protocol.PacketType;
4+
import me.rothes.protocolstringreplacer.api.replacer.ReplacerConfig;
5+
import me.rothes.protocolstringreplacer.api.user.PsrUser;
6+
import me.rothes.protocolstringreplacer.packetlisteners.server.AbstractServerPacketListener;
7+
import me.rothes.protocolstringreplacer.replacer.ListenType;
8+
9+
import java.util.function.BiPredicate;
10+
11+
public abstract class BaseUpdateTeamListener extends AbstractServerPacketListener {
12+
13+
protected final BiPredicate<ReplacerConfig, PsrUser> teamDNameFilter = (replacerConfig, user) ->
14+
containType(replacerConfig) && checkFilter(user, replacerConfig) && replacerConfig.handleScoreboardTeamDisplayName();
15+
protected final BiPredicate<ReplacerConfig, PsrUser> teamPrefixFilter = (replacerConfig, user) ->
16+
containType(replacerConfig) && checkFilter(user, replacerConfig) && replacerConfig.handleScoreboardTeamPrefix();
17+
protected final BiPredicate<ReplacerConfig, PsrUser> teamSuffixFilter = (replacerConfig, user) ->
18+
containType(replacerConfig) && checkFilter(user, replacerConfig) && replacerConfig.handleScoreboardTeamSuffix();
19+
20+
protected BaseUpdateTeamListener() {
21+
super(PacketType.Play.Server.SCOREBOARD_TEAM, ListenType.SCOREBOARD);
22+
}
23+
24+
}
Lines changed: 14 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,39 @@
11
package me.rothes.protocolstringreplacer.packetlisteners.server.scoreboard;
22

3-
import com.comphenix.protocol.PacketType;
43
import com.comphenix.protocol.events.PacketContainer;
54
import com.comphenix.protocol.events.PacketEvent;
6-
import com.comphenix.protocol.utility.MinecraftReflection;
7-
import com.comphenix.protocol.wrappers.WrappedChatComponent;
8-
import me.rothes.protocolstringreplacer.api.replacer.ReplacerConfig;
5+
import com.comphenix.protocol.reflect.StructureModifier;
96
import me.rothes.protocolstringreplacer.api.user.PsrUser;
10-
import me.rothes.protocolstringreplacer.replacer.ListenType;
117
import org.jetbrains.annotations.NotNull;
128

13-
import java.lang.reflect.Field;
14-
import java.util.Arrays;
15-
import java.util.List;
16-
import java.util.Optional;
17-
import java.util.function.BiPredicate;
18-
import java.util.stream.Collectors;
19-
20-
public class UpdateTeam extends AbstractScoreBoardListener {
21-
22-
protected final BiPredicate<ReplacerConfig, PsrUser> teamDNameFilter = (replacerConfig, user) ->
23-
containType(replacerConfig) && checkFilter(user, replacerConfig) && replacerConfig.handleScoreboardTeamDisplayName();
24-
protected final BiPredicate<ReplacerConfig, PsrUser> teamPrefixFilter = (replacerConfig, user) ->
25-
containType(replacerConfig) && checkFilter(user, replacerConfig) && replacerConfig.handleScoreboardTeamPrefix();
26-
protected final BiPredicate<ReplacerConfig, PsrUser> teamSuffixFilter = (replacerConfig, user) ->
27-
containType(replacerConfig) && checkFilter(user, replacerConfig) && replacerConfig.handleScoreboardTeamSuffix();
28-
29-
private final Field displayName;
30-
private final Field prefix;
31-
private final Field suffix;
32-
33-
public UpdateTeam() {
34-
super(PacketType.Play.Server.SCOREBOARD_TEAM, ListenType.SCOREBOARD);
35-
36-
Class<?> info = PacketType.Play.Server.SCOREBOARD_TEAM.getPacketClass().getDeclaredClasses()[0];
37-
List<Field> collect = Arrays.stream(info.getDeclaredFields())
38-
.filter(it -> it.getType() == MinecraftReflection.getIChatBaseComponentClass())
39-
.collect(Collectors.toList());
40-
displayName = collect.get(0);
41-
displayName.setAccessible(true);
42-
prefix = collect.get(1);
43-
prefix.setAccessible(true);
44-
suffix = collect.get(2);
45-
suffix.setAccessible(true);
46-
}
9+
public final class UpdateTeam extends BaseUpdateTeamListener {
4710

11+
@Override
4812
protected void process(@NotNull PacketEvent packetEvent) {
4913
PsrUser user = getEventUser(packetEvent);
5014
if (user == null) {
5115
return;
5216
}
5317
PacketContainer packet = packetEvent.getPacket();
54-
55-
Optional<?> read = (Optional<?>) packet.getModifier().withType(Optional.class).read(0);
56-
if (!read.isPresent()) {
18+
StructureModifier<String> strings = packet.getStrings();
19+
String replacedText = getReplacedText(packetEvent, user, listenType, strings.read(1), teamDNameFilter);
20+
if (replacedText == null) {
5721
return;
5822
}
23+
strings.write(1, replacedText);
5924

60-
Object o = read.get();
61-
if (processField(o, prefix, packetEvent, user, teamPrefixFilter)) {
25+
replacedText = getReplacedText(packetEvent, user, listenType, strings.read(2), teamPrefixFilter);
26+
if (replacedText == null) {
6227
return;
6328
}
64-
if (processField(o, displayName, packetEvent, user, teamDNameFilter)) {
29+
strings.write(2, replacedText);
30+
31+
replacedText = getReplacedText(packetEvent, user, listenType, strings.read(3), teamSuffixFilter);
32+
if (replacedText == null) {
6533
return;
6634
}
67-
processField(o, suffix, packetEvent, user, teamSuffixFilter);
68-
}
35+
strings.write(3, replacedText);
6936

70-
private boolean processField(Object infoObj, Field field, PacketEvent event, PsrUser user,
71-
BiPredicate<ReplacerConfig, PsrUser> filter) {
72-
try {
73-
WrappedChatComponent wrappedChatComponent = WrappedChatComponent.fromHandle(field.get(infoObj));
74-
String json = wrappedChatComponent.getJson();
75-
String replacedJson = getReplacedJson(event, user, listenType, json, filter);
76-
if (replacedJson == null) {
77-
return true;
78-
}
79-
wrappedChatComponent.setJson(replacedJson);
80-
field.set(infoObj, wrappedChatComponent.getHandle());
81-
} catch (IllegalAccessException e) {
82-
throw new RuntimeException(e);
83-
}
84-
return false;
8537
}
8638

8739
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package me.rothes.protocolstringreplacer.packetlisteners.server.scoreboard;
2+
3+
import com.comphenix.protocol.events.PacketContainer;
4+
import com.comphenix.protocol.events.PacketEvent;
5+
import com.comphenix.protocol.reflect.StructureModifier;
6+
import com.comphenix.protocol.wrappers.WrappedChatComponent;
7+
import me.rothes.protocolstringreplacer.api.user.PsrUser;
8+
import org.jetbrains.annotations.NotNull;
9+
10+
public final class UpdateTeamPost13 extends BaseUpdateTeamListener {
11+
12+
@Override
13+
protected void process(@NotNull PacketEvent packetEvent) {
14+
PsrUser user = getEventUser(packetEvent);
15+
if (user == null) {
16+
return;
17+
}
18+
PacketContainer packet = packetEvent.getPacket();
19+
StructureModifier<WrappedChatComponent> chatComponents = packet.getChatComponents();
20+
WrappedChatComponent wrappedChatComponent = chatComponents.read(0);
21+
String json = wrappedChatComponent.getJson();
22+
WrappedChatComponent replaced = getReplacedJsonWrappedComponent(packetEvent, user, listenType, json, teamDNameFilter);
23+
if (replaced == null) {
24+
return;
25+
}
26+
chatComponents.write(0, replaced);
27+
28+
wrappedChatComponent = chatComponents.read(1);
29+
json = wrappedChatComponent.getJson();
30+
replaced = getReplacedJsonWrappedComponent(packetEvent, user, listenType, json, teamPrefixFilter);
31+
if (replaced == null) {
32+
return;
33+
}
34+
chatComponents.write(1, replaced);
35+
36+
wrappedChatComponent = chatComponents.read(2);
37+
json = wrappedChatComponent.getJson();
38+
replaced = getReplacedJsonWrappedComponent(packetEvent, user, listenType, json, teamSuffixFilter);
39+
if (replaced == null) {
40+
return;
41+
}
42+
chatComponents.write(2, replaced);
43+
}
44+
45+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package me.rothes.protocolstringreplacer.packetlisteners.server.scoreboard;
2+
3+
import com.comphenix.protocol.PacketType;
4+
import com.comphenix.protocol.events.PacketContainer;
5+
import com.comphenix.protocol.events.PacketEvent;
6+
import com.comphenix.protocol.utility.MinecraftReflection;
7+
import com.comphenix.protocol.wrappers.WrappedChatComponent;
8+
import me.rothes.protocolstringreplacer.api.replacer.ReplacerConfig;
9+
import me.rothes.protocolstringreplacer.api.user.PsrUser;
10+
import org.jetbrains.annotations.NotNull;
11+
12+
import java.lang.reflect.Field;
13+
import java.util.Arrays;
14+
import java.util.List;
15+
import java.util.Optional;
16+
import java.util.function.BiPredicate;
17+
import java.util.stream.Collectors;
18+
19+
public final class UpdateTeamPost17 extends BaseUpdateTeamListener {
20+
21+
private final Field displayName;
22+
private final Field prefix;
23+
private final Field suffix;
24+
25+
public UpdateTeamPost17() {
26+
Class<?> info = PacketType.Play.Server.SCOREBOARD_TEAM.getPacketClass().getDeclaredClasses()[0];
27+
List<Field> collect = Arrays.stream(info.getDeclaredFields())
28+
.filter(it -> it.getType() == MinecraftReflection.getIChatBaseComponentClass())
29+
.collect(Collectors.toList());
30+
displayName = collect.get(0);
31+
displayName.setAccessible(true);
32+
prefix = collect.get(1);
33+
prefix.setAccessible(true);
34+
suffix = collect.get(2);
35+
suffix.setAccessible(true);
36+
}
37+
38+
protected void process(@NotNull PacketEvent packetEvent) {
39+
PsrUser user = getEventUser(packetEvent);
40+
if (user == null) {
41+
return;
42+
}
43+
PacketContainer packet = packetEvent.getPacket();
44+
45+
Optional<?> read = (Optional<?>) packet.getModifier().withType(Optional.class).read(0);
46+
if (!read.isPresent()) {
47+
return;
48+
}
49+
50+
Object o = read.get();
51+
if (processField(o, prefix, packetEvent, user, teamPrefixFilter)) {
52+
return;
53+
}
54+
if (processField(o, displayName, packetEvent, user, teamDNameFilter)) {
55+
return;
56+
}
57+
processField(o, suffix, packetEvent, user, teamSuffixFilter);
58+
}
59+
60+
private boolean processField(Object infoObj, Field field, PacketEvent event, PsrUser user,
61+
BiPredicate<ReplacerConfig, PsrUser> filter) {
62+
try {
63+
WrappedChatComponent wrappedChatComponent = WrappedChatComponent.fromHandle(field.get(infoObj));
64+
String json = wrappedChatComponent.getJson();
65+
String replacedJson = getReplacedJson(event, user, listenType, json, filter);
66+
if (replacedJson == null) {
67+
return true;
68+
}
69+
wrappedChatComponent.setJson(replacedJson);
70+
field.set(infoObj, wrappedChatComponent.getHandle());
71+
} catch (IllegalAccessException e) {
72+
throw new RuntimeException(e);
73+
}
74+
return false;
75+
}
76+
77+
}

0 commit comments

Comments
 (0)