2016-02-02 72 views
0

我正在製作一個UHC插件,我需要在傳送用戶之前預先生成世界,以便加載所有的塊。我發現這是無效的,因爲這些塊在沒有人時會卸載。我的一個朋友建議我用這個:傳送玩家之前爆炸世界的Bukkit API

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); 
    } 

而且別的地方我有一個事件處理程序處理該塊是在映射的時間塊卸載事件。我的問題是我對這個谷歌API很少或沒有經驗,我正在這裏修復CacheBuilder,我不完全確定我在做什麼錯。我意識到createExpensiveGraph是一種方法,但我不知道它應該在番石榴api內還是我需要做我自己的。我想知道是否有人可能有更好的方法來解決我的世界問題,或者在創建一個chacheloader的新實例時幫助解釋我做錯了什麼。任何輸入都會很棒,謝謝!

回答

0

在不應該卸載它的時間內(在玩家被傳送到那裏之前),您可以將這些塊保留在列表中,並且聽取ChunkUnloadEvent,如果它試圖卸載列表中的一個塊(並且在玩家被傳送後當然也會從列表中移除大塊)。一個加載所有塊的BukkitRunnable,等待它們完成,然後傳送玩家可能是一個很好的方法。

我假設你想要這個工作大多爲那些尚未生成塊,因爲一個瞬移玩家到產生了一大塊,但根本沒有加載到內存但應該不會造成太大因爲加載生成的塊通常花費不到一分鐘(客戶端上看到的延遲僅僅是因爲塊的呈現/數據包的發送)。

OnChunkLoad事件被稱爲後的塊完成生成所述基本地形(並因此不能被取消),其幸好意味着該isLoaded()boolean可以用作在一個組塊中的簡單地形已經產生的指示。最後一件事情:如果沒有玩家在附近,加載塊不會卸載至少幾秒鐘(儘管如果服務器擁有更多玩家/使用更多資源,這種延遲是否會減少),所以延遲傳送5個滴答聲允許時間產生新的塊,我懷疑他們已經開始卸載之前5滴答已經過去,特別是如果你只是預加載一個單一的塊(事實上,當我測試這個,我的服務器從來沒有卸載單塊,只有一次我開始預加載多個塊,他們卸載後15-30秒,但也許這是不同的一個更大的或不同的服務器上)

我有代碼爲此編寫,我用來測試我的想法,雖然希望這是足夠的信息h請你出去(張貼我的代碼會使這篇文章太長),但讓我知道你是否需要任何更具體的幫助!