1212import org .bukkit .event .EventHandler ;
1313import org .bukkit .event .EventPriority ;
1414import org .bukkit .event .Listener ;
15+ import org .bukkit .map .MapFont ;
16+ import org .bukkit .map .MinecraftFont ;
1517
1618import java .util .ArrayList ;
1719import java .util .List ;
1820
1921public class ServerPingListener implements Listener {
2022
23+ private static final MapFont MINECRAFT_FONT = MinecraftFont .Font ;
24+ private static final int MOTD_WIDTH_PIXELS = 154 ;
25+ private static final int SPACE_WIDTH = MINECRAFT_FONT .getWidth (" " );
26+
2127 @ EventHandler (priority = EventPriority .HIGH )
2228 public void onServerPing (PaperServerListPingEvent event ) {
2329 String serverName = ServerSettingsAPI .getApi ().getServerName ();
@@ -32,11 +38,12 @@ public void onServerPing(PaperServerListPingEvent event) {
3238 int length = serverName .length ();
3339
3440 Component serverNameComponent = Component .empty ();
41+ List <String > gradient_colors = ServerSettingsAPI .getApi ().getServerNameGradient ();
3542 for (int i = 0 ; i < length ; i ++) {
3643 serverNameComponent = serverNameComponent .append (Gradient .gradient (
3744 String .valueOf (serverName .charAt (i )),
38- "#50FB08" ,
39- "#006EFF" ,
45+ gradient_colors . getFirst () ,
46+ gradient_colors . get ( 1 ) ,
4047 i ,
4148 length - 1
4249 ));
@@ -49,56 +56,52 @@ public void onServerPing(PaperServerListPingEvent event) {
4956 .append (Component .text (serverVersion , NamedTextColor .GOLD ))
5057 .append (Component .text ("] " , NamedTextColor .WHITE ))
5158 .append (Component .text (" M" , NamedTextColor .GOLD , TextDecoration .OBFUSCATED ))
52- .append (Component .text ("\n " ));
59+ .append (Component .text ("\n " ));
5360
54- int extraShift = 5 ;
61+ int extraShift = 10 ;
5562
5663 if (Bukkit .hasWhitelist ()) {
5764 String info = "Info: Whitelist enabled!" ;
58- Component centered = centerLines (wrapText (info , totalWidth ), totalWidth , NamedTextColor .GOLD , extraShift );
65+ Component centered = centerLinesPixelAccurate (wrapText (info , totalWidth ), NamedTextColor .GOLD , extraShift );
66+ event .motd (header .append (centered ));
5967 event .getListedPlayers ().removeIf (listedPlayerInfo -> {
6068 OfflinePlayer offline = Bukkit .getOfflinePlayer (listedPlayerInfo .id ());
6169 return PlayerIdentityAPI .getApi ().isVanished (offline );
6270 });
6371 long visibleCount = event .getListedPlayers ().size ();
6472 event .setNumPlayers ((int ) visibleCount );
65- event .motd (header .append (centered ));
6673 return ;
6774 }
6875
6976 if (ServerSettingsAPI .getApi ().isMaintenanceEnabled ()) {
70- List <String > lines = new ArrayList <>();
71- lines .add ("Info: Server is in maintenance!" );
72- String maintenanceReason = ServerSettingsAPI .getApi ().getMaintenanceReason ().trim ();
73- if (!maintenanceReason .isEmpty ()) {
74- lines .addAll (wrapText (maintenanceReason , totalWidth ));
75- }
76- Component firstLine = centerLines (List .of (lines .getFirst ()), totalWidth , NamedTextColor .GOLD , extraShift );
77- List <String > detailLines = lines .size () > 1 ? lines .subList (1 , lines .size ()) : List .of ();
78- Component details = centerLines (detailLines , totalWidth , NamedTextColor .RED , extraShift );
77+ String maintenance = "Info: Server is in maintenance!" ;
78+ Component centered = centerLinesPixelAccurate (wrapText (maintenance , totalWidth ), NamedTextColor .GOLD , extraShift + 2 );
79+ event .motd (header .append (centered ));
80+
7981 event .getListedPlayers ().removeIf (listedPlayerInfo -> {
8082 OfflinePlayer offline = Bukkit .getOfflinePlayer (listedPlayerInfo .id ());
8183 return PlayerIdentityAPI .getApi ().isVanished (offline );
8284 });
8385 long visibleCount = event .getListedPlayers ().size ();
8486 event .setNumPlayers ((int ) visibleCount );
85- event .motd (header .append (firstLine ).append (details ));
8687 return ;
8788 }
8889
8990 if (Bukkit .getOnlinePlayers ().size () >= Bukkit .getMaxPlayers ()) {
9091 String info = "Info: Server is full!" ;
91- Component centered = centerLines (wrapText (info , totalWidth ), totalWidth , NamedTextColor .RED , extraShift );
92+ Component centered = centerLinesPixelAccurate (wrapText (info , totalWidth ), NamedTextColor .RED , extraShift );
93+ event .motd (header .append (centered ));
9294 event .getListedPlayers ().removeIf (listedPlayerInfo -> {
9395 OfflinePlayer offline = Bukkit .getOfflinePlayer (listedPlayerInfo .id ());
9496 return PlayerIdentityAPI .getApi ().isVanished (offline );
9597 });
96- event .motd (header .append (centered ));
98+ long visibleCount = event .getListedPlayers ().size ();
99+ event .setNumPlayers ((int ) visibleCount );
97100 return ;
98101 }
99102
100103 String info = "Info: Server is online!" ;
101- Component centered = centerLines (wrapText (info , totalWidth ), totalWidth , NamedTextColor .GREEN , extraShift );
104+ Component centered = centerLinesPixelAccurate (wrapText (info , totalWidth ), NamedTextColor .GREEN , extraShift );
102105 event .motd (header .append (centered ));
103106 event .getListedPlayers ().removeIf (listedPlayerInfo -> {
104107 OfflinePlayer offline = Bukkit .getOfflinePlayer (listedPlayerInfo .id ());
@@ -131,15 +134,26 @@ private static List<String> wrapText(String text, int width) {
131134 return lines ;
132135 }
133136
134- private static Component centerLines (List <String > lines , int width , net .kyori .adventure .text .format .NamedTextColor color , int extraShift ) {
137+ private static int getPixelWidth (String text ) {
138+ String stripped = text .replaceAll ("[§&][0-9a-fk-or]" , "" );
139+ return MINECRAFT_FONT .getWidth (stripped );
140+ }
141+
142+ private static int calculateCenterSpaces (String text ) {
143+ int textWidth = getPixelWidth (text );
144+ int padding = (MOTD_WIDTH_PIXELS - textWidth ) / 2 ;
145+ return Math .max (0 , padding / SPACE_WIDTH );
146+ }
147+
148+ private static Component centerLinesPixelAccurate (List <String > lines , NamedTextColor color , int extraShift ) {
135149 if (lines == null || lines .isEmpty ()) {
136150 return Component .empty ();
137151 }
138152 Component result = Component .empty ();
139153 for (int i = 0 ; i < lines .size (); i ++) {
140154 String line = lines .get (i );
141- int padding = Math . max ( 0 , ( width - line . length ()) / 2 + extraShift ) ;
142- String pad = " " .repeat (padding );
155+ int spacesNeeded = calculateCenterSpaces ( line ) + extraShift ;
156+ String pad = " " .repeat (Math . max ( 0 , spacesNeeded ) );
143157 result = result .append (Component .text (pad )).append (Component .text (line , color ));
144158 if (i < lines .size () - 1 ) {
145159 result = result .append (Component .text ("\n " ));
0 commit comments