Skyblock Builder

Skyblock Builder

10M Downloads

Server wont start, "Name and ID cannot both be blank..." errors

rruy-dev opened this issue · 11 comments

commented

Minecraft version

1.19.2

LibX version

5.0.12

Skyblock Builder version

5.1.20

Forge version

1.20.1

The latest.log file

https://mclo.gs/0ouQB5o

Issue description

Seaopolis server wont boot, issue began a few days ago
There is an error spam from SkyblockBuilder, "Name and ID cannot both be blank..."

Steps to reproduce

No response

Other information

Unsure what to do to troubleshoot this on my end, things were running smooth for awhile and this seemed to happen suddenly
If its a corruption with the skyblock_builder.dat file, would there be a way to fix it?

commented

You're using version 5.1.20. Try again with 5.1.23, in this version, some things changed related to this piece of code.

commented

Just tried on v5.1.23 and the issue is still present
Heres the latest.log
https://mclo.gs/A2aKxD8#L1824
and debug.log if that can help
https://mclo.gs/njfrSvD#L10784

commented

I'm not sure how to test this properly since I don't fully understand why exactly this happens. Please try with this mod file:
SkyblockBuilder-1.20.1-5.1.24-test.zip

If the problem still occurs on default setup, set forceUnsecureProfileNames to true. This is a new config value which should avoid this kind of problem. If there's still a problem, please tell me. I'll try to fix it.

Changes made for this test version:

Index: src/main/java/de/melanx/skyblockbuilder/util/RandomUtility.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/de/melanx/skyblockbuilder/util/RandomUtility.java b/src/main/java/de/melanx/skyblockbuilder/util/RandomUtility.java
--- a/src/main/java/de/melanx/skyblockbuilder/util/RandomUtility.java	(revision e9fc6a0c211b5981778ff3744fd64eb99dccd7c5)
+++ b/src/main/java/de/melanx/skyblockbuilder/util/RandomUtility.java	(date 1728153345667)
@@ -155,7 +155,15 @@
                 if (gameProfile.isPresent()) {
                     profiles.add(gameProfile.get());
                 } else {
-                    GameProfile profile = server.getSessionService().fillProfileProperties(new GameProfile(id, null), level.getServer().enforceSecureProfile());
+                    GameProfile profile;
+                    GameProfile unnamedProfile = new GameProfile(id, null);
+                    boolean enforceProfileSecurity = CustomizationConfig.forceUnsecureProfileNames || level.getServer().enforceSecureProfile();
+                    try {
+                        profile = server.getSessionService().fillProfileProperties(unnamedProfile, enforceProfileSecurity);
+                    } catch (IllegalArgumentException e) {
+                        SkyblockBuilder.getLogger().error("Problems filling profile properties for id {} with requiring secure {}", id, enforceProfileSecurity);
+                        profile = unnamedProfile;
+                    }
 
                     if (profile.getName() != null) {
                         profileCache.add(profile);
Index: src/main/java/de/melanx/skyblockbuilder/config/common/CustomizationConfig.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/de/melanx/skyblockbuilder/config/common/CustomizationConfig.java b/src/main/java/de/melanx/skyblockbuilder/config/common/CustomizationConfig.java
--- a/src/main/java/de/melanx/skyblockbuilder/config/common/CustomizationConfig.java	(revision e9fc6a0c211b5981778ff3744fd64eb99dccd7c5)
+++ b/src/main/java/de/melanx/skyblockbuilder/config/common/CustomizationConfig.java	(date 1728153345662)
@@ -14,4 +14,7 @@
             "The island and all its blocks remain at this position!",
             "This position will not be used for any new team, only the remaining team will be deleted."})
     public static boolean deleteTeamsAutomatically = false;
+
+    @Config("You may enable this when you encounter problems with game profiles")
+    public static boolean forceUnsecureProfileNames = false;
 }
commented

Tried out this jar, still getting the same errors, including with using the new customization config forceUnsecureProfileNames set to true.
Here's the skyblock_builder.dat from the servers world/data folder, hopefully it helps troubleshoot this issue
skyblockbuilder_data.zip
Thanks again for working with me to fix this

commented

Thank you!
Maybe it's a weird request, but could you also send me your usernamecache.json file? Maybe I can simplify this whole process. And I can't use my own file since it only contains my name. I don't have a large user base like your server :D

commented

Sure here it is
usernamecache.zip
I had tried backing it up, and deleting it from the server to see if that fixes this issue, but no dice on that

commented

Thank you for your help on this issue! I hope everything's fixed now :)
And yes, the new config and changes on the networking code are the cause for that problem. But that should be fixed when everybody has the correct version :)

commented

I'm so sorry, I forgot about it. Will try that today.

commented

Hey any more information I can offer to aid in the fix for this?
I'm not sure what else would be applicable here, but if you need any other server files feel free to ask

commented

Please try this version as well.
SkyblockBuilder-1.20.1-5.1.24-test.zip

I'm now using the usernamecache.json file before asking the Internet. Profiles are now sent in batches of 1000 profiles per packet (I think that wasn't neccessary but I saw a problem which was caused on another point blablabla).
Using your data, I encountered a problem with the packet size. I recommend the mod XL Packets to fix the problem. On my machine, it worked using this mod.

Here are the code changes compared to 5.1.23
Index: src/main/java/de/melanx/skyblockbuilder/util/RandomUtility.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/de/melanx/skyblockbuilder/util/RandomUtility.java b/src/main/java/de/melanx/skyblockbuilder/util/RandomUtility.java
--- a/src/main/java/de/melanx/skyblockbuilder/util/RandomUtility.java	(revision e9fc6a0c211b5981778ff3744fd64eb99dccd7c5)
+++ b/src/main/java/de/melanx/skyblockbuilder/util/RandomUtility.java	(date 1728804317688)
@@ -35,6 +35,7 @@
 import net.minecraft.world.level.block.state.BlockState;
 import net.minecraft.world.level.block.state.properties.BlockStateProperties;
 import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
+import net.minecraftforge.common.UsernameCache;
 import net.minecraftforge.fml.ModList;
 import org.moddingx.libx.annotation.meta.RemoveIn;
 
@@ -150,12 +151,26 @@
                     continue;
                 }
 
+                if (UsernameCache.containsUUID(id)) {
+                    String lastKnownUsername = UsernameCache.getLastKnownUsername(id);
+                    profiles.add(new GameProfile(id, lastKnownUsername));
+                    continue;
+                }
+
                 uncachedProfilesAmount++;
                 Optional<GameProfile> gameProfile = profileCache.get(id);
                 if (gameProfile.isPresent()) {
                     profiles.add(gameProfile.get());
                 } else {
-                    GameProfile profile = server.getSessionService().fillProfileProperties(new GameProfile(id, null), level.getServer().enforceSecureProfile());
+                    GameProfile profile;
+                    GameProfile unnamedProfile = new GameProfile(id, null);
+                    boolean enforceProfileSecurity = CustomizationConfig.forceUnsecureProfileNames || level.getServer().enforceSecureProfile();
+                    try {
+                        profile = server.getSessionService().fillProfileProperties(unnamedProfile, enforceProfileSecurity);
+                    } catch (IllegalArgumentException e) {
+                        SkyblockBuilder.getLogger().error("Problems filling profile properties for id {} with requiring secure {}", id, enforceProfileSecurity);
+                        profile = unnamedProfile;
+                    }
 
                     if (profile.getName() != null) {
                         profileCache.add(profile);
Index: src/main/java/de/melanx/skyblockbuilder/config/common/CustomizationConfig.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/de/melanx/skyblockbuilder/config/common/CustomizationConfig.java b/src/main/java/de/melanx/skyblockbuilder/config/common/CustomizationConfig.java
--- a/src/main/java/de/melanx/skyblockbuilder/config/common/CustomizationConfig.java	(revision e9fc6a0c211b5981778ff3744fd64eb99dccd7c5)
+++ b/src/main/java/de/melanx/skyblockbuilder/config/common/CustomizationConfig.java	(date 1728153345662)
@@ -14,4 +14,7 @@
             "The island and all its blocks remain at this position!",
             "This position will not be used for any new team, only the remaining team will be deleted."})
     public static boolean deleteTeamsAutomatically = false;
+
+    @Config("You may enable this when you encounter problems with game profiles")
+    public static boolean forceUnsecureProfileNames = false;
 }
Index: src/main/java/de/melanx/skyblockbuilder/network/SkyblockDataUpdateMessage.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/de/melanx/skyblockbuilder/network/SkyblockDataUpdateMessage.java b/src/main/java/de/melanx/skyblockbuilder/network/SkyblockDataUpdateMessage.java
--- a/src/main/java/de/melanx/skyblockbuilder/network/SkyblockDataUpdateMessage.java	(revision e9fc6a0c211b5981778ff3744fd64eb99dccd7c5)
+++ b/src/main/java/de/melanx/skyblockbuilder/network/SkyblockDataUpdateMessage.java	(date 1728810255942)
@@ -68,7 +68,7 @@
         @Override
         public SkyblockDataUpdateMessage decode(FriendlyByteBuf buffer) {
             SkyblockSavedData data = new SkyblockSavedData();
-            data.load(Objects.requireNonNull(buffer.readNbt()));
+            data.load(Objects.requireNonNull(buffer.readAnySizeNbt()));
             return new SkyblockDataUpdateMessage(data, buffer.readUUID());
         }
     }
Index: src/main/java/de/melanx/skyblockbuilder/network/SkyNetwork.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/de/melanx/skyblockbuilder/network/SkyNetwork.java b/src/main/java/de/melanx/skyblockbuilder/network/SkyNetwork.java
--- a/src/main/java/de/melanx/skyblockbuilder/network/SkyNetwork.java	(revision e9fc6a0c211b5981778ff3744fd64eb99dccd7c5)
+++ b/src/main/java/de/melanx/skyblockbuilder/network/SkyNetwork.java	(date 1728806841372)
@@ -17,6 +17,7 @@
 import org.moddingx.libx.network.NetworkX;
 
 import javax.annotation.Nullable;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -79,7 +80,7 @@
             return;
         }
 
-        this.channel.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new ProfilesUpdateMessage(this.getProfilesTag((ServerLevel) player.getCommandSenderWorld())));
+        this.sendProfilesInBatches(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), RandomUtility.getGameProfiles((ServerLevel) player.getCommandSenderWorld()));
     }
 
     public void updateProfiles(Level level) {
@@ -87,7 +88,9 @@
             return;
         }
 
-        this.channel.send(PacketDistributor.ALL.noArg(), new ProfilesUpdateMessage(this.getProfilesTag((ServerLevel) level)));
+        Set<GameProfile> gameProfiles = RandomUtility.getGameProfiles((ServerLevel) level);
+
+        this.sendProfilesInBatches(PacketDistributor.ALL.noArg(), gameProfiles);
     }
 
     public void updateTemplateNames(Player player, List<String> names) {
@@ -102,22 +105,26 @@
         this.channel.send(PacketDistributor.ALL.noArg(), new UpdateTemplateNamesMessage(names));
     }
 
-    private CompoundTag getProfilesTag(ServerLevel level) {
-        Set<GameProfile> profileCache = RandomUtility.getGameProfiles(level);
-        CompoundTag profiles = new CompoundTag();
-        ListTag tags = new ListTag();
+    private void sendProfilesInBatches(PacketDistributor.PacketTarget target, Set<GameProfile> allGameProfiles) {
+        final int batchSize = 1000;
+        Set<GameProfile> currentBatch = new HashSet<>(batchSize);
+
+        for (GameProfile profile : allGameProfiles) {
+            currentBatch.add(profile);
 
-        // load the cache and look for all profiles
-        profileCache.forEach(profile -> {
-            if (profile.getId() != null && profile.getName() != null) {
-                CompoundTag tag = new CompoundTag();
-                tag.putUUID("Id", profile.getId());
-                tag.putString("Name", profile.getName());
-                tags.add(tag);
+            if (currentBatch.size() == batchSize) {
+                this.sendProfileBatch(target, currentBatch);
+                currentBatch.clear();
             }
-        });
+        }
 
-        profiles.put("Profiles", tags);
-        return profiles;
+        // send any remaining profiles in the last batch
+        if (!currentBatch.isEmpty()) {
+            this.sendProfileBatch(target, currentBatch);
+        }
+    }
+
+    private void sendProfileBatch(PacketDistributor.PacketTarget target, Set<GameProfile> profiles) {
+        this.channel.send(target, new ProfilesUpdateMessage(profiles));
     }
 }
Index: src/main/java/de/melanx/skyblockbuilder/network/ProfilesUpdateMessage.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/de/melanx/skyblockbuilder/network/ProfilesUpdateMessage.java b/src/main/java/de/melanx/skyblockbuilder/network/ProfilesUpdateMessage.java
--- a/src/main/java/de/melanx/skyblockbuilder/network/ProfilesUpdateMessage.java	(revision e9fc6a0c211b5981778ff3744fd64eb99dccd7c5)
+++ b/src/main/java/de/melanx/skyblockbuilder/network/ProfilesUpdateMessage.java	(date 1728806665110)
@@ -3,7 +3,6 @@
 import com.mojang.authlib.GameProfile;
 import de.melanx.skyblockbuilder.client.GameProfileCache;
 import net.minecraft.nbt.CompoundTag;
-import net.minecraft.nbt.Tag;
 import net.minecraft.network.FriendlyByteBuf;
 import net.minecraftforge.network.NetworkEvent;
 import org.moddingx.libx.network.PacketHandler;
@@ -14,7 +13,7 @@
 import java.util.UUID;
 import java.util.function.Supplier;
 
-public record ProfilesUpdateMessage(CompoundTag profiles) {
+public record ProfilesUpdateMessage(Set<GameProfile> profiles) {
 
     public static class Handler implements PacketHandler<ProfilesUpdateMessage> {
 
@@ -25,17 +24,7 @@
 
         @Override
         public boolean handle(ProfilesUpdateMessage msg, Supplier<NetworkEvent.Context> ctx) {
-            Set<GameProfile> profiles = new HashSet<>();
-            for (Tag tag : msg.profiles.getList("Profiles", Tag.TAG_COMPOUND)) {
-                CompoundTag nbt = (CompoundTag) tag;
-
-                UUID id = nbt.getUUID("Id");
-                String name = nbt.getString("Name");
-
-                profiles.add(new GameProfile(id, name));
-            }
-
-            GameProfileCache.addProfiles(profiles);
+            GameProfileCache.addProfiles(msg.profiles);
             return true;
         }
     }
@@ -49,12 +38,32 @@
 
         @Override
         public void encode(ProfilesUpdateMessage msg, FriendlyByteBuf buffer) {
-            buffer.writeNbt(msg.profiles);
+            int size = msg.profiles.size();
+            buffer.writeVarInt(size);
+            msg.profiles.forEach(profile -> {
+                CompoundTag tag = new CompoundTag();
+                tag.putUUID("Id", profile.getId());
+                tag.putString("Name", profile.getName());
+                buffer.writeNbt(tag);
+            });
         }
 
         @Override
         public ProfilesUpdateMessage decode(FriendlyByteBuf buffer) {
-            return new ProfilesUpdateMessage(buffer.readNbt());
+            int size = buffer.readVarInt();
+            Set<GameProfile> profiles = new HashSet<>();
+            for (int i = 0; i < size; i++) {
+                CompoundTag tag = buffer.readNbt();
+                if (tag == null) {
+                    continue;
+                }
+
+                UUID id = tag.getUUID("Id");
+                String name = tag.getString("Name");
+                profiles.add(new GameProfile(id, name));
+            }
+
+            return new ProfilesUpdateMessage(profiles);
         }
     }
 }
commented

This worked to fix the issue!
There was a config change done though, so the pack will need to be updated in-order for players to join, as they get kicked when trying to join on older versions of the mod, and Seaopolis has v5.1.20
2024-10-14_13 58 03
Already in contact with the Seaopolis devs to include this in the pack when this fix update is pushed to Curseforge