Skip to content

逃走币系统

文档版本:基于 2026-06-01 代码分析

概述

逃走币系统采用双轨制设计:回合币(Round Coin)在单局游戏中实时产出,总币(Total Coin)跨局永久累积。通过 RfmCoinStorageService 代理层管理本地 NBT 存储和可选的 PostgreSQL 云存储,每局结束时执行结算将回合币转换为总币。


核心概念

双轨制

属性回合币(Round Coin)总币(Total Coin)
存储PersistentRfmHunterRoundSavedDataPersistentRfmPlayerCoinsSavedData
存活周期每局重置跨局累积
产出机制tick 中按 rate_per_second 自动发放回合结算时通过 addCoinsByMap 累加
手动指令/nfa rfm coin clear(仅清零回合币)/nfa rfm coin add|sub|set|clear_total

产出率档位

rate_per_second 配置项经过规范化,只允许 4 个离散档位:

输入值实际生效
<= 5050
<= 100100(默认)
<= 200200
> 200500

架构设计

逃走币流向图

mermaid
flowchart LR
    subgraph InGame["局内产出"]
        Tick["每 tick"] -->|rate_per_second| Round["回合币<br/>PersistentRfmHunterRoundSavedData"]
    end

    subgraph Settlement["回合结算"]
        Round -->|"settleRoundAndBroadcast()"| Adjust["结对调整<br/>RfmPairingManager"]
        Adjust -->|"addCoinsByMap()"| Total["总币<br/>PersistentRfmPlayerCoinsSavedData"]
        Adjust -->|"appendRoundSettlement()"| CSV["CSV结算备份"]
    end

    subgraph Cloud["云存储(可选)"]
        Total -->|"writeOne()双写"| PG[("PostgreSQL<br/>mc_rfm_coin.rfm_player_coin")]
        PG -->|"每10分钟自动"| Total
        PG -->|"sync down指令"| Total
    end

    subgraph Display["显示"]
        Total -->|"syncToTabList"| SB["计分板<br/>nfa_rfm_coin"]
    end

云存储同步模式

mermaid
flowchart TD
    A[coin.storage.enabled] -->|true| B[Cloud Mode]
    A -->|false| C[Local Mode]

    B --> D["每次 writeOne() 双写<br/>本地NBT + PostgreSQL"]
    B --> E["每10分钟 tick 自动<br/>syncLocalToCloud()"]
    B --> F["指令手动<br/>sync up / down / now"]

    D --> G{SQL 异常?}
    G -->|是| H[自动回退 Local Mode<br/>通知在线管理员]
    G -->|否| I[继续 Cloud Mode]

关键文件

文件说明
com/chenxi/chenxi_rfm/server/rfm/RfmCoinStorageService.java逃走币存储代理(本地+云端)
com/chenxi/chenxi_rfm/server/rfm/RfmCoinPostgresService.javaPostgreSQL 数据库操作
com/chenxi/chenxi_rfm/server/rfm/RfmCoinCryptoService.javaAES-256/GCM 凭证加密
com/chenxi/chenxi_rfm/server/rfm/RfmCoinFileSyncService.javaCSV 结算文件追加
com/chenxi/chenxi_rfm/server/rfm/RfmCoinScoreboardService.java计分板同步
com/chenxi/chenxi_rfm/server/config/rfm/PersistentRfmPlayerCoinsSavedData.java总币 NBT 存储
com/chenxi/chenxi_rfm/server/config/rfm/PersistentRfmHunterRoundSavedData.java回合币 NBT 存储
com/chenxi/chenxi_rfm/server/config/rfm/RfmServerConfigStore.java服务端配置(rate、db参数)
com/chenxi/chenxi_rfm/server/rfm/RfmHunterSystemManager.javatick 产出调度 + 结算流程

关键流程

tick 产出机制

每 tick 调用链:

ServerTickEvent.Post
  → RfmGameSessionManager.tick()
    → RfmHunterSystemManager.tickRunning()
      → awardRoundCoinsByTime(server, elapsedSeconds, nowMillis)
        → 计算距上次发币的毫秒差
        → 如果 passed >= 1000ms:
            steps = passed / 1000L
            for i in 1..steps:
              awardRoundCoins(server)  // 每秒发放一次

awardRoundCoins 内部逻辑:

  1. 获取当前 ratePerSecond
  2. 遍历所有存活的参与者逃走者
  3. 跳过叛节者(traitor 不产生回合币)
  4. 跳过逃走币锁定状态(coinLocked 玩家)
  5. 对符合条件的逃走者:roundData.addRoundCoins(uuid, rate)

产出只在 NORMAL 阶段进行。PAUSED 和 COUNTDOWN_FROZEN 阶段不产币。

结算流程

游戏结束时 settleRoundAndBroadcast()

  1. 获取所有参与者 UUID
  2. 读取每人的回合币 rawRoundCoins
  3. 若有 eliminatedReward(淘汰补偿=roundCoins/10,弃权补偿=roundCoins/2),使用补偿值替代
  4. RfmPairingManager.applySettlementAdjustments() — COIN 模式取高,LIFE 模式相加
  5. RfmCoinStorageService.addCoinsByMap() — 写入总币
  6. RfmCoinFileSyncService.appendRoundSettlement() — 追加 CSV
  7. 全服广播结算排名

PostgreSQL 云存储

加密凭证

  • 密钥种子 = 服务器目录绝对路径
  • 加密算法 = AES-256/GCM,IV 随机 12 字节
  • 存储时加密,读取时解密

数据库表mc_rfm_coin.rfm_player_coin

  • online_uuidoffline_uuidplayer_namecoin_totalupdated_at
  • 唯一索引:online_uuid(非空时)、offline_uuid(非空时)

数据持久化

PersistentRfmPlayerCoinsSavedData

文件:<world>/data/nfa_rfm/rfm_player_coins.dat

Map<UUID, Integer> totalCoins

计分板

  • 目标名:nfa_rfm_coin,显示名"逃走币"
  • 显示槽位:DisplaySlot.LIST(TAB 列表)
  • 每次总币变更后自动同步

指令

指令权限说明
/nfa rfm coin add <targets> <amount>MASTER_OR_CB增加指定玩家的总币
/nfa rfm coin sub <targets> <amount>MASTER_OR_CB扣除指定玩家的总币
/nfa rfm coin set <targets> <amount>MASTER_OR_CB设置指定玩家的总币值
/nfa rfm coin clear <targets>MASTER_OR_CB清零指定玩家的回合币(仅回合币)
/nfa rfm coin clear_total <targets>MASTER_OR_CB清零指定玩家的总币
/nfa rfm coin sync upMASTER_OR_CB手动上传本地数据到云存储
/nfa rfm coin sync downMASTER_OR_CB手动从云存储下载数据覆盖本地
/nfa rfm coin sync nowMASTER_OR_CB立即同步云存储

注意事项 / 限制

  1. 产出仅对存活非叛节逃走者:叛节者不产币,被淘汰和弃权者不产币。
  2. 暂停时先结算pauseGame() 会先调用 onGamePaused() 结算已产生的逃走币,再冻结产出。
  3. SQL 异常自动回退:云存储写入失败时自动切回本地模式,并向在线管理员发送红色警告。
  4. 离散档位:逃走币产出率只有 4 个档位,输入非标准值会被自动规范化为最近的档位。
  5. 淘汰补偿:正常淘汰时锁定 roundCoins / 10 作为补偿;弃权时锁定 roundCoins / 2

相关文档