我正在制作一个UHC插件,我需要在传送用户之前预先生成世界,所以我加载了所有的块。我发现这是无效的,因为当它们上面没有人时,这些块会卸载。我的一位朋友建议我用这个:
Map<Pair<Integer, Integer>, Object> map = CacheBuilder.newBuilder().expireAfterWrite(500, TimeUnit.MILLISECONDS).build(new CacheLoader<Key, Graph>() {
@Override
public Graph load(Key key) { // no checked exception
return createExpensiveGraph(key);
}
});
teleport(Location, Player) {
map.put(new Pair(location,getChunk.getX, location.getChunk.getZ));
location.getChunk().load;
Bukkit.getScheduler.runTaskLater(plugin, () -> player.teleport(location), 5L);
}
另外,我会有一个eventhandler处理chunk unload事件的时间是块在Mapping中。我的问题是我对这个谷歌API的经验几乎没有,我正在这里CacheBuilder,而且我并不完全确定我做错了什么。我意识到createExpensiveGraph是一种方法,但我不知道它是否应该在guava api中,或者我需要自己创建。我想知道是否有人可能有更好的方法来解决我预先创建世界的问题,或者帮助解释在创建新的chacheloader实例时我做错了什么。任何输入都会很棒,谢谢!
答案 0 :(得分:0)
你可以在不应该卸载它们之前(在播放器被传送到那里之前)将块保留在列表中并听取ChunkUnloadEvent
,如果它试图卸载其中一个块就取消它在列表中(当然,在传送播放器后再次从列表中删除块)。一个BukkitRunnable
加载所有的块,等待它们完成,然后传送播放器可能是一个很好的方法。
我假设您希望这主要用于尚未生成的块,因为将播放器传送到已生成的块但尚未加载到内存中但尚未加入因为加载生成的块通常需要少于一个滴答(客户端上看到的延迟只是因为渲染块/发送数据包),所以会造成太多麻烦。
在块完成生成基本地形(因此无法取消)之后,OnChunkLoad
事件被称为,幸运的是,isLoaded()
boolean
可以用作生成块中简单地形的指示符。
最后一件事:如果附近没有玩家,加载的块不会卸载至少几秒钟(虽然如果服务器有更多玩家/正在使用更多资源,我不肯定这种延迟会减少)所以延迟5个刻度的teleport允许生成新块的时间,我怀疑它们已经在这5个刻度已经过去之前就已经开始卸载了,特别是如果你只预加载一个块(事实上,当我测试它时,我的服务器永远不会卸载单个块,只有在我开始预加载多个块后才会在15-30秒后卸载它们,但在更大或不同的服务器上可能会有所不同)
我为此编写的代码用于测试我的想法,虽然希望这是足够的信息来帮助你(发布我的代码会使这个帖子太长),但如果你需要更具体的帮助,请告诉我有这个!