Jump to content
  • Home
  • Files
  • Docs
  • Merch
Topics
  • All Content

  • This Topic
  • This Forum

  • Advanced Search
  • Existing user? Sign In  

    Sign In



    • Not recommended on shared computers


    • Forgot your password?

  • Sign Up
  • All Activity
  • Home
  • Mod Developer Central
  • Modder Support
  • [SOLVED] [1.12.2] NBT UUID loading as 00000-000 or empty string and nether not saving
1.13 Update Notes for Mod Creators
Sign in to follow this  
Followers 0
hiotewdew

[SOLVED] [1.12.2] NBT UUID loading as 00000-000 or empty string and nether not saving

By hiotewdew, December 19, 2018 in Modder Support

  • Reply to this topic
  • Start new topic

Recommended Posts

hiotewdew    3

hiotewdew

hiotewdew    3

  • Stone Miner
  • hiotewdew
  • Members
  • 3
  • 84 posts
Posted December 19, 2018 (edited)

I'm working on a claim system mod, and I'm using WorldSavedData to serialize the claims, including UUIDs of owners/members. However, I've run into an issue. When the data is saved, it saves with the proper UUID, confirmed by NBTExplorer.

image.png.ba1bf5e14d1151f7d893695623c43058.png

However upon loading the data, if I use UUIDs instead of strings I get 000000-00000-0000 as my UUID

and if I use strings and parse it into a UUID, I get an invalid string that causes a crash. (Presumably empty string or 00000-000-000)

See comment below.

The integer array loads properly and I've ensured everything is serverside.

Another issue I've run into is that the data from the nether isn't saved.

image.png.69014f443d0acbb8952b1c8d3d1d48d3.png

There's no dat file, even though I am using perWorldStorage.

 

Here's how my serializer works.

It starts in my event handler, which has the following events:

@SubscribeEvent
	public void onWorldLoad(WorldEvent.Load e) {
		if(!e.getWorld().isRemote) {
			ClaimManager.getManager().deserialize(e.getWorld());
		}
	}

	@SubscribeEvent
	public void onWorldSave(WorldEvent.Save e) {
		if(!e.getWorld().isRemote) {
			ClaimManager.getManager().serialize(e.getWorld());
		}
	}

Which both of the following fire properly and go to my ClaimManager (responsible for adding and removing claims from the official claims list)
These two methods are the beef of the bunch:

Spoiler

 


/** Forces a world to save claim data 
	 * @param world - The world to be saved **/
	public void serialize(World world) {
		if(!world.isRemote) {
			ClaimSerializer store = ClaimSerializer.get(world);
			for(ClaimArea claim : claims) {
				if(claim.getDimensionID() == world.provider.getDimension()) {
					int[] claimVals = claim.getSelfAsInt();
					UUID owner = claim.getOwner();
					UUID ownerOffline = claim.getOwnerOffline();
					String serialName = claim.getSerialName();
					NBTTagCompound data = new NBTTagCompound();
					data.setIntArray("CLAIMINFO", claimVals);
					data.setString("OWNERUID", owner.toString());
					data.setString("OWNERUIDOFF", ownerOffline.toString());
					System.out.println("Owner: " + owner);
					for(EnumPerm perm : EnumPerm.values()) {
						NBTTagCompound members = new NBTTagCompound();
						for(UUID member : claim.getArrayForPermission(perm)) {
							members.setString("MEMBER_" + member.toString(), member.toString());
						}
						data.setTag("MEMBERS_" + perm.name(), members);
					}
					store.data.setTag("CLAIM_" + serialName, data);
					store.markDirty();
					System.out.println("Saving claim: " + serialName);
				}
			}
		}
	}

	/** Forces a world to load claim data. 
	 * Overwrites new claim data since last load!
	 * @param world - The world to be saved **/
	public void deserialize(World world) {
		if(!world.isRemote) {
			ClaimSerializer store = ClaimSerializer.get(world);
			NBTTagCompound comp = store.data;
			if(comp != null ) {
				for(String key : comp.getKeySet()) {
					System.out.println("Loading " + key);
					NBTTagCompound data = comp.getCompoundTag(key);
					int[] claimVals = data.getIntArray("CLAIMINFO");
					UUID owner = UUID.fromString(comp.getString("OWNERUID"));
					UUID ownerOffline = UUID.fromString(comp.getString("OWNERUIDOFF"));
					System.out.println("Owner: " + owner);
					if(claimVals.length > 0 && claimVals[0] == 0 && claimVals[1] == world.provider.getDimension()) {
						System.out.println("Valid version.");
						ClaimArea claim = new ClaimArea(claimVals[1], claimVals[2], claimVals[3], claimVals[4], claimVals[5], owner, ownerOffline);
						for(String key2 : data.getKeySet()) {
							if(key2.startsWith("MEMBERS_")) {
								NBTTagCompound members = data.getCompoundTag(key2);
								for(String key3 : members.getKeySet()) {
									if(key3.startsWith("MEMBER_")) {
										UUID member = UUID.fromString(members.getString(key3));
										claim.addMember(EnumPerm.valueOf(key2.replaceAll("MEMBERS_", "")), member);
									}
								}
							}
						}
						this.addClaim(claim);
					} else {
						ClaimIt.logger.log(Level.FATAL, "Detected version that doesn't exist yet! Mod was downgraded? Claim cannot be loaded.");
					}
				}
			}
		}
	}

 

This is my actual WorldSavedData (ClaimSerializer):

public class ClaimSerializer extends WorldSavedData {
	private static final String DATA_NAME = Ref.MOD_ID + "_ClaimsData";
	public NBTTagCompound data = new NBTTagCompound();
	
	public ClaimSerializer() {
		super(DATA_NAME);
	}
	
	public ClaimSerializer(String s) {
		super(s);
	}
	
	@Override
	public void readFromNBT(NBTTagCompound nbt) {
		data = nbt;
	}
	@Override
	public NBTTagCompound writeToNBT(NBTTagCompound compound) {
		compound = data;
		return compound;
	}
	
	public static ClaimSerializer get(World world) {
		ClaimSerializer save = (ClaimSerializer) world.getPerWorldStorage().getOrLoadData(ClaimSerializer.class, DATA_NAME);
		if(save == null) {
			save = new ClaimSerializer();
			world.getMapStorage().setData(DATA_NAME, save);
		}
		return save;
	}
}

 

As you can see, it uses getPerWorldStorage, and is provided the world instance from the original event to return a storage, but for some reason nothing is saved to the nether. I've tested this on both a server and singleplayer. It always loads as an empty UUID and doesn't save nether info. The UUID issue only happens when the game is exited and started. Any ideas?

 

For more context, my source: https://github.com/itsmeow/ClaimIt/tree/master/src/main/java/its_meow/claimit

Edited December 20, 2018 by hiotewdew
Mark as solved
  • Quote

Share this post


Link to post
Share on other sites

hiotewdew    3

hiotewdew

hiotewdew    3

  • Stone Miner
  • hiotewdew
  • Members
  • 3
  • 84 posts
Posted December 19, 2018

Nevermind on the UUID issue. I am doing comp.getString() which is not the same as data.getString(). But the nether issue still stands.

  • Quote

Share this post


Link to post
Share on other sites

V0idWa1k3r    386

V0idWa1k3r

V0idWa1k3r    386

  • World Shaper
  • V0idWa1k3r
  • Members
  • 386
  • 1773 posts
Posted December 19, 2018

Why are you using WorldSavedData? AFAIK that's one per minecraft save file. If you want one per dimension use capabilities.

  • Quote

Share this post


Link to post
Share on other sites

diesieben07    6680

diesieben07

diesieben07    6680

  • Reality Controller
  • diesieben07
  • Forum Team
  • 6680
  • 45687 posts
Posted December 19, 2018
7 hours ago, V0idWa1k3r said:

Why are you using WorldSavedData? AFAIK that's one per minecraft save file. If you want one per dimension use capabilities.

WorldSavedData can also be per dimension, if getPerWorldStorage is used.

  • Thanks 1
  • Quote

Share this post


Link to post
Share on other sites

Animefan8888    677

Animefan8888

Animefan8888    677

  • Reality Controller
  • Animefan8888
  • Forge Modder
  • 677
  • 5746 posts
Posted December 20, 2018
18 hours ago, V0idWa1k3r said:

Why are you using WorldSavedData? AFAIK that's one per minecraft save file. If you want one per dimension use capabilities.

A world capability is just a wrapper around a WorldSavedData anyways.

  • Quote

Share this post


Link to post
Share on other sites

hiotewdew    3

hiotewdew

hiotewdew    3

  • Stone Miner
  • hiotewdew
  • Members
  • 3
  • 84 posts
Posted December 20, 2018

Figured it out. My get method uses both getMapStorage and getPerWorldStorage.

public static ClaimSerializer get(World world) {
  // PER WORLD STORAGE
		ClaimSerializer save = (ClaimSerializer) world.getPerWorldStorage().getOrLoadData(ClaimSerializer.class, DATA_NAME);
		if(save == null) {
			save = new ClaimSerializer();
          // MAP STORAGE!
			world.getMapStorage().setData(DATA_NAME, save); 
		}
		return save;
	}
  • Quote

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Insert image from URL
×
  • Desktop
  • Tablet
  • Phone
Sign in to follow this  
Followers 0
Go To Topic Listing



  • Recently Browsing

    No registered users viewing this page.

  • Posts

    • SilviaX_92
      Forge having problem loading mods

      By SilviaX_92 · Posted 1 hour ago

      Hi DaemonUmbra, I think I was told to do that by the Pixelmon installation instruction but apparently I misunderstood the wording...   I tried and it worked! Thank you so so much you saved me from a Minecraft without Mods!   Have a wonderful day/night!
    • Draco18s
      MoonPhase help

      By Draco18s · Posted 2 hours ago

      Events don't return values. Second, I'm pretty sure getMoonPhase() is client side only.
    • GatoLeyo
      MoonPhase help

      By GatoLeyo · Posted 2 hours ago

      Im new at modding so probably this have an obvious error but plz somebody tell me how can i make this works, it is intended to return a value in relation to the moon phase       public float endWorldTick(TickEvent.WorldTickEvent event)      {         float x = 0;         if(event.side.isServer() && event.phase == TickEvent.Phase.END)          {             World world = event.world;             if(world.provider.getDimension() == 0) {                 if(world.getMoonPhase() == 1.0f)                  {                   x = 15.0f;                 }             }         }         return x;     }  
    • DaemonUmbra
      Can't see anything on minecraft menu screen except for the bottom left corner

      By DaemonUmbra · Posted 3 hours ago

      Please don't Necro old threads, if you have an issue make your own.
    • DaemonUmbra
      Forge having problem loading mods

      By DaemonUmbra · Posted 3 hours ago

      You changed "Game Directory" to your mods folder. The Game Directory is supposed to be the folder that contains the mods folder, .minecraft by default
  • Topics

    • SilviaX_92
      4
      Forge having problem loading mods

      By SilviaX_92
      Started 6 hours ago

    • GatoLeyo
      1
      MoonPhase help

      By GatoLeyo
      Started 2 hours ago

    • florgonn
      4
      Can't see anything on minecraft menu screen except for the bottom left corner

      By florgonn
      Started July 30, 2014

    • Casual
      1
      1.12.2 crash on game start

      By Casual
      Started 3 hours ago

    • PulseBeat_02
      14
      [1.12.2] Forge Crashes While Just Loading Into Loading Screen

      By PulseBeat_02
      Started December 13, 2018

  • Who's Online (See full list)

    • SerpentDagger
    • DavidM
    • thinkverse
  • All Activity
  • Home
  • Mod Developer Central
  • Modder Support
  • [SOLVED] [1.12.2] NBT UUID loading as 00000-000 or empty string and nether not saving
  • Theme
  • Contact Us
  • Discord

Copyright © 2019 ForgeDevelopment LLC · Ads by Curse Powered by Invision Community