@yyyu-star/arcade-kit 0.19.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +43 -0
  3. package/dist/client.d.ts +44 -1
  4. package/dist/client.d.ts.map +1 -1
  5. package/dist/client.js +103 -0
  6. package/dist/client.js.map +1 -1
  7. package/dist/fun-logic.d.ts +14 -2
  8. package/dist/fun-logic.d.ts.map +1 -1
  9. package/dist/fun-logic.js +19 -4
  10. package/dist/fun-logic.js.map +1 -1
  11. package/dist/game.d.ts +7 -0
  12. package/dist/game.d.ts.map +1 -1
  13. package/dist/game.js +38 -0
  14. package/dist/game.js.map +1 -1
  15. package/dist/internal.d.ts +4 -0
  16. package/dist/internal.d.ts.map +1 -1
  17. package/dist/internal.js +6 -0
  18. package/dist/internal.js.map +1 -1
  19. package/dist/match.d.ts +85 -0
  20. package/dist/match.d.ts.map +1 -0
  21. package/dist/match.js +361 -0
  22. package/dist/match.js.map +1 -0
  23. package/dist/meter.d.ts +38 -0
  24. package/dist/meter.d.ts.map +1 -1
  25. package/dist/meter.js +56 -14
  26. package/dist/meter.js.map +1 -1
  27. package/dist/protocol.d.ts +35 -0
  28. package/dist/protocol.d.ts.map +1 -1
  29. package/dist/protocol.js.map +1 -1
  30. package/dist/room.d.ts +48 -1
  31. package/dist/room.d.ts.map +1 -1
  32. package/dist/room.js +157 -17
  33. package/dist/room.js.map +1 -1
  34. package/dist/table-chat.d.ts +2 -0
  35. package/dist/table-chat.d.ts.map +1 -1
  36. package/dist/table-chat.js +25 -2
  37. package/dist/table-chat.js.map +1 -1
  38. package/dist/table-fun.d.ts.map +1 -1
  39. package/dist/table-fun.js +4 -4
  40. package/dist/table-fun.js.map +1 -1
  41. package/dist/worker.d.ts +12 -0
  42. package/dist/worker.d.ts.map +1 -1
  43. package/dist/worker.js +44 -1
  44. package/dist/worker.js.map +1 -1
  45. package/package.json +5 -1
  46. package/src/client.ts +118 -1
  47. package/src/fun-logic.ts +31 -4
  48. package/src/game.ts +40 -0
  49. package/src/internal.ts +8 -0
  50. package/src/match.ts +371 -0
  51. package/src/meter.ts +68 -12
  52. package/src/protocol.ts +41 -0
  53. package/src/room.ts +171 -18
  54. package/src/table-chat.ts +25 -3
  55. package/src/table-fun.ts +4 -3
  56. package/src/worker.ts +44 -2
@@ -62,6 +62,36 @@ export declare const CLOSE_REASON: {
62
62
  * - bad_options 400 开房时带的选项不合格(0.4.0,游戏 Worker 传了 options 时才会有)。
63
63
  */
64
64
  export type CreateError = 'login' | 'forbidden' | 'has_room' | 'daily_limit' | 'busy' | 'unavailable' | 'bad_options';
65
+ /**
66
+ * 快速匹配(0.20.0,docs/match.md)转单机的原因:
67
+ * - alone 等到时间只有自己在排;daily_limit 这个人今天的联机局数用完了;busy 今天联机的人太多(全站门槛);
68
+ * - unavailable 计量或房间暂时连不上;too_often 这一小时排得太多了;replaced 同一个人在别的页面又排了一次(这一页不用管了)。
69
+ */
70
+ export type MatchSoloWhy = 'alone' | 'daily_limit' | 'busy' | 'unavailable' | 'too_often' | 'replaced';
71
+ /** 排队时的人数(0.20.0):n 是现在排着几个人(含自己),seats 是一桌最多几个真人,left 是离"不等了"还剩几毫秒(按房间的钟算好的差值) */
72
+ export interface MatchWaitingMsg {
73
+ t: 'waiting';
74
+ n: number;
75
+ seats: number;
76
+ left: number;
77
+ }
78
+ /** 凑成一桌了(0.20.0):用 code 照常进房(RoomClient),房间只认排进来的这几个人 */
79
+ export interface MatchedMsg {
80
+ t: 'matched';
81
+ code: string;
82
+ }
83
+ /** 不排了,转本机单机(0.20.0) */
84
+ export interface MatchSoloMsg {
85
+ t: 'solo';
86
+ why: MatchSoloWhy;
87
+ }
88
+ /** 这个人已经有一个开着的房间(0.20.0):不排队,页面带他回那个房间 */
89
+ export interface MatchHasRoomMsg {
90
+ t: 'has_room';
91
+ code: string;
92
+ }
93
+ /** 排队连接上的下行消息(0.20.0)。排队连接只收不发,浏览器发什么都会被 1008 断开 */
94
+ export type MatchDownMsg = MatchWaitingMsg | MatchedMsg | MatchSoloMsg | MatchHasRoomMsg;
65
95
  /** 不重连的关闭码。 */
66
96
  export declare function isFinalClose(code: number): boolean;
67
97
  /** 坐到某个座位(等人时选空位,开打后可以接管电脑的座位)。 */
@@ -163,6 +193,11 @@ export interface RoomInfo {
163
193
  pause?: {
164
194
  until: number;
165
195
  };
196
+ /**
197
+ * 快速匹配凑出来的桌(0.20.0):只有排进来的人能进、没有房主、人到齐(或等满 RoomLimits.matchJoinMs)自动开打。
198
+ * 页面据此藏起房间码、邀请、叫人和"开打"按钮
199
+ */
200
+ match?: true;
166
201
  }
167
202
  /** 一帧画面:按座位过滤过的游戏视图,delay 是相对上一帧的播放延迟(电脑连续出牌时用,4.4)。 */
168
203
  export interface Frame<V = unknown> {
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,qBAAqB;AACrB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC;AAC3B,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC;AAE3B,sBAAsB;AACtB,MAAM,CAAC,MAAM,YAAY,GAAG,YAAY,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,qBAAqB;IACrB,MAAM,EAAE,IAAI;IACZ,iBAAiB;IACjB,MAAM,EAAE,IAAI;IACZ,uCAAuC;IACvC,QAAQ,EAAE,IAAI;IACd,+BAA+B;IAC/B,UAAU,EAAE,IAAI;IAChB,yBAAyB;IACzB,QAAQ,EAAE,IAAI;IACd,6DAA6D;IAC7D,IAAI,EAAE,IAAI;IACV,uBAAuB;IACvB,MAAM,EAAE,IAAI;IACZ,iBAAiB;IACjB,MAAM,EAAE,IAAI;IACZ,gCAAgC;IAChC,YAAY,EAAE,IAAI;IAClB,gDAAgD;IAChD,SAAS,EAAE,IAAI;IACf,gDAAgD;IAChD,IAAI,EAAE,IAAI;IACV,2BAA2B;IAC3B,YAAY,EAAE,IAAI;IAClB,gBAAgB;IAChB,SAAS,EAAE,IAAI;CACP,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,KAAK,EAAE,OAAO;CACN,CAAC;AAaX,eAAe;AACf,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI,KAAK,KAAK,CAAC,MAAM,IAAI,IAAI,KAAK,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC,CAAC;AACzF,CAAC;AAqLD;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,CAAU,CAAC;AAc3H;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,CAAU,CAAC"}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,qBAAqB;AACrB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC;AAC3B,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC;AAE3B,sBAAsB;AACtB,MAAM,CAAC,MAAM,YAAY,GAAG,YAAY,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,qBAAqB;IACrB,MAAM,EAAE,IAAI;IACZ,iBAAiB;IACjB,MAAM,EAAE,IAAI;IACZ,uCAAuC;IACvC,QAAQ,EAAE,IAAI;IACd,+BAA+B;IAC/B,UAAU,EAAE,IAAI;IAChB,yBAAyB;IACzB,QAAQ,EAAE,IAAI;IACd,6DAA6D;IAC7D,IAAI,EAAE,IAAI;IACV,uBAAuB;IACvB,MAAM,EAAE,IAAI;IACZ,iBAAiB;IACjB,MAAM,EAAE,IAAI;IACZ,gCAAgC;IAChC,YAAY,EAAE,IAAI;IAClB,gDAAgD;IAChD,SAAS,EAAE,IAAI;IACf,gDAAgD;IAChD,IAAI,EAAE,IAAI;IACV,2BAA2B;IAC3B,YAAY,EAAE,IAAI;IAClB,gBAAgB;IAChB,SAAS,EAAE,IAAI;CACP,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,KAAK,EAAE,OAAO;CACN,CAAC;AAiDX,eAAe;AACf,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI,KAAK,KAAK,CAAC,MAAM,IAAI,IAAI,KAAK,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC,CAAC;AACzF,CAAC;AA0LD;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,CAAU,CAAC;AAc3H;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,CAAU,CAAC"}
package/dist/room.d.ts CHANGED
@@ -82,6 +82,11 @@ export interface RoomLimits {
82
82
  * 到了还办不完就记日志照样删(办事的一方要有自己的兜底,比如钱包到期退回买入)
83
83
  */
84
84
  closingMs: number;
85
+ /**
86
+ * 快速匹配的桌(0.20.0):建好以后最多等排进来的人这么久,到了还没连上的座位由电脑代打、照样开打(人后来到了交还给他)。
87
+ * 都连上了就不等,马上开
88
+ */
89
+ matchJoinMs: number;
85
90
  }
86
91
  /** 4.5、4.6 的默认值。 */
87
92
  export declare const DEFAULT_LIMITS: RoomLimits;
@@ -92,6 +97,26 @@ export type CreateOutcome = {
92
97
  r: 'has_room';
93
98
  code: string;
94
99
  };
100
+ /**
101
+ * 匹配开桌的结果(kitCreateMatch → match.ts 的 MatchQueue,0.20.0)。refused:计量挡了某个人(has_room 带他那个房间的码),
102
+ * userId 为 null 是全站忙(busy);这一桌一个名额都没占,排队那边把这个人请出去再凑
103
+ */
104
+ export type MatchOutcome = {
105
+ r: 'created' | 'exists' | 'bad' | 'bad_options' | 'error' | 'unavailable';
106
+ } | {
107
+ r: 'refused';
108
+ userId: string;
109
+ why: 'has_room';
110
+ code: string;
111
+ } | {
112
+ r: 'refused';
113
+ userId: string;
114
+ why: 'daily_limit';
115
+ } | {
116
+ r: 'refused';
117
+ userId: null;
118
+ why: 'busy';
119
+ };
95
120
  export declare abstract class GameRoom<S, A, V, Env = unknown, O = unknown, E extends RoomEffect = RoomEffect> extends DurableObject<Env> {
96
121
  protected abstract readonly game: RoomGame<S, A, V, O, E>;
97
122
  protected readonly limits: RoomLimits;
@@ -160,7 +185,10 @@ export declare abstract class GameRoom<S, A, V, Env = unknown, O = unknown, E ex
160
185
  lastStepFailed: boolean;
161
186
  /** 写了还没报给计量的行数 */
162
187
  private unmetered;
163
- /** 这一步做完以后要还房主的名额(打完、关房),entry 最后去找计量 */
188
+ /**
189
+ * 这一步做完以后要还的名额(打完、关房;房主一个人,匹配桌是排进来的每个人),entry 最后去找计量。
190
+ * refund:匹配桌开打时没来的人(0.20.0),连当天的开房次数一起退给他(全站开房数不退,桌子开成了)
191
+ */
164
192
  private release;
165
193
  /** 计量最近一次说的门槛(内存;被驱逐就重新问) */
166
194
  private level;
@@ -183,6 +211,16 @@ export declare abstract class GameRoom<S, A, V, Env = unknown, O = unknown, E ex
183
211
  * 占不到就不建房间、这个房间对象什么都不写;占到了却没建成,退回去。
184
212
  */
185
213
  kitCreate(code: string, host: Identity, rawOpts?: unknown): Promise<CreateOutcome>;
214
+ /**
215
+ * 快速匹配开桌(0.20.0,只有 match.ts 的排队对象经 RPC 调):players 按排队先后,每人占一个开房名额(计量一次占齐,占不齐一个都不占),
216
+ * 建房时把他们按 matchSeats 坐好。和 kitCreate 一样:码撞了回 exists、什么都不写;占到了却没建成就退回去。
217
+ */
218
+ kitCreateMatch(code: string, players: Identity[], rawOpts?: unknown): Promise<MatchOutcome>;
219
+ /**
220
+ * 快速匹配时 n 个人坐哪几个座位(0.20.0,可选覆盖):count 是这一局用几个座位,返回 n 个不重复的座位号(排队先后的顺序)。
221
+ * 默认随机(crypto,不在规则核心里);比如两个真人要坐对家,游戏在这里给。给的不合格(重复、越界、个数不对)就按默认的随机
222
+ */
223
+ protected matchSeats(n: number, count: number): number[];
186
224
  /** 进房:只认 kit 自己拼的内部地址(worker.ts 的 acceptJoin),身份在 x-kit-user 头里。 */
187
225
  fetch(request: Request): Promise<Response>;
188
226
  webSocketMessage(ws: WebSocket, message: string | ArrayBuffer): Promise<void>;
@@ -231,6 +269,8 @@ export declare abstract class GameRoom<S, A, V, Env = unknown, O = unknown, E ex
231
269
  /** 进房被拒:接受升级后马上用关闭码关掉(浏览器拿不到 HTTP 状态码)。 */
232
270
  private refuse;
233
271
  private create;
272
+ /** 匹配桌(0.20.0):和 create 一样建表、存一行、设闹钟,只是排进来的人都先坐好(算掉线,连上就"回来"),记下最晚开打的时间。 */
273
+ private createMatch;
234
274
  /** 进房(含重连):接受、记座位、发快照,中间没有 await(4.5 续局的写法)。 */
235
275
  private join;
236
276
  private onMessage;
@@ -253,6 +293,13 @@ export declare abstract class GameRoom<S, A, V, Env = unknown, O = unknown, E ex
253
293
  private sit;
254
294
  private leave;
255
295
  private start;
296
+ /**
297
+ * 开打:空座位由电脑补满,入座的人从这一刻起绑在自己的座位上,返回要广播的帧。
298
+ * 匹配桌(0.20.0)到点还没连上的人:座位照样绑给他,电脑先代打(auto),他连上就交还
299
+ */
300
+ private beginPlay;
301
+ /** 匹配桌在等人,排进来的人都连上了 */
302
+ private matchReady;
256
303
  /**
257
304
  * 开局拿随机:写了 begin 的给 256 位熵(只在这里用一次,房间不存;游戏要接着发牌就把它放进自己的状态,那只在服务端)。
258
305
  * 只有 start 的旧游戏照旧给 32 位种子,记一条警告:这种种子能被玩家用手牌反推出来。
@@ -1 +1 @@
1
- {"version":3,"file":"room.d.ts","sourceRoot":"","sources":["../src/room.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"room.d.ts","sourceRoot":"","sources":["../src/room.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAa,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,KAAK,QAAQ,EAAmE,MAAM,eAAe,CAAC;AAoB/G,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAClH,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,WAAW,UAAU;IACzB,2BAA2B;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,oBAAoB;AACpB,eAAO,MAAM,cAAc,EAAE,UAsB5B,CAAC;AAkHF,mDAAmD;AACnD,MAAM,MAAM,aAAa,GACrB;IAAE,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,KAAK,GAAG,aAAa,GAAG,OAAO,GAAG,aAAa,GAAG,MAAM,GAAG,aAAa,CAAA;CAAE,GACtG;IAAE,CAAC,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpC;;;GAGG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,KAAK,GAAG,aAAa,GAAG,OAAO,GAAG,aAAa,CAAA;CAAE,GAC7E;IAAE,CAAC,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,CAAC,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,aAAa,CAAA;CAAE,GACpD;IAAE,CAAC,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAShD,8BAAsB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,SAAS,UAAU,GAAG,UAAU,CAAE,SAAQ,aAAa,CAAC,GAAG,CAAC;IAC/H,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1D,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAkB;IAEvD;;;;OAIG;IACH,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAEtE;IAED;;;;;OAKG;IACH,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,CAAG;IAEpC;;;;;;OAMG;IACH,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAG;IAEpE;;;;;;OAMG;IACH,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,OAAO,CAAA;KAAE,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAYvH;IAED;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAWjE;IAED,qBAAqB;IACrB,OAAO,CAAC,EAAE,CAAgC;IAC1C,2DAA2D;IAC3D,OAAO,CAAC,OAAO,CAA4B;IAC3C,0CAA0C;IAC1C,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;IACvD,0DAA0D;IAC1D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqD;IAC7E,oDAAoD;IACpD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqD;IAClF,OAAO,CAAC,cAAc,CAA0B;IAChD,8CAA8C;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA+B;IACzD,OAAO,CAAC,aAAa,CAAyB;IAC9C,2DAA2D;IAC3D,OAAO,CAAC,MAAM,CAAK;IACnB,sBAAsB;IACtB,cAAc,SAAK;IACnB,aAAa,SAAK;IAClB,8BAA8B;IAC9B,WAAW,SAAK;IAChB,cAAc,UAAS;IACvB,kBAAkB;IAClB,OAAO,CAAC,SAAS,CAAK;IACtB;;;OAGG;IACH,OAAO,CAAC,OAAO,CAAiE;IAChF,6BAA6B;IAC7B,OAAO,CAAC,KAAK,CAAkD;IAC/D,uBAAuB;IACvB,OAAO,CAAC,YAAY,CAAK;IACzB,mCAAmC;IACnC,OAAO,CAAC,OAAO,CAAS;IACxB,8BAA8B;IAC9B,OAAO,CAAC,OAAO,CAAS;IACxB,wCAAwC;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,WAAW,CAAS;IAC5B,kDAAkD;IAClD,OAAO,CAAC,cAAc,CAAS;IAC/B,mCAAmC;IACnC,QAAQ,CAAC,UAAU,sDAAuB;IAE1C,YAAY,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG,EAK5C;IAID;;;OAGG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAuBvF;IAED;;;OAGG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAyBhG;IAED;;;OAGG;IACH,SAAS,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAEvD;IAED,oEAAoE;IACrD,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAYxD;IAEc,gBAAgB,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3F;IAEc,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUxE;IAEc,cAAc,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1D;IAEc,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAmBpC;IAED;;;;OAIG;YACW,KAAK;IA+BnB;;;;;OAKG;YACW,YAAY;IAiB1B;;;;;OAKG;YACW,cAAc;IAe5B;;;OAGG;IACH,SAAS,CAAC,cAAc,IAAI,sBAAsB,GAAG,SAAS,CAE7D;IAED,OAAO,CAAC,KAAK;IAKb;;;;OAIG;YACW,SAAS;IAsCvB,+DAA+D;IAC/D,OAAO,CAAC,QAAQ;IAShB;;;OAGG;YACW,YAAY;IAiB1B,2CAA2C;IAC3C,OAAO,CAAC,MAAM;IASd,OAAO,CAAC,MAAM;IAoBd,4EAA4E;IAC5E,OAAO,CAAC,WAAW;IAyBnB,gDAAgD;IAChD,OAAO,CAAC,IAAI;IA2FZ,OAAO,CAAC,SAAS;IAsCjB;;;;OAIG;IACH,OAAO,CAAC,KAAK;IAoBb;;;OAGG;IACH,OAAO,CAAC,IAAI;IAYZ,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,QAAQ;IAYhB,sDAAsD;IACtD,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,GAAG;IAwCX,OAAO,CAAC,KAAK;IAYb,OAAO,CAAC,KAAK;IAeb;;;OAGG;IACH,OAAO,CAAC,SAAS;IAyBjB,uBAAuB;IACvB,OAAO,CAAC,UAAU;IAIlB;;;OAGG;IACH,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,GAAG;IAgCX;;;OAGG;IACH,OAAO,CAAC,SAAS;IAQjB;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAYnB,sDAAsD;IACtD,OAAO,CAAC,MAAM;IAuBd,OAAO,CAAC,OAAO;IAyDf,yBAAyB;IACzB,OAAO,CAAC,YAAY;IAkBpB;;;OAGG;IACH,OAAO,CAAC,SAAS;IASjB;;;OAGG;IACH,OAAO,CAAC,IAAI;IAeZ;;;OAGG;IACH,OAAO,CAAC,IAAI;IAyBZ,oEAAoE;IACpE,OAAO,CAAC,WAAW;IAcnB;;;;OAIG;IACH,OAAO,CAAC,OAAO;IAiBf,uDAAuD;IACvD,OAAO,CAAC,WAAW;IAQnB;;;OAGG;IACH,OAAO,CAAC,MAAM;IAad,OAAO,CAAC,QAAQ;IAIhB,iCAAiC;IACjC,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,QAAQ;IAKhB;;;OAGG;IACH,OAAO,CAAC,QAAQ;IAahB,+CAA+C;IAC/C,OAAO,CAAC,WAAW;IAMnB;;;OAGG;IACH,OAAO,CAAC,OAAO;IAkBf;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAmBlB,OAAO,CAAC,MAAM;IAKd,qDAAqD;IACrD,OAAO,CAAC,OAAO;IAiCf,uCAAuC;IACvC,OAAO,CAAC,SAAS;IAcjB;;;;OAIG;YACW,UAAU;IAiCxB;;;OAGG;IACH,OAAO,CAAC,MAAM;IA8Cd,sEAAsE;IACtE,OAAO,CAAC,WAAW;IAgBnB;;;OAGG;IACH,OAAO,CAAC,MAAM;IAsBd,2BAA2B;IAC3B,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,SAAS;IAIjB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,IAAI;IAeZ,oDAAoD;IACpD,OAAO,CAAC,IAAI;IAUZ;;;;OAIG;IACH,OAAO,CAAC,SAAS;IA4BjB,0BAA0B;IAC1B,OAAO,CAAC,IAAI;IAcZ,OAAO,CAAC,OAAO;IAIf,gCAAgC;IAChC,OAAO,CAAC,YAAY;IAOpB,oDAAoD;IACpD,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,QAAQ;IA8BhB,kDAAkD;IAClD,OAAO,CAAC,OAAO;IAKf,sCAAsC;IACtC,OAAO,CAAC,QAAQ;IAIhB,2CAA2C;IAC3C,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,OAAO;IAiBf,OAAO,CAAC,QAAQ;IAMhB,2EAA2E;IAC3E,OAAO,CAAC,SAAS;IAmBjB,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,MAAM;IAId;;;OAGG;IACH,OAAO,CAAC,SAAS;CAUlB;AAuFD,gDAAgD;AAChD,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAMD,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,GAAG,SAAS,CAYpE;AAED,+CAA+C;AAC/C,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,iEAAiE;AACjE,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAYjE"}
package/dist/room.js CHANGED
@@ -45,6 +45,7 @@ export const DEFAULT_LIMITS = {
45
45
  chatPerMin: 10,
46
46
  meterBatch: 200,
47
47
  closingMs: 60 * 60_000,
48
+ matchJoinMs: 20_000,
48
49
  };
49
50
  /** 闹钟里出错时,过这么久再醒来重试(不用"马上",免得每次都出错时连着计费)。 */
50
51
  const ALARM_RETRY_MS = 60_000;
@@ -164,7 +165,10 @@ export class GameRoom extends DurableObject {
164
165
  lastStepFailed = false;
165
166
  /** 写了还没报给计量的行数 */
166
167
  unmetered = 0;
167
- /** 这一步做完以后要还房主的名额(打完、关房),entry 最后去找计量 */
168
+ /**
169
+ * 这一步做完以后要还的名额(打完、关房;房主一个人,匹配桌是排进来的每个人),entry 最后去找计量。
170
+ * refund:匹配桌开打时没来的人(0.20.0),连当天的开房次数一起退给他(全站开房数不退,桌子开成了)
171
+ */
168
172
  release = null;
169
173
  /** 计量最近一次说的门槛(内存;被驱逐就重新问) */
170
174
  level = null;
@@ -221,6 +225,49 @@ export class GameRoom extends DurableObject {
221
225
  await meter.kitRelease(host.userId, code, 0, true).catch(() => console.error('meter release failed', code));
222
226
  return { r: out instanceof Response ? 'error' : out };
223
227
  }
228
+ /**
229
+ * 快速匹配开桌(0.20.0,只有 match.ts 的排队对象经 RPC 调):players 按排队先后,每人占一个开房名额(计量一次占齐,占不齐一个都不占),
230
+ * 建房时把他们按 matchSeats 坐好。和 kitCreate 一样:码撞了回 exists、什么都不写;占到了却没建成就退回去。
231
+ */
232
+ async kitCreateMatch(code, players, rawOpts) {
233
+ const fixed = this.checkOpts(rawOpts);
234
+ if (fixed === undefined || (rawOpts !== undefined && !this.game.options))
235
+ return { r: 'bad_options' };
236
+ if (!validPlayers(code, players, fixed.count))
237
+ return { r: 'bad' };
238
+ const meter = this.meter();
239
+ const users = players.map((p) => p.userId);
240
+ let reserved = false;
241
+ if (meter && !this.load()) {
242
+ try {
243
+ const r = await meter.kitReserveMany(users, code, Date.now() + this.limits.maxLifeMs);
244
+ if (!r.ok) {
245
+ if (r.error === 'has_room')
246
+ return { r: 'refused', userId: r.userId, why: 'has_room', code: r.code };
247
+ return r.error === 'daily_limit' ? { r: 'refused', userId: r.userId, why: 'daily_limit' } : { r: 'refused', userId: null, why: 'busy' };
248
+ }
249
+ reserved = true;
250
+ }
251
+ catch (e) {
252
+ console.error('meter unreachable, refusing match room', e instanceof Error ? e.message : e);
253
+ return { r: 'unavailable' };
254
+ }
255
+ }
256
+ const before = this.maxStepWrites;
257
+ const out = await this.entry(() => this.createMatch(code, players, fixed));
258
+ if (out === 'created')
259
+ this.maxStepWrites = before;
260
+ else if (reserved && meter)
261
+ await meter.kitReleaseMany(users, code, 0, true).catch(() => console.error('meter release failed', code));
262
+ return { r: out instanceof Response ? 'error' : out };
263
+ }
264
+ /**
265
+ * 快速匹配时 n 个人坐哪几个座位(0.20.0,可选覆盖):count 是这一局用几个座位,返回 n 个不重复的座位号(排队先后的顺序)。
266
+ * 默认随机(crypto,不在规则核心里);比如两个真人要坐对家,游戏在这里给。给的不合格(重复、越界、个数不对)就按默认的随机
267
+ */
268
+ matchSeats(n, count) {
269
+ return randomSeats(n, count);
270
+ }
224
271
  /** 进房:只认 kit 自己拼的内部地址(worker.ts 的 acceptJoin),身份在 x-kit-user 头里。 */
225
272
  async fetch(request) {
226
273
  const url = new URL(request.url);
@@ -391,7 +438,9 @@ export class GameRoom extends DurableObject {
391
438
  this.release = null;
392
439
  this.unmetered = 0;
393
440
  try {
394
- const level = release ? await meter.kitRelease(release.host, release.code, n) : await meter.kitReport(n);
441
+ const level = release
442
+ ? await meter.kitReleaseMany(release.users, release.code, n, release.refund === true, false)
443
+ : await meter.kitReport(n);
395
444
  this.level = { value: level, at: Date.now() };
396
445
  this.meterRetryAt = 0;
397
446
  }
@@ -428,7 +477,7 @@ export class GameRoom extends DurableObject {
428
477
  async newcomerGate(userId) {
429
478
  const meter = this.meter();
430
479
  const st = this.load();
431
- if (!meter || !st || st.host === userId || this.seatOf(userId) !== null || this.boundOf(userId) !== null)
480
+ if (!meter || !st || st.host === userId || this.seatOf(userId) !== null || this.boundOf(userId) !== null || st.match?.users.includes(userId))
432
481
  return null;
433
482
  if (this.sockets().some((o) => attachmentOf(o)?.userId === userId))
434
483
  return null;
@@ -473,6 +522,34 @@ export class GameRoom extends DurableObject {
473
522
  this.save();
474
523
  return 'created';
475
524
  }
525
+ /** 匹配桌(0.20.0):和 create 一样建表、存一行、设闹钟,只是排进来的人都先坐好(算掉线,连上就"回来"),记下最晚开打的时间。 */
526
+ createMatch(code, players, fixed) {
527
+ if (this.load())
528
+ return 'exists';
529
+ this.writes += this.ctx.storage.sql.exec(`CREATE TABLE IF NOT EXISTS ${TABLE} (k INTEGER PRIMARY KEY, v TEXT NOT NULL)`).rowsWritten;
530
+ const now = Date.now();
531
+ const seats = Array.from({ length: this.game.seats }, () => emptySeat());
532
+ let order;
533
+ try {
534
+ order = this.matchSeats(players.length, fixed.count);
535
+ }
536
+ catch (e) {
537
+ console.error('matchSeats threw', e instanceof Error ? e.message : e);
538
+ order = [];
539
+ }
540
+ if (!validSeats(order, players.length, fixed.count))
541
+ order = randomSeats(players.length, fixed.count);
542
+ players.forEach((p, i) => (seats[order[i]] = humanSeat(p.userId, p.name, now)));
543
+ this.st = {
544
+ sv: 1, code, host: players[0].userId, createdAt: now, status: 'waiting', seq: 0, gameSeq: 0, turnSeq: 0, seats, game: null, rulesVersion: null,
545
+ turnSince: null, aiAt: null, noHumanSince: now, inbound: 0, inboundBy: {}, joins: {}, owners: seats.map(() => null),
546
+ ...(fixed.opts !== undefined ? { opts: fixed.opts } : {}),
547
+ match: { users: players.map((p) => p.userId), joinBy: now + this.limits.matchJoinMs },
548
+ };
549
+ this.planAlarm();
550
+ this.save();
551
+ return 'created';
552
+ }
476
553
  /** 进房(含重连):接受、记座位、发快照,中间没有 await(4.5 续局的写法)。 */
477
554
  join(me, rawCv, chat = false) {
478
555
  const pair = new WebSocketPair();
@@ -494,6 +571,11 @@ export class GameRoom extends DurableObject {
494
571
  server.close(CLOSE.tooOld, 'client too old');
495
572
  return done();
496
573
  }
574
+ // 匹配桌只认排进来的人(0.20.0):房间码不给页面看,别人拿到码也进不来、看不了,回的和"没有这个房间"一样
575
+ if (st.match && !st.match.users.includes(me.userId)) {
576
+ server.close(CLOSE.noRoom, 'no room');
577
+ return done();
578
+ }
497
579
  const seat = this.seatOf(me.userId);
498
580
  const others = this.sockets().filter((o) => o !== server && attachmentOf(o));
499
581
  const mine = others.filter((o) => attachmentOf(o).userId === me.userId);
@@ -550,9 +632,11 @@ export class GameRoom extends DurableObject {
550
632
  st.joins[me.userId] = used + 1;
551
633
  st.noHumanSince = null;
552
634
  }
635
+ // 匹配桌的人到齐了:不等,和这次进房同一步开打(还是只写这一行和闹钟)
636
+ const frames = changed && this.matchReady(st) ? this.beginPlay(st, Date.now()) : [{ state: st.game, delay: 0 }];
553
637
  // 状态没变(没入座的人进来、在线时又从别的设备连一次)不写库、不广播
554
638
  if (changed)
555
- this.commit({ frames: [{ state: st.game, delay: 0 }] }, server);
639
+ this.commit({ frames }, server);
556
640
  this.send(server, this.welcome(seat, this.boundOf(me.userId)));
557
641
  return done();
558
642
  }
@@ -699,6 +783,9 @@ export class GameRoom extends DurableObject {
699
783
  const target = st.seats[raw];
700
784
  if (st.status === 'over')
701
785
  return this.reject(ws, 'room_over');
786
+ // 匹配桌等人时座位是排好的,不换(开打以后离座、回座照常)
787
+ if (st.match && st.status === 'waiting')
788
+ return this.reject(ws, 'seat_taken');
702
789
  if (st.status === 'waiting') {
703
790
  // 开房时定了选项的(0.4.0):这一局用不到的座位现在就不让坐,免得房主开打时才被 seat_closed 拒
704
791
  if (st.opts !== undefined && raw >= this.countOf(st.opts))
@@ -741,7 +828,7 @@ export class GameRoom extends DurableObject {
741
828
  }
742
829
  leave(seat) {
743
830
  const st = this.st;
744
- if (seat === null)
831
+ if (seat === null || (st.match && st.status === 'waiting'))
745
832
  return;
746
833
  // 等人时空出来;开打后由电脑接手(不判负),轮到它就接着出。座位还绑着他,留下昵称给牌桌显示"电脑代某某打"
747
834
  st.seats[seat] = st.status === 'playing' ? { ...aiSeat(), name: st.seats[seat].name } : emptySeat();
@@ -756,8 +843,8 @@ export class GameRoom extends DurableObject {
756
843
  }
757
844
  start(ws, me, seat, rawOpts) {
758
845
  const st = this.st;
759
- // 房主选择开打(9.1)
760
- if (me.userId !== st.host)
846
+ // 房主选择开打(9.1);匹配桌没有房主,到齐或到点自动开(0.20.0)
847
+ if (me.userId !== st.host || st.match)
761
848
  return this.reject(ws, 'not_host');
762
849
  if (st.status !== 'waiting')
763
850
  return this.reject(ws, 'already_started');
@@ -769,22 +856,44 @@ export class GameRoom extends DurableObject {
769
856
  const checked = fixed ?? this.checkOpts(rawOpts);
770
857
  if (!checked)
771
858
  return this.reject(ws, 'bad_options');
772
- const { opts, count } = checked;
773
- if (st.seats.some((s, i) => i >= count && s.kind === 'human'))
859
+ if (st.seats.some((s, i) => i >= checked.count && s.kind === 'human'))
774
860
  return this.reject(ws, 'seat_closed');
775
- // 空座位由电脑补满;入座的人从这一刻起绑在自己的座位上
861
+ this.commit({ frames: this.beginPlay(st, Date.now(), checked) });
862
+ }
863
+ /**
864
+ * 开打:空座位由电脑补满,入座的人从这一刻起绑在自己的座位上,返回要广播的帧。
865
+ * 匹配桌(0.20.0)到点还没连上的人:座位照样绑给他,电脑先代打(auto),他连上就交还
866
+ */
867
+ beginPlay(st, now, checked) {
868
+ const { opts, count } = checked ?? { opts: st.opts, count: this.countOf(st.opts) };
776
869
  st.seats = st.seats.map((s, i) => (s.kind === 'empty' && i < count ? aiSeat() : s));
870
+ if (st.match) {
871
+ const absent = [];
872
+ for (const s of st.seats) {
873
+ if (s.kind !== 'human' || s.awaySince === null)
874
+ continue;
875
+ s.auto = true;
876
+ absent.push(s.userId);
877
+ }
878
+ // 没来的人(关了页面、网断了):他的开房名额和当天次数退给他,不然白扣一个、还被 has_room 卡到这桌打完。
879
+ // 他后来回来照样能接着打这个座位(座位还绑着他)
880
+ if (absent.length)
881
+ this.release = { users: absent, code: st.code, refund: true };
882
+ }
777
883
  st.owners = st.seats.map((s) => (s.kind === 'human' ? s.userId : null));
778
884
  st.rulesVersion = this.game.rulesVersion;
779
885
  st.game = this.begin(st.code, { opts, seats: st.seats.map((s) => s.kind) });
780
886
  st.gameSeq = st.seq + 1;
781
887
  st.turnSeq = st.gameSeq;
782
888
  st.status = 'playing';
783
- const now = Date.now();
784
889
  st.turnSince = now;
785
890
  if (!this.game.over(st.game))
786
891
  this.stalled(this.actorsOf(st.game));
787
- this.commit({ frames: [{ state: st.game, delay: 0 }, ...this.runAuto(now)] });
892
+ return [{ state: st.game, delay: 0 }, ...this.runAuto(now)];
893
+ }
894
+ /** 匹配桌在等人,排进来的人都连上了 */
895
+ matchReady(st) {
896
+ return !!st.match && st.status === 'waiting' && st.seats.every((s) => s.kind !== 'human' || s.awaySince === null);
788
897
  }
789
898
  /**
790
899
  * 开局拿随机:写了 begin 的给 256 位熵(只在这里用一次,房间不存;游戏要接着发牌就把它放进自己的状态,那只在服务端)。
@@ -904,6 +1013,9 @@ export class GameRoom extends DurableObject {
904
1013
  return this.closeRoom();
905
1014
  const frames = [];
906
1015
  let changed = false;
1016
+ // 匹配桌等够了(0.20.0):没来的由电脑代打,照样开
1017
+ if (st.match && st.status === 'waiting' && now >= st.match.joinBy)
1018
+ return this.commit({ frames: this.beginPlay(st, now) });
907
1019
  // 掉线超过宽限:电脑托管(只在开打以后有意义,等人时不管)
908
1020
  for (const s of st.status === 'playing' ? st.seats : []) {
909
1021
  if (s.kind === 'human' && s.awaySince !== null && !s.auto && now >= s.awaySince + this.limits.graceMs) {
@@ -967,6 +1079,8 @@ export class GameRoom extends DurableObject {
967
1079
  ds.push(st.effectsAt);
968
1080
  if (st.noHumanSince !== null)
969
1081
  ds.push(st.noHumanSince + this.limits.noHumanMs);
1082
+ if (st.match && st.status === 'waiting')
1083
+ ds.push(st.match.joinBy);
970
1084
  if (st.status === 'playing') {
971
1085
  for (const s of st.seats)
972
1086
  if (s.kind === 'human' && s.awaySince !== null && !s.auto)
@@ -1027,7 +1141,7 @@ export class GameRoom extends DurableObject {
1027
1141
  if (over) {
1028
1142
  st.status = 'over';
1029
1143
  st.turnSince = null;
1030
- this.release = { host: st.host, code: st.code };
1144
+ this.release = releaseOf(st);
1031
1145
  return;
1032
1146
  }
1033
1147
  const after = this.turnOf(next);
@@ -1080,7 +1194,7 @@ export class GameRoom extends DurableObject {
1080
1194
  console.error('game has nobody to act but is not over', st.code);
1081
1195
  st.status = 'over';
1082
1196
  st.turnSince = null;
1083
- this.release = { host: st.host, code: st.code };
1197
+ this.release = releaseOf(st);
1084
1198
  return true;
1085
1199
  }
1086
1200
  /** 超时代出:先用 timeout,被规则拒了再用 ai 试一次。都不行返回 false(记日志)。 */
@@ -1474,7 +1588,7 @@ export class GameRoom extends DurableObject {
1474
1588
  st.ending = { reason, at: Date.now() };
1475
1589
  st.effectsAt = null;
1476
1590
  st.effectTries = 0;
1477
- this.release = { host: st.host, code: st.code };
1591
+ this.release = releaseOf(st);
1478
1592
  this.closing = false;
1479
1593
  this.planAlarm();
1480
1594
  this.save();
@@ -1490,7 +1604,7 @@ export class GameRoom extends DurableObject {
1490
1604
  ws.close(CLOSE.roomClosed, reason);
1491
1605
  }
1492
1606
  if (this.st)
1493
- this.release = { host: this.st.host, code: this.st.code };
1607
+ this.release = releaseOf(this.st);
1494
1608
  this.st = null;
1495
1609
  this.alarmToSet = null;
1496
1610
  this.alarmAt = null;
@@ -1554,12 +1668,13 @@ export class GameRoom extends DurableObject {
1554
1668
  turn,
1555
1669
  ...(st.opts !== undefined ? { opts: st.opts } : {}),
1556
1670
  ...(until !== null ? { pause: { until } } : {}),
1671
+ ...(st.match ? { match: true } : {}),
1557
1672
  };
1558
1673
  }
1559
1674
  /** 这个房间的自己人:房主、坐着的、开打后绑过座位的。猜码超限时只放他们进(0.14.0) */
1560
1675
  insider(userId) {
1561
1676
  const st = this.load();
1562
- return !!st && (st.host === userId || this.seatOf(userId) !== null || this.boundOf(userId) !== null);
1677
+ return !!st && (st.host === userId || this.seatOf(userId) !== null || this.boundOf(userId) !== null || !!st.match?.users.includes(userId));
1563
1678
  }
1564
1679
  /** 房主,或者开打后绑过座位的人:旁观名额不算他们(0.14.0) */
1565
1680
  ownsRoom(st, userId) {
@@ -1666,6 +1781,31 @@ function sameGroup(before, seat, after) {
1666
1781
  function validHost(code, host) {
1667
1782
  return ROOM_CODE_RE.test(code) && !!host && typeof host.userId === 'string' && !!host.userId && typeof host.name === 'string';
1668
1783
  }
1784
+ /** 打完、关房时要还谁的名额:匹配桌是排进来的每个人,好友房是房主 */
1785
+ function releaseOf(st) {
1786
+ return { users: st.match ? [...st.match.users] : [st.host], code: st.code };
1787
+ }
1788
+ /** 匹配桌的人:1 到 count 个、userId 不重复、各自像个身份 */
1789
+ function validPlayers(code, players, count) {
1790
+ if (!Array.isArray(players) || players.length < 1 || players.length > count)
1791
+ return false;
1792
+ if (!players.every((p) => validHost(code, p)))
1793
+ return false;
1794
+ return new Set(players.map((p) => p.userId)).size === players.length;
1795
+ }
1796
+ function validSeats(order, n, count) {
1797
+ return Array.isArray(order) && order.length === n && new Set(order).size === n && order.every((x) => Number.isInteger(x) && x >= 0 && x < count);
1798
+ }
1799
+ /** 从 0..count-1 里随机挑 n 个座位(crypto;房间里的随机,不是规则核心) */
1800
+ function randomSeats(n, count) {
1801
+ const all = Array.from({ length: count }, (_, i) => i);
1802
+ const r = crypto.getRandomValues(new Uint32Array(count));
1803
+ for (let i = count - 1; i > 0; i--) {
1804
+ const j = r[i] % (i + 1);
1805
+ [all[i], all[j]] = [all[j], all[i]];
1806
+ }
1807
+ return all.slice(0, n);
1808
+ }
1669
1809
  function emptySeat() {
1670
1810
  return { kind: 'empty', userId: null, name: null, awaySince: null, auto: false, lastMoveId: null };
1671
1811
  }