77
88import java .util .*;
99import java .util .stream .Collectors ;
10+
1011import lombok .RequiredArgsConstructor ;
1112import net .azisaba .ryuzupluginchat .RyuZUPluginChat ;
1213import net .azisaba .ryuzupluginchat .event .AsyncChannelMessageEvent ;
1718import net .azisaba .ryuzupluginchat .message .data .GlobalMessageData ;
1819import net .azisaba .ryuzupluginchat .message .data .PrivateMessageData ;
1920import net .azisaba .ryuzupluginchat .message .data .SystemMessageData ;
20- import net .azisaba .ryuzupluginchat .util .Chat ;
21- import net .azisaba .ryuzupluginchat .util .TaskSchedulingUtils ;
21+ import net .azisaba .ryuzupluginchat .util .*;
22+ import net .kyori .adventure .text .serializer .gson .GsonComponentSerializer ;
23+ import net .kyori .adventure .text .serializer .legacy .LegacyComponentSerializer ;
24+ import net .kyori .adventure .text .serializer .plain .PlainTextComponentSerializer ;
25+ import net .md_5 .bungee .chat .ComponentSerializer ;
2226import org .bukkit .Bukkit ;
23- import org .bukkit .ChatColor ;
2427import org .bukkit .entity .Player ;
2528
2629@ RequiredArgsConstructor
2730public class MessageProcessor {
28-
31+ // net.kyori.adventure.text.Component
32+ private static final char [] COMPONENT_CLASS_NAME =
33+ new char [] {'n' , 'e' , 't' , '.' , 'k' , 'y' , 'o' , 'r' , 'i' , '.' , 'a' , 'd' , 'v' , 'e' , 'n' , 't' , 'u' , 'r' , 'e' ,
34+ '.' , 't' , 'e' , 'x' , 't' , '.' , 'C' , 'o' , 'm' , 'p' , 'o' , 'n' , 'e' , 'n' , 't' };
35+ // net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
36+ private static final char [] LEGACY_COMPONENT_SERIALIZER_CLASS_NAME =
37+ new char [] {'n' , 'e' , 't' , '.' , 'k' , 'y' , 'o' , 'r' , 'i' , '.' , 'a' , 'd' , 'v' , 'e' , 'n' , 't' , 'u' , 'r' , 'e' ,
38+ '.' , 't' , 'e' , 'x' , 't' , '.' , 's' , 'e' , 'r' , 'i' , 'a' , 'l' , 'i' , 'z' , 'e' , 'r' , '.' ,
39+ 'l' , 'e' , 'g' , 'a' , 'c' , 'y' , '.' , 'L' , 'e' , 'g' , 'a' , 'c' , 'y' , 'C' , 'o' , 'm' , 'p' , 'o' , 'n' , 'e' ,
40+ 'n' , 't' , 'S' , 'e' , 'r' , 'i' , 'a' , 'l' , 'i' , 'z' , 'e' , 'r' };
41+ private static final LegacyComponentSerializer LEGACY_DESERIALIZER =
42+ LegacyComponentSerializer .builder ()
43+ .character ('&' )
44+ .hexColors ()
45+ .extractUrls ()
46+ .build ();
47+ private static final LegacyComponentSerializer LEGACY_SERIALIZER_HEX =
48+ LegacyComponentSerializer .builder ()
49+ .character ('§' )
50+ .hexColors ()
51+ .build ();
52+ private static final LegacyComponentSerializer LEGACY_SERIALIZER_UNUSUAL_X_REPEATED_HEX =
53+ LegacyComponentSerializer .builder ()
54+ .character ('§' )
55+ .hexColors ()
56+ .useUnusualXRepeatedCharacterHexFormat ()
57+ .build ();
2958 private final RyuZUPluginChat plugin ;
3059
60+ private void sendRGBMessage (Player player , String message ) {
61+ RGBStatus rgbStatus = isRGBSupported (player );
62+ if (rgbStatus == RGBStatus .SERVER_AND_CLIENT || rgbStatus == RGBStatus .SERVER_ONLY ) {
63+ try {
64+ // Try to invoke Player#sendMessage(Component) in Paper API
65+ Class <?> legacyComponentSerializerClass = Class .forName (new String (LEGACY_COMPONENT_SERIALIZER_CLASS_NAME ));
66+ Object legacyAmpersand = legacyComponentSerializerClass .getMethod ("legacyAmpersand" ).invoke (null );
67+ Object component = legacyComponentSerializerClass .getMethod ("deserialize" , String .class ).invoke (legacyAmpersand , message );
68+ Player .class .getMethod ("sendMessage" , Class .forName (new String (COMPONENT_CLASS_NAME ))).invoke (player , component );
69+ } catch (ReflectiveOperationException ignored ) {
70+ try {
71+ player .spigot ().sendMessage (ComponentSerializer .parse (GsonComponentSerializer .gson ().serialize (LEGACY_DESERIALIZER .deserialize (message ))));
72+ } catch (Exception ignored2 ) {
73+ player .sendMessage (LEGACY_SERIALIZER_HEX .serialize (LEGACY_DESERIALIZER .deserialize (message )));
74+ }
75+ }
76+ } else if (rgbStatus == RGBStatus .CLIENT_ONLY ) {
77+ if (Bukkit .getPluginManager ().getPlugin ("ViaVersion" ) != null ) {
78+ String json = GsonComponentSerializer .gson ().serialize (LEGACY_DESERIALIZER .deserialize (message ));
79+ ViaUtil .sendJsonMessage (player , json );
80+ } else {
81+ // no way to send RGB chat :(
82+ player .sendMessage (LegacyComponentSerializer .legacySection ().serialize (LEGACY_DESERIALIZER .deserialize (message )));
83+ }
84+ } else {
85+ player .sendMessage (LegacyComponentSerializer .legacySection ().serialize (LEGACY_DESERIALIZER .deserialize (message )));
86+ }
87+ }
88+
3189 public void processGlobalMessage (GlobalMessageData data ) {
3290 String message = data .format ();
3391
@@ -56,10 +114,10 @@ public void processGlobalMessage(GlobalMessageData data) {
56114 }
57115
58116 for (Player player : event .getRecipients ()) {
59- player . sendMessage ( message );
117+ sendRGBMessage ( player , message );
60118 }
61119
62- plugin .getLogger ().info ("[Global-Chat] " + ChatColor . stripColor ( message ));
120+ plugin .getLogger ().info ("[Global-Chat] " + PlainTextComponentSerializer . plainText (). serialize ( LegacyComponentSerializer . legacyAmpersand (). deserialize ( message ) ));
63121 }
64122
65123 public void processChannelChatMessage (ChannelChatMessageData data ) {
@@ -78,7 +136,7 @@ public void processChannelChatMessage(ChannelChatMessageData data) {
78136
79137 plugin
80138 .getLogger ()
81- .info (Chat .f ("[Channel-Chat] ({0}) {1}" , channel .getName (), ChatColor . stripColor ( message )));
139+ .info (Chat .f ("[Channel-Chat] ({0}) {1}" , channel .getName (), PlainTextComponentSerializer . plainText (). serialize ( LegacyComponentSerializer . legacyAmpersand (). deserialize ( message ) )));
82140
83141 Set <Player > recipients ;
84142 if (data .isFromDiscord ()) {
@@ -137,7 +195,7 @@ public void processChannelChatMessage(ChannelChatMessageData data) {
137195 }
138196
139197 for (Player player : event .getRecipients ()) {
140- player . sendMessage ( message );
198+ sendRGBMessage ( player , message );
141199 }
142200 }
143201
@@ -169,7 +227,7 @@ public void processUndeliveredPrivateMessage(PrivateMessageData data) {
169227 recipients .add (targetPlayer );
170228 }
171229
172- plugin .getLogger ().info ("[Private-Chat] " + ChatColor . stripColor ( message ));
230+ plugin .getLogger ().info ("[Private-Chat] " + PlainTextComponentSerializer . plainText (). serialize ( LegacyComponentSerializer . legacyAmpersand (). deserialize ( message ) ));
173231
174232 AsyncPrivateMessageEvent event = new AsyncPrivateMessageEvent (data , recipients );
175233 Bukkit .getPluginManager ().callEvent (event );
@@ -178,7 +236,7 @@ public void processUndeliveredPrivateMessage(PrivateMessageData data) {
178236 }
179237
180238 for (Player player : event .getRecipients ()) {
181- player . sendMessage ( message );
239+ sendRGBMessage ( player , message );
182240 }
183241
184242 RyuZUPluginChat .newChain ()
@@ -221,7 +279,7 @@ public void notifyDeliveredPrivateMessage(PrivateMessageData data) {
221279 String message = data .format ();
222280
223281 for (Player player : event .getRecipients ()) {
224- player . sendMessage ( message );
282+ sendRGBMessage ( player , message );
225283 }
226284 }
227285
@@ -270,4 +328,38 @@ public void processSystemMessage(SystemMessageData data) {
270328 private Map <String , String > convertObjectIntoMap (Object mapObject ) {
271329 return (Map <String , String >) mapObject ;
272330 }
331+
332+ enum RGBStatus {
333+ UNSUPPORTED ,
334+ SERVER_AND_CLIENT ,
335+ SERVER_ONLY ,
336+ CLIENT_ONLY ,
337+ }
338+
339+ private static RGBStatus isRGBSupported (Player player ) {
340+ String version = Bukkit .getVersion ();
341+ boolean modern = !version .contains ("MC: 1.15" ) && !version .contains ("MC: 1.14" ) && !version .contains ("MC: 1.13" ) &&
342+ !version .contains ("MC: 1.12" ) && !version .contains ("MC: 1.11" ) && !version .contains ("MC: 1.10" ) &&
343+ !version .contains ("MC: 1.9" ) && !version .contains ("MC: 1.8" );
344+ if (Bukkit .getPluginManager ().getPlugin ("ViaVersion" ) == null ) {
345+ if (modern ) {
346+ return RGBStatus .SERVER_AND_CLIENT ;
347+ } else {
348+ return RGBStatus .UNSUPPORTED ;
349+ }
350+ }
351+ if (ViaUtil .isRGBSupportedVersion (player )) {
352+ if (modern ) {
353+ return RGBStatus .SERVER_AND_CLIENT ;
354+ } else {
355+ return RGBStatus .CLIENT_ONLY ;
356+ }
357+ } else {
358+ if (modern ) {
359+ return RGBStatus .SERVER_ONLY ;
360+ } else {
361+ return RGBStatus .UNSUPPORTED ;
362+ }
363+ }
364+ }
273365}
0 commit comments