@yyyu-star/arcade-kit 0.13.1 → 0.15.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.
- package/CHANGELOG.md +25 -0
- package/README.md +16 -5
- package/dist/internal.d.ts +6 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +8 -0
- package/dist/internal.js.map +1 -1
- package/dist/meter.d.ts +15 -0
- package/dist/meter.d.ts.map +1 -1
- package/dist/meter.js +27 -0
- package/dist/meter.js.map +1 -1
- package/dist/qr.d.ts +15 -0
- package/dist/qr.d.ts.map +1 -0
- package/dist/qr.js +264 -0
- package/dist/qr.js.map +1 -0
- package/dist/room.d.ts +12 -2
- package/dist/room.d.ts.map +1 -1
- package/dist/room.js +31 -12
- package/dist/room.js.map +1 -1
- package/dist/share.d.ts +33 -14
- package/dist/share.d.ts.map +1 -1
- package/dist/share.js +99 -22
- package/dist/share.js.map +1 -1
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +44 -3
- package/dist/worker.js.map +1 -1
- package/package.json +2 -1
- package/src/internal.ts +11 -0
- package/src/meter.ts +37 -0
- package/src/qr.ts +259 -0
- package/src/room.ts +35 -13
- package/src/share.ts +104 -24
- package/src/worker.ts +42 -4
package/src/worker.ts
CHANGED
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
import { identify, sameOrigin } from './auth.js';
|
|
14
14
|
import { type GuestOptions, isStandalone, type ModeEnv } from './guest.js';
|
|
15
15
|
import { CLOSE, type CreateError, ROOM_CODE_RE } from './protocol.js';
|
|
16
|
-
import { identityHeader, type Identity, KIT_HOST, newRoomCode, roomStub } from './internal.js';
|
|
17
|
-
|
|
16
|
+
import { identityHeader, type Identity, KIT_HOST, LIMITED_HEADER, meterStub, MISS_HEADER, missStub, newRoomCode, roomStub } from './internal.js';
|
|
17
|
+
// 只引类型:meter.ts 依赖 cloudflare:workers,游戏会在普通 Node 的测试里加载本文件
|
|
18
|
+
import type { MeterEnv, RoomMeter } from './meter.js';
|
|
18
19
|
import type { CreateOutcome } from './room.js';
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -119,11 +120,48 @@ export async function acceptJoin(request: Request, env: KitEnv, code: string, op
|
|
|
119
120
|
const w = await who(request, env, opts, false);
|
|
120
121
|
if ('error' in w) return w.error === 'anonymous' ? refuse(CLOSE.unauthorized, 'login first') : refuse(CLOSE.tryLater, 'try later');
|
|
121
122
|
const me = w.user;
|
|
123
|
+
// 进房猜码(0.14.0):这一小时"码不存在"超了门槛的人(或 IP)带上 LIMITED_HEADER,房间只放自己人进,别人不管房间在不在都回 1013,
|
|
124
|
+
// 说不出房间在不在;在打的人照常重连。计量连不上时同样处理(和开房一样不放新人进来)
|
|
125
|
+
const guard = missGuard(env, me.userId, request.headers.get('cf-connecting-ip'));
|
|
126
|
+
let limited = false;
|
|
127
|
+
try {
|
|
128
|
+
limited = !!guard && !(await guard.ok());
|
|
129
|
+
} catch (e) {
|
|
130
|
+
console.error('join guard failed', e instanceof Error ? e.message : e);
|
|
131
|
+
limited = true;
|
|
132
|
+
}
|
|
122
133
|
// 新建请求,只带认好的身份和客户端版本;浏览器带来的 x-kit-user 之类的头一律不转
|
|
123
134
|
const cv = new URL(request.url).searchParams.get('cv') ?? '0';
|
|
124
|
-
|
|
125
|
-
headers: { upgrade: 'websocket', 'x-kit-user': identityHeader(me) },
|
|
135
|
+
const res = await roomStub(env.ROOM, code).fetch(`https://${KIT_HOST}/ws?cv=${encodeURIComponent(cv)}`, {
|
|
136
|
+
headers: { upgrade: 'websocket', 'x-kit-user': identityHeader(me), ...(limited ? { [LIMITED_HEADER]: '1' } : {}) },
|
|
126
137
|
});
|
|
138
|
+
if (!res.headers.has(MISS_HEADER)) return res;
|
|
139
|
+
// 房间说"这个码没有房间":记一次(按人、按 IP 各 1 行,再报进当天的写入),转给浏览器的回话不带这个内部头
|
|
140
|
+
if (guard) await guard.miss().catch((e: unknown) => console.error('join miss record failed', e instanceof Error ? e.message : e));
|
|
141
|
+
return new Response(null, { status: 101, webSocket: res.webSocket });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* 按人、按 IP 数"码不存在"(0.14.0,第三轮审计:6 位房间码能一个个试)。没绑 METER(单独部署、测试里没配)就不管,和开房额度一样。
|
|
146
|
+
* 没有 IP 头(本地开发)只按人算
|
|
147
|
+
*/
|
|
148
|
+
function missGuard(env: KitEnv, userId: string, ip: string | null): { ok(): Promise<boolean>; miss(): Promise<void> } | null {
|
|
149
|
+
const ns = env.METER;
|
|
150
|
+
if (!ns) return null;
|
|
151
|
+
const keys: [string, 'user' | 'ip'][] = [[`u:${userId}`, 'user']];
|
|
152
|
+
if (ip) keys.push([`ip:${ip}`, 'ip']);
|
|
153
|
+
const stub = (k: string) => missStub(ns, k) as DurableObjectStub<RoomMeter>;
|
|
154
|
+
return {
|
|
155
|
+
async ok() {
|
|
156
|
+
const blocked = await Promise.all(keys.map(([k, kind]) => stub(k).kitMissBlocked(kind)));
|
|
157
|
+
return !blocked.includes(true);
|
|
158
|
+
},
|
|
159
|
+
async miss() {
|
|
160
|
+
await Promise.all(keys.map(([k]) => stub(k).kitMiss()));
|
|
161
|
+
// 这几行也记进当天的写入(计量自己的规矩),报一次计量再写 1 行
|
|
162
|
+
await (meterStub(ns) as DurableObjectStub<RoomMeter>).kitReport(keys.length);
|
|
163
|
+
},
|
|
164
|
+
};
|
|
127
165
|
}
|
|
128
166
|
|
|
129
167
|
function refuse(code: number, reason: string): Response {
|