SpongeAPI
SpongeAPI copied to clipboard
Manipulate blocks send to the client?
The idea is to manipulate the chunks/blocks send to the client. So that we can hide or fake certain types of blocks.
I am aware that we can send blocks to the player with the ´Viewer´ object. But if your trying to make something that prevents cheating (xray), It might be better to not send the blocks in the first place.
We should add a kind of ChunkTranformer that would edit the chunk data when the chunk is going to be sent to the client (without loading it ?)
Well it's possible, slightly buggy tho.
Yes but you're using mixin, it would be nice if the API would allow us to edit chunks when packets are generated. I've also seen you got a performance issue because you're loading a lot of unloaded chunks, to avoid loading them, the API should provide us a kind of raw data of the unloaded chunks being sent
Yeah, and so will Sponge 😉. Although the chunk issues are caused by the way I calculate the obfuscated blocks.
I think the neatest thing that should be in the API in some sort of "Player World" (this is about the same what my api in noxray does). So we could do the following for example:
//pseudocode
void onPlayerMove(event){
player.getNetworkWorld().setBlock(Blocks.Gold, player.getPosition().translate(0,-1,0);
player.getWorld().getGlobalNetworkWorld().setBlock(Blocks.Diamond, player.getPosition().translate(0,-1,0);
//update blocks after modification to limit network traffic (bulk update)
player.getGlobalNetworkWorld().update(p -> !p.getName().equals(player.getName()))
player.getNetWorkWorld().update()
}
Also with have the following events:
- NetworkBlockSendEvent: Sends a block to a certain location
- NetworkChunkSendEvent: Sends a chunk to the client/player
- NetworkWorldSendEvent: Sends a collection of chunks to player (on join/teleport/fast travel)
These events will basicly be fired upon sending and will also populate the NetworkWorld.
One problem with this is that this does increase the memory footprint a lot. Since you basically hold a copy of the "viewable" world for each player. It's also important that it's a copy, if you for example wanna spoof the chest content you don't wanna edit the chest in the world. To make sure we don't hurt other servers that don't wanna use this the api would have to need some sort of Enable function, that plugins can call upon using.
Another problem is that the events are being send from the players network thread. What means that you are somewhat limited in things you can call during that event. We also will need safeguards sending blocks during those events since that will cause a deadlock.
Nice work! It would be nice if a similar API could be added in SpongeAPI. It could be a ClientBlockVolume, a ClientEntityUniverse, and many others client side stuffs, also, it might be related or an alternative to Contexts and Contextual data #1046 However, is the copy of the viewable chunk a copy of the whole chunk or only the modified blocks ? Is it really necessary to keep this copy ?
Maybe it shouldn't be. But upon modifying this "NetworkWorld" it's important that the blocks in the world (world data) remain unchanged. Problem with have some sort of link with the core blocks to avoid copying, will modify them if you call the method. Unless sponge has some sort of immutable class that can pass for a block, I don't think this would be a good idea.
Try BlockState
s for the block storage, and EntitySnapshot
s and TileEntitySnapshot
s for the entities and tile entities.
I'm really interested in this so I could port NonEuclid from Spigot to Sponge. In NonEuclid, depending on a player's location, I want them to see one of two possible hallways (neither of which actually exist in the world). Using sendBlockChange() doesn't cut it because anything that causes the real block or chunk to be resent to the client causes the fake hallway to disappear. NonEuclid currently addresses this in Spigot by using ProtocolLib to modify block change packets and detect chunk packets. (I'm also interested in https://github.com/SpongePowered/SpongeAPI/pull/1046 so I can make it so a player who sees hallway A can't see a player inside it who sees hallway B.)
Is any of this idea affected by changes proposed in https://github.com/SpongePowered/SpongeAPI/pull/1046 or https://github.com/SpongePowered/SpongeAPI/issues/1614?
You might want to look at https://github.com/Yeregorix/Mirage I think it uses the same concept I explained here (since the plugin is based on my old NoXray plugin).
Pinging @Yeregorix.
Since the view will be different for each player I think the best solution is to mixin in PlayerChunkMapEntry
to listen for block changes or packet sending and to modify these packets. However it's not very simple, you can also wait for an API but you may wait a very long time.