Files
hanfuit 645b64fe21 DNF90 服务端与启动器完整源码(含 GM 工具功能增强)
服务端(Go):
- GM 塞背包/带属性装备发放:在线角色推送 op14 增量物品行,背包实时刷新,无需回角色选择界面
- GM 改金币/改等级:去掉在线拒绝,落库后推送 op14 钱包/op37 等级状态,在线实时刷新
- 等级端点统一切换到新版 GMSetCharacterLevel(自带在线刷新)
- 无限/锁死疲劳模式 + 燃烧疲劳:每房间消耗 2 点、打怪与通关经验双倍
- 燃烧疲劳开关时给所有在线角色推送系统提示(op12 mode 0)
- 深渊史诗掉率:GM 全局倍率 + 城镇增益药剂窗口倍率,真实接入掉落结算

启动器(Python/JS):
- 标题栏自绘、窗口 1204x717、禁止拖拽改大小、仅最小化/关闭
- GM 工具:疲劳与燃烧、深渊史诗掉率、拍卖行上架(单一定价对齐)
- 拍卖行上架前端对齐服务端单一价格语义,修复 400 报错
2026-11-04 14:31:55 +08:00

77 lines
2.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package dnfbridge
import "longheng.io/server/internal/modules/dnf/raid"
func (s *Service) runtimeRaidFiendWarConfig() (*raid.FiendWarConfig, error) {
s.raidFiendWarMu.Lock()
defer s.raidFiendWarMu.Unlock()
if s.raidFiendWar != nil || s.raidFiendWarErr != nil {
return s.raidFiendWar, s.raidFiendWarErr
}
s.initialEquipmentMu.Lock()
archive, err := s.initialEquipmentArchiveLocked()
s.initialEquipmentMu.Unlock()
if err != nil {
s.raidFiendWarErr = err
return nil, err
}
s.raidFiendWar, s.raidFiendWarErr = raid.LoadFiendWarConfig(archive)
return s.raidFiendWar, s.raidFiendWarErr
}
func runtimeRaidMemberLimit(state runtimeRaidState) int {
if state.RaidMode == runtimeRaidOwnerFiendWar {
if state.FiendWarConfig == nil {
return 0
}
return state.FiendWarConfig.MemberMax
}
return raid.MaxAttackPartyMembers
}
// currentFiendWarSquadCount 是超时空的小队编制数。
//
// 操作员 2026-10-02 的定案:
//
// 「超时空总共有8个编制 跟其他攻坚战不一样的是 每个小队编制仅可放1人
// 最有力的证明是 小队编制界面 每个小队后面三格都是锁住的」
//
// 副本侧也对得上:罗什那两张地图的 `[player number]` 是 `2 8`(最少 2 人、最多 8 人)。
const currentFiendWarSquadCount = 8
// runtimeRaidGroupMaxFor 返回"这个团有几个小队编制"(客户端小队编制界面画几行)。
//
// 超时空是 **8**;安东/卢克沿用既有的 runtimeRaidMaxGroups(10,40 人格子)。
func runtimeRaidGroupMaxFor(state runtimeRaidState) byte {
if state.RaidMode == runtimeRaidOwnerFiendWar {
return currentFiendWarSquadCount
}
return runtimeRaidMaxGroups
}
// runtimeRaidGroupSizeFor 返回"一个小队编制能站几个人"。
//
// 超时空是 **1** —— 客户端的小队编制界面每队后面三格是锁住的,团长把 B 拖进
// 已经有 A 的队时,**A 被挤成单人(未编队)、B 占这个位置**,而不是整脚拒绝;
// 见 moveRuntimeRaidMember 里那条挤人分支。其余团仍然是 4 人一队。
//
// 这条尺子同时管着"普通队伍 → 小队编号"的自动同步
// (runtimeRaidSquadForOrdinaryPartyLedBy):超时空里两个人在镇上组了队,
// 他们会被分到**两个不同的编制**,而不是挤进同一队。
func runtimeRaidGroupSizeFor(state runtimeRaidState) int {
if state.RaidMode == runtimeRaidOwnerFiendWar {
return 1
}
return runtimeRaidGroupSize
}
// runtimeRaidGroupLimit 是这个团的小队编制数上限(按人数上限除以每队容量算)。
// 超时空每队 1 人 ⇒ 就是 8。
func runtimeRaidGroupLimit(state runtimeRaidState) byte {
size := runtimeRaidGroupSizeFor(state)
if size <= 0 {
return 0
}
return byte((runtimeRaidMemberLimit(state) + size - 1) / size)
}