Jump to content

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


Recommended Posts

Posted (edited)

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
Posted
  On 9/5/2019 at 12:40 AM, Pi Man said:

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

Expand  

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)?

Expand  

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.

Posted

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));
			
		}
		
	}

 

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...

×   Pasted as rich text.   Restore formatting

  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.

Announcements



×
×
  • Create New...

Important Information

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