Players other then the tool user do not always see changes
Peter200lx opened this issue ยท 6 comments
There is an issue where block updates are not being sent properly. This has been resolved for the wielder of the tool (pickhax, paint, chainsaw and more) by throwing a sendBlockChange() to the tool user. A more universal fix needs to be found, as this fix only helps the player in question, and not all the other players in the area.
Issue: When a player changes a blocks id/data at range, no-one other then the tool user sees the change.
(Living?)Entities have a function that will get nearby entities, so you could loop through them and send the block update to the people nearby the player.
Ah! That is a good catch.
.getNearbyEntities(x, y, z)
Parameters:
x - 1/2 the size of the box along x axis
y - 1/2 the size of the box along y axis
z - 1/2 the size of the box along z axis
The question now is how large we want the search box to be. This will require research into how far out a player can have a block loaded. I also need to find out how heavy this function is to make sure it is safe to run every time that a block is placed.
While this isn't the ideal solution of having everyone updated without manual assistance, this will provide a much better stop-gap measure.
You also could use target.getWorld().refreshChunk(target.getChunk().getX(), target.getChunk().getZ());
On another note to get the view distance (in chunks) is gc.server.getViewDistance();
searching through entities may or may not be (Depending how entities are managed on the server) faster then my fix.
Well, I've done research on this, and I can think of two different ways to perform the update of other users. Sadly the refreshChunk() function didn't seem to do any good.
This method performs best when there are no monsters or entities other then players in the world:
int horizon = (gc.server.getViewDistance() + 1) * 16;
List<Entity> inViewDist = subject.getNearbyEntities(horizon, horizon, horizon);
for(Entity other: inViewDist) {
if((other != null)&&(other instanceof Player)) {
((Player) other).sendBlockChange(loc, type, data);
}
}
This code does the nearby check itself, but doesn't muck about with all the other entity types.
int horizon = (gc.server.getViewDistance() + 1) * 16;
int horSqr = horizon * horizon;
Player[] online = gc.server.getOnlinePlayers();
for(Player other: online) {
if(loc.getWorld().equals(other.getWorld())) {
if(loc.distanceSquared(other.getLocation()) < horSqr) {
other.sendBlockChange(loc, type, data);
}
}
}
So far I've not found a great way to test both and compare, but I'm leaning to the server.getOnlinePlayers path. I've tested both code blocks and they both allow other players to see the updated changes. Please let me know if you have any suggestions on which path would scale better for more players, more entities, and other concerns I might not have thought of yet.
I did end up going with the second path (server.getOnlinePlayers). The number of online users seems like it should scale better then the localized entities. I've made a build of this commit, please let me know how many players you have tested it with at once, and if you had any issues.
http://dl.dropbox.com/u/71355/ToolBelt_4a73003.jar