Files
90CNServer/server/internal/modules/dnf/dnfenum/aligned_test.go
T
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

210 lines
8.0 KiB
Go

// 本文件验证已对齐 DNF 协议号的模块化注册表。
package dnfenum
import "testing"
func TestLookupAlignedCommandDirectDomains(t *testing.T) {
tests := []struct {
name string
opcode CmdPacket
domain AlignedDomain
support AlignedSupport
}{
{name: "inventory delete", opcode: CmdPacketDeleteItem, domain: AlignedDomainInventory, support: AlignedSupportDirect},
{name: "inventory event level up", opcode: CmdPacketRequestEventServerLevelUp, domain: AlignedDomainInventory, support: AlignedSupportDirect},
{name: "inventory shared effect item", opcode: CmdPacketUseSharedEffectItem, domain: AlignedDomainInventory, support: AlignedSupportDirect},
{name: "inventory weapon forging", opcode: CmdPacketUpgradeItemSeparate, domain: AlignedDomainInventory, support: AlignedSupportDirect},
// 扩容券:现场 2026-10-03 客户端发了 op430/op408,服务端当时没有路由所以
// 一条回包都没发("使用后没效果")。
{name: "inventory container upgrade (bag voucher)", opcode: CmdPacketUpgradeInventory, domain: AlignedDomainInventory, support: AlignedSupportDirect},
{name: "inventory container upgrade (cargo voucher)", opcode: CmdPacketUpgradeCargo, domain: AlignedDomainInventory, support: AlignedSupportDirect},
{name: "pet rename", opcode: CmdPacketRenameCreature, domain: AlignedDomainPet, support: AlignedSupportDirect},
{name: "pet hatch egg", opcode: CmdPacketHatchCreatureEgg, domain: AlignedDomainPet, support: AlignedSupportDirect},
{name: "skill slot", opcode: CmdPacketChangeSkillslot, domain: AlignedDomainSkill, support: AlignedSupportDirect},
{name: "skill init", opcode: CmdPacketSkillInit, domain: AlignedDomainSkill, support: AlignedSupportDirect},
{name: "account cargo", opcode: CmdPacketCreateAccountCargo, domain: AlignedDomainCargo, support: AlignedSupportDirect},
{name: "mailbox open", opcode: CmdPacketMailboxOpen, domain: AlignedDomainMail, support: AlignedSupportDirect},
{name: "mailbox send", opcode: CmdPacketMailboxSend, domain: AlignedDomainMail, support: AlignedSupportDirect},
{name: "mailbox extract", opcode: CmdPacketMailboxExtractItem, domain: AlignedDomainMail, support: AlignedSupportDirect},
{name: "mailbox state", opcode: CmdPacketChangeLetterStat, domain: AlignedDomainMail, support: AlignedSupportDirect},
{name: "mailbox account roles", opcode: CmdPacketRequestServerCharacterList, domain: AlignedDomainMail, support: AlignedSupportDirect},
{name: "party set info", opcode: CmdPacketSetPartyInfo, domain: AlignedDomainParty, support: AlignedSupportDirect},
{name: "dungeon pick item", opcode: CmdPacketGetItem, domain: AlignedDomainDungeon, support: AlignedSupportDirect},
{name: "clone title animation", opcode: CmdPacketSetCloneTitle, domain: AlignedDomainAvatarTitle, support: AlignedSupportDirect},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, ok := LookupAlignedCommand(uint16(tt.opcode))
if !ok {
t.Fatalf("LookupAlignedCommand(%d) not found", tt.opcode)
}
if got.Domain != tt.domain || got.Support != tt.support {
t.Fatalf("LookupAlignedCommand(%d) = domain %q support %q, want domain %q support %q",
tt.opcode, got.Domain, got.Support, tt.domain, tt.support)
}
})
}
}
func TestConclusionACommandsAreDirect(t *testing.T) {
directA := []CmdPacket{
CmdPacketSelectCharacter,
CmdPacketCreateCharacter,
CmdPacketDeleteCharacter,
CmdPacketReturnSelectCharacter,
CmdPacketGetUserinfo,
CmdPacketCheckDoubleCharacterName,
CmdPacketSetPartyInfo,
CmdPacketLeaveParty,
CmdPacketCallPartyMemberRealtimeInfo,
CmdPacketDeleteItem,
CmdPacketMoveItemspace,
CmdPacketSortItem,
CmdPacketBuyItem,
CmdPacketSellItem,
CmdPacketRepairEquipment,
CmdPacketDisjointItem,
CmdPacketUseStackable,
CmdPacketRequestEventServerLevelUp,
CmdPacketUseSharedEffectItem,
CmdPacketUpgradeItem,
CmdPacketUpgradeItemSeparate,
CmdPacketEnchantByBead,
CmdPacketRenameCreature,
CmdPacketHatchCreature,
CmdPacketHatchCreatureEgg,
CmdPacketRequestHatchedCreature,
CmdPacketUseBoosterItem,
CmdPacketUseRandomboxItem,
CmdPacketCompoundAvatar,
CmdPacketUseEmblem,
CmdPacketAddAvatarSocket,
CmdPacketTitleBookPut,
CmdPacketTitleBookGet,
CmdPacketSetCloneTitle,
CmdPacketChangeSkillslot,
CmdPacketBuySkill,
CmdPacketSkillInit,
CmdPacketChangeAnotherSkillTree,
CmdPacketSkillCommandCustomizing,
CmdPacketSkillCommandAllDefault,
CmdPacketCreateAccountCargo,
CmdPacketUpgradeAccountCargo,
CmdPacketDepositMoney,
CmdPacketWithdrawMoney,
CmdPacketRequestItemLock,
CmdPacketRequestItemUnlock,
CmdPacketRequestItemUnlockCancel,
CmdPacketEnterSelectDungeon,
CmdPacketSelectDungeon,
CmdPacketGetItem,
CmdPacketMoveMap,
CmdPacketAcceptQuest,
CmdPacketGiveupQuest,
CmdPacketSetQuestTrigger,
CmdPacketFinishQuest,
CmdPacketMailboxSend,
CmdPacketMailboxExtractItem,
CmdPacketMailboxOpen,
CmdPacketChangeLetterStat,
CmdPacketMultiMailboxSend,
CmdPacketQueryCharacInfoMailbox,
CmdPacketRequestServerCharacterList,
}
for _, opcode := range directA {
got, ok := LookupAlignedCommand(uint16(opcode))
if !ok {
t.Fatalf("A command %d missing from aligned commands", opcode)
}
if got.Support != AlignedSupportDirect {
t.Fatalf("A command %d support = %q, want %q", opcode, got.Support, AlignedSupportDirect)
}
}
}
func TestPartyMCPPartialCommands(t *testing.T) {
partial := []CmdPacket{
CmdPacketRegisterQuickParty,
CmdPacketDirectEntranceDungeonQuickParty,
CmdPacketReserveLeaveParty,
CmdPacketChangePartyMemberPosition,
CmdPacketEntryIntoParty,
CmdPacketEntryIntoPartyFinish,
}
for _, opcode := range partial {
got, ok := LookupAlignedCommand(uint16(opcode))
if !ok {
t.Fatalf("party partial command %d missing from aligned commands", opcode)
}
if got.Domain != AlignedDomainParty || got.Support != AlignedSupportPartial {
t.Fatalf("party partial command %d = domain %q support %q", opcode, got.Domain, got.Support)
}
}
}
func TestRaidMCPPartialCommands(t *testing.T) {
partial := []CmdPacket{
CmdPacketCreateRaid,
CmdPacketLeaveRaid,
CmdPacketStartRaid,
CmdPacketSetRaidWaiting,
CmdPacketRejoinRaid,
CmdPacketRaidManagerWork,
CmdPacketModifyRaidInfo,
CmdPacketRaidOtherChannelRequestJoin,
CmdPacketRaidMemberChangeState,
CmdPacketRaidUserMoveChannelFail,
CmdPacketRaidOtherChannelList,
CmdPacketRaidCheckRaidUser,
}
for _, opcode := range partial {
got, ok := LookupAlignedCommand(uint16(opcode))
if !ok {
t.Fatalf("raid partial command %d missing from aligned commands", opcode)
}
if got.Domain != AlignedDomainRaid || got.Support != AlignedSupportPartial {
t.Fatalf("raid partial command %d = domain %q support %q", opcode, got.Domain, got.Support)
}
}
}
func TestLookupBlockedMigration(t *testing.T) {
if _, ok := LookupAlignedCommand(uint16(CmdPacketGetItembox)); ok {
t.Fatalf("519 must not be treated as a reusable package command")
}
blocked, ok := LookupBlockedMigration(uint16(CmdPacketGetItembox))
if !ok {
t.Fatalf("LookupBlockedMigration(519) not found")
}
if blocked.Domain != AlignedDomainPackage {
t.Fatalf("blocked 519 domain = %q, want %q", blocked.Domain, AlignedDomainPackage)
}
}
func TestCurrentEXEBlocksOldCharacterSkillInfoMapping(t *testing.T) {
if _, ok := LookupAlignedCommand(uint16(CmdPacketRequestCharacSkillInfo)); ok {
t.Fatalf("484 must not be treated as a current EXE skill command")
}
blocked, ok := LookupBlockedMigration(uint16(CmdPacketRequestCharacSkillInfo))
if !ok || blocked.Domain != AlignedDomainSkill {
t.Fatalf("blocked 484 = %+v, found=%t", blocked, ok)
}
}
func TestAlignedCommandsSortedCopy(t *testing.T) {
commands := AlignedCommands()
if len(commands) == 0 {
t.Fatalf("AlignedCommands is empty")
}
for i := 1; i < len(commands); i++ {
if commands[i-1].Opcode > commands[i].Opcode {
t.Fatalf("AlignedCommands not sorted at %d: %d > %d", i, commands[i-1].Opcode, commands[i].Opcode)
}
}
commands[0].Note = "changed by test"
again := AlignedCommands()
if again[0].Note == "changed by test" {
t.Fatalf("AlignedCommands returned mutable backing data")
}
}