koishipro-core.js 1.2.2 → 1.2.4
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 +75 -0
- package/dist/index.cjs +159 -40
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +156 -39
- package/dist/index.mjs.map +4 -4
- package/dist/src/advancors/combined-advancor.d.ts +2 -0
- package/dist/src/advancors/index.d.ts +9 -0
- package/dist/src/advancors/limit-advancor.d.ts +4 -0
- package/dist/src/advancors/map-advancor.d.ts +8 -0
- package/dist/src/advancors/no-effect-advancor.d.ts +1 -0
- package/dist/src/advancors/player-view-advancor.d.ts +3 -0
- package/dist/src/advancors/select-card-advancor.d.ts +7 -0
- package/dist/src/advancors/slient-advancor.d.ts +2 -0
- package/dist/src/advancors/static-advancor.d.ts +2 -0
- package/dist/src/advancors/summon-place-advancor.d.ts +5 -0
- package/dist/src/advancors/types.d.ts +2 -0
- package/dist/src/ocgcore-duel.d.ts +2 -0
- package/dist/src/play-yrp.d.ts +1 -8
- package/dist/src/types/card-location.d.ts +5 -0
- package/dist/src/types/index.d.ts +1 -0
- package/index.ts +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -162,6 +162,26 @@ Represents a single duel instance with full lifecycle management.
|
|
|
162
162
|
- `endDuel(): void`
|
|
163
163
|
End the duel and clean up resources.
|
|
164
164
|
|
|
165
|
+
**Advance Helpers (Advancors):**
|
|
166
|
+
- `advance(advancor?: Advancor): Generator<OcgcoreProcessResult>`
|
|
167
|
+
Advances the duel processing loop. It repeatedly calls `process()`, and when a response is required, it invokes your advancor. It stops when the duel ends, a retry is requested, or your advancor returns `undefined`.
|
|
168
|
+
|
|
169
|
+
**Example (Advance + Advancor)**
|
|
170
|
+
```ts
|
|
171
|
+
import { createOcgcoreWrapper, SlientAdvancor } from 'koishipro-core.js';
|
|
172
|
+
|
|
173
|
+
const wrapper = await createOcgcoreWrapper();
|
|
174
|
+
// ...setScriptReader / setCardReader / create duel / start duel...
|
|
175
|
+
|
|
176
|
+
const duel = wrapper.createDuel(1234);
|
|
177
|
+
|
|
178
|
+
for (const result of duel.advance(SlientAdvancor())) {
|
|
179
|
+
if (result.message) {
|
|
180
|
+
console.log(result.message);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
165
185
|
**Card Management:**
|
|
166
186
|
- `newCard(card: OcgcoreNewCardParams): void`
|
|
167
187
|
Add a card to the duel.
|
|
@@ -267,6 +287,61 @@ for (const { duel, result } of playYrpStep(wrapper, yrpBytes)) {
|
|
|
267
287
|
}
|
|
268
288
|
```
|
|
269
289
|
|
|
290
|
+
|
|
291
|
+
### Advancors
|
|
292
|
+
Advancors are small response producers. You pass them into `duel.advance(...)` and they auto-generate response bytes for the current message. If multiple advancors are combined, the first one that returns a response wins.
|
|
293
|
+
|
|
294
|
+
**Type**
|
|
295
|
+
```ts
|
|
296
|
+
import { YGOProMsgResponseBase } from 'ygopro-msg-encode';
|
|
297
|
+
|
|
298
|
+
export type Advancor<T extends YGOProMsgResponseBase = YGOProMsgResponseBase> =
|
|
299
|
+
(message: T) => Uint8Array | null | undefined;
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
#### `SlientAdvancor()`
|
|
303
|
+
Calls `defaultResponse()` for any message. In practice, this auto-answers optional effect prompts with “do not activate” and is ideal for fast-forwarding.
|
|
304
|
+
|
|
305
|
+
#### `NoEffectAdvancor()`
|
|
306
|
+
Only responds to `SelectChain` when there are **no** chains available, allowing the duel to continue. It does not auto-decline effect prompts. Use this when you want to handle effect prompts yourself.
|
|
307
|
+
|
|
308
|
+
#### `SummonPlaceAdvancor(placeAndPosition?)`
|
|
309
|
+
Auto-selects summon placement (`SelectPlace`) and position (`SelectPosition`). You can pass a partial filter to constrain player/location/sequence/position.
|
|
310
|
+
|
|
311
|
+
#### `SelectCardAdvancor(...filters)`
|
|
312
|
+
Selects cards by matching filters (e.g., code, location, controller). Supports several message types like `SelectCard`, `SelectUnselectCard`, `SelectSum`, `SelectTribute`.
|
|
313
|
+
|
|
314
|
+
#### `StaticAdvancor(items)`
|
|
315
|
+
Returns a fixed sequence of responses you provide. Each call consumes one item.
|
|
316
|
+
|
|
317
|
+
#### `CombinedAdvancor(...advancors)`
|
|
318
|
+
Runs advancors in order and returns the first non-`undefined` response. This is the same combiner used by `advance(...)` internally.
|
|
319
|
+
|
|
320
|
+
#### `MapAdvancor(...handlers)`
|
|
321
|
+
Dispatches by message class. Each handler maps a message type to an advancor function.
|
|
322
|
+
|
|
323
|
+
#### `MapAdvancorHandler(msgClass, cb)`
|
|
324
|
+
Helper for building `MapAdvancor` handler objects.
|
|
325
|
+
|
|
326
|
+
#### `LimitAdvancor(advancor, limit)`
|
|
327
|
+
Wraps an advancor and only allows it to return a response `limit` times.
|
|
328
|
+
|
|
329
|
+
#### `OnceAdvancor(advancor)`
|
|
330
|
+
Shorthand for `LimitAdvancor(advancor, 1)`.
|
|
331
|
+
|
|
332
|
+
#### `PlayerViewAdvancor(player, advancor)`
|
|
333
|
+
Runs the inner advancor only when `responsePlayer()` matches the specified player.
|
|
334
|
+
|
|
335
|
+
#### Composition
|
|
336
|
+
You can combine advancors to form a pipeline:
|
|
337
|
+
```ts
|
|
338
|
+
duel.advance(
|
|
339
|
+
SlientAdvancor(),
|
|
340
|
+
SummonPlaceAdvancor(),
|
|
341
|
+
SelectCardAdvancor({ code: 28985331 }),
|
|
342
|
+
);
|
|
343
|
+
```
|
|
344
|
+
|
|
270
345
|
### Card Reader
|
|
271
346
|
|
|
272
347
|
#### `SqljsCardReader(...dbs: Database[]): CardReader`
|
package/dist/index.cjs
CHANGED
|
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
// index.ts
|
|
30
30
|
var index_exports = {};
|
|
31
31
|
__export(index_exports, {
|
|
32
|
+
CombinedAdvancor: () => CombinedAdvancor,
|
|
32
33
|
DirCardReader: () => DirCardReader,
|
|
33
34
|
DirReader: () => DirReader,
|
|
34
35
|
DirScriptReader: () => DirScriptReader,
|
|
@@ -36,21 +37,29 @@ __export(index_exports, {
|
|
|
36
37
|
LEN_EMPTY: () => LEN_EMPTY,
|
|
37
38
|
LEN_FAIL: () => LEN_FAIL,
|
|
38
39
|
LEN_HEADER: () => LEN_HEADER,
|
|
40
|
+
LimitAdvancor: () => LimitAdvancor,
|
|
39
41
|
MESSAGE_BUFFER_SIZE: () => MESSAGE_BUFFER_SIZE,
|
|
42
|
+
MapAdvancor: () => MapAdvancor,
|
|
43
|
+
MapAdvancorHandler: () => MapAdvancorHandler,
|
|
40
44
|
MapReader: () => MapReader,
|
|
41
45
|
MapScriptReader: () => MapScriptReader,
|
|
46
|
+
NoEffectAdvancor: () => NoEffectAdvancor,
|
|
42
47
|
OcgcoreDuel: () => OcgcoreDuel,
|
|
43
48
|
OcgcoreDuelOptionFlag: () => OcgcoreDuelOptionFlag,
|
|
44
49
|
OcgcoreDuelRule: () => OcgcoreDuelRule,
|
|
45
50
|
OcgcoreMessageType: () => OcgcoreMessageType,
|
|
46
51
|
OcgcoreWrapper: () => OcgcoreWrapper,
|
|
52
|
+
OnceAdvancor: () => OnceAdvancor,
|
|
53
|
+
PlayerViewAdvancor: () => PlayerViewAdvancor,
|
|
47
54
|
QUERY_BUFFER_SIZE: () => QUERY_BUFFER_SIZE,
|
|
48
55
|
REGISTRY_BUFFER_SIZE: () => REGISTRY_BUFFER_SIZE,
|
|
56
|
+
SlientAdvancor: () => SlientAdvancor,
|
|
49
57
|
SqljsCardReader: () => SqljsCardReader,
|
|
58
|
+
StaticAdvancor: () => StaticAdvancor,
|
|
59
|
+
SummonPlaceAdvancor: () => SummonPlaceAdvancor,
|
|
50
60
|
ZipReader: () => ZipReader,
|
|
51
61
|
ZipScriptReader: () => ZipScriptReader,
|
|
52
62
|
_OcgcoreConstants: () => vendor_exports,
|
|
53
|
-
consumeResponseFromOcgcoreProcess: () => consumeResponseFromOcgcoreProcess,
|
|
54
63
|
createDuelFromYrp: () => createDuelFromYrp,
|
|
55
64
|
createOcgcoreWrapper: () => createOcgcoreWrapper,
|
|
56
65
|
createSqljsCardReader: () => createSqljsCardReader,
|
|
@@ -62,7 +71,6 @@ __export(index_exports, {
|
|
|
62
71
|
parseRegistryKeys: () => parseRegistryKeys,
|
|
63
72
|
playYrp: () => playYrp,
|
|
64
73
|
playYrpStep: () => playYrpStep,
|
|
65
|
-
processYrpDuelStep: () => processYrpDuelStep,
|
|
66
74
|
testCard: () => testCard
|
|
67
75
|
});
|
|
68
76
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -261,6 +269,22 @@ var OcgcoreDuel = class {
|
|
|
261
269
|
message: parsedMessage
|
|
262
270
|
};
|
|
263
271
|
}
|
|
272
|
+
*advance(advancor) {
|
|
273
|
+
while (true) {
|
|
274
|
+
const res = this.process();
|
|
275
|
+
yield res;
|
|
276
|
+
if (res.status === 2 || res.message instanceof import_ygopro_msg_encode3.YGOProMsgRetry) {
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
if (res.status === 1 && res.raw.length > 0) {
|
|
280
|
+
const response = advancor?.(res.message);
|
|
281
|
+
if (!response) {
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
this.setResponse(response);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
264
288
|
newCard(card) {
|
|
265
289
|
this.ocgcoreWrapper.ocgcoreModule._new_card(
|
|
266
290
|
this.duelPtr,
|
|
@@ -1191,6 +1215,7 @@ async function DirCardReader(sqljs, ...baseDirs) {
|
|
|
1191
1215
|
|
|
1192
1216
|
// src/play-yrp.ts
|
|
1193
1217
|
var import_ygopro_yrp_encode = require("ygopro-yrp-encode");
|
|
1218
|
+
var import_ygopro_msg_encode5 = require("ygopro-msg-encode");
|
|
1194
1219
|
var { LOCATION_DECK, LOCATION_EXTRA, POS_FACEDOWN_DEFENSE } = import_ygopro_msg_encode.OcgcoreScriptConstants;
|
|
1195
1220
|
function normalizeYrp(input) {
|
|
1196
1221
|
if (input instanceof import_ygopro_yrp_encode.YGOProYrp) {
|
|
@@ -1290,45 +1315,19 @@ function createDuelFromYrp(wrapper, yrpInput) {
|
|
|
1290
1315
|
duel.startDuel(yrp.opt >>> 0);
|
|
1291
1316
|
return { yrp, duel };
|
|
1292
1317
|
}
|
|
1293
|
-
function consumeResponseFromOcgcoreProcess(duel, result, responses) {
|
|
1294
|
-
if (result.raw.length > 0 && result.raw[0] === import_ygopro_msg_encode.OcgcoreCommonConstants.MSG_RETRY) {
|
|
1295
|
-
throw new Error("Got MSG_RETRY");
|
|
1296
|
-
}
|
|
1297
|
-
if (result.status === 0) {
|
|
1298
|
-
return false;
|
|
1299
|
-
}
|
|
1300
|
-
if (result.status === 1) {
|
|
1301
|
-
if (result.raw.length === 0) {
|
|
1302
|
-
return false;
|
|
1303
|
-
}
|
|
1304
|
-
const response = responses.shift();
|
|
1305
|
-
if (!response) {
|
|
1306
|
-
return true;
|
|
1307
|
-
}
|
|
1308
|
-
duel.setResponse(response);
|
|
1309
|
-
return false;
|
|
1310
|
-
}
|
|
1311
|
-
return true;
|
|
1312
|
-
}
|
|
1313
|
-
function* processYrpDuelStep(duel, yrp) {
|
|
1314
|
-
const responses = yrp.responses.slice();
|
|
1315
|
-
while (true) {
|
|
1316
|
-
const result = duel.process();
|
|
1317
|
-
yield {
|
|
1318
|
-
duel,
|
|
1319
|
-
result,
|
|
1320
|
-
responses
|
|
1321
|
-
};
|
|
1322
|
-
if (consumeResponseFromOcgcoreProcess(duel, result, responses)) {
|
|
1323
|
-
break;
|
|
1324
|
-
}
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
1318
|
function* playYrpStep(ocgcoreWrapper, yrpInput) {
|
|
1328
1319
|
const { yrp, duel } = createDuelFromYrp(ocgcoreWrapper, yrpInput);
|
|
1320
|
+
const responses = yrp.responses.slice();
|
|
1329
1321
|
try {
|
|
1330
|
-
for (const
|
|
1331
|
-
yield
|
|
1322
|
+
for (const result of duel.advance(() => responses.shift())) {
|
|
1323
|
+
yield {
|
|
1324
|
+
duel,
|
|
1325
|
+
result,
|
|
1326
|
+
responses
|
|
1327
|
+
};
|
|
1328
|
+
if (result.message instanceof import_ygopro_msg_encode5.YGOProMsgRetry) {
|
|
1329
|
+
throw new Error("Got MSG_RETRY");
|
|
1330
|
+
}
|
|
1332
1331
|
}
|
|
1333
1332
|
} finally {
|
|
1334
1333
|
duel.endDuel();
|
|
@@ -1385,12 +1384,125 @@ function testCard(ocgcoreWrapper, ...ids) {
|
|
|
1385
1384
|
return logs;
|
|
1386
1385
|
}
|
|
1387
1386
|
|
|
1387
|
+
// src/advancors/slient-advancor.ts
|
|
1388
|
+
var SlientAdvancor = () => {
|
|
1389
|
+
return (msg) => {
|
|
1390
|
+
return msg.defaultResponse();
|
|
1391
|
+
};
|
|
1392
|
+
};
|
|
1393
|
+
|
|
1394
|
+
// src/advancors/static-advancor.ts
|
|
1395
|
+
var import_nfkit = require("nfkit");
|
|
1396
|
+
var StaticAdvancor = (items) => {
|
|
1397
|
+
const _items = (0, import_nfkit.makeArray)(items).slice();
|
|
1398
|
+
return () => _items.shift();
|
|
1399
|
+
};
|
|
1400
|
+
|
|
1401
|
+
// src/advancors/no-effect-advancor.ts
|
|
1402
|
+
var import_ygopro_msg_encode6 = require("ygopro-msg-encode");
|
|
1403
|
+
|
|
1404
|
+
// src/advancors/map-advancor.ts
|
|
1405
|
+
var MapAdvancorHandler = (msgClass, cb) => ({
|
|
1406
|
+
msgClass,
|
|
1407
|
+
cb
|
|
1408
|
+
});
|
|
1409
|
+
var MapAdvancor = (...handlers) => {
|
|
1410
|
+
const handlerMap = /* @__PURE__ */ new Map();
|
|
1411
|
+
for (const handleObj of handlers) {
|
|
1412
|
+
handlerMap.set(handleObj.msgClass, handleObj.cb);
|
|
1413
|
+
}
|
|
1414
|
+
return (msg) => {
|
|
1415
|
+
const cb = handlerMap.get(
|
|
1416
|
+
msg.constructor
|
|
1417
|
+
);
|
|
1418
|
+
if (cb != null) {
|
|
1419
|
+
const res = cb(msg);
|
|
1420
|
+
if (res != null) {
|
|
1421
|
+
return res;
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
return void 0;
|
|
1425
|
+
};
|
|
1426
|
+
};
|
|
1427
|
+
|
|
1428
|
+
// src/advancors/no-effect-advancor.ts
|
|
1429
|
+
var NoEffectAdvancor = () => MapAdvancor(
|
|
1430
|
+
MapAdvancorHandler(import_ygopro_msg_encode6.YGOProMsgSelectChain, (msg) => {
|
|
1431
|
+
if (msg.chains.length) {
|
|
1432
|
+
return;
|
|
1433
|
+
}
|
|
1434
|
+
return msg.prepareResponse(void 0);
|
|
1435
|
+
})
|
|
1436
|
+
);
|
|
1437
|
+
|
|
1438
|
+
// src/advancors/combined-advancor.ts
|
|
1439
|
+
var CombinedAdvancor = (...advancors) => {
|
|
1440
|
+
return (msg) => {
|
|
1441
|
+
for (const advancor of advancors) {
|
|
1442
|
+
const res = advancor(msg);
|
|
1443
|
+
if (res != null) {
|
|
1444
|
+
return res;
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
return void 0;
|
|
1448
|
+
};
|
|
1449
|
+
};
|
|
1450
|
+
|
|
1451
|
+
// src/advancors/limit-advancor.ts
|
|
1452
|
+
var LimitAdvancor = (a, limit = 1) => {
|
|
1453
|
+
let called = 0;
|
|
1454
|
+
return (msg) => {
|
|
1455
|
+
if (called >= limit) {
|
|
1456
|
+
return void 0;
|
|
1457
|
+
}
|
|
1458
|
+
const res = a(msg);
|
|
1459
|
+
if (res !== void 0) {
|
|
1460
|
+
called++;
|
|
1461
|
+
}
|
|
1462
|
+
return res;
|
|
1463
|
+
};
|
|
1464
|
+
};
|
|
1465
|
+
var OnceAdvancor = (a) => LimitAdvancor(a, 1);
|
|
1466
|
+
|
|
1467
|
+
// src/advancors/player-view-advancor.ts
|
|
1468
|
+
var PlayerViewAdvancor = (player, a) => (msg) => {
|
|
1469
|
+
if (msg.responsePlayer() === player) {
|
|
1470
|
+
return a(msg);
|
|
1471
|
+
}
|
|
1472
|
+
return void 0;
|
|
1473
|
+
};
|
|
1474
|
+
|
|
1475
|
+
// src/advancors/summon-place-advancor.ts
|
|
1476
|
+
var import_ygopro_msg_encode7 = require("ygopro-msg-encode");
|
|
1477
|
+
var SummonPlaceAdvancor = (placeAndPosition = {}) => MapAdvancor(
|
|
1478
|
+
MapAdvancorHandler(import_ygopro_msg_encode7.YGOProMsgSelectPlace, (msg) => {
|
|
1479
|
+
const places = msg.getSelectablePlaces().filter(
|
|
1480
|
+
(p) => (placeAndPosition.player == null || p.player === placeAndPosition.player) && (placeAndPosition.location == null || p.location === placeAndPosition.location) && (placeAndPosition.sequence == null || p.sequence === placeAndPosition.sequence)
|
|
1481
|
+
).slice(0, msg.count);
|
|
1482
|
+
return msg.prepareResponse(places);
|
|
1483
|
+
}),
|
|
1484
|
+
MapAdvancorHandler(import_ygopro_msg_encode7.YGOProMsgSelectPosition, (msg) => {
|
|
1485
|
+
if (placeAndPosition.position) {
|
|
1486
|
+
return msg.prepareResponse(placeAndPosition.position);
|
|
1487
|
+
}
|
|
1488
|
+
const possiblePositions = msg.positions;
|
|
1489
|
+
for (let i = 0; i < 8; i++) {
|
|
1490
|
+
const value = 1 << i;
|
|
1491
|
+
if ((possiblePositions & value) !== 0) {
|
|
1492
|
+
return msg.prepareResponse(value);
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
return void 0;
|
|
1496
|
+
})
|
|
1497
|
+
);
|
|
1498
|
+
|
|
1388
1499
|
// index.ts
|
|
1389
1500
|
if (typeof globalThis !== "undefined" && !globalThis.Buffer) {
|
|
1390
1501
|
globalThis.Buffer = import_buffer.Buffer;
|
|
1391
1502
|
}
|
|
1392
1503
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1393
1504
|
0 && (module.exports = {
|
|
1505
|
+
CombinedAdvancor,
|
|
1394
1506
|
DirCardReader,
|
|
1395
1507
|
DirReader,
|
|
1396
1508
|
DirScriptReader,
|
|
@@ -1398,21 +1510,29 @@ if (typeof globalThis !== "undefined" && !globalThis.Buffer) {
|
|
|
1398
1510
|
LEN_EMPTY,
|
|
1399
1511
|
LEN_FAIL,
|
|
1400
1512
|
LEN_HEADER,
|
|
1513
|
+
LimitAdvancor,
|
|
1401
1514
|
MESSAGE_BUFFER_SIZE,
|
|
1515
|
+
MapAdvancor,
|
|
1516
|
+
MapAdvancorHandler,
|
|
1402
1517
|
MapReader,
|
|
1403
1518
|
MapScriptReader,
|
|
1519
|
+
NoEffectAdvancor,
|
|
1404
1520
|
OcgcoreDuel,
|
|
1405
1521
|
OcgcoreDuelOptionFlag,
|
|
1406
1522
|
OcgcoreDuelRule,
|
|
1407
1523
|
OcgcoreMessageType,
|
|
1408
1524
|
OcgcoreWrapper,
|
|
1525
|
+
OnceAdvancor,
|
|
1526
|
+
PlayerViewAdvancor,
|
|
1409
1527
|
QUERY_BUFFER_SIZE,
|
|
1410
1528
|
REGISTRY_BUFFER_SIZE,
|
|
1529
|
+
SlientAdvancor,
|
|
1411
1530
|
SqljsCardReader,
|
|
1531
|
+
StaticAdvancor,
|
|
1532
|
+
SummonPlaceAdvancor,
|
|
1412
1533
|
ZipReader,
|
|
1413
1534
|
ZipScriptReader,
|
|
1414
1535
|
_OcgcoreConstants,
|
|
1415
|
-
consumeResponseFromOcgcoreProcess,
|
|
1416
1536
|
createDuelFromYrp,
|
|
1417
1537
|
createOcgcoreWrapper,
|
|
1418
1538
|
createSqljsCardReader,
|
|
@@ -1424,7 +1544,6 @@ if (typeof globalThis !== "undefined" && !globalThis.Buffer) {
|
|
|
1424
1544
|
parseRegistryKeys,
|
|
1425
1545
|
playYrp,
|
|
1426
1546
|
playYrpStep,
|
|
1427
|
-
processYrpDuelStep,
|
|
1428
1547
|
testCard
|
|
1429
1548
|
});
|
|
1430
1549
|
//# sourceMappingURL=index.cjs.map
|