Преглед изворни кода

Fixing a major bug with sub-skills not being shown when using commands

nossr50 пре 4 година
родитељ
комит
cb9c7acceb
3 измењених фајлова са 133 додато и 37 уклоњено
  1. 4 0
      Changelog.txt
  2. 4 4
      pom.xml
  3. 125 33
      src/main/java/com/gmail/nossr50/util/TextComponentFactory.java

+ 4 - 0
Changelog.txt

@@ -1,3 +1,7 @@
+Version 2.1.153
+    Fixed a bug where most sub-skills were not being displayed when using a skills command (for example /taming)
+    Fixed a bug where some URL links were not being colored
+
 Version 2.1.152
     Fixed a bug where Tree Feller would sometimes double drop blocks inappropriately
     Fixed a bug with bleed damage calculations and player armor

+ 4 - 4
pom.xml

@@ -2,7 +2,7 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.gmail.nossr50.mcMMO</groupId>
     <artifactId>mcMMO</artifactId>
-    <version>2.1.152</version>
+    <version>2.1.153-SNAPSHOT</version>
     <name>mcMMO</name>
     <url>https://github.com/mcMMO-Dev/mcMMO</url>
     <scm>
@@ -202,17 +202,17 @@
         <dependency>
             <groupId>net.kyori</groupId>
             <artifactId>adventure-text-serializer-gson</artifactId>
-            <version>4.1.1</version>
+            <version>4.2.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>net.kyori</groupId>
             <artifactId>adventure-api</artifactId>
-            <version>4.1.1</version>
+            <version>4.2.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>net.kyori</groupId>
             <artifactId>adventure-nbt</artifactId>
-            <version>4.1.1</version>
+            <version>4.2.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>net.kyori</groupId>

+ 125 - 33
src/main/java/com/gmail/nossr50/util/TextComponentFactory.java

@@ -22,11 +22,15 @@ import net.kyori.adventure.text.event.HoverEvent;
 import net.kyori.adventure.text.format.NamedTextColor;
 import net.kyori.adventure.text.format.TextColor;
 import net.kyori.adventure.text.format.TextDecoration;
+import org.bukkit.ChatColor;
 import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
+import java.lang.reflect.Array;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
-import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * This class handles many of the JSON components that mcMMO makes and uses
@@ -105,49 +109,138 @@ public class TextComponentFactory {
         ), MessageType.SYSTEM);
     }
 
-    public static void sendPlayerSubSkillList(Player player, List<Component> textComponents)
-    {
-        TextComponent emptySpace = Component.space();
+    public static void sendPlayerSubSkillList(@NotNull Player player, @NotNull List<Component> subSkillComponents) {
+        final Audience audience = mcMMO.getAudiences().player(player);
 
-        AtomicReference<Component> messageToSend = new AtomicReference<>();
-        int newLineCount = 0; //Hacky solution to wordwrap problems
+        //@ Signs, done for style
+        Component space = Component.space();
+        TextComponent atSignComponent = Component.text(LocaleLoader.getString("JSON.Hover.AtSymbolSkills"));
 
-        final Audience audience = mcMMO.getAudiences().player(player);
-        for (Component textComponent : textComponents) {
-            //Don't send more than 3 subskills per line to avoid MOST wordwrap problems
-            if(newLineCount > 2)
-            {
-                Component toSend = messageToSend.get();
-                if (toSend != null) {
-                    audience.sendMessage(Identity.nil(), toSend.append(emptySpace));
-                }
+        //Only send 3 sub-skills per line
+        Component[][] splitSubSkills = splitComponentsIntoGroups(subSkillComponents, 3);
+        ArrayList<Component> individualLinesToSend = new ArrayList<>();
 
-                messageToSend.set(null);
-                newLineCount = 0;
-            }
-            //Style the skills into @links
-            final String originalTxt = textComponent instanceof TextComponent ? ((TextComponent) textComponent).content() : "";
+        //Create each line
+        for (Component[] componentArray : splitSubSkills) {
+            individualLinesToSend.add(fromArray(componentArray, atSignComponent, space));
+        }
+
+        //Send each group
+        for(Component curLine : individualLinesToSend) {
+            audience.sendMessage(Identity.nil(), curLine);
+        }
+    }
 
-            TextComponent.Builder stylizedText = Component.text().content(LocaleLoader.getString("JSON.Hover.AtSymbolSkills"));
-            addChild(stylizedText, originalTxt);
+    /**
+     * Makes a single component from an array of components, can optionally add prefixes and suffixes to come before and after each component
+     * @param componentsArray target array
+     * @return
+     */
+    private static @NotNull Component fromArray(@NotNull Component[] componentsArray, @Nullable Component prefixComponent, @Nullable Component suffixComponent) {
+        TextComponent.Builder componentBuilder = Component.text();
 
-            if(textComponent.hoverEvent() != null)
-                stylizedText.hoverEvent(textComponent.hoverEvent());
+        for(Component component : componentsArray) {
+            if(component == null) //Individual elements can be null
+                continue;
 
-            if(textComponent.clickEvent() != null)
-                stylizedText.clickEvent(textComponent.clickEvent());
+            if(prefixComponent != null)
+                componentBuilder.append(prefixComponent);
 
-            messageToSend.set(stylizedText.build().append(emptySpace));
+            componentBuilder.append(component);
+
+            if(suffixComponent != null)
+                componentBuilder.append(suffixComponent);
 
-            newLineCount++;
         }
 
-        Component toSend = messageToSend.get();
-        if (toSend != null) {
-            audience.sendMessage(Identity.nil(), toSend.append(emptySpace));
+        return componentBuilder.build();
+    }
+
+
+    /**
+     * Takes a list of components and splits them into arrays each with a maximum element limit
+     * Individual elements in [][X] may be null
+     *
+     * @param components target component list
+     * @param groupsSize maximum size per array
+     * @return a 2D array with components split into groups
+     */
+    private static @NotNull Component[][] splitComponentsIntoGroups(@NotNull List<Component> components, int groupsSize) {
+        int groupCount = (int) Math.ceil((double) components.size() / (double) groupsSize);
+
+        Component[][] splitGroups = new Component[groupCount][groupsSize];
+
+        int groupsFinished = 0;
+
+        while (groupsFinished < groupCount) {
+            //Fill group with members
+            for(int i = 0; i < groupsSize; i++) {
+                int indexOfPotentialMember = i + (groupsFinished * 3); //Groups don't always fill all members neatly
+
+                //Some groups won't have entirely non-null elements
+                if(indexOfPotentialMember > components.size()-1) {
+                    break;
+                }
+
+                Component potentialMember = components.get(indexOfPotentialMember);
+
+                //Make sure the potential member exists because of rounding
+                if(potentialMember != null) {
+                    splitGroups[groupsFinished][i] = potentialMember;
+                }
+            }
+
+            //Another group is finished
+            groupsFinished++;
         }
+
+        return splitGroups;
     }
 
+
+//    public static void sendPlayerSubSkillList(Player player, List<Component> textComponents)
+//    {
+//        TextComponent emptySpace = Component.space();
+//
+//        AtomicReference<Component> messageToSend = new AtomicReference<>();
+//        int newLineCount = 0; //Hacky solution to wordwrap problems
+//
+//        final Audience audience = mcMMO.getAudiences().player(player);
+//        for (Component textComponent : textComponents) {
+//            //Don't send more than 3 subskills per line to avoid MOST wordwrap problems
+//            if(newLineCount > 2)
+//            {
+//                Component toSend = messageToSend.get();
+//                if (toSend != null) {
+//                    audience.sendMessage(Identity.nil(), toSend.append(emptySpace));
+//                }
+//
+//                messageToSend.set(null);
+//                newLineCount = 0;
+//            }
+//            //Style the skills into @links
+//            final String originalTxt = textComponent instanceof TextComponent ? ((TextComponent) textComponent).content() : "";
+//
+//            TextComponent.Builder stylizedText = Component.text().content(LocaleLoader.getString("JSON.Hover.AtSymbolSkills"));
+//            addChild(stylizedText, originalTxt);
+//
+//            if(textComponent.hoverEvent() != null)
+//                stylizedText.hoverEvent(textComponent.hoverEvent());
+//
+//            if(textComponent.clickEvent() != null)
+//                stylizedText.clickEvent(textComponent.clickEvent());
+//
+//            messageToSend.set(stylizedText.build().append(emptySpace));
+//
+//            newLineCount++;
+//        }
+//
+//        Component toSend = messageToSend.get();
+//        if (toSend != null) {
+//            audience.sendMessage(Identity.nil(), toSend.append(emptySpace));
+//        }
+//    }
+
     private static Component getWebLinkTextComponent(McMMOWebLinks webLinks)
     {
         TextComponent.Builder webTextComponent;
@@ -201,8 +294,7 @@ public class TextComponentFactory {
     }
 
     private static void addChild(ComponentBuilder<?, ?> webTextComponent, String childName) {
-        TextComponent childComponent = Component.text(childName);
-        childComponent.color(NamedTextColor.BLUE);
+        TextComponent childComponent = Component.text(childName).color(NamedTextColor.BLUE);
         webTextComponent.append(childComponent);
     }