1.12.2 Force all chunks visible to specific player to refresh (blocks sent by packets included)

Discussion in 'Spigot Plugin Development' started by CabbageRoll_, Nov 1, 2020.

  1. Is there any dedicated function that would unload then load all the chunks or i would have to go through all the chunks in range (defaults to 10)?
    And the other way around, how could i detect which chunks are loaded by the player and which are not for resending the "fake blocks" when the original ones load again automatically (due to player moving out and back in)?

    Context: specific players see a "layer of fake blocks" which others cannot. If they leave the group, blocks should go. When they join a group, blocks should appear. This happens currently but after exiting fake blocks will remain hanging around and when joining/moving in and out of range they won't reappear again.

    I have ideas about this being a separate empty world containing all the block changes then combining it (is it possible to override the normal chunk loading procedure?), just storing the edited blocks, i dont know the adequate solution.
    #1 CabbageRoll_, Nov 1, 2020
    Last edited: Nov 1, 2020
  2. There is no method inside the API that would allow you to just get a set of chunks that are currently "seen" by the player.
    There is likely multiple reasons for that:
    The first being that chunk sending and re-sending happens mostly on the players client in the way that it is actually not the server who sends the chunks, but the player who requests them and the servers responding to those requests.
    The second reason is, that all of this mostly happens on the "network layer" of the server and as far as I know together with chunk loading and unloading happens on a different thread all together (EDIT: I can only confirm this for Paper spigot which is not supported here), which means that at any given time you would use a method that gets all chunks currently loaded by the player, this information could potentially be wrong due to the fact that those threads are not synchronized.
    The third reason (probably) is, that every client can have different settings for their view distance which doesn't directly affect the server, but instead how many chunks the client requests from the server.

    If you really need a way to "easily" tell, what chunks are loaded by the client, the only way I can see working with the API right away is the Player.getClientViewDistance() method provided.
    You could then make your own estimate of what chunks are loaded by the player, but as mentioned earlier this information would not be guaranteed to be correct due to chunk loading being asynchronous.
    If you want it to be 100% correct, you would also need to take chunk loading / unloading into consideration and keep track of all these informations about every player at any given point in time.

    Also your idea of creating a seperate empty world for you block changes is a very bad idea. Creating, (un)loading and changing worlds are very expensive operations for the server.
    Consider just putting all the changes into a seperate data structure and create one per player. Could be something like a Map<Player, Set/List<BlockState>> or if you only have one block type even just <Map<Player, Set/List<Location/Vector>> or similiar to represent it.
    #2 Noxyro, Nov 1, 2020
    Last edited: Nov 1, 2020