DNF90 服务端与启动器完整源码(含 GM 工具功能增强)
服务端(Go): - GM 塞背包/带属性装备发放:在线角色推送 op14 增量物品行,背包实时刷新,无需回角色选择界面 - GM 改金币/改等级:去掉在线拒绝,落库后推送 op14 钱包/op37 等级状态,在线实时刷新 - 等级端点统一切换到新版 GMSetCharacterLevel(自带在线刷新) - 无限/锁死疲劳模式 + 燃烧疲劳:每房间消耗 2 点、打怪与通关经验双倍 - 燃烧疲劳开关时给所有在线角色推送系统提示(op12 mode 0) - 深渊史诗掉率:GM 全局倍率 + 城镇增益药剂窗口倍率,真实接入掉落结算 启动器(Python/JS): - 标题栏自绘、窗口 1204x717、禁止拖拽改大小、仅最小化/关闭 - GM 工具:疲劳与燃烧、深渊史诗掉率、拍卖行上架(单一定价对齐) - 拍卖行上架前端对齐服务端单一价格语义,修复 400 报错
This commit is contained in:
commit
645b64fe21
4388 files changed
+1405457
No files matched your search
@@ -0,0 +1,115 @@
|
||||
package dnfbridge
|
||||
|
||||
// ============================================================================
|
||||
// 神秘异次元遗迹「双组计数下发」—— 已定位通道,但本树格式对不上,未实施
|
||||
//
|
||||
// 【本树真正的"计数器表"通道】dungeon_tower_settlement.go:
|
||||
//
|
||||
// currentAdventureTowerCountsMsgID = 1294 // 计数器表(class-0 通知)
|
||||
// currentTowerCharacterEntryMsgID = 546 // 角色侧条目
|
||||
//
|
||||
// op1294 的 body 恰好 4 个 u8,由 writeCurrentAdventureTowerCounters 写出:
|
||||
//
|
||||
// TowerRemaining[绝望], TowerLimits[绝望], TowerRemaining[悲叹], TowerLimits[悲叹]
|
||||
//
|
||||
// op546 的 body 是 `u32 道具ID + u8 剩余`(11008 绝望塔 / 5115 悲叹塔),
|
||||
// 每次发两条。op1294 重建 tooltip 时会清掉不在表里的行 —— 这正是报告里
|
||||
// "原塔类行一并保留,避免替换整张计数表时清除原值"所指的那张表。
|
||||
//
|
||||
// 目前 op1294 只在**塔类通关**时发送(dungeon_settlement_result_send.go:139
|
||||
// 的 `plan.TowerRewardMsgID != 0` 分支),所以进入 107/0 时客户端从未收到过
|
||||
// 任何计数表。
|
||||
//
|
||||
// 【为什么没有实施】三处与报告不一致,凭猜下发会写坏客户端 UI 状态:
|
||||
//
|
||||
// 1. 报告说「按当前 EXE 的 op1331 读取器」发送;但本树
|
||||
// dnfenum.CmdPacketAtPriest2Awakening = 1331,且**全代码库没有任何发送
|
||||
// op1331 的代码**,客户端抓包也从未发出过 1331。
|
||||
// 2. 报告要下发的是"账号总用量 + 各角色各图用量"两组;而 op1294 的 4 字节
|
||||
// 结构放的是"塔类剩余/上限 × 2 座塔",**结构上装不下**另一组。
|
||||
// 3. op16(选图请求,dungeoncmd.SelectDungeonRequest)字段已全部核对:
|
||||
// DungeonID/Difficulty/EntryOption/SelectionMode/RuntimeState/RuntimeToken/
|
||||
// Reserved/PartyState/LeaderObjectKey/SpecialMode,**没有次数字段** ——
|
||||
// 说明次数只能是服务端单向下发,客户端不回报。
|
||||
//
|
||||
// 【下一步需要的证据】只要用户确认"进 107/0 停在选图页时界面上是否显示剩余
|
||||
// 次数",就能判定:不显示 => 该客户端不需要这项,服务端计数已经生效(超额入场
|
||||
// 会被 Preflight/Commit 拒绝);显示 => 确为 op1294 那张表,再按"追加两组字节"
|
||||
// 试发并用明文探针观测界面变化。在拿到这个观察前不写猜测格式。
|
||||
// ============================================================================
|
||||
|
||||
// ============================================================================
|
||||
// 神秘异次元遗迹「保底奖励」—— 已查清:现有独立掉落机制已经覆盖,无需改动
|
||||
//
|
||||
// 五件奖励道具(PVF 实测,均在库):
|
||||
//
|
||||
// 490006024 闪耀的次元精华 stackable/490006001/chn_490006024.stk
|
||||
// 490004769 绿色次元精华 stackable/490004001/chn_490004769.stk
|
||||
// 490004770 红色次元精华 stackable/490004001/chn_490004770.stk
|
||||
// 490004771 黄色次元精华 stackable/490004001/chn_490004771.stk
|
||||
// 490004772 蓝色次元精华 stackable/490004001/chn_490004772.stk
|
||||
//
|
||||
// 【来源】etc/independent_drop.etc(服务端常量 currentDungeonIndependentDropPath
|
||||
// = "Etc/Independent_Drop.etc",大小写不敏感)。该表的记录格式已由
|
||||
// parseCurrentDungeonIndependentDrops 解析为 17 个字段:
|
||||
//
|
||||
// values[0] 记录类型(0=怪物, 1=APC)
|
||||
// values[1] 对象代码(怪物号)
|
||||
// values[2] 道具 ID
|
||||
// values[3..7] 五档难度的概率
|
||||
// values[8..12] 五档难度的判定次数
|
||||
// values[13..15] 等级下限/上限/难度过滤
|
||||
// values[16] list 标志
|
||||
//
|
||||
// 表里与本活动相关的条目(概率 1000000,恰好等于
|
||||
// currentDungeonIndependentDropDenominator):
|
||||
//
|
||||
// 62040 490004769 概率 1000000×5 次数 1×5
|
||||
// 110889 490004769 概率 1000000×5 次数 2×5
|
||||
// 110890 490004769 概率 1000000×5 次数 1×5
|
||||
// 110891 490004769 概率 1000000×5 次数 1×5
|
||||
// 110880 490006024 概率 1000000×5 次数 1×5
|
||||
// 110881 490006024 概率 1000000×5 次数 1×5
|
||||
// 110920 490004770 概率 1000000×5 次数 4×5
|
||||
// 110921 490004770 概率 1000000×5 次数 8×5
|
||||
// 110925 490004771 概率 1000000×5 次数 10×5
|
||||
// 110926 490004771 概率 1000000×5 次数 10×5
|
||||
// 110927 490004771 概率 1000000×5 次数 40×5
|
||||
// 110936 490004772 概率 1000000×5 次数 3×5 ← 现场实测属于副本 4910
|
||||
// 110938 490004772 概率 1000000×5 次数 6×5
|
||||
//
|
||||
// 【为什么这就是"保底"而无需改代码】rollCurrentDungeonIndependentDropEntries
|
||||
// 对 type 0 的判定是:
|
||||
//
|
||||
// probability := currentDungeonIndependentDropProbability(Probability[difficulty], bonusPercent)
|
||||
// for attempt := 0; attempt < attempts; attempt++ {
|
||||
// if probability <= rng.Next(currentDungeonIndependentDropDenominator) { continue }
|
||||
// result = append(result, entry.ItemID)
|
||||
// }
|
||||
//
|
||||
// rng.Next(1000000) 取值区间是 [0,999999],所以 probability == 1000000 时
|
||||
// `probability <= rng.Next(...)` **恒为假**,每次判定都命中 —— 即 attempts 次
|
||||
// 全部掉落。这些条目因此每次击杀都稳定产出固定数量,正是"保底奖励"。
|
||||
//
|
||||
// 现场佐证:探针曾记录 MOBLEVEL dungeon=4910 ... code=110936 ——
|
||||
// 110936 正是掉落 490004772(蓝色次元精华)的那只怪,且它确实出现在 4910。
|
||||
//
|
||||
// 结论:**不需要为保底奖励新增任何服务端发放逻辑**(可继续遵守报告要求的
|
||||
// "不新增自定义掉率或奖励")。此前"五图 dgn 无 reward/drop 段"的观察是对的,
|
||||
// 但精华并不写在 dgn 里,而写在独立掉落表里 —— 这一点已在本次纠正。
|
||||
// ============================================================================
|
||||
|
||||
// currentAbisGuaranteeRewardItemIDs 是五件保底奖励道具的 PVF 身份,以及它们在
|
||||
// etc/independent_drop.etc 中对应的怪物掉落者。仅供核对,不参与任何发放路径
|
||||
// (发放由既有的独立掉落链路完成)。
|
||||
var currentAbisGuaranteeRewardItemIDs = [...]struct {
|
||||
ItemID uint32
|
||||
Name string
|
||||
MonsterID int64
|
||||
}{
|
||||
{490006024, "闪耀的次元精华", 110880},
|
||||
{490004769, "绿色次元精华", 110889},
|
||||
{490004770, "红色次元精华", 110920},
|
||||
{490004771, "黄色次元精华", 110925},
|
||||
{490004772, "蓝色次元精华", 110936},
|
||||
}
|
||||
Reference in new issue
Block a user