Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

[solved] [1.12.2] getting offline player capability on different online client

Featured Replies

Posted

First of all I have been modding for just over a year now, but this is my first post.  With that out of the way, on to the problem.

 

I have a gui that lists players that have joined in a team with you (the teams are saved in a world capability), and it displays their aura (saved as a capability on the player).  This works fine as long as every member of the team is on the server, however if there is a member of the team that is not on the server, opening this gui will cause a crash because the client can not find the player.

the current offending line of code (line 254 of Team Capability class)

this.world.getPlayerEntityByUUID(UUID.fromString(teamnbt.getString(teamkey)))

when the team capability is being deserialized from nbt (after being sent from the server to the client)

(world can be either a client world or server world)

 

so my main question is, can you get an EntityPlayer instance of an offline player on the client?  Can you get the data of an offline player on a client (similar to using player.dat on a server)?  Is there another way to display the capability data on the client of the offline player?

 

Team Capability class

Reveal hidden contents

 

Gui class

Reveal hidden contents

 

(this is an old screenshot with the same player in all four slots, but it serves it's purpose of showing why I want the capability data exposed)
2019-04-18_17_56_56.png.5728e004b87d2d1b2fae4438960719f3.png

 

similar thread (but this only works on the server instead of the client I think)

 

 

also completely unrelated but
Player404

(which is a random player generated by the IDE) is actually registered to a real player
https://mcuuid.net/?q=Player404

Edited by Pi Man
solved

  On 9/5/2019 at 12:40 AM, Pi Man said:

can you get an EntityPlayer instance of an offline player on the client?

Not really.

  On 9/5/2019 at 12:40 AM, Pi Man said:

Can you get the data of an offline player on a client (similar to using player.dat on a server)?

Yes you can do this. I've done it recently you need to create an EntityPlayerMP instance on the server and load it's nbt. With a little digging you'll find where the nbt is loaded. Then you need to send the data to the client via a packet. Then store the data until the client player no longer needs it.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

  • Author

alright, so I got a solution
 

so what I did was when trying to save a client I've been just sending the UUID, now when the client is offline and trying to be saved, I also send the nbt data of the client as well as the username.

then on the receiving side, if the player is not found with the UUID, I call a proxy method to generate a "fake player" to take it's place.

Common Proxy:

	public EntityPlayer loadPlayer(NBTTagCompound teamnbt, String key, World world) {
		
		GameProfile profile = FMLCommonHandler.instance().getMinecraftServerInstance().getPlayerProfileCache().getProfileByUUID(UUID.fromString(teamnbt.getString(key)));
		EntityPlayerMP member = new EntityPlayerMP(FMLCommonHandler.instance().getMinecraftServerInstance(), (WorldServer) world, profile , new PlayerInteractionManager(world));
		FMLCommonHandler.instance().getMinecraftServerInstance().getPlayerList().setPlayerManager(new WorldServer[] {(WorldServer) world});
		member.deserializeNBT(FMLCommonHandler.instance().getMinecraftServerInstance().getPlayerList().getPlayerNBT(member));
		member.mountEntityAndWakeUp();
		
		return member;

	}

 

Client Proxy:

	@Override
	public EntityPlayer loadPlayer(NBTTagCompound teamnbt, String key, World world) {
		EntityPlayer member;
		if (world.isRemote) {
			GameProfile profile = new GameProfile(UUID.fromString(teamnbt.getString(key)), teamnbt.getString(key + "name"));
			TileEntitySkull.updateGameprofile(profile);
			member = new EntityOtherPlayerMP(world, profile);
			member.deserializeNBT(teamnbt.getCompoundTag(key + "data"));
			member.setEntityId(teamnbt.getInteger(key + "id"));
		}
		else {
			member = super.loadPlayer(teamnbt, key, world);
		}
		
		return member;
	}

 

Serializing:

	@Override
	public NBTTagCompound serialize() {
		
		requests.removeIf(request -> (request.getSender() == null || request.getReceiver() == null));
		teams.removeIf(team -> team.size() < 2);
		
		NBTTagCompound nbt = new NBTTagCompound();
		NBTTagCompound teamsnbt = new NBTTagCompound();
		NBTTagCompound requestsnbt = new NBTTagCompound();
		
		Integer i = 0;
		for (List<EntityPlayer> team : teams) {
			NBTTagCompound teamnbt = new NBTTagCompound();
			Integer j = 0;
			for (EntityPlayer player : team) {
				if (player != null) {
					teamnbt.setString(j.toString(), player.getCachedUniqueIdString());
					if (player instanceof EntityPlayerMP && ((EntityPlayerMP)player).hasDisconnected()) {
						teamnbt.setTag(j.toString() + "data", player.writeToNBT(new NBTTagCompound()));
						teamnbt.setInteger(j.toString() + "id", player.getEntityId());
						teamnbt.setString(j.toString() + "name", player.getName());
					}
					j++;
				}
			}
			teamnbt.setInteger("size", j);
			teamsnbt.setTag(i.toString(), teamnbt);
			i++;
		}
		
		i = 0;
		for (Request request : requests) {
			requestsnbt.setString(i.toString() + "sender", request.getSender().getCachedUniqueIdString());
			requestsnbt.setString(i.toString() + "receiver", request.getReceiver().getCachedUniqueIdString());
			i++;
		}
		
		nbt.setTag("teams", teamsnbt);
		nbt.setTag("requests", requestsnbt);
		nbt.setInteger("requestSize", i);
		
		System.out.println(nbt);
		
		return nbt;
		
	}

 

Deserializing:

	@Override
	public void deserialize(NBTTagCompound nbt) {
		
		teams.clear();
		requests.clear();
		
		NBTTagCompound teamsnbt = nbt.getCompoundTag("teams");
		NBTTagCompound requestsnbt = nbt.getCompoundTag("requests");
		
		for (String key : teamsnbt.getKeySet()) {
			
			NBTTagCompound teamnbt = teamsnbt.getCompoundTag(key);
			List<EntityPlayer> team = new ArrayList<>();
			int i2 = teamnbt.getInteger("size");
			for (Integer i = 0; i < i2; i++) {
				EntityPlayer member = this.world.getPlayerEntityByUUID(UUID.fromString(teamnbt.getString(i.toString())));
				if (member == null) {
					member = RWBYModels.proxy.loadPlayer(teamnbt, i.toString(), world);
				}
				team.add(member);
			}
			
			teams.add(team);
			
		}
		
		int i1 = nbt.getInteger("requestSize");
		
		for (Integer i = 0; i < i1; i++) {
			
			EntityPlayer sender = world.getPlayerEntityByUUID(UUID.fromString(requestsnbt.getString(i.toString() + "sender")));
			EntityPlayer receiver = world.getPlayerEntityByUUID(UUID.fromString(requestsnbt.getString(i.toString() + "receiver")));
			
			requests.add(new Request(sender, receiver));
			
		}
		
	}

 

  • Author

ummm, how do I edit the title of this topic?

 

Edited by Pi Man

  On 9/10/2019 at 12:02 AM, Pi Man said:

ummm, how do I edit the title of this topic?

 

Edit your original post.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

Important Information

By using this site, you agree to our Terms of Use.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.