服务端(Go): - GM 塞背包/带属性装备发放:在线角色推送 op14 增量物品行,背包实时刷新,无需回角色选择界面 - GM 改金币/改等级:去掉在线拒绝,落库后推送 op14 钱包/op37 等级状态,在线实时刷新 - 等级端点统一切换到新版 GMSetCharacterLevel(自带在线刷新) - 无限/锁死疲劳模式 + 燃烧疲劳:每房间消耗 2 点、打怪与通关经验双倍 - 燃烧疲劳开关时给所有在线角色推送系统提示(op12 mode 0) - 深渊史诗掉率:GM 全局倍率 + 城镇增益药剂窗口倍率,真实接入掉落结算 启动器(Python/JS): - 标题栏自绘、窗口 1204x717、禁止拖拽改大小、仅最小化/关闭 - GM 工具:疲劳与燃烧、深渊史诗掉率、拍卖行上架(单一定价对齐) - 拍卖行上架前端对齐服务端单一价格语义,修复 400 报错
242 lines
8.3 KiB
Go
242 lines
8.3 KiB
Go
// 本文件把已确认的攻坚队 C2S 命令纳入模块化分流。
|
||
package raid
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
|
||
"longheng.io/server/internal/modules/dnf/alignedcmd"
|
||
"longheng.io/server/internal/modules/dnf/dnfenum"
|
||
)
|
||
|
||
type handler struct{}
|
||
|
||
// NewHandler 创建攻坚队协议处理器。
|
||
func NewHandler() alignedcmd.Handler {
|
||
return handler{}
|
||
}
|
||
|
||
// Domain 返回攻坚队业务域。
|
||
func (handler) Domain() dnfenum.AlignedDomain {
|
||
return dnfenum.AlignedDomainRaid
|
||
}
|
||
|
||
// Handle 解析已确认的攻坚队 C2S 命令,并禁止模块层伪造成攻坚成功;在线刷新由 dnfbridge/后续 raid owner 推 0x24F。
|
||
func (handler) Handle(_ context.Context, req alignedcmd.Request) (alignedcmd.Result, error) {
|
||
switch dnfenum.CmdPacket(req.Opcode) {
|
||
case dnfenum.CmdPacketCreateRaid:
|
||
return handleCreateRaid(req), nil
|
||
case dnfenum.CmdPacketLeaveRaid:
|
||
return handleLeaveRaid(req), nil
|
||
case dnfenum.CmdPacketStartRaid:
|
||
return handleStartRaid(req), nil
|
||
case dnfenum.CmdPacketRaidEntryCostInfo:
|
||
return handleEntryCostInfo(req), nil
|
||
case dnfenum.CmdPacketRaidSetSymbol:
|
||
return handleSetSymbol(req), nil
|
||
case dnfenum.CmdPacketSetRaidWaiting:
|
||
return handleSetWaiting(req), nil
|
||
case dnfenum.CmdPacketRejoinRaid:
|
||
return handleRejoinRaid(req), nil
|
||
case dnfenum.CmdPacketRaidManagerWork:
|
||
return handleManagerWork(req), nil
|
||
case dnfenum.CmdPacketModifyRaidInfo:
|
||
return handleModifyRaidInfo(req), nil
|
||
case dnfenum.CmdPacketRaidOtherChannelRequestJoin:
|
||
return handleOtherChannelRequestJoin(req), nil
|
||
case dnfenum.CmdPacketRaidMemberChangeState:
|
||
return handleMemberChangeState(req), nil
|
||
case dnfenum.CmdPacketRaidUserMoveChannelFail:
|
||
return handleUserMoveChannelFail(req), nil
|
||
case dnfenum.CmdPacketRaidOtherChannelList:
|
||
return handleOtherChannelList(req), nil
|
||
case dnfenum.CmdPacketRaidCheckRaidUser:
|
||
return handleCheckRaidUser(req), nil
|
||
default:
|
||
return alignedcmd.Result{
|
||
Handled: false,
|
||
ResponseAllowed: false,
|
||
Operation: "unregistered",
|
||
Reason: fmt.Sprintf("raid 模块未登记 opcode %d", req.Opcode),
|
||
}, nil
|
||
}
|
||
}
|
||
|
||
func handleCreateRaid(req alignedcmd.Request) alignedcmd.Result {
|
||
parsed, err := DecodeCreateRaidRequest(req.Body)
|
||
if err != nil {
|
||
return raidPendingParseError("raid_create", err)
|
||
}
|
||
return raidPending("raid_create", fmt.Sprintf(
|
||
"MCP 20260705:664 创建攻坚队 body=u8,dstr name,u8 tail;route=%d name_len=%d tail=%d;真实成功后应推 0x24F mode=3",
|
||
parsed.RouteOrRaidType,
|
||
len(parsed.NameBytes),
|
||
parsed.TailFlag,
|
||
))
|
||
}
|
||
|
||
func handleLeaveRaid(req alignedcmd.Request) alignedcmd.Result {
|
||
parsed, err := DecodeLeaveRaidRequest(req.Body)
|
||
if err != nil {
|
||
return raidPendingParseError("raid_leave", err)
|
||
}
|
||
return raidPending("raid_leave", fmt.Sprintf(
|
||
"MCP 20260705:665 离开攻坚队 body=u16 key=%d;真实成功后应推 0x24F mode=3 或清空攻坚 UI",
|
||
parsed.RaidOrMemberKey,
|
||
))
|
||
}
|
||
|
||
func handleStartRaid(req alignedcmd.Request) alignedcmd.Result {
|
||
if err := DecodeStartRaidRequest(req.Body); err != nil {
|
||
return raidPendingParseError("raid_start", err)
|
||
}
|
||
return raidPending("raid_start", "MCP 20260705:666 开始攻坚为空包;服务端开始后按 group_index/slot_order 自动创建普通 4 人小队")
|
||
}
|
||
|
||
func handleRejoinRaid(req alignedcmd.Request) alignedcmd.Result {
|
||
parsed, err := DecodeRejoinRaidRequest(req.Body)
|
||
if err != nil {
|
||
return raidPendingParseError("raid_rejoin", err)
|
||
}
|
||
return raidPending("raid_rejoin", fmt.Sprintf(
|
||
"MCP 20260705:668 重新加入攻坚 body=u32 raid_key=0x%08X;后续由服务端重推 0x24F mode=3",
|
||
parsed.RaidKey,
|
||
))
|
||
}
|
||
|
||
func handleSetWaiting(req alignedcmd.Request) alignedcmd.Result {
|
||
parsed, err := DecodeSetWaitingRequest(req.Body)
|
||
if err != nil {
|
||
return raidPendingParseError("raid_set_waiting", err)
|
||
}
|
||
return raidPending("raid_set_waiting", fmt.Sprintf(
|
||
"MCP 20260705:667 攻坚等待状态 body=u8 flag,u8 route;flag=%d route=%d;对象级刷新待 0x24F mode=2 继续确认",
|
||
parsed.Flag,
|
||
parsed.RouteRaidType,
|
||
))
|
||
}
|
||
|
||
func handleEntryCostInfo(req alignedcmd.Request) alignedcmd.Result {
|
||
parsed, err := DecodeEntryCostInfoRequest(req.Body)
|
||
if err != nil {
|
||
return raidPendingParseError("raid_entry_cost_info", err)
|
||
}
|
||
return raidPending("raid_entry_cost_info", fmt.Sprintf(
|
||
"MCP 20260705: 658 RaidEntryCostInfo body=u8 enabled=%d;这是入场消耗/材料信息请求,未确认 S2C 成功结构前不自动回包",
|
||
parsed.Enabled,
|
||
))
|
||
}
|
||
|
||
func handleSetSymbol(req alignedcmd.Request) alignedcmd.Result {
|
||
parsed, err := DecodeSetSymbolRequest(req.Body)
|
||
if err != nil {
|
||
return raidPendingParseError("raid_set_symbol", err)
|
||
}
|
||
return raidPending("raid_set_symbol", fmt.Sprintf(
|
||
"MCP 20260705: 662 RaidSetSymbol body=u32,u32,u8;source=0x%08X target=0x%08X symbol=%d;先登记,不伪造 raid 标记同步",
|
||
parsed.SourceValue,
|
||
parsed.TargetValue,
|
||
parsed.Symbol,
|
||
))
|
||
}
|
||
|
||
func handleManagerWork(req alignedcmd.Request) alignedcmd.Result {
|
||
parsed, err := DecodeManagerWorkRequest(req.Body)
|
||
if err != nil {
|
||
return raidPendingParseError("raid_manager_work", err)
|
||
}
|
||
return raidPending("raid_manager_work", fmt.Sprintf(
|
||
"MCP 20260705:669 仅是攻坚队长编辑请求,S2C 669 为 DoNothing;需更新成员 %d 到小组 %d 后推 0x24F mode=3",
|
||
parsed.MemberCharKey,
|
||
parsed.TargetGroup,
|
||
))
|
||
}
|
||
|
||
func handleOtherChannelRequestJoin(req alignedcmd.Request) alignedcmd.Result {
|
||
parsed, err := DecodeOtherChannelRequestJoinRequest(req.Body)
|
||
if err != nil {
|
||
return raidPendingParseError("raid_other_channel_request_join", err)
|
||
}
|
||
return raidPending("raid_other_channel_request_join", fmt.Sprintf(
|
||
"MCP 20260705:820 跨频道攻坚申请 body=u8,u16,u32,u16;mode=%d target=%d client=0x%08X route=%d;需要公共频道 owner 决定回包",
|
||
parsed.Mode,
|
||
parsed.TargetKey,
|
||
parsed.ClientValue,
|
||
parsed.RouteRaidType,
|
||
))
|
||
}
|
||
|
||
func handleMemberChangeState(req alignedcmd.Request) alignedcmd.Result {
|
||
parsed, err := DecodeMemberChangeStateRequest(req.Body)
|
||
if err != nil {
|
||
return raidPendingParseError("raid_member_change_state", err)
|
||
}
|
||
return raidPending("raid_member_change_state", fmt.Sprintf(
|
||
"MCP 20260705:823 成员状态变化 body=u8 state=%d;在线实现更新 member state 后推 0x24F mode=3",
|
||
parsed.State,
|
||
))
|
||
}
|
||
|
||
func handleUserMoveChannelFail(req alignedcmd.Request) alignedcmd.Result {
|
||
parsed, err := DecodeUserMoveChannelFailRequest(req.Body)
|
||
if err != nil {
|
||
return raidPendingParseError("raid_user_move_channel_fail", err)
|
||
}
|
||
return raidPending("raid_user_move_channel_fail", fmt.Sprintf(
|
||
"MCP 20260705:824 跨频道移动失败 body=u8,u16;mode=%d target=%d;只记录,不伪造成功",
|
||
parsed.Mode,
|
||
parsed.TargetKey,
|
||
))
|
||
}
|
||
|
||
func handleOtherChannelList(req alignedcmd.Request) alignedcmd.Result {
|
||
parsed, err := DecodeOtherChannelListRequest(req.Body)
|
||
if err != nil {
|
||
return raidPendingParseError("raid_other_channel_list", err)
|
||
}
|
||
return raidPending("raid_other_channel_list", fmt.Sprintf(
|
||
"MCP 20260705:831 公共频道攻坚列表 body=u8 或 u8,raw8,dstr;mode=%d has_ctx=%v name_len=%d;列表回包待公共频道 owner",
|
||
parsed.Mode,
|
||
parsed.HasContext,
|
||
len(parsed.NameBytes),
|
||
))
|
||
}
|
||
|
||
func handleCheckRaidUser(req alignedcmd.Request) alignedcmd.Result {
|
||
parsed, err := DecodeCheckRaidUserRequest(req.Body)
|
||
if err != nil {
|
||
return raidPendingParseError("raid_check_user", err)
|
||
}
|
||
return raidPending("raid_check_user", fmt.Sprintf(
|
||
"MCP 20260705:889 攻坚用户检查 body=u8,u16;mode=%d target=%d;S2C 889 是复杂列表,禁止最小假成功",
|
||
parsed.Mode,
|
||
parsed.TargetKey,
|
||
))
|
||
}
|
||
|
||
func handleModifyRaidInfo(req alignedcmd.Request) alignedcmd.Result {
|
||
parsed, err := DecodeModifyRaidInfoRequest(req.Body)
|
||
if err != nil {
|
||
return raidPendingParseError("raid_modify_info", err)
|
||
}
|
||
return raidPending("raid_modify_info", fmt.Sprintf(
|
||
"MCP 20260705:670 修改攻坚信息 body=u8,dstr name,u8 tail;route=%d name_len=%d tail=%d;真实成功后应推 0x24F mode=3",
|
||
parsed.RouteOrRaidType,
|
||
len(parsed.NameBytes),
|
||
parsed.TailFlag,
|
||
))
|
||
}
|
||
|
||
func raidPendingParseError(operation string, err error) alignedcmd.Result {
|
||
return raidPending(operation, fmt.Sprintf("%s 请求体解析失败:%v;禁止伪造成攻坚成功", operation, err))
|
||
}
|
||
|
||
func raidPending(operation string, reason string) alignedcmd.Result {
|
||
return alignedcmd.Result{
|
||
Handled: true,
|
||
ResponseAllowed: false,
|
||
Operation: operation,
|
||
Reason: reason,
|
||
}
|
||
}
|