Jump to content

Recommended Posts

Posted

I have an item (basically totem), that will teleport player to its spawnpoint after fell in void. I use PlayerList#respawn method to teleport player back, but it throws NullPointerException. The code is below:

private void activateTotem(World world, ServerPlayerEntity player, ItemStack itemStack)
{
	player.fallDistance=0F;
	ItemStack totem=itemStack.copy();
	Minecraft minecraft=Minecraft.getInstance();
	if(world.dimension()==World.END) player.moveTo(100.5F, 49F, 0.5F);
	else player=world.getServer().getPlayerList().respawn(player, false);
	if(minecraft.gameMode.getPlayerMode().isSurvival()) itemStack.shrink(1);
	DistExecutor.unsafeRunWhenOn(Dist.CLIENT, ()->()->minecraft.gameRenderer.displayItemActivation(totem));
	minecraft.particleEngine.createTrackingEmitter(player, ParticleTypes.PORTAL, 40);
	world.playSound((PlayerEntity)null, player.blockPosition(), SoundEvents.TOTEM_USE, SoundCategory.PLAYERS, 2F, 1F);
	player.playSound(SoundEvents.TOTEM_USE, 2F, 1F);
}

Is there any errors or am i just do something wrong?

Posted (edited)

 

2 minutes ago, diesieben07 said:

This code will hard-crash on servers, the Minecraft class does not exist there.

Show the stacktrace of the exception.

 

[17:29:37] [Server thread/ERROR] [minecraft/MinecraftServer]: Encountered an unexpected exception
net.minecraft.crash.ReportedException: Ticking player
	at net.minecraft.network.NetworkSystem.tick(NetworkSystem.java:137) ~[forge:?] {re:classloading}
	at net.minecraft.server.MinecraftServer.tickChildren(MinecraftServer.java:865) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.tickServer(MinecraftServer.java:787) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.integrated.IntegratedServer.tickServer(IntegratedServer.java:78) ~[forge:?] {re:classloading,pl:runtimedistcleaner:A}
	at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:642) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:232) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_291] {}
Caused by: java.lang.NullPointerException
	at net.minecraft.world.server.TicketManager.removePlayer(TicketManager.java:227) ~[forge:?] {re:classloading}
	at net.minecraft.world.server.ChunkManager.updatePlayerStatus(ChunkManager.java:843) ~[forge:?] {re:classloading}
	at net.minecraft.world.server.ChunkManager.removeEntity(ChunkManager.java:982) ~[forge:?] {re:classloading}
	at net.minecraft.world.server.ServerChunkProvider.removeEntity(ServerChunkProvider.java:454) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.world.server.ServerWorld.removeEntityComplete(ServerWorld.java:905) ~[forge:?] {re:classloading}
	at net.minecraft.world.server.ServerWorld.removeEntity(ServerWorld.java:951) ~[forge:?] {re:classloading}
	at net.minecraft.world.server.ServerWorld.removePlayer(ServerWorld.java:968) ~[forge:?] {re:classloading}
	at net.minecraft.server.management.PlayerList.respawn(PlayerList.java:411) ~[forge:?] {re:classloading}
	at com.mclich.engmod.item.TotemOfAbyssItem.activateTotem(TotemOfAbyssItem.java:72) ~[?:?] {re:classloading}
	at com.mclich.engmod.item.TotemOfAbyssItem.inventoryTick(TotemOfAbyssItem.java:58) ~[?:?] {re:classloading}
	at net.minecraft.item.ItemStack.inventoryTick(ItemStack.java:434) ~[forge:?] {re:classloading,xf:fml:forge:filled_map.4,xf:fml:forge:itemstack}
	at net.minecraft.entity.player.PlayerInventory.tick(PlayerInventory.java:238) ~[forge:?] {re:classloading}
	at net.minecraft.entity.player.PlayerEntity.aiStep(PlayerEntity.java:487) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.entity.LivingEntity.tick(LivingEntity.java:2158) ~[forge:?] {re:classloading}
	at net.minecraft.entity.player.PlayerEntity.tick(PlayerEntity.java:223) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.entity.player.ServerPlayerEntity.doTick(ServerPlayerEntity.java:404) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.network.play.ServerPlayNetHandler.tick(ServerPlayNetHandler.java:207) ~[forge:?] {re:classloading}
	at net.minecraft.network.NetworkManager.tick(NetworkManager.java:226) ~[forge:?] {re:classloading}
	at net.minecraft.network.NetworkSystem.tick(NetworkSystem.java:134) ~[forge:?] {re:classloading}
	... 6 more
Edited by mclich
Posted (edited)
5 minutes ago, diesieben07 said:

Honestly I have no idea.

So as i understand the exception occurs when game tries to delete player from the chunk, but can not find it there:

public void removePlayer(SectionPos p_219367_1_, ServerPlayerEntity p_219367_2_) {
      long i = p_219367_1_.chunk().toLong();
      ObjectSet<ServerPlayerEntity> objectset = this.playersPerChunk.get(i);
      objectset.remove(p_219367_2_);
      if (objectset.isEmpty()) {
         this.playersPerChunk.remove(i);
         this.naturalSpawnChunkCounter.update(i, Integer.MAX_VALUE, false);
         this.playerTicketManager.update(i, Integer.MAX_VALUE, false);
      }

   }

 objectset.remove(p_219367_2_) that line actually throws NullPointerException, am i right?

Edited by mclich
Posted (edited)
On 10/17/2021 at 6:15 PM, diesieben07 said:

Yes.

Can you post a Git repo of your mod so I can debug this locally?

Sorry for not responding for a while. Here is my repo: https://github.com/mclich/ElderNorseGods.git
A little update: the strange thing is that even an exception occurs, player will be teleported to spawn point anyway, but after that player just cannot move, break blocks or do any other action. Main camera still moves, but it looks like it "stuck" inside players head

Edited by mclich
Posted
20 minutes ago, diesieben07 said:

I am not sure how to best do this.

do the same thing as vanilla in DeathScreen...?
i'm not sure if this would work, but the normal respawn logic is fired when you click the Respawn-Button in the DeathScreen
which is LocalPlayer#respawn, it will send a ServerboundClientCommandPacket with the respawn Action to the Server,
the handle methode on Server use the same code your are running (PlayerList#respawn), but with the missing data (position and look)

Posted
35 minutes ago, Luis_ST said:

do the same thing as vanilla in DeathScreen...?
i'm not sure if this would work, but the normal respawn logic is fired when you click the Respawn-Button in the DeathScreen
which is LocalPlayer#respawn, it will send a ServerboundClientCommandPacket with the respawn Action to the Server,
the handle methode on Server use the same code your are running (PlayerList#respawn), but with the missing data (position and look)

I also tried it. Instead of 

world.getServer().getPlayerList().respawn(player, false)

i tried 

DistExecutor.unsafeRunWhenOn(Dist.CLIENT, ()->()->Minecraft.getInstance().player.respawn())

but it actually did nothing

Posted
3 minutes ago, diesieben07 said:

This is not what runWhenOn does! You are still on the server thread here, you must check that you are on the logical client side using World#isClientSide. Then you can use DistExecutor.

Oh, i thought DistExecutor.runWhenOn can be called not depending on logical side. Thanks for information, i'll try fix it

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.