218 lines
8.5 KiB
Go
218 lines
8.5 KiB
Go
package routers
|
||
|
||
import (
|
||
"context"
|
||
"sync"
|
||
)
|
||
|
||
var _ = sync.Mutex{}
|
||
var _ = context.Background
|
||
|
||
//
|
||
// 单机麻将(1 真人 + 3 NPC)—— 移植自捐赠分支 DRMK-PS_09_HyNB-v1.9-R64 的
|
||
// GameRouter.MahjongOnline.cs(391 行)+ MahjongRules4229938.cs(329 行,零改动直拷)。
|
||
// 为什么现在能做(2026-10-04 重估,推翻 10-03 的"重活、建议单独排期"判断):
|
||
// 1. 主线 MethodIds.json 与该分支字节级相同,40+ 个 SyncMj* 常量本来就全齐,不需要搬协议表;
|
||
// 2. 该分支带 .runtime/r62-mahjong-wire-samples.json(41KB 实机抓包),
|
||
// SyncMjLoginResult 里三个 NPC 座位就是 Player101/102/103,
|
||
// 说明实机跑的正是"1 真人 + 3 NPC"这个形态;
|
||
// 3. 原实现的 Coop 依赖只集中在 5 个辅助函数里(MahjongPeers / NotifyCoopPeerAsync /
|
||
// CoopRoster.TryGetBySession / CoopChanges / ActivityLobbies),
|
||
// 单人场景下全部退化为 MahjongGate + 直连推送。
|
||
// wire 形状逐字段照抄捐赠端,未重新推导。本机复核过的样本片段(SyncMjLoginResult):
|
||
// FF + U64(pid) + U64(agentId) + I32(templateId) + U32(level) + UxString(name) +
|
||
// FF 00 + U32(templateId) + U32(0) + I32(score=10000) + I32(seat) + U32(0) + U32(0),
|
||
// 四座位之后接 FF 05 + 4 个 bool + I32(owner)。
|
||
// 已知局限:Mj.Automatic 的对手策略是"能胡就胡 + 弃定缺花色/摸切 + 别人出牌一律 Pass",
|
||
// 所以 NPC 不会碰/杠/吃。规则层能打完整局,但对手很笨。
|
||
// 客户端侧确认无本地 AI(Gameplay/Majiang/ 22 个 lua 里 AI/Robot 零命中)。
|
||
// 没登记的号:Exit(63320834) 与 Chi(63693559) 故意不进白名单 ——
|
||
// 前者名字太通用(别的玩法也在用),后者 XLCH 规则本来就不吃。
|
||
//
|
||
func GameRouter_MahjongSolo_NextMahjongRoom(ctx context.Context, ) uint64 {
|
||
// Router implementation for GameRouter_MahjongSolo_NextMahjongRoom
|
||
return 0
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_NewMahjongIds(ctx context.Context, ) []any {
|
||
// Router implementation for GameRouter_MahjongSolo_NewMahjongIds
|
||
return nil
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_FindMahjong(ctx context.Context, session *GameSession) any {
|
||
// Router implementation for GameRouter_MahjongSolo_FindMahjong
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_HumanSeat(ctx context.Context, g any) int32 {
|
||
// Router implementation for GameRouter_MahjongSolo_HumanSeat
|
||
return 0
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_FillMahjongSeats(ctx context.Context, g any, playerPid uint64, templateId uint32, playerName string, human int32) any {
|
||
// Router implementation for GameRouter_MahjongSolo_FillMahjongSeats
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_MjSend(ctx context.Context, g any, method uint32, body any) any {
|
||
// Router implementation for GameRouter_MahjongSolo_MjSend
|
||
var zero any; return zero
|
||
}
|
||
|
||
// ---------------------------------------------------------------- wire(照抄捐赠端)
|
||
func GameRouter_MahjongSolo_MjInts(ctx context.Context, w any, values []any) any {
|
||
// Router implementation for GameRouter_MahjongSolo_MjInts
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_MjTile(ctx context.Context, w any, g any, tile int32, reveal bool) any {
|
||
// Router implementation for GameRouter_MahjongSolo_MjTile
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_MjTiles(ctx context.Context, w any, g any, tiles []any, reveal bool) any {
|
||
// Router implementation for GameRouter_MahjongSolo_MjTiles
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_MjVisible(ctx context.Context, g any, seat int32, viewer int32) bool {
|
||
// Router implementation for GameRouter_MahjongSolo_MjVisible
|
||
return true
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_MjMeld(ctx context.Context, w any, g any, m any, reveal bool) any {
|
||
// Router implementation for GameRouter_MahjongSolo_MjMeld
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_MjMelds(ctx context.Context, w any, g any, melds []any, seat int32, viewer int32) any {
|
||
// Router implementation for GameRouter_MahjongSolo_MjMelds
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_MjInfo(ctx context.Context, g any, viewer int32) any {
|
||
// Router implementation for GameRouter_MahjongSolo_MjInfo
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_MjRoom(ctx context.Context, g any, viewer int32) any {
|
||
// Router implementation for GameRouter_MahjongSolo_MjRoom
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_MjWorldRoom(ctx context.Context, g any) any {
|
||
// Router implementation for GameRouter_MahjongSolo_MjWorldRoom
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_MjResult(ctx context.Context, g any) any {
|
||
// Router implementation for GameRouter_MahjongSolo_MjResult
|
||
var zero any; return zero
|
||
}
|
||
|
||
// ---------------------------------------------------------------- 流程
|
||
func GameRouter_MahjongSolo_LoadMahjongCoreAsync(ctx context.Context, g any) any {
|
||
// Router implementation for GameRouter_MahjongSolo_LoadMahjongCoreAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_BeginMahjongCoreAsync(ctx context.Context, g any) any {
|
||
// Router implementation for GameRouter_MahjongSolo_BeginMahjongCoreAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_FlushMahjongEvents(ctx context.Context, g any) any {
|
||
// Router implementation for GameRouter_MahjongSolo_FlushMahjongEvents
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_MjResumePromptAsync(ctx context.Context, g any, seat int32) any {
|
||
// Router implementation for GameRouter_MahjongSolo_MjResumePromptAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_MjSendOptionsAsync(ctx context.Context, g any, seat int32) any {
|
||
// Router implementation for GameRouter_MahjongSolo_MjSendOptionsAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// 让三个 NPC 座位把该做的动作做掉(换牌 / 定缺 / 摸切 / 胡 / 过)。
|
||
// Mj.Automatic 自带守卫(State、轮次、是否已响应),所以无脑轮询是安全的。
|
||
//
|
||
func GameRouter_MahjongSolo_RunMahjongNpcTurnsAsync(ctx context.Context, g any) any {
|
||
// Router implementation for GameRouter_MahjongSolo_RunMahjongNpcTurnsAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_RemoveMahjongGameCoreAsync(ctx context.Context, g any) any {
|
||
// Router implementation for GameRouter_MahjongSolo_RemoveMahjongGameCoreAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_WatchMahjongAsync(ctx context.Context, g any) any {
|
||
// Router implementation for GameRouter_MahjongSolo_WatchMahjongAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
// ---------------------------------------------------------------- 入口 / 打牌
|
||
func GameRouter_MahjongSolo_MahjongPlayerName(ctx context.Context, ) string {
|
||
// Router implementation for GameRouter_MahjongSolo_MahjongPlayerName
|
||
return ""
|
||
}
|
||
|
||
//
|
||
// AskStartMahjongGame(63184671) —— 单机麻将入口。
|
||
// C2S = roomType(u8) + npcIdLs(List7Bit u32) + seatIndex(i32) + addFavor(bool) + gameType(u8)。
|
||
// RET = void(空 body + retcode 0,与捐赠端同形)。
|
||
//
|
||
func GameRouter_MahjongSolo_MahjongStart4229938(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_MahjongSolo_MahjongStart4229938
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_MahjongRequest4229938(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_MahjongSolo_MahjongRequest4229938
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_TryMjTile(ctx context.Context, reader any, g any, tile int32) bool {
|
||
// Router implementation for GameRouter_MahjongSolo_TryMjTile
|
||
return true
|
||
}
|
||
|
||
func GameRouter_MahjongSolo_TryMjTiles(ctx context.Context, body []byte, g any, count int32, tiles []any) bool {
|
||
// Router implementation for GameRouter_MahjongSolo_TryMjTiles
|
||
return true
|
||
}
|
||
|
||
// ---------------------------------------------------------------- 状态
|
||
// 一个座位的展示身份(对应 SyncMjLoginResult 每座位那 16 段)。
|
||
type MjSeatInfo struct {
|
||
Pid uint64 `json:"pid"`
|
||
AgentId uint64 `json:"agentId"`
|
||
RemoteAgentId uint64 `json:"remoteAgentId"`
|
||
TemplateId int32 `json:"templateId"`
|
||
Level uint32 `json:"level"`
|
||
Name string `json:"name"`
|
||
IsHuman bool `json:"isHuman"`
|
||
}
|
||
|
||
type MahjongGame struct {
|
||
Room uint64 `json:"room"`
|
||
Session *GameSession `json:"session"`
|
||
Players []uint64 `json:"players"`
|
||
Seats []MjSeatInfo `json:"seats"`
|
||
Ready []uint64 `json:"ready"`
|
||
Loaded []uint64 `json:"loaded"`
|
||
Again []uint64 `json:"again"`
|
||
Auto []byte `json:"auto"`
|
||
Misses []int32 `json:"misses"`
|
||
Rules Mj `json:"rules"`
|
||
WireIds []int32 `json:"wireIds"`
|
||
Phase byte `json:"phase"`
|
||
SeenVersion int32 `json:"seenVersion"`
|
||
Clock int64 `json:"clock"`
|
||
}
|
||
|