most-box 0.1.5 → 0.1.7

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 (389) hide show
  1. package/README.md +31 -19
  2. package/out/404/index.html +3 -3
  3. package/out/404.html +3 -3
  4. package/out/__next.__PAGE__.txt +6 -6
  5. package/out/__next._full.txt +16 -16
  6. package/out/__next._head.txt +3 -3
  7. package/out/__next._index.txt +8 -8
  8. package/out/__next._tree.txt +5 -5
  9. package/out/_next/static/chunks/0-c8h4u1i2f78.js +1 -0
  10. package/out/_next/static/chunks/02j6ojja7vzp8.js +1 -0
  11. package/out/_next/static/chunks/06im3as4nwfil.js +1 -0
  12. package/out/_next/static/chunks/0nwdp-n94owg0.css +1 -0
  13. package/out/_next/static/chunks/0sq_0pwxnhby2.js +1 -0
  14. package/out/_next/static/chunks/1ei8b9nw-ea8p.css +1 -0
  15. package/out/_next/static/chunks/1h-f81ddyfcmx.css +1 -0
  16. package/out/_next/static/chunks/{02jvyg27pp0mz.js → 1v-molv0hbcjl.js} +1 -1
  17. package/out/_next/static/chunks/22h69_zwmttt4.js +1 -0
  18. package/out/_next/static/chunks/23zlmarf-go2x.js +1 -0
  19. package/out/_next/static/chunks/24k_4-y4ym0df.js +1 -0
  20. package/out/_next/static/chunks/258tyt1xt34p4.css +1 -0
  21. package/out/_next/static/chunks/2693fczty5yr8.js +1 -0
  22. package/out/_next/static/chunks/26hcvxjw9do9d.js +1 -0
  23. package/out/_next/static/chunks/2_i1b78h0yiu_.js +1 -0
  24. package/out/_next/static/chunks/2fmkcw8ui5xp3.js +5 -0
  25. package/out/_next/static/chunks/2uget3ephe4e3.js +736 -0
  26. package/out/_next/static/chunks/2va-v1iiap4zv.js +1 -0
  27. package/out/_next/static/chunks/2vm9uslik2wfi.css +5 -0
  28. package/out/_next/static/chunks/3e9ia0hs-pqvs.css +1 -0
  29. package/out/_next/static/chunks/3ejz1mdljwwqf.css +1 -0
  30. package/out/_next/static/chunks/3fea100s764m-.js +1 -0
  31. package/out/_next/static/chunks/3g0c367tk4esf.js +1 -0
  32. package/out/_next/static/chunks/3mccxoa60ley8.js +1 -0
  33. package/out/_next/static/chunks/{0gcsdf57gcm6h.js → 3oe03qxgd_rid.js} +1 -1
  34. package/out/_next/static/chunks/3r5wf57k0gys9.js +1 -0
  35. package/out/_next/static/chunks/3yc_zd5vxq0j7.css +1 -0
  36. package/out/_next/static/chunks/418_591yp64lx.css +23 -0
  37. package/out/_next/static/chunks/43l72x-2z3zxb.js +1 -0
  38. package/out/_next/static/chunks/{turbopack-05qngmxam3ar~.js → turbopack-026p0g9v9_pva.js} +1 -1
  39. package/out/_not-found/__next._full.txt +13 -13
  40. package/out/_not-found/__next._head.txt +3 -3
  41. package/out/_not-found/__next._index.txt +8 -8
  42. package/out/_not-found/__next._not-found.__PAGE__.txt +4 -4
  43. package/out/_not-found/__next._not-found.txt +3 -3
  44. package/out/_not-found/__next._tree.txt +3 -3
  45. package/out/_not-found/index.html +3 -3
  46. package/out/_not-found/index.txt +13 -13
  47. package/out/admin/__next._full.txt +15 -15
  48. package/out/admin/__next._head.txt +3 -3
  49. package/out/admin/__next._index.txt +8 -8
  50. package/out/admin/__next._tree.txt +4 -4
  51. package/out/admin/__next.admin.__PAGE__.txt +4 -4
  52. package/out/admin/__next.admin.txt +4 -4
  53. package/out/admin/index.html +3 -3
  54. package/out/admin/index.txt +15 -15
  55. package/out/app/__next._full.txt +14 -14
  56. package/out/app/__next._head.txt +3 -3
  57. package/out/app/__next._index.txt +8 -8
  58. package/out/app/__next._tree.txt +3 -3
  59. package/out/app/__next.app.__PAGE__.txt +4 -4
  60. package/out/app/__next.app.txt +3 -3
  61. package/out/app/index.html +3 -3
  62. package/out/app/index.txt +14 -14
  63. package/out/chat/__next._full.txt +15 -15
  64. package/out/chat/__next._head.txt +3 -3
  65. package/out/chat/__next._index.txt +8 -8
  66. package/out/chat/__next._tree.txt +4 -4
  67. package/out/chat/__next.chat.__PAGE__.txt +4 -4
  68. package/out/chat/__next.chat.txt +4 -4
  69. package/out/chat/index.html +3 -3
  70. package/out/chat/index.txt +15 -15
  71. package/out/chat/join/__next._full.txt +15 -15
  72. package/out/chat/join/__next._head.txt +3 -3
  73. package/out/chat/join/__next._index.txt +8 -8
  74. package/out/chat/join/__next._tree.txt +4 -4
  75. package/out/chat/join/__next.chat.join.__PAGE__.txt +4 -4
  76. package/out/chat/join/__next.chat.join.txt +3 -3
  77. package/out/chat/join/__next.chat.txt +4 -4
  78. package/out/chat/join/index.html +3 -3
  79. package/out/chat/join/index.txt +15 -15
  80. package/out/demo/__next._full.txt +27 -0
  81. package/out/demo/__next._head.txt +5 -0
  82. package/out/demo/__next._index.txt +9 -0
  83. package/out/demo/__next._tree.txt +7 -0
  84. package/out/demo/__next.demo.__PAGE__.txt +12 -0
  85. package/out/demo/__next.demo.txt +5 -0
  86. package/out/demo/index.html +17 -0
  87. package/out/demo/index.txt +27 -0
  88. package/out/download/__next._full.txt +37 -35
  89. package/out/download/__next._head.txt +3 -3
  90. package/out/download/__next._index.txt +8 -8
  91. package/out/download/__next._tree.txt +5 -5
  92. package/out/download/__next.download.__PAGE__.txt +7 -7
  93. package/out/download/__next.download.txt +3 -3
  94. package/out/download/index.html +3 -3
  95. package/out/download/index.txt +37 -35
  96. package/out/game/__next._full.txt +13 -13
  97. package/out/game/__next._head.txt +3 -3
  98. package/out/game/__next._index.txt +8 -8
  99. package/out/game/__next._tree.txt +4 -4
  100. package/out/game/__next.game.__PAGE__.txt +2 -2
  101. package/out/game/__next.game.txt +4 -4
  102. package/out/game/gandengyan/__next._full.txt +16 -16
  103. package/out/game/gandengyan/__next._head.txt +3 -3
  104. package/out/game/gandengyan/__next._index.txt +8 -8
  105. package/out/game/gandengyan/__next._tree.txt +5 -5
  106. package/out/game/gandengyan/__next.game.gandengyan.__PAGE__.txt +5 -5
  107. package/out/game/gandengyan/__next.game.gandengyan.txt +3 -3
  108. package/out/game/gandengyan/__next.game.txt +4 -4
  109. package/out/game/gandengyan/index.html +3 -3
  110. package/out/game/gandengyan/index.txt +16 -16
  111. package/out/game/index.html +1 -1
  112. package/out/game/index.txt +13 -13
  113. package/out/game/zhajinhua/__next._full.txt +16 -15
  114. package/out/game/zhajinhua/__next._head.txt +3 -3
  115. package/out/game/zhajinhua/__next._index.txt +8 -8
  116. package/out/game/zhajinhua/__next._tree.txt +5 -4
  117. package/out/game/zhajinhua/__next.game.txt +4 -4
  118. package/out/game/zhajinhua/__next.game.zhajinhua.__PAGE__.txt +5 -4
  119. package/out/game/zhajinhua/__next.game.zhajinhua.txt +3 -3
  120. package/out/game/zhajinhua/index.html +3 -3
  121. package/out/game/zhajinhua/index.txt +16 -15
  122. package/out/index.html +3 -3
  123. package/out/index.txt +16 -16
  124. package/out/note/__next._full.txt +14 -14
  125. package/out/note/__next._head.txt +3 -3
  126. package/out/note/__next._index.txt +8 -8
  127. package/out/note/__next._tree.txt +3 -3
  128. package/out/note/__next.note.__PAGE__.txt +4 -4
  129. package/out/note/__next.note.txt +3 -3
  130. package/out/note/index.html +3 -3
  131. package/out/note/index.txt +14 -14
  132. package/out/ping/__next._full.txt +16 -16
  133. package/out/ping/__next._head.txt +3 -3
  134. package/out/ping/__next._index.txt +8 -8
  135. package/out/ping/__next._tree.txt +5 -5
  136. package/out/ping/__next.ping.__PAGE__.txt +5 -5
  137. package/out/ping/__next.ping.txt +4 -4
  138. package/out/ping/index.html +3 -3
  139. package/out/ping/index.txt +16 -16
  140. package/out/web3/__next._full.txt +15 -15
  141. package/out/web3/__next._head.txt +3 -3
  142. package/out/web3/__next._index.txt +8 -8
  143. package/out/web3/__next._tree.txt +4 -4
  144. package/out/web3/__next.web3.__PAGE__.txt +4 -4
  145. package/out/web3/__next.web3.txt +4 -4
  146. package/out/web3/ed25519/__next._full.txt +13 -13
  147. package/out/web3/ed25519/__next._head.txt +3 -3
  148. package/out/web3/ed25519/__next._index.txt +8 -8
  149. package/out/web3/ed25519/__next._tree.txt +4 -4
  150. package/out/web3/ed25519/__next.web3.ed25519.__PAGE__.txt +2 -2
  151. package/out/web3/ed25519/__next.web3.ed25519.txt +3 -3
  152. package/out/web3/ed25519/__next.web3.txt +4 -4
  153. package/out/web3/ed25519/index.html +1 -1
  154. package/out/web3/ed25519/index.txt +13 -13
  155. package/out/web3/index.html +3 -3
  156. package/out/web3/index.txt +15 -15
  157. package/out/web3/tools/__next._full.txt +13 -13
  158. package/out/web3/tools/__next._head.txt +3 -3
  159. package/out/web3/tools/__next._index.txt +8 -8
  160. package/out/web3/tools/__next._tree.txt +4 -4
  161. package/out/web3/tools/__next.web3.tools.__PAGE__.txt +2 -2
  162. package/out/web3/tools/__next.web3.tools.txt +3 -3
  163. package/out/web3/tools/__next.web3.txt +4 -4
  164. package/out/web3/tools/index.html +1 -1
  165. package/out/web3/tools/index.txt +13 -13
  166. package/package.json +23 -23
  167. package/server/src/core/gameRoom.js +12 -0
  168. package/server/src/core/mostLink.js +1 -1
  169. package/server/src/core/zhajinhua.js +82 -14
  170. package/server/src/games/gandengyan.js +79 -14
  171. package/server/src/http/app.js +25 -2
  172. package/server/src/http/nodeStatus.js +37 -0
  173. package/server/src/index.js +160 -25
  174. package/out/_next/static/chunks/0.4ov9319fecg.css +0 -1
  175. package/out/_next/static/chunks/0._8s6pbfw.xk.js +0 -1
  176. package/out/_next/static/chunks/06lttvu7563zo.css +0 -1
  177. package/out/_next/static/chunks/09h7l4i38xc7q.css +0 -24
  178. package/out/_next/static/chunks/09hqx79-jkvm_.css +0 -1
  179. package/out/_next/static/chunks/09vcm1ku9k7o8.js +0 -1
  180. package/out/_next/static/chunks/0c6e_d2jq179x.js +0 -1
  181. package/out/_next/static/chunks/0ccalho416.d7.js +0 -1
  182. package/out/_next/static/chunks/0exj_tg.ew-t3.js +0 -1
  183. package/out/_next/static/chunks/0f-wz5d~tv-r4.js +0 -1
  184. package/out/_next/static/chunks/0f0jhsujtf-61.js +0 -1
  185. package/out/_next/static/chunks/0h4r.qtmpa6eh.js +0 -1
  186. package/out/_next/static/chunks/0hyds~bp.auvh.js +0 -1
  187. package/out/_next/static/chunks/0iq1h7g4dudg8.js +0 -1
  188. package/out/_next/static/chunks/0knnzo9aih48r.js +0 -1
  189. package/out/_next/static/chunks/0nzyk~sg_tn._.js +0 -1
  190. package/out/_next/static/chunks/0o9ce4cyf76by.js +0 -736
  191. package/out/_next/static/chunks/0t_3xxx4zkerp.js +0 -5
  192. package/out/_next/static/chunks/0w~2fjq86t7c7.css +0 -1
  193. package/out/_next/static/chunks/0xdwau5k2augv.css +0 -4
  194. package/out/_next/static/chunks/0xrqerhosrp9~.js +0 -1
  195. package/out/_next/static/chunks/0xx_10jns1.s7.css +0 -1
  196. package/out/_next/static/chunks/14-fm9r_mom81.js +0 -1
  197. package/out/_next/static/chunks/14jhy~xia8lh8.js +0 -1
  198. /package/out/_next/static/chunks/{0bld2u_ld~va2.js → 0-jy8rfo075fy.js} +0 -0
  199. /package/out/_next/static/chunks/{0bliugh5lxw55.js → 0-kczrcxjk7lc.js} +0 -0
  200. /package/out/_next/static/chunks/{00d9h1tddnnnd.js → 012yllpioyi-k.js} +0 -0
  201. /package/out/_next/static/chunks/{00tkdqwxch-3s.js → 02f7w-ybfnvpd.js} +0 -0
  202. /package/out/_next/static/chunks/{01l3o90g~1z42.js → 04_v8i3c2y4ni.js} +0 -0
  203. /package/out/_next/static/chunks/{01xlw8hd842-c.js → 05-c3ty_6dwfk.js} +0 -0
  204. /package/out/_next/static/chunks/{01mfky9camw6i.js → 052vp9tk7oqx6.js} +0 -0
  205. /package/out/_next/static/chunks/{01r.v-pqs1vrm.js → 05k6874y7n0cw.js} +0 -0
  206. /package/out/_next/static/chunks/{02zzxfop_k6tl.css → 09g8c9-u_uh1z.css} +0 -0
  207. /package/out/_next/static/chunks/{03edqrb4zdj~g.js → 0az8vxg2gfuhm.js} +0 -0
  208. /package/out/_next/static/chunks/{03h_6oo-gqkhz.js → 0b899y85ei3i_.js} +0 -0
  209. /package/out/_next/static/chunks/{03~yq9q893hmn.js → 0cz1d0mv5g_q7.js} +0 -0
  210. /package/out/_next/static/chunks/{04hcgsanv1hhu.js → 0eg1osglq6nq7.js} +0 -0
  211. /package/out/_next/static/chunks/{05g2q0w5b34.g.js → 0hlvocunlbrjs.js} +0 -0
  212. /package/out/_next/static/chunks/{05of77xycbt8~.js → 0i9k23rx749fx.js} +0 -0
  213. /package/out/_next/static/chunks/{05zwemzfjx3sh.js → 0j6wiyqf1637r.js} +0 -0
  214. /package/out/_next/static/chunks/{06dpc5df94.v1.js → 0knzyzd1jvley.js} +0 -0
  215. /package/out/_next/static/chunks/{06e1~1-z_ic9a.js → 0kp8ujaqwut11.js} +0 -0
  216. /package/out/_next/static/chunks/{075s7sn.ns~u5.js → 0n92y9hb-ta0u.js} +0 -0
  217. /package/out/_next/static/chunks/{07dynrbvd3.f4.js → 0nybb-z3ufrbx.js} +0 -0
  218. /package/out/_next/static/chunks/{07r9nn-pzlgg1.js → 0o-o9af-grvj8.js} +0 -0
  219. /package/out/_next/static/chunks/{07p~uva5pwgwe.js → 0oxr0r0aewn99.js} +0 -0
  220. /package/out/_next/static/chunks/{08576xhv~~jck.js → 0qh3b90ouc9bd.js} +0 -0
  221. /package/out/_next/static/chunks/{08qqf0rsi3oot.js → 0s7i7nfr9j3b1.js} +0 -0
  222. /package/out/_next/static/chunks/{08u211~k~qu52.js → 0sh_jm8siqvek.js} +0 -0
  223. /package/out/_next/static/chunks/{08.72abkgwy9g.js → 0t86ducxkqweb.js} +0 -0
  224. /package/out/_next/static/chunks/{098.p.2-zm4p7.js → 0u0j5i6-n4oqd.js} +0 -0
  225. /package/out/_next/static/chunks/{09ngvtajm7e5y.js → 0v73vfxjds7sj.js} +0 -0
  226. /package/out/_next/static/chunks/{09ps~-43n5qyo.js → 0ve8ixremhwy0.js} +0 -0
  227. /package/out/_next/static/chunks/{09v7_0gclxr46.js → 0vv5cwj6kr506.js} +0 -0
  228. /package/out/_next/static/chunks/{09yql86dir9c4.js → 0w3wf8o-ewec9.js} +0 -0
  229. /package/out/_next/static/chunks/{09zmlfljowj1~.js → 0w6o4o76scrb2.js} +0 -0
  230. /package/out/_next/static/chunks/{0n4t80gjc3q5h.js → 1-88dio6azz54.js} +0 -0
  231. /package/out/_next/static/chunks/{0cn9a7aimbdzq.js → 12zg24u7mbv4z.js} +0 -0
  232. /package/out/_next/static/chunks/{0d3f-nk3c.2re.js → 14lsse587-ccf.js} +0 -0
  233. /package/out/_next/static/chunks/{0dtohpf7~3d12.js → 16qtikqm_sate.js} +0 -0
  234. /package/out/_next/static/chunks/{0e531nije_ln2.js → 17_ly1mk2z3q8.js} +0 -0
  235. /package/out/_next/static/chunks/{0e5zvj_rh0z3m.js → 181421-y2xzj7.js} +0 -0
  236. /package/out/_next/static/chunks/{0myp4sjagr~h0.js → 1_e-vuvfsntao.js} +0 -0
  237. /package/out/_next/static/chunks/{0e-3e8h7g99yf.js → 1aljc62wfhqhr.js} +0 -0
  238. /package/out/_next/static/chunks/{0f4y~rkk-n81e.js → 1b7mbzsylsn-m.js} +0 -0
  239. /package/out/_next/static/chunks/{0fk~0~p7ivfn1.js → 1cjakikh0o1tm.js} +0 -0
  240. /package/out/_next/static/chunks/{0fw6juc~lsj3z.js → 1dfzez629llzh.js} +0 -0
  241. /package/out/_next/static/chunks/{0g0u7785a73vo.js → 1e4ilit3ave6c.js} +0 -0
  242. /package/out/_next/static/chunks/{0gze5uso1mbe9.js → 1gzgcv355ziff.js} +0 -0
  243. /package/out/_next/static/chunks/{0g_fpgh7drfda.js → 1h0o6fj73le9_.js} +0 -0
  244. /package/out/_next/static/chunks/{0hf.aosc-7172.js → 1in766ibz5l-p.js} +0 -0
  245. /package/out/_next/static/chunks/{0hgz35c1ejbs9.js → 1ip_c70si4tj2.js} +0 -0
  246. /package/out/_next/static/chunks/{0hrw-r.xmvmsq.js → 1jlu197-yog_n.js} +0 -0
  247. /package/out/_next/static/chunks/{0hzg4al.v~8~m.js → 1k788fny29y_j.js} +0 -0
  248. /package/out/_next/static/chunks/{0ig8a4sazk3~2.css → 1lxjpnw925-0p.css} +0 -0
  249. /package/out/_next/static/chunks/{0ip9xrols_83o.js → 1mnhfyfn52md5.js} +0 -0
  250. /package/out/_next/static/chunks/{0j4-d0qf.v~kn.js → 1o8brm8yipzn4.js} +0 -0
  251. /package/out/_next/static/chunks/{0jhdeq.j9_02m.js → 1p8oa39bqu6ed.js} +0 -0
  252. /package/out/_next/static/chunks/{0jy63h3i-y69i.js → 1qmnmb_dutuw8.js} +0 -0
  253. /package/out/_next/static/chunks/{0kdnx_u-60k9s.js → 1s6rdcw0q185p.js} +0 -0
  254. /package/out/_next/static/chunks/{0kq~edq42o1-c.js → 1ta0w8zc7tae7.js} +0 -0
  255. /package/out/_next/static/chunks/{0l682p362d-5w.js → 1uvi_hie0s3z5.js} +0 -0
  256. /package/out/_next/static/chunks/{0m68p9txef5rs.js → 1y36s6sv2z7r4.js} +0 -0
  257. /package/out/_next/static/chunks/{0mme-fm5d2oz2.js → 1zf4i-oj7n-ll.js} +0 -0
  258. /package/out/_next/static/chunks/{0y.li-~3oybew.js → 2-vtwv8h_uokj.js} +0 -0
  259. /package/out/_next/static/chunks/{0n.qlfk~z7o.6.js → 2227enga_0c-6.js} +0 -0
  260. /package/out/_next/static/chunks/{0oz3yl6_-716p.js → 24zr4q96g-eii.js} +0 -0
  261. /package/out/_next/static/chunks/{0pqt~8bl3ukh4.js → 27jktro2p5rq9.js} +0 -0
  262. /package/out/_next/static/chunks/{0yl2t7cs-n_ng.js → 2_cqphhur0a6t.js} +0 -0
  263. /package/out/_next/static/chunks/{0yq3kh.hchtm_.js → 2_s88st3j0tql.js} +0 -0
  264. /package/out/_next/static/chunks/{0ys0l5au.9c2c.js → 2_y6edbaubqrt.js} +0 -0
  265. /package/out/_next/static/chunks/{0qqupeexg83u7.js → 2at8y3pbt5cue.js} +0 -0
  266. /package/out/_next/static/chunks/{0rb-ri481.kc9.js → 2cv1zex4has67.js} +0 -0
  267. /package/out/_next/static/chunks/{0rsnmahfd.59p.js → 2e6j5h4ftd4jd.js} +0 -0
  268. /package/out/_next/static/chunks/{0rt6rgnvr-s_p.js → 2e8b26r0td7ou.js} +0 -0
  269. /package/out/_next/static/chunks/{0runh28p_gg6..js → 2ecppdrjm9cs4.js} +0 -0
  270. /package/out/_next/static/chunks/{0shy.t1fwqcev.js → 2gl0wusc9zf3d.js} +0 -0
  271. /package/out/_next/static/chunks/{0t2xr05rlu96l.js → 2im7c515bo69p.js} +0 -0
  272. /package/out/_next/static/chunks/{0t6h56rhg1y5i.js → 2ixaku9ie8hym.js} +0 -0
  273. /package/out/_next/static/chunks/{0tdqd1zunusgk.js → 2jhnrjgj_k2-z.js} +0 -0
  274. /package/out/_next/static/chunks/{0ujbnp38x63ek.js → 2n6pb94vmohgf.js} +0 -0
  275. /package/out/_next/static/chunks/{0ukyg~tkm~h2m.css → 2nbju8t9-ux58.css} +0 -0
  276. /package/out/_next/static/chunks/{0v68pdrp54lb-.js → 2pdxw43rsbho0.js} +0 -0
  277. /package/out/_next/static/chunks/{0vsm0m5sxrb.3.js → 2r6z3vlfw0ppd.js} +0 -0
  278. /package/out/_next/static/chunks/{0vzlz.iboqo3c.js → 2rskzmv3skmq3.js} +0 -0
  279. /package/out/_next/static/chunks/{0w87vbpkf-ogd.js → 2stoe6xiau1b3.js} +0 -0
  280. /package/out/_next/static/chunks/{0xgg0~kmf3gd-.js → 2wqoc60afpg_5.js} +0 -0
  281. /package/out/_next/static/chunks/{0xj24-70ptdzp.js → 2wyvwsayrr98o.js} +0 -0
  282. /package/out/_next/static/chunks/{0xxlx772fr3x4.js → 2y3o2mnyfnx68.js} +0 -0
  283. /package/out/_next/static/chunks/{16i.qbk8t8gf_.js → 3-7y7sjol3yto.js} +0 -0
  284. /package/out/_next/static/chunks/{0z48pmi6buytt.js → 3089gugfv3ov9.js} +0 -0
  285. /package/out/_next/static/chunks/{0zapnvgy89mg..js → 30s3_0brd77ky.js} +0 -0
  286. /package/out/_next/static/chunks/{0_s~ebb-7b2hr.js → 35idql3ziq0wz.js} +0 -0
  287. /package/out/_next/static/chunks/{0_w-0-2z5oqd_.js → 35unmm4isvqg5.js} +0 -0
  288. /package/out/_next/static/chunks/{0-n3pg7th.zza.js → 389wmv2b6x2nn.js} +0 -0
  289. /package/out/_next/static/chunks/{0~4f5p6tvn1lq.js → 39-oy5n969lo6.js} +0 -0
  290. /package/out/_next/static/chunks/{0~3ik-hfp9s-7.js → 39yvee40syj70.js} +0 -0
  291. /package/out/_next/static/chunks/{0~_0ys.2whxbw.js → 3clhij8e1eul0.js} +0 -0
  292. /package/out/_next/static/chunks/{0~_ui9l7.2sxf.js → 3cnsdzbvm3q7p.js} +0 -0
  293. /package/out/_next/static/chunks/{0~.-vxi5oc.r0.js → 3cxmalqqghdac.js} +0 -0
  294. /package/out/_next/static/chunks/{0.4j.0k5a64vg.js → 3d9p88evh2scq.js} +0 -0
  295. /package/out/_next/static/chunks/{0.ozi1_x2.m.~.js → 3eyprczj7yrg6.js} +0 -0
  296. /package/out/_next/static/chunks/{0.t5wlt51zou5.js → 3f9v_gtppe4hs.js} +0 -0
  297. /package/out/_next/static/chunks/{0.w4hkvap~bva.js → 3fj0amtzqae6f.js} +0 -0
  298. /package/out/_next/static/chunks/{1037jlyw5~7ht.js → 3gf98e08a-l_e.js} +0 -0
  299. /package/out/_next/static/chunks/{1045hfzu533z0.js → 3gi6og9m_yaak.js} +0 -0
  300. /package/out/_next/static/chunks/{104e5nmc.c-pl.js → 3giw7r1lii84y.js} +0 -0
  301. /package/out/_next/static/chunks/{109taw1pbh-0b.js → 3gzhy1cs_f2oi.js} +0 -0
  302. /package/out/_next/static/chunks/{10ynz1dy483wf.js → 3i_ceknny1oqt.js} +0 -0
  303. /package/out/_next/static/chunks/{10x7~onqwp338.js → 3iw0815ssih3b.js} +0 -0
  304. /package/out/_next/static/chunks/{11hds.mg~4_r-.js → 3kun-vwr7nzd4.js} +0 -0
  305. /package/out/_next/static/chunks/{11ibzaklcauw~.js → 3kxm1e-b1er3_.js} +0 -0
  306. /package/out/_next/static/chunks/{11z.0s6.42b.p.js → 3mc8fynmv71yg.js} +0 -0
  307. /package/out/_next/static/chunks/{126enaq~f7scl.js → 3n6cor2n9zyn7.js} +0 -0
  308. /package/out/_next/static/chunks/{12pep-2t-qg4n.css → 3or2h8swxfxyj.css} +0 -0
  309. /package/out/_next/static/chunks/{12-9n56l0y3yr.js → 3ppt04b6xqz29.js} +0 -0
  310. /package/out/_next/static/chunks/{1380op_pfk.qo.js → 3ql2pi_m5_5p_.js} +0 -0
  311. /package/out/_next/static/chunks/{14a4fwbiq.l3z.js → 3t-6u8caafiu9.js} +0 -0
  312. /package/out/_next/static/chunks/{146oiw1bggtn4.js → 3tqdzb_n12tdm.js} +0 -0
  313. /package/out/_next/static/chunks/{14cowsqn95m1k.js → 3u6zpg943kpst.js} +0 -0
  314. /package/out/_next/static/chunks/{14dtd3l03v.kx.js → 3uaedu2hf291z.js} +0 -0
  315. /package/out/_next/static/chunks/{14tm3qa-v9o-4.js → 3vladx3wh0d4k.js} +0 -0
  316. /package/out/_next/static/chunks/{14_inksek_rth.js → 3w4o9hklow6fg.js} +0 -0
  317. /package/out/_next/static/chunks/{14_po2rb_arn4.js → 3w56w25z6u89b.js} +0 -0
  318. /package/out/_next/static/chunks/{157z7bowux3xj.js → 3x1y_gkazt6kx.js} +0 -0
  319. /package/out/_next/static/chunks/{15m1_677az2cm.js → 3y7r1h96dtcov.js} +0 -0
  320. /package/out/_next/static/chunks/{15v.~.ne6ogkk.js → 3z0hydntmwg19.js} +0 -0
  321. /package/out/_next/static/chunks/{15-o4kb-evqd7.js → 3zhu1svjr0bc5.js} +0 -0
  322. /package/out/_next/static/chunks/{16u9f35gylw8l.js → 404orp1erq__7.js} +0 -0
  323. /package/out/_next/static/chunks/{17ajyb5ogk5yj.js → 41talcs-dc2tc.js} +0 -0
  324. /package/out/_next/static/chunks/{17dyfxbq8yz8n.js → 421pn8weymo-b.js} +0 -0
  325. /package/out/_next/static/chunks/{180zln9pcq9ih.js → 44987pmr20now.js} +0 -0
  326. /package/out/_next/static/chunks/{1814izi5gh.kp.js → 449ygeh62gitc.js} +0 -0
  327. /package/out/_next/static/{2smv1H9Y4Z2Ri-SL-UFgR → eXddCOt9eyz0j78b1m4Ex}/_buildManifest.js +0 -0
  328. /package/out/_next/static/{2smv1H9Y4Z2Ri-SL-UFgR → eXddCOt9eyz0j78b1m4Ex}/_clientMiddlewareManifest.js +0 -0
  329. /package/out/_next/static/{2smv1H9Y4Z2Ri-SL-UFgR → eXddCOt9eyz0j78b1m4Ex}/_ssgManifest.js +0 -0
  330. /package/out/_next/static/media/{KaTeX_AMS-Regular.0b~8ki5y928w2.woff → KaTeX_AMS-Regular.10y3kupq4t663.woff} +0 -0
  331. /package/out/_next/static/media/{KaTeX_AMS-Regular.0p1vbqd84i2~o.woff2 → KaTeX_AMS-Regular.25ieegmnh38ts.woff2} +0 -0
  332. /package/out/_next/static/media/{KaTeX_AMS-Regular.173t6ktr7uf-w.ttf → KaTeX_AMS-Regular.418dr7cz3fo2x.ttf} +0 -0
  333. /package/out/_next/static/media/{KaTeX_Caligraphic-Bold.01-pzluls4zgb.woff2 → KaTeX_Caligraphic-Bold.06b-ya9t43ioz.woff2} +0 -0
  334. /package/out/_next/static/media/{KaTeX_Caligraphic-Bold.0x2v1lwn~880f.woff → KaTeX_Caligraphic-Bold.2vmk2hva4ctha.woff} +0 -0
  335. /package/out/_next/static/media/{KaTeX_Caligraphic-Bold.16zv5fax0h0ka.ttf → KaTeX_Caligraphic-Bold.40ltxhe834pns.ttf} +0 -0
  336. /package/out/_next/static/media/{KaTeX_Caligraphic-Regular.02i3z7wig438t.ttf → KaTeX_Caligraphic-Regular.07-7u27-nhn_r.ttf} +0 -0
  337. /package/out/_next/static/media/{KaTeX_Caligraphic-Regular.0rysu1t-ncjq8.woff2 → KaTeX_Caligraphic-Regular.2eph4dlhid_m9.woff2} +0 -0
  338. /package/out/_next/static/media/{KaTeX_Caligraphic-Regular.10927swgekwun.woff → KaTeX_Caligraphic-Regular.3gxeetazf831f.woff} +0 -0
  339. /package/out/_next/static/media/{KaTeX_Fraktur-Bold.0et27v~3~4uhe.ttf → KaTeX_Fraktur-Bold.19yqa_tc9d_gx.ttf} +0 -0
  340. /package/out/_next/static/media/{KaTeX_Fraktur-Bold.0e-16u10iuyyf.woff → KaTeX_Fraktur-Bold.1alcy76__wdj2.woff} +0 -0
  341. /package/out/_next/static/media/{KaTeX_Fraktur-Bold.0w23i72~hprpq.woff2 → KaTeX_Fraktur-Bold.2sasz-d-jtw8y.woff2} +0 -0
  342. /package/out/_next/static/media/{KaTeX_Fraktur-Regular.0b.riegzdfue2.woff → KaTeX_Fraktur-Regular.110oo81prr9n5.woff} +0 -0
  343. /package/out/_next/static/media/{KaTeX_Fraktur-Regular.0rekyoa-52fj_.woff2 → KaTeX_Fraktur-Regular.2d10y4xmjvzlf.woff2} +0 -0
  344. /package/out/_next/static/media/{KaTeX_Fraktur-Regular.0vjwa15znhk~4.ttf → KaTeX_Fraktur-Regular.2qhy34r6a05dn.ttf} +0 -0
  345. /package/out/_next/static/media/{KaTeX_Main-Bold.09i7~607shf-h.ttf → KaTeX_Main-Bold.0us_n0tnxlxu7.ttf} +0 -0
  346. /package/out/_next/static/media/{KaTeX_Main-Bold.09lmynrorhcbw.woff → KaTeX_Main-Bold.0v1esh257kqpe.woff} +0 -0
  347. /package/out/_next/static/media/{KaTeX_Main-Bold.16pfc63_du6mx.woff2 → KaTeX_Main-Bold.3-rowy8o6_4ky.woff2} +0 -0
  348. /package/out/_next/static/media/{KaTeX_Main-BoldItalic.0cp37g7x1q8h6.woff → KaTeX_Main-BoldItalic.13355ck5zr48q.woff} +0 -0
  349. /package/out/_next/static/media/{KaTeX_Main-BoldItalic.0d54rk08rx11s.woff2 → KaTeX_Main-BoldItalic.14r2naom8mrec.woff2} +0 -0
  350. /package/out/_next/static/media/{KaTeX_Main-BoldItalic.15j6k~hix2t_0.ttf → KaTeX_Main-BoldItalic.3x_u9cepaced0.ttf} +0 -0
  351. /package/out/_next/static/media/{KaTeX_Main-Italic.0382gqciexmbu.woff → KaTeX_Main-Italic.0afv392dj4w59.woff} +0 -0
  352. /package/out/_next/static/media/{KaTeX_Main-Italic.06o5nq0_91v60.woff2 → KaTeX_Main-Italic.0lig0v9j0700p.woff2} +0 -0
  353. /package/out/_next/static/media/{KaTeX_Main-Italic.0su4i6mm18-wo.ttf → KaTeX_Main-Italic.2hkw3230mfwcv.ttf} +0 -0
  354. /package/out/_next/static/media/{KaTeX_Main-Regular.08zh8z.7shijf.ttf → KaTeX_Main-Regular.0symfa7dqj6jd.ttf} +0 -0
  355. /package/out/_next/static/media/{KaTeX_Main-Regular.0diheg01zyoph.woff → KaTeX_Main-Regular.15u8r3b2y7fv4.woff} +0 -0
  356. /package/out/_next/static/media/{KaTeX_Main-Regular.0kaf-ag2_wkm-.woff2 → KaTeX_Main-Regular.1ryvsdzh2w1_e.woff2} +0 -0
  357. /package/out/_next/static/media/{KaTeX_Math-BoldItalic.0ajzxypnbx1h1.ttf → KaTeX_Math-BoldItalic.0y5w36a5aq__2.ttf} +0 -0
  358. /package/out/_next/static/media/{KaTeX_Math-BoldItalic.0ck1myuerwyqw.woff → KaTeX_Math-BoldItalic.12pl58orkw9rg.woff} +0 -0
  359. /package/out/_next/static/media/{KaTeX_Math-BoldItalic.0ja97dn.cpc87.woff2 → KaTeX_Math-BoldItalic.1oopuu636h4il.woff2} +0 -0
  360. /package/out/_next/static/media/{KaTeX_Math-Italic.09xkhecjcn5r9.woff → KaTeX_Math-Italic.0w0b1ugh62cfr.woff} +0 -0
  361. /package/out/_next/static/media/{KaTeX_Math-Italic.0x23a-bmp-5tg.ttf → KaTeX_Math-Italic.2vkekfblmz5nb.ttf} +0 -0
  362. /package/out/_next/static/media/{KaTeX_Math-Italic.0zrha2c4sl2je.woff2 → KaTeX_Math-Italic.32405s1aq8vas.woff2} +0 -0
  363. /package/out/_next/static/media/{KaTeX_SansSerif-Bold.05a9.pc1j_zx9.woff2 → KaTeX_SansSerif-Bold.0h3wi2z_eouyg.woff2} +0 -0
  364. /package/out/_next/static/media/{KaTeX_SansSerif-Bold.0jcl-ayi1uun0.woff → KaTeX_SansSerif-Bold.1ovw5p-yjp56g.woff} +0 -0
  365. /package/out/_next/static/media/{KaTeX_SansSerif-Bold.0re8y.dm7.mt5.ttf → KaTeX_SansSerif-Bold.2d03q85pwxpti.ttf} +0 -0
  366. /package/out/_next/static/media/{KaTeX_SansSerif-Italic.0a0234dc3s62j.woff2 → KaTeX_SansSerif-Italic.0wkjc4dm2kcit.woff2} +0 -0
  367. /package/out/_next/static/media/{KaTeX_SansSerif-Italic.0judofdln9731.woff → KaTeX_SansSerif-Italic.1qavw__2zz8gk.woff} +0 -0
  368. /package/out/_next/static/media/{KaTeX_SansSerif-Italic.10z1iap9pfus8.ttf → KaTeX_SansSerif-Italic.3i-q087b23-m8.ttf} +0 -0
  369. /package/out/_next/static/media/{KaTeX_SansSerif-Regular.0h9yjlugq4q_e.woff → KaTeX_SansSerif-Regular.1i4afx8nk8n4r.woff} +0 -0
  370. /package/out/_next/static/media/{KaTeX_SansSerif-Regular.0v6gcj32-czft.woff2 → KaTeX_SansSerif-Regular.2peiewu59z3d-.woff2} +0 -0
  371. /package/out/_next/static/media/{KaTeX_SansSerif-Regular.0zm18kga42ebc.ttf → KaTeX_SansSerif-Regular.31pbu25feko_c.ttf} +0 -0
  372. /package/out/_next/static/media/{KaTeX_Script-Regular.0c4.h-mer83d_.woff2 → KaTeX_Script-Regular.11h14300o9pd0.woff2} +0 -0
  373. /package/out/_next/static/media/{KaTeX_Script-Regular.0q14y6zkzlpob.ttf → KaTeX_Script-Regular.28p_x7iz71ofe.ttf} +0 -0
  374. /package/out/_next/static/media/{KaTeX_Script-Regular.0ze6v4r_-99oy.woff → KaTeX_Script-Regular.3110jb9c-bxna.woff} +0 -0
  375. /package/out/_next/static/media/{KaTeX_Size1-Regular.013x6a4ierotp.woff2 → KaTeX_Size1-Regular.03lhvx36ekcou.woff2} +0 -0
  376. /package/out/_next/static/media/{KaTeX_Size1-Regular.0kidw0oi.m68o.woff → KaTeX_Size1-Regular.1slf4bh0hc6vm.woff} +0 -0
  377. /package/out/_next/static/media/{KaTeX_Size1-Regular.0m6y-i6wfokni.ttf → KaTeX_Size1-Regular.1y57-ck23ey8c.ttf} +0 -0
  378. /package/out/_next/static/media/{KaTeX_Size2-Regular.0blpmluwilgbg.woff → KaTeX_Size2-Regular.0-kwyvx03omo8.woff} +0 -0
  379. /package/out/_next/static/media/{KaTeX_Size2-Regular.0d5inmyp-tyv3.woff2 → KaTeX_Size2-Regular.14s5gg-puz6h-.woff2} +0 -0
  380. /package/out/_next/static/media/{KaTeX_Size2-Regular.0wnhnvj-.k9d5.ttf → KaTeX_Size2-Regular.2u0s-b07k2o9m.ttf} +0 -0
  381. /package/out/_next/static/media/{KaTeX_Size3-Regular.01h0xm_sfctj3.woff → KaTeX_Size3-Regular.04o9a_02gu_e8.woff} +0 -0
  382. /package/out/_next/static/media/{KaTeX_Size3-Regular.0iukctyhw5j56.woff2 → KaTeX_Size3-Regular.1n1rgzz84z8r9.woff2} +0 -0
  383. /package/out/_next/static/media/{KaTeX_Size3-Regular.0jl8mqyf4gzpn.ttf → KaTeX_Size3-Regular.1pkn-dge4q0fv.ttf} +0 -0
  384. /package/out/_next/static/media/{KaTeX_Size4-Regular.0w3.rb_c4stzk.woff2 → KaTeX_Size4-Regular.2sgotkdv3dcyv.woff2} +0 -0
  385. /package/out/_next/static/media/{KaTeX_Size4-Regular.0wr_9l81-mu06.ttf → KaTeX_Size4-Regular.2uelkfk2yna5e.ttf} +0 -0
  386. /package/out/_next/static/media/{KaTeX_Size4-Regular.12tvaesf3.zl3.woff → KaTeX_Size4-Regular.3p2r1l7xmebxv.woff} +0 -0
  387. /package/out/_next/static/media/{KaTeX_Typewriter-Regular.0c4zdxz~8frhm.woff2 → KaTeX_Typewriter-Regular.11gr2d2wuwz77.woff2} +0 -0
  388. /package/out/_next/static/media/{KaTeX_Typewriter-Regular.0cgrzn5l3kao5.woff → KaTeX_Typewriter-Regular.12f8myjij3617.woff} +0 -0
  389. /package/out/_next/static/media/{KaTeX_Typewriter-Regular.128~qc3858otl.ttf → KaTeX_Typewriter-Regular.3nee9kjfy6nm8.ttf} +0 -0
@@ -179,7 +179,7 @@ export function canStartRound(players = []) {
179
179
  return eligible.length >= ZHJ_MIN_PLAYERS && eligible.length <= ZHJ_MAX_PLAYERS
180
180
  }
181
181
 
182
- export function startRound({ roomCode, players, hostAddress, roundId = createRoundId(), random = Math.random }) {
182
+ export function startRound({ roomCode, players, hostAddress, previousSeq = 0, previousWinner = '', roundId = createRoundId(), random = Math.random }) {
183
183
  const participants = players
184
184
  .filter(player => Number(player.chips) >= ZHJ_ANTE)
185
185
  .slice(0, ZHJ_MAX_PLAYERS)
@@ -204,17 +204,24 @@ export function startRound({ roomCode, players, hostAddress, roundId = createRou
204
204
  }
205
205
  })
206
206
 
207
- const hostIndex = Math.max(
208
- 0,
209
- publicPlayers.findIndex(player => player.address === normalizeAddress(hostAddress))
210
- )
211
- const turnAddress = publicPlayers[(hostIndex + 1) % publicPlayers.length].address
207
+ let turnAddress
208
+ const winnerNorm = normalizeAddress(previousWinner)
209
+ const winnerIndex = winnerNorm
210
+ ? publicPlayers.findIndex(p => normalizeAddress(p.address) === winnerNorm)
211
+ : -1
212
+ if (winnerIndex >= 0) {
213
+ turnAddress = publicPlayers[winnerIndex].address
214
+ } else {
215
+ const randomIndex = Math.floor(random() * publicPlayers.length)
216
+ turnAddress = publicPlayers[randomIndex].address
217
+ }
218
+
212
219
  const round = {
213
220
  roomCode: normalizeRoomCode(roomCode),
214
221
  roundId,
215
222
  status: 'playing',
216
223
  host: normalizeAddress(hostAddress),
217
- seq: 1,
224
+ seq: previousSeq + 1,
218
225
  startedAt: Date.now(),
219
226
  ante: ZHJ_ANTE,
220
227
  pot: ZHJ_ANTE * publicPlayers.length,
@@ -226,6 +233,8 @@ export function startRound({ roomCode, players, hostAddress, roundId = createRou
226
233
  showdown: null,
227
234
  appliedEventIds: [],
228
235
  hands,
236
+ actionCounts: {},
237
+ compareReveal: {},
229
238
  }
230
239
 
231
240
  return round
@@ -268,6 +277,10 @@ export function normalizePublicRoundState(input) {
268
277
  appliedEventIds: Array.isArray(input.appliedEventIds)
269
278
  ? input.appliedEventIds.map(String)
270
279
  : [],
280
+ actionCounts: input.actionCounts && typeof input.actionCounts === 'object' ? clone(input.actionCounts) : {},
281
+ compareReveal: input.compareReveal && typeof input.compareReveal === 'object' ? clone(input.compareReveal) : {},
282
+ lastCompare: input.lastCompare && typeof input.lastCompare === 'object' ? clone(input.lastCompare) : null,
283
+ finishedAt: input.finishedAt ? Number(input.finishedAt) : null,
271
284
  }
272
285
  }
273
286
 
@@ -290,8 +303,7 @@ export function validatePlayerAction(round, actionEvent, authorAddress) {
290
303
  }
291
304
 
292
305
  if (action === 'call') {
293
- const need = Math.max(0, state.currentBet - player.bet)
294
- return player.chips >= need ? { ok: true } : { ok: false, error: '筹码不足,不能跟注' }
306
+ return player.chips >= ZHJ_ANTE ? { ok: true } : { ok: false, error: '筹码不足,不能跟注' }
295
307
  }
296
308
 
297
309
  if (action === 'raise') {
@@ -309,6 +321,11 @@ export function validatePlayerAction(round, actionEvent, authorAddress) {
309
321
  if (!target || target === author || !targetPlayer || targetPlayer.status !== 'active') {
310
322
  return { ok: false, error: '请选择有效的比牌对象' }
311
323
  }
324
+ const activePlayers = state.players.filter(p => p.status === 'active')
325
+ const allActed = activePlayers.every(p => (state.actionCounts?.[p.address] || 0) >= 1)
326
+ if (!allActed) {
327
+ return { ok: false, error: '第一轮不能比牌,请先跟注或加注' }
328
+ }
312
329
  const need = Math.max(0, state.currentBet - player.bet)
313
330
  return player.chips >= need ? { ok: true } : { ok: false, error: '筹码不足,不能比牌' }
314
331
  }
@@ -341,12 +358,16 @@ export function applyPlayerAction(round, actionEvent, authorAddress) {
341
358
  if (actionEvent.action === 'fold') {
342
359
  player.status = 'folded'
343
360
  state.lastAction = `${player.name} 弃牌`
361
+ incrementActionCount(state, author)
344
362
  return maybeFinishOrAdvance(state, author)
345
363
  }
346
364
 
347
365
  if (actionEvent.action === 'call') {
348
- payToCurrentBet(state, player)
366
+ player.chips -= ZHJ_ANTE
367
+ player.bet += ZHJ_ANTE
368
+ state.pot += ZHJ_ANTE
349
369
  state.lastAction = `${player.name} 跟注`
370
+ incrementActionCount(state, author)
350
371
  return maybeFinishOrAdvance(state, author)
351
372
  }
352
373
 
@@ -355,6 +376,7 @@ export function applyPlayerAction(round, actionEvent, authorAddress) {
355
376
  state.currentBet += amount
356
377
  payToCurrentBet(state, player)
357
378
  state.lastAction = `${player.name} 加注 ${amount}`
379
+ incrementActionCount(state, author)
358
380
  return maybeFinishOrAdvance(state, author)
359
381
  }
360
382
 
@@ -362,10 +384,38 @@ export function applyPlayerAction(round, actionEvent, authorAddress) {
362
384
  payToCurrentBet(state, player)
363
385
  const targetAddress = normalizeAddress(actionEvent.target)
364
386
  const targetPlayer = state.players.find(item => item.address === targetAddress)
387
+ const initiatorLooked = player.looked
388
+ const targetLookedBefore = targetPlayer.looked
365
389
  const diff = compareHands(state.hands?.[author] || [], state.hands?.[targetAddress] || [])
390
+ const winner = diff >= 0 ? player : targetPlayer
366
391
  const loser = diff >= 0 ? targetPlayer : player
367
392
  loser.status = 'folded'
393
+ loser.looked = true
394
+ if (!state.compareReveal) state.compareReveal = {}
395
+ const bothLooked = initiatorLooked && targetLookedBefore
396
+ const neitherLooked = !initiatorLooked && !targetLookedBefore
397
+ if (bothLooked) {
398
+ state.compareReveal[author] = state.hands?.[targetAddress] || []
399
+ state.compareReveal[targetAddress] = state.hands?.[author] || []
400
+ } else if (neitherLooked) {
401
+ state.compareReveal[loser.address] = state.hands?.[winner.address] || []
402
+ } else {
403
+ const lookedPlayer = initiatorLooked ? player : targetPlayer
404
+ const unlookedPlayer = initiatorLooked ? targetPlayer : player
405
+ state.compareReveal[lookedPlayer.address] = state.hands?.[unlookedPlayer.address] || []
406
+ state.compareReveal[loser.address] = state.hands?.[winner.address] || []
407
+ }
408
+ state.lastCompare = {
409
+ initiator: author,
410
+ target: targetAddress,
411
+ winner: winner.address,
412
+ loser: loser.address,
413
+ initiatorLooked,
414
+ targetLooked: targetLookedBefore,
415
+ timestamp: Date.now(),
416
+ }
368
417
  state.lastAction = `${player.name} 与 ${targetPlayer.name} 比牌,${loser.name} 出局`
418
+ incrementActionCount(state, author)
369
419
  return maybeFinishOrAdvance(state, author)
370
420
  }
371
421
 
@@ -387,7 +437,11 @@ export function getAllowedActions(round, address) {
387
437
  if (ZHJ_RAISE_STEPS.some(amount => validatePlayerAction(round, { action: 'raise', amount }, player.address).ok)) {
388
438
  actions.push('raise')
389
439
  }
390
- if (getActiveRoundPlayers(round).length > 1) actions.push('compare')
440
+ if (getActiveRoundPlayers(round).length > 1) {
441
+ const activePlayers = round.players.filter(p => p.status === 'active')
442
+ const allActed = activePlayers.every(p => (round.actionCounts?.[p.address] || 0) >= 1)
443
+ if (allActed) actions.push('compare')
444
+ }
391
445
  actions.push('fold')
392
446
  return actions
393
447
  }
@@ -403,6 +457,12 @@ export function chooseBotAction(round, address, random = Math.random) {
403
457
  item => item.address !== botAddress
404
458
  )
405
459
 
460
+ function canCompare() {
461
+ if (!allowedActions.includes('compare') || activeOpponents.length === 0) return false
462
+ const target = activeOpponents[0].address
463
+ return validatePlayerAction(round, { action: 'compare', target }, botAddress).ok
464
+ }
465
+
406
466
  if (
407
467
  allowedActions.includes('look') &&
408
468
  !player?.looked &&
@@ -412,7 +472,7 @@ export function chooseBotAction(round, address, random = Math.random) {
412
472
  }
413
473
 
414
474
  if (
415
- allowedActions.includes('compare') &&
475
+ canCompare() &&
416
476
  activeOpponents.length === 1 &&
417
477
  handStrength >= 0.54 &&
418
478
  random() < 0.58
@@ -426,7 +486,7 @@ export function chooseBotAction(round, address, random = Math.random) {
426
486
  }
427
487
 
428
488
  if (
429
- allowedActions.includes('compare') &&
489
+ canCompare() &&
430
490
  activeOpponents.length > 0 &&
431
491
  handStrength >= 0.82 &&
432
492
  random() < 0.36
@@ -455,6 +515,11 @@ function payToCurrentBet(state, player) {
455
515
  state.pot += need
456
516
  }
457
517
 
518
+ function incrementActionCount(state, address) {
519
+ if (!state.actionCounts) state.actionCounts = {}
520
+ state.actionCounts[address] = (state.actionCounts[address] || 0) + 1
521
+ }
522
+
458
523
  function maybeFinishOrAdvance(state, fromAddress) {
459
524
  const active = getActiveRoundPlayers(state)
460
525
  if (active.length === 1) {
@@ -466,15 +531,18 @@ function maybeFinishOrAdvance(state, fromAddress) {
466
531
 
467
532
  function finishRound(state, winnerAddress) {
468
533
  const winner = state.players.find(player => player.address === winnerAddress)
534
+ const winAmount = state.pot
469
535
  if (winner) {
470
536
  winner.chips += state.pot
471
537
  }
472
538
  state.status = 'finished'
473
539
  state.winner = winnerAddress
540
+ state.winAmount = winAmount
474
541
  state.turnAddress = ''
475
542
  state.showdown = state.hands ? clone(state.hands) : null
476
- state.lastAction = winner ? `${winner.name} 赢得 ${state.pot} 筹码` : '本局结束'
543
+ state.lastAction = winner ? `${winner.name} 赢得 ${winAmount} 筹码` : '本局结束'
477
544
  state.pot = 0
545
+ state.finishedAt = Date.now()
478
546
  return advanceSeq(state)
479
547
  }
480
548
 
@@ -3,7 +3,7 @@ const RANKS = ['3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A', '2']
3
3
  const STRAIGHT_RANKS = RANKS.filter(rank => rank !== '2')
4
4
  const RANK_VALUE = new Map(RANKS.map((rank, index) => [rank, index + 3]))
5
5
  const INITIAL_HAND_SIZE = 5
6
- const SEALED_PENALTY = 15
6
+ const SEALED_PENALTY = 20
7
7
  const INITIAL_SCORE = 1000
8
8
 
9
9
  export function createGanDengYanRoom({
@@ -128,6 +128,7 @@ export function playGanDengYanCards(room, address, cardIds) {
128
128
  return { ok: false, error: '出的牌压不过上一手', state: publicGanDengYanRoom(state) }
129
129
  }
130
130
 
131
+ cards.sort(compareCards)
131
132
  player.hand = player.hand.filter(card => !cardIds.includes(card.id))
132
133
  player.handCount = player.hand.length
133
134
  player.playedCards += cards.length
@@ -181,6 +182,45 @@ export function passGanDengYanTurn(room, address) {
181
182
  return { ok: true, state: publicGanDengYanRoom(state) }
182
183
  }
183
184
 
185
+ export function removeGanDengYanPlayer(room, address) {
186
+ const state = hydrateGanDengYanRoom(room)
187
+ if (!state) return null
188
+ const normalizedAddress = normalizeAddress(address)
189
+ const index = state.players.findIndex(p => p.address === normalizedAddress)
190
+ if (index === -1) return publicGanDengYanRoom(state)
191
+ const leaving = state.players[index]
192
+ const wasCurrentTurn = state.currentSeat === leaving.seat
193
+ const wasLastWinner = state.lastWinnerSeat === leaving.seat
194
+ state.players.splice(index, 1)
195
+ state.passSeats = state.passSeats.filter(seat => seat !== leaving.seat)
196
+ state.log.unshift(`${leaving.name} 已退出房间`)
197
+ const remaining = orderedPlayers(state)
198
+ if (state.status === 'playing') {
199
+ if (remaining.length <= 1) {
200
+ if (remaining.length === 1) {
201
+ finishGame(state, remaining[0])
202
+ } else {
203
+ state.status = 'finished'
204
+ state.log.unshift('玩家不足,本局结束')
205
+ }
206
+ } else {
207
+ if (wasCurrentTurn) {
208
+ const active = activePlayers(state)
209
+ if (active.length > 0) {
210
+ const nextIndex = active.findIndex(p => p.seat > leaving.seat)
211
+ state.currentSeat = active[nextIndex >= 0 ? nextIndex : 0].seat
212
+ }
213
+ }
214
+ if (wasLastWinner && state.table) {
215
+ state.table = null
216
+ state.passSeats = []
217
+ }
218
+ }
219
+ }
220
+ state.seq += 1
221
+ return publicGanDengYanRoom(state)
222
+ }
223
+
184
224
  export function publicGanDengYanRoom(room) {
185
225
  if (!room) return null
186
226
  return {
@@ -188,7 +228,9 @@ export function publicGanDengYanRoom(room) {
188
228
  ownerAddress: room.ownerAddress,
189
229
  status: room.status,
190
230
  seq: Number(room.seq || 1),
231
+ deck: Array.isArray(room.deck) ? room.deck.map(publicCard) : [],
191
232
  deckCount: room.deck?.length || Number(room.deckCount || 0),
233
+ discard: Array.isArray(room.discard) ? room.discard.map(publicCard) : [],
192
234
  discardCount: room.discard?.length || Number(room.discardCount || 0),
193
235
  currentSeat: Number(room.currentSeat || 0),
194
236
  lastWinnerSeat:
@@ -237,7 +279,7 @@ export function hydrateGanDengYanRoom(input) {
237
279
  players: Array.isArray(input.players)
238
280
  ? input.players.map(normalizeRoundPlayer).filter(Boolean)
239
281
  : [],
240
- deck: Array.isArray(input.deck) ? input.deck.map(normalizeCard).filter(Boolean) : [],
282
+ deck: Array.isArray(input.deck) ? input.deck.map(expandCompactCard).filter(Boolean) : [],
241
283
  discard: Array.isArray(input.discard)
242
284
  ? input.discard.map(normalizeCard).filter(Boolean)
243
285
  : [],
@@ -274,6 +316,7 @@ export function hydrateGanDengYanRoom(input) {
274
316
 
275
317
  export function analyzeCards(cards) {
276
318
  if (!cards?.length) return null
319
+ cards = [...cards].sort(compareCards)
277
320
  const jokerCount = cards.filter(isJoker).length
278
321
  const normals = cards.filter(card => !isJoker(card))
279
322
  if (normals.length === 0) return null
@@ -303,15 +346,22 @@ function analyzeBomb(cards, normals, jokerCount) {
303
346
 
304
347
  function analyzeStraight(cards) {
305
348
  if (cards.length < 3) return null
349
+ const jokerCount = cards.filter(isJoker).length
350
+ const normals = cards.filter(card => !isJoker(card))
306
351
  for (let start = 0; start <= STRAIGHT_RANKS.length - cards.length; start += 1) {
307
352
  const values = STRAIGHT_RANKS.slice(start, start + cards.length).map(rank =>
308
353
  RANK_VALUE.get(rank)
309
354
  )
310
- if (
311
- cards.every(
312
- (card, index) => isJoker(card) || cardValue(card) === values[index]
313
- )
314
- ) {
355
+ const remaining = [...values]
356
+ let matched = 0
357
+ for (const card of normals) {
358
+ const idx = remaining.indexOf(cardValue(card))
359
+ if (idx !== -1) {
360
+ remaining.splice(idx, 1)
361
+ matched += 1
362
+ }
363
+ }
364
+ if (matched + jokerCount === cards.length && remaining.length === jokerCount) {
315
365
  return makeCombo('straight', values.at(-1), cards.length, values)
316
366
  }
317
367
  }
@@ -321,16 +371,23 @@ function analyzeStraight(cards) {
321
371
  function analyzePairStraight(cards) {
322
372
  if (cards.length < 4 || cards.length % 2 !== 0) return null
323
373
  const pairCount = cards.length / 2
374
+ const jokerCount = cards.filter(isJoker).length
375
+ const normals = cards.filter(card => !isJoker(card))
324
376
  for (let start = 0; start <= STRAIGHT_RANKS.length - pairCount; start += 1) {
325
377
  const pairValues = STRAIGHT_RANKS.slice(start, start + pairCount).map(rank =>
326
378
  RANK_VALUE.get(rank)
327
379
  )
328
- const values = pairValues.flatMap(value => [value, value])
329
- if (
330
- cards.every(
331
- (card, index) => isJoker(card) || cardValue(card) === values[index]
332
- )
333
- ) {
380
+ const remaining = pairValues.flatMap(value => [value, value])
381
+ let matched = 0
382
+ for (const card of normals) {
383
+ const idx = remaining.indexOf(cardValue(card))
384
+ if (idx !== -1) {
385
+ remaining.splice(idx, 1)
386
+ matched += 1
387
+ }
388
+ }
389
+ if (matched + jokerCount === cards.length && remaining.length === jokerCount) {
390
+ const values = pairValues.flatMap(value => [value, value])
334
391
  return makeCombo('pairStraight', pairValues.at(-1), cards.length, values)
335
392
  }
336
393
  }
@@ -448,7 +505,7 @@ function finishGame(room, winner) {
448
505
  for (const player of orderedPlayers(room)) {
449
506
  if (player.seat === winner.seat) continue
450
507
  const sealed = player.playedCards === 0
451
- const loss = sealed ? SEALED_PENALTY : player.hand.length * room.baseScore
508
+ const loss = sealed ? SEALED_PENALTY : player.hand.length * room.baseScore * 0.5
452
509
  player.score -= loss
453
510
  winnerGain += loss
454
511
  losers.push({
@@ -553,6 +610,14 @@ function suitValue(suit) {
553
610
  return { D: 0, C: 1, H: 2, S: 3, Joker: 4 }[suit] || 0
554
611
  }
555
612
 
613
+ function expandCompactCard(input) {
614
+ if (typeof input === 'string') {
615
+ const [suit, rank] = input.split('-')
616
+ return normalizeCard({ id: input, suit, rank })
617
+ }
618
+ return normalizeCard(input)
619
+ }
620
+
556
621
  function publicCard(card) {
557
622
  return {
558
623
  id: card.id,
@@ -697,8 +697,11 @@ export function createApp(engine, options = {}) {
697
697
  }
698
698
 
699
699
  try {
700
+ const timeout =
701
+ body.timeout === undefined ? undefined : Number(body.timeout)
700
702
  const result = await engine.checkDownloadAvailability(body.link, {
701
703
  ownerAddress: c.get('userAddress'),
704
+ timeout: Number.isFinite(timeout) && timeout > 0 ? timeout : undefined,
702
705
  })
703
706
  return c.json({ success: true, ...result })
704
707
  } catch (err) {
@@ -952,7 +955,11 @@ export function createApp(engine, options = {}) {
952
955
  const result = await engine.createChannel(
953
956
  body.name.trim(),
954
957
  body.type || 'personal',
955
- { ownerAddress: c.get('userAddress') }
958
+ {
959
+ ownerAddress: c.get('userAddress'),
960
+ displayName: body.displayName,
961
+ avatar: body.avatar,
962
+ }
956
963
  )
957
964
  return c.json({ success: true, ...result })
958
965
  } catch (err) {
@@ -998,6 +1005,18 @@ export function createApp(engine, options = {}) {
998
1005
  }
999
1006
  })
1000
1007
 
1008
+ app.get('/api/channels/:name/members', c => {
1009
+ try {
1010
+ return c.json(
1011
+ engine.getChannelMembers(c.req.param('name'), {
1012
+ ownerAddress: c.get('userAddress'),
1013
+ })
1014
+ )
1015
+ } catch (err) {
1016
+ return badRequestOrAppError(c, err)
1017
+ }
1018
+ })
1019
+
1001
1020
  app.post('/api/channels/:name/messages', async c => {
1002
1021
  const name = c.req.param('name')
1003
1022
  const body = await c.req.json()
@@ -1022,7 +1041,11 @@ export function createApp(engine, options = {}) {
1022
1041
  body.content,
1023
1042
  body.author,
1024
1043
  body.authorName,
1025
- { ownerAddress: c.get('userAddress'), attachment: body.attachment }
1044
+ {
1045
+ ownerAddress: c.get('userAddress'),
1046
+ attachment: body.attachment,
1047
+ avatar: body.avatar,
1048
+ }
1026
1049
  )
1027
1050
  return c.json({ success: true, message })
1028
1051
  } catch (err) {
@@ -137,6 +137,43 @@ export function buildOpenApiSpec(appPort) {
137
137
  responses: { 200: { description: 'Pull task result' } },
138
138
  },
139
139
  },
140
+ '/api/files': {
141
+ get: {
142
+ summary: 'List published files for the authenticated local user',
143
+ responses: { 200: { description: 'Published file list' } },
144
+ },
145
+ },
146
+ '/api/publish': {
147
+ post: {
148
+ summary: 'Publish a file and start seeding by CID',
149
+ responses: { 200: { description: 'Published CID and most:// link' } },
150
+ },
151
+ },
152
+ '/api/download/check': {
153
+ post: {
154
+ summary:
155
+ 'Check whether a most:// link is locally available or discoverable',
156
+ responses: { 200: { description: 'Download availability result' } },
157
+ },
158
+ },
159
+ '/api/download': {
160
+ post: {
161
+ summary: 'Start downloading a most:// link',
162
+ responses: { 200: { description: 'Download task result' } },
163
+ },
164
+ },
165
+ '/api/download/cancel': {
166
+ post: {
167
+ summary: 'Cancel an active download task',
168
+ responses: { 200: { description: 'Cancellation result' } },
169
+ },
170
+ },
171
+ '/api/files/{cid}/download': {
172
+ get: {
173
+ summary: 'Read a locally held file by CID',
174
+ responses: { 200: { description: 'File bytes' } },
175
+ },
176
+ },
140
177
  },
141
178
  }
142
179
  }