PaperMC / Paper

The most widely used, high performance Minecraft server that aims to fix gameplay and mechanics inconsistencies
https://papermc.io/
Other
10.06k stars 2.34k forks source link

Expose canvases / RenderData in CraftMapView #10063

Closed EvertBt closed 7 months ago

EvertBt commented 11 months ago

Is your feature request related to a problem?

I want to be able to copy all pixels of a map for each layer/MapRenderer to be able to store it. I would like this feature so that players can view world maps across multiple servers by storing the layers in a db.

Describe the solution you'd like.

Perhaps a method like: Map<Player, MapCanvas> getCanvases(MapRenderer renderer); To retrieve the player to canvas map that is stored in CraftMapView. Could simply be implemented by using return new HashMap<>(CraftMapView#canvases.get(renderer));

I am not entirely sure of how RenderData works, but if this is cached data of the entire map compressed to one layer it would be super useful to have as well, to prevent having to save multiple layers separately.

Describe alternatives you've considered.

There is no API way to do this at the moment. You can use internals to retrieve the canvas.

There is the possibility for implementing your own MapCanvas, call render using that canvas and then retrieve the pixels, but this is flawed for custom renderers where for example a custom image is only made to render once. + this is just a really hacky way

Other

some people mentioned that exposing CraftWorldMap#getHandle#colors may be useful as well, "to be able to access the vanilla data"

Cryptite commented 11 months ago

This may not help in your particular case but the way we handled this on Loka was a fork of Paper where we could relocate the common data storage folder in order to use a singular directory that all of our survival servers referenced for mapmaking.

https://github.com/Cryptite/Slice/blob/master/patches/server/0030-Shared-Data-Storage.patch

With symlinking this may be helpful too but I can also see the desire for being able to use a db for this.

EvertBt commented 11 months ago

It's a really cool idea to have a shared directory for this! A simple api method would probably be easiest for most people though, as i really would like to store the bytes in a db for other uses.

EvertBt commented 11 months ago

After some further testing using reflection, it appears that CraftMapView#canvases and CraftMapView#renderCache is empty for world maps, so i will assume that these fields are used for "virtual" maps? CraftMapView#worldMap.colors does contain data, assuming that this is the original map pixel data.

If this is correct (please correct me) i propose 3 new methods: