texas-poker-core 1.4.21 → 1.4.23

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.
package/README.md CHANGED
@@ -591,4 +591,12 @@ fix: 修复结算金额分配异常
591
591
  修复 player reset 字段遗漏
592
592
 
593
593
  ## 1.4.21
594
- 引入领域事件&增加回放功能
594
+
595
+ 引入领域事件&增加回放功能
596
+
597
+ ## 1.4.22
598
+
599
+ 增加外部设置玩家手牌&结算信息的方法
600
+
601
+ ## 1.4.23
602
+ bugfix
@@ -52,6 +52,11 @@ var HandSettlement = exports.HandSettlement = /*#__PURE__*/function () {
52
52
  value: function getPlayerEval(userId) {
53
53
  return _classPrivateFieldGet(_evalByUserId, this).get(userId);
54
54
  }
55
+ }, {
56
+ key: "setPlayerEval",
57
+ value: function setPlayerEval(userId, evalData) {
58
+ _classPrivateFieldGet(_evalByUserId, this).set(userId, evalData);
59
+ }
55
60
  }, {
56
61
  key: "reset",
57
62
  value: function reset() {
@@ -166,6 +166,11 @@ var Controller = /*#__PURE__*/function () {
166
166
  value: function getShowdownEvalForPlayer(player) {
167
167
  return _classPrivateFieldGet(_hand, this).settlement.getPlayerEval(player.id);
168
168
  }
169
+ }, {
170
+ key: "setShowdownEvalForPlayer",
171
+ value: function setShowdownEvalForPlayer(player, evalData) {
172
+ _classPrivateFieldGet(_hand, this).settlement.setPlayerEval(player.id, evalData);
173
+ }
169
174
  }, {
170
175
  key: "activePlayer",
171
176
  get: function get() {
@@ -110,6 +110,17 @@ var DealerService = exports.DealerService = /*#__PURE__*/function () {
110
110
  }, _classPrivateFieldGet(_table, this).button.getNextPlayer());
111
111
  return hole;
112
112
  }
113
+ }, {
114
+ key: "setHoleCardsForPlayer",
115
+ value: function setHoleCardsForPlayer(player, pokes) {
116
+ if (!_classPrivateFieldGet(_table, this).button) return;
117
+ var seatIndex = -1;
118
+ _classPrivateFieldGet(_table, this).loop(function (p, i) {
119
+ if (p === player) seatIndex = i;
120
+ }, _classPrivateFieldGet(_table, this).button.getNextPlayer());
121
+ if (seatIndex < 0) return;
122
+ _classPrivateFieldGet(_dealtBoard, this).setHoleCardsAt(seatIndex, pokes);
123
+ }
113
124
  }, {
114
125
  key: "addAction",
115
126
  value: function addAction(player) {
@@ -103,6 +103,11 @@ var Dealer = /*#__PURE__*/function () {
103
103
  value: function getHoleCardsForPlayer(player) {
104
104
  return _classPrivateFieldGet(_service, this).getHoleCardsForPlayer(player);
105
105
  }
106
+ }, {
107
+ key: "setHoleCardsForPlayer",
108
+ value: function setHoleCardsForPlayer(player, pokes) {
109
+ _classPrivateFieldGet(_service, this).setHoleCardsForPlayer(player, pokes);
110
+ }
106
111
  }, {
107
112
  key: "players",
108
113
  get: function get() {
@@ -5,6 +5,12 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.DealtBoard = void 0;
8
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
9
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
10
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
11
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
12
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
13
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
8
14
  function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
9
15
  function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
10
16
  function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
@@ -46,5 +52,12 @@ var DealtBoard = exports.DealtBoard = /*#__PURE__*/function () {
46
52
  commonPokes: _classPrivateFieldGet(_commonPokes, this)
47
53
  };
48
54
  }
55
+ }, {
56
+ key: "setHoleCardsAt",
57
+ value: function setHoleCardsAt(index, pokes) {
58
+ if (!Number.isInteger(index) || index < 0) return;
59
+ while (_classPrivateFieldGet(_handPokes, this).length <= index) _classPrivateFieldGet(_handPokes, this).push([]);
60
+ _classPrivateFieldGet(_handPokes, this)[index] = _toConsumableArray(pokes);
61
+ }
49
62
  }]);
50
63
  }();
@@ -494,6 +494,16 @@ var Player = exports.Player = /*#__PURE__*/function () {
494
494
  value: function getHandPokes() {
495
495
  return _toConsumableArray(_classPrivateFieldGet(_dealerRing, this).getHoleCardsForPlayer(this));
496
496
  }
497
+ }, {
498
+ key: "setHandPokes",
499
+ value: function setHandPokes(pokes) {
500
+ _classPrivateFieldGet(_dealerRing, this).setHoleCardsForPlayer(this, pokes);
501
+ }
502
+ }, {
503
+ key: "setShowdownEval",
504
+ value: function setShowdownEval(evalData) {
505
+ _classPrivateFieldGet(_handSession, this).setShowdownEvalForPlayer(this, evalData);
506
+ }
497
507
  }, {
498
508
  key: "earn",
499
509
  value: function earn(money) {
@@ -44,7 +44,7 @@ var _idToPlayerMap = /*#__PURE__*/new WeakMap();
44
44
  var _Room_brand = /*#__PURE__*/new WeakSet();
45
45
  // 房间
46
46
  var Room = /*#__PURE__*/function () {
47
- function Room(options) {
47
+ function Room(_options) {
48
48
  _classCallCheck(this, Room);
49
49
  /** 仅当 `seats_open` 时通过;否则抛出给定错误码(设角色与座位结构变更复用同一谓词) */
50
50
  _classPrivateMethodInitSpec(this, _Room_brand);
@@ -65,12 +65,12 @@ var Room = /*#__PURE__*/function () {
65
65
  _defineProperty(this, "fail", function (error) {
66
66
  throw error;
67
67
  });
68
- var dealer = options.dealer,
69
- owner = options.owner,
70
- initialChips = options.initialChips,
71
- _options$maximumCount = options.maximumCountOfPlayers,
68
+ var dealer = _options.dealer,
69
+ owner = _options.owner,
70
+ initialChips = _options.initialChips,
71
+ _options$maximumCount = _options.maximumCountOfPlayers,
72
72
  maximumCountOfPlayers = _options$maximumCount === void 0 ? 10 : _options$maximumCount,
73
- fail = options.fail;
73
+ fail = _options.fail;
74
74
  _classPrivateFieldSet(_owner, this, owner);
75
75
  _classPrivateFieldSet(_dealer, this, dealer);
76
76
  _classPrivateFieldSet(_initialChips, this, initialChips);
@@ -307,34 +307,16 @@ var Room = /*#__PURE__*/function () {
307
307
  var player = _classPrivateFieldGet(_idToPlayerMap, this).get(userId);
308
308
  this.watch(player);
309
309
  }
310
-
310
+ }, {
311
+ key: "remove",
312
+ value:
311
313
  /**
312
314
  * @description 玩家退出房间。仅 **已入座**(`on-set`、在环上)时在 `seats_locked` 下会拦截;
313
315
  * 仅观战(`hang`)可随时离房,不触发锁座校验。
314
316
  * @param player
315
317
  */
316
- }, {
317
- key: "remove",
318
- value: function remove(player) {
319
- if (!player || !_classPrivateGetter(_Room_brand, this, _get_players).has(player)) return this.fail(new _TexasError.default(_TexasError.TexasCoreErrorCode.ROOM_LEAVE_NOT_MEMBER));
320
- var seatedAtRing = _classPrivateFieldGet(_playersOnSet, this).has(player);
321
- if (seatedAtRing) {
322
- _assertClassBrand(_Room_brand, this, _assertSeatsOpen).call(this, _TexasError.TexasCoreErrorCode.ROOM_SEATS_LOCKED_FOR_MUTATION);
323
- }
324
- var isOwner = player === _classPrivateFieldGet(_owner, this);
325
- _classPrivateFieldGet(_idToPlayerMap, this).delete(player.getUserInfo().id);
326
- if (seatedAtRing) {
327
- _classPrivateFieldGet(_dealer, this).remove(player);
328
- _classPrivateFieldGet(_playersOnSet, this).delete(player);
329
- } else {
330
- _classPrivateFieldGet(_playersHang, this).delete(player);
331
- }
332
- // owner 仅是房间治理语义:不阻塞牌桌退出;若 owner 退出则在当前成员中挑一位兜底。
333
- if (isOwner && this.totalPlayersCount > 0) {
334
- var fallbackOwner = this.getAllPlayers()[0];
335
- if (fallbackOwner) _classPrivateFieldSet(_owner, this, fallbackOwner);
336
- }
337
- return null;
318
+ function remove(player) {
319
+ return _assertClassBrand(_Room_brand, this, _removeInternal).call(this, player);
338
320
  }
339
321
  }, {
340
322
  key: "removeById",
@@ -342,6 +324,19 @@ var Room = /*#__PURE__*/function () {
342
324
  var player = _classPrivateFieldGet(_idToPlayerMap, this).get(userId);
343
325
  return this.remove(player);
344
326
  }
327
+
328
+ /**
329
+ * 系统级强制移除:即使 seats_locked 也允许摘掉在座玩家。
330
+ * 仅用于 onLock 清退/风控踢人等服务端策略场景。
331
+ */
332
+ }, {
333
+ key: "removeByIdForce",
334
+ value: function removeByIdForce(userId) {
335
+ var player = _classPrivateFieldGet(_idToPlayerMap, this).get(userId);
336
+ return _assertClassBrand(_Room_brand, this, _removeInternal).call(this, player, {
337
+ ignoreSeatLockForSeated: true
338
+ });
339
+ }
345
340
  }, {
346
341
  key: "status",
347
342
  get: function get() {
@@ -385,4 +380,25 @@ function _beforeSetRoles() {
385
380
  function _get_players(_this) {
386
381
  return new Set([].concat(_toConsumableArray(_classPrivateFieldGet(_playersOnSet, _this)), _toConsumableArray(_classPrivateFieldGet(_playersHang, _this))));
387
382
  }
383
+ function _removeInternal(player, options) {
384
+ if (!player || !_classPrivateGetter(_Room_brand, this, _get_players).has(player)) return this.fail(new _TexasError.default(_TexasError.TexasCoreErrorCode.ROOM_LEAVE_NOT_MEMBER));
385
+ var seatedAtRing = _classPrivateFieldGet(_playersOnSet, this).has(player);
386
+ if (seatedAtRing && !(options !== null && options !== void 0 && options.ignoreSeatLockForSeated)) {
387
+ _assertClassBrand(_Room_brand, this, _assertSeatsOpen).call(this, _TexasError.TexasCoreErrorCode.ROOM_SEATS_LOCKED_FOR_MUTATION);
388
+ }
389
+ var isOwner = player === _classPrivateFieldGet(_owner, this);
390
+ _classPrivateFieldGet(_idToPlayerMap, this).delete(player.getUserInfo().id);
391
+ if (seatedAtRing) {
392
+ _classPrivateFieldGet(_dealer, this).remove(player);
393
+ _classPrivateFieldGet(_playersOnSet, this).delete(player);
394
+ } else {
395
+ _classPrivateFieldGet(_playersHang, this).delete(player);
396
+ }
397
+ // owner 仅是房间治理语义:不阻塞牌桌退出;若 owner 退出则在当前成员中挑一位兜底。
398
+ if (isOwner && this.totalPlayersCount > 0) {
399
+ var fallbackOwner = this.getAllPlayers()[0];
400
+ if (fallbackOwner) _classPrivateFieldSet(_owner, this, fallbackOwner);
401
+ }
402
+ return null;
403
+ }
388
404
  var _default = exports.default = Room;
@@ -226,6 +226,13 @@ var Texas = /*#__PURE__*/function () {
226
226
  this.room.unlockSeats();
227
227
  }
228
228
 
229
+ /** 系统级移除(可绕过 seats_locked);用于 onLock 清退/风控踢人等服务端策略。 */
230
+ }, {
231
+ key: "removePlayerByIdAsSystem",
232
+ value: function removePlayerByIdAsSystem(userId) {
233
+ this.room.removeByIdForce(userId);
234
+ }
235
+
229
236
  /**
230
237
  * 开始本手:`HandStarted` / 盲注等事件进入缓冲,且队列入队首人 `turn_handoff`。
231
238
  * 须随后 drain 并消费队列,首条 `TurnOffered` 才会出现。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "texas-poker-core",
3
- "version": "1.4.21",
3
+ "version": "1.4.23",
4
4
  "description": "德州扑克核心功能",
5
5
  "main": "dist/index.js",
6
6
  "types": "types/index.d.ts",
@@ -20,6 +20,7 @@ export declare class HandSettlement {
20
20
  #private;
21
21
  get snapshot(): RankSettlementSnapshot;
22
22
  getPlayerEval(userId: number): ShowdownPlayerEval | undefined;
23
+ setPlayerEval(userId: number, evalData: ShowdownPlayerEval): void;
23
24
  reset(): void;
24
25
  settleFromCommonBoard(allSeatedPlayers: Player[], playersStillInShowdown: Player[], commonPokes: Poke[]): void;
25
26
  }
@@ -55,6 +55,7 @@ declare class Controller implements GameComponent, PlayerHandSession<Player> {
55
55
  }[];
56
56
  get stage(): StageEnum;
57
57
  getShowdownEvalForPlayer(player: Player): ShowdownPlayerEval | undefined;
58
+ setShowdownEvalForPlayer(player: Player, evalData: ShowdownPlayerEval): void;
58
59
  get activePlayer(): Player | null;
59
60
  recordPlayerAction(player: Player, options: {
60
61
  emitPot: boolean;
@@ -24,6 +24,7 @@ export declare class DealerService implements GameComponent {
24
24
  * 手牌唯一数据源为 {@link DealtBoard};下标与发牌顺序一致(从庄家下家起绕桌一圈)。
25
25
  */
26
26
  getHoleCardsForPlayer(player: Player): Poke[];
27
+ setHoleCardsForPlayer(player: Player, pokes: readonly Poke[]): void;
27
28
  addAction(player: Player): void;
28
29
  initialRoles(buttonPlayer?: Player): undefined;
29
30
  reArrangeRoles(): undefined;
@@ -1,3 +1,4 @@
1
+ import type { Poke } from '../Deck/constant';
1
2
  import type { PlayerDealerRing } from '../playerSessionPorts';
2
3
  import type { GameComponent, TexasErrorCallback } from '../gameContracts';
3
4
  import Deck from '../Deck';
@@ -29,6 +30,7 @@ declare class Dealer implements GameComponent, PlayerDealerRing<Player> {
29
30
  getPokes(): import("..").DealSnapshot;
30
31
  /** 该玩家在 {@link DealtBoard} 中对应座位的手牌(Player 不再私有缓存) */
31
32
  getHoleCardsForPlayer(player: Player): ("hj" | "h2" | "h3" | "h4" | "h5" | "h6" | "h7" | "h8" | "h9" | "ht" | "hq" | "hk" | "ha" | "s2" | "s3" | "s4" | "s5" | "s6" | "s7" | "s8" | "s9" | "st" | "sj" | "sq" | "sk" | "sa" | "d2" | "d3" | "d4" | "d5" | "d6" | "d7" | "d8" | "d9" | "dt" | "dj" | "dq" | "dk" | "da" | "c2" | "c3" | "c4" | "c5" | "c6" | "c7" | "c8" | "c9" | "ct" | "cj" | "cq" | "ck" | "ca")[];
33
+ setHoleCardsForPlayer(player: Player, pokes: readonly Poke[]): void;
32
34
  get players(): Player[];
33
35
  get stakes(): TableStakes;
34
36
  /** 大盲注额;与 `stakes.bigBlind` 同义 */
@@ -11,4 +11,5 @@ export declare class DealtBoard {
11
11
  capture(snapshot: DealSnapshot): void;
12
12
  reset(): void;
13
13
  getPokes(): DealSnapshot;
14
+ setHoleCardsAt(index: number, pokes: readonly Poke[]): void;
14
15
  }
@@ -132,6 +132,13 @@ export declare class Player implements GameComponent {
132
132
  log(prefix?: string): void;
133
133
  /** 手牌唯一存于荷官侧快照,经 {@link Dealer.getHoleCardsForPlayer} 按座位解析 */
134
134
  getHandPokes(): Poke[];
135
+ setHandPokes(pokes: readonly Poke[]): void;
136
+ setShowdownEval(evalData: {
137
+ bestFiveCards: Poke[];
138
+ rankSignature: RankSignature;
139
+ rankStrength: number;
140
+ rankCategory: RankCategory;
141
+ }): void;
135
142
  earn(money: number): void;
136
143
  resetCurrentStageTotalAmount(): void;
137
144
  /**
@@ -94,6 +94,11 @@ declare class Room implements GameComponent {
94
94
  */
95
95
  remove(player?: Player): number | null;
96
96
  removeById(userId: number): number | null;
97
+ /**
98
+ * 系统级强制移除:即使 seats_locked 也允许摘掉在座玩家。
99
+ * 仅用于 onLock 清退/风控踢人等服务端策略场景。
100
+ */
101
+ removeByIdForce(userId: number): number | null;
97
102
  get status(): RoomStatus;
98
103
  has(userId: number): boolean;
99
104
  setStatus(status: RoomStatus): void;
@@ -66,6 +66,8 @@ declare class Texas {
66
66
  dealCards(): TexasDomainEvent[];
67
67
  lockSeats(): void;
68
68
  unlockSeats(): void;
69
+ /** 系统级移除(可绕过 seats_locked);用于 onLock 清退/风控踢人等服务端策略。 */
70
+ removePlayerByIdAsSystem(userId: number): void;
69
71
  /**
70
72
  * 开始本手:`HandStarted` / 盲注等事件进入缓冲,且队列入队首人 `turn_handoff`。
71
73
  * 须随后 drain 并消费队列,首条 `TurnOffered` 才会出现。
@@ -14,6 +14,7 @@ export interface PlayerDealerRing<TPlayer = unknown> {
14
14
  map<R>(callback: (player: TPlayer, index: number) => R): R[];
15
15
  filter(callback: (player: TPlayer, index: number) => boolean): TPlayer[];
16
16
  getHoleCardsForPlayer(player: TPlayer): Poke[];
17
+ setHoleCardsForPlayer(player: TPlayer, pokes: readonly Poke[]): void;
17
18
  }
18
19
  /**
19
20
  * `Player` 需要的「本手阶段机」视图,避免依赖整个 {@link Controller}。
@@ -27,6 +28,7 @@ export interface PlayerHandSession<TPlayer = unknown> {
27
28
  /** 当前轮到行动的玩家;翻前贴盲完成前可能为 `null` */
28
29
  readonly activePlayer: TPlayer | null;
29
30
  getShowdownEvalForPlayer(player: TPlayer): ShowdownPlayerEval | undefined;
31
+ setShowdownEvalForPlayer(player: TPlayer, evalData: ShowdownPlayerEval): void;
30
32
  tryToEndGame(): boolean;
31
33
  /** 下注轮已结束且尚未到河牌时,可推迟进街并由业务调用 `applyPendingStageAdvance` */
32
34
  canDeferBettingRoundStageAdvance(): boolean;