Class GashaponFactory

java.lang.Object
server.gashapon.GashaponFactory

public final class GashaponFactory extends Object
轉蛋機總管(單例),以 npcId 為鍵持有所有 Gashapon 機台,供 NPC 腳本查詢抽獎。

啟動時(或 !reloadgashpon)自資料表 gashapons 讀入全部機台,每台再自行載入其 gashapon_items 獎勵。對外查詢入口為 getGashaponByNpcId(int),由 scripting.NPCConversationManager#getGashapon() 以當前對話 NPC 的編號呼叫。

並發策略:以 ReentrantReadWriteLock 保護機台對照表 gashaponNpc。重載時的資料庫 I/O 在不持有寫鎖的情況下進行(先讀進暫存 Map),僅在最後「換上新對照表」的瞬間取得寫鎖, 縮短鎖持有時間並避免持鎖做 I/O。讀取失敗只記錄錯誤、保留原有快取。

  • Method Details

    • getInstance

      public static GashaponFactory getInstance()
      取得單例。採雙重檢查鎖定;首次建立時記錄載入訊息、建構並執行一次全量重載, 最後才把建立完成的實例指派給 instance(確保其他執行緒看不到尚未載入完成的半成品)。
      Returns:
      轉蛋機總管單例
    • reloadGashapons

      public void reloadGashapons()
      全量重載所有轉蛋機。

      先在不持寫鎖下自 gashapons 讀出每一列並 new Gashapon(...)(各機台建構子自行查 其獎勵)放進以 npcId 為鍵的暫存 Map;接著在寫鎖內以 clear()+putAll() 一次換掉對照表。 讀取失敗只記錄錯誤、保留原有快取。

    • reloadGashapons

      public void reloadGashapons(int npcId)
      只重載單一機台(以 npcId 鍵入),避免全量重載時的全清。

      在不持寫鎖下查 gashapons WHERE npcId = ?:若有列則於寫鎖內 put 新建的機台; 若無列則於寫鎖內 remove 該鍵(代表該機台已從資料庫移除)。讀取失敗只記錄錯誤、保留原有快取。

      Parameters:
      npcId - 要重載的機台 NPC 編號
    • getGashaponByNpcId

      public Gashapon getGashaponByNpcId(int npcId)
      依 NPC 編號取得對應的轉蛋機。
      Parameters:
      npcId - NPC 編號
      Returns:
      對應的轉蛋機,或在無對應機台時回傳 null
    • getGashaponNpcList

      public Map<Integer,String> getGashaponNpcList()
      取得所有機台的「idname」對照(快照),供後台清單顯示。
      Returns:
      機台主鍵對名稱的對照表