i also do not care if "you probably shouldn't use craftbukkit non-reflectively" as i'd prefer not to waste my time writing an implementation that's actually useful. i'll depend on what i need to depend to get what i need. this is simply a cheat on top of a cheat, and is probably good insight on how you could achieve this.
Created
March 16, 2021 02:11
-
-
Save bfu4/f224f4736f11328a4c2304c38f09e0c3 to your computer and use it in GitHub Desktop.
force bukkit to render all maps by id on player join (fuck you)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.lang.reflect.Field; | |
import java.util.ArrayList; | |
import java.util.List; | |
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; | |
import org.bukkit.craftbukkit.v1_16_R3.map.CraftMapView; | |
import org.bukkit.craftbukkit.v1_16_R3.map.RenderData; | |
import org.bukkit.event.EventHandler; | |
import org.bukkit.event.Listener; | |
import org.bukkit.event.player.PlayerJoinEvent; | |
public class PlayerJoinListener implements Listener { | |
// CraftMapView#renderCache | |
private static Field craftBukkitRenderCache; | |
static { | |
try { | |
craftBukkitRenderCache = CraftMapView.class.getDeclaredField("renderCache"); | |
craftBukkitRenderCache.setAccessible(true); | |
} catch (NoSuchFieldException e) { | |
// do something | |
} | |
} | |
@EventHandler | |
public void onPlayerJoin(PlayerJoinEvent event) { | |
// We need CraftPlayer for this invocation | |
CraftPlayer player = (CraftPlayer) event.getPlayer(); | |
// Supply this, we're going to do this in a lambda | |
List<Integer> mapsYouWantToRender = getTheMapsYouWantToRender(); | |
// Lambda for iteration | |
mapsYouWantToRender.forEach(map -> { | |
// get a map by the current iterated map id. you store these somewhere, i'd hope | |
MapView view = Bukkit.getMap(map); | |
// don't do anything if it's null | |
if (view != null) { | |
// cast to get the mapview we need | |
CraftMapView craftMapView = (CraftMapView) view; | |
try { | |
// steal the cache | |
Map<CraftPlayer, RenderData> cache = (Map<CraftPlayer, RenderData>) field.get(craftMapView); | |
// check to see if the cache contains the player who just logged in | |
if (!cache.containsKey(player)) { | |
// no? lets render the mapview to the player | |
craftMapView.render(player); | |
// update the map (send it back) | |
player.sendMap(view); | |
} | |
} catch (IllegalAccessException e) { | |
// whatever | |
} | |
} | |
}); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.bukkit.map.MapRenderer; | |
import org.bukkit.map.MapCanvas; | |
import org.bukkit.map.MapView; | |
public class SomeRenderer extends MapRenderer { | |
public SomeRenderer() { | |
// The first trick of this is feeding "true" into the super call | |
// Since MapRenderer is really a CraftRenderer, this sets CraftRenderer#isContextual to true | |
// We need to trick the actual render implementation so that the player it caches is not null, | |
// so we need CraftRenderer#isContextual to return true. | |
super(true); | |
} | |
@Override | |
public void render(MapView mapView, MapCanvas mapCanvas, Player player) { | |
// Do something | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment