koishipro-core.js 1.0.2 → 1.0.6

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/dist/index.cjs CHANGED
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  var index_exports = {};
31
31
  __export(index_exports, {
32
32
  CardDataStruct: () => CardDataStruct,
33
+ DirReader: () => DirReader,
33
34
  LEN_EMPTY: () => LEN_EMPTY,
34
35
  LEN_FAIL: () => LEN_FAIL,
35
36
  LEN_HEADER: () => LEN_HEADER,
@@ -47,18 +48,13 @@ __export(index_exports, {
47
48
  ZipReader: () => ZipReader,
48
49
  createOcgcoreWrapper: () => createOcgcoreWrapper,
49
50
  createSqljsCardReader: () => createSqljsCardReader,
50
- encodeUtf8: () => encodeUtf8,
51
51
  normalizeStartDuelOptions: () => normalizeStartDuelOptions,
52
52
  parseCardQuery: () => parseCardQuery,
53
53
  parseFieldCardQuery: () => parseFieldCardQuery,
54
54
  parseFieldInfo: () => parseFieldInfo,
55
55
  parseRegistryDump: () => parseRegistryDump,
56
56
  parseRegistryKeys: () => parseRegistryKeys,
57
- playYrp: () => playYrp,
58
- readI32: () => readI32,
59
- readU16: () => readU16,
60
- readU32: () => readU32,
61
- readU8: () => readU8
57
+ playYrp: () => playYrp
62
58
  });
63
59
  module.exports = __toCommonJS(index_exports);
64
60
  var import_buffer = require("buffer");
@@ -456,11 +452,17 @@ function readU32(buf, offset) {
456
452
  );
457
453
  }
458
454
 
459
- // src/adapters/ocgcore-parsers.ts
455
+ // src/utility/utf8.ts
456
+ var encoder = new TextEncoder();
460
457
  var decoder = new TextDecoder("utf-8");
458
+ function encodeUtf8(value) {
459
+ return encoder.encode(value);
460
+ }
461
461
  function decodeUtf8(value) {
462
462
  return decoder.decode(value);
463
463
  }
464
+
465
+ // src/adapters/ocgcore-parsers.ts
464
466
  function parseCardInfo(payload) {
465
467
  let offset = 0;
466
468
  const flags = readI32(payload, offset) >>> 0;
@@ -742,13 +744,6 @@ function normalizeStartDuelOptions(options) {
742
744
  return ((duelRule & 65535) << 16 | duelOptions & 65535) >>> 0;
743
745
  }
744
746
 
745
- // src/utility/utf8.ts
746
- var encoder = new TextEncoder();
747
- var decoder2 = new TextDecoder("utf-8");
748
- function encodeUtf8(value) {
749
- return encoder.encode(value);
750
- }
751
-
752
747
  // src/ocgcore-duel.ts
753
748
  var OcgcoreDuel = class {
754
749
  constructor(ocgcoreWrapper, duelPtr) {
@@ -1003,6 +998,9 @@ var OcgcoreWrapper = class {
1003
998
  this.scriptReaderFunc = 0;
1004
999
  this.cardReaderFunc = 0;
1005
1000
  this.messageHandlerFunc = 0;
1001
+ this.scriptReaders = [];
1002
+ this.cardReaders = [];
1003
+ this.messageHandlers = [];
1006
1004
  this.encoder = new TextEncoder();
1007
1005
  this.decoder = new TextDecoder("utf-8");
1008
1006
  this.duels = /* @__PURE__ */ new Map();
@@ -1010,6 +1008,101 @@ var OcgcoreWrapper = class {
1010
1008
  this.heapView = new DataView(this.heapU8.buffer);
1011
1009
  this.scriptBufferSize = options?.scriptBufferSize ?? 1048576;
1012
1010
  this.logBufferSize = options?.logBufferSize ?? 1024;
1011
+ this.scriptReaderFunc = this.createFunction((scriptPtr, lenPtr) => {
1012
+ const scriptPath = this.getUTF8String(scriptPtr);
1013
+ let content;
1014
+ for (const reader of this.scriptReaders) {
1015
+ try {
1016
+ content = reader(scriptPath);
1017
+ } catch {
1018
+ content = null;
1019
+ }
1020
+ if (content != null) {
1021
+ break;
1022
+ }
1023
+ }
1024
+ if (content == null) {
1025
+ return 0;
1026
+ }
1027
+ if (!this.scriptBufferPtr) {
1028
+ this.scriptBufferPtr = this.ocgcoreModule._malloc(
1029
+ this.scriptBufferSize
1030
+ );
1031
+ }
1032
+ const bytes = typeof content === "string" ? this.encoder.encode(content) : content;
1033
+ if (bytes.length > this.scriptBufferSize) {
1034
+ this.ocgcoreModule._free(this.scriptBufferPtr);
1035
+ this.scriptBufferPtr = this.ocgcoreModule._malloc(bytes.length);
1036
+ this.scriptBufferSize = bytes.length;
1037
+ }
1038
+ this.heapU8.set(bytes, this.scriptBufferPtr);
1039
+ this.heapView.setInt32(lenPtr, bytes.length, true);
1040
+ return this.scriptBufferPtr;
1041
+ }, "iii");
1042
+ this.ocgcoreModule._set_script_reader(this.scriptReaderFunc);
1043
+ this.cardReaderFunc = this.createFunction((cardId, cardDataPtr) => {
1044
+ let data;
1045
+ for (const reader of this.cardReaders) {
1046
+ try {
1047
+ data = reader(cardId);
1048
+ } catch {
1049
+ data = null;
1050
+ }
1051
+ if (data) {
1052
+ break;
1053
+ }
1054
+ }
1055
+ if (!data) {
1056
+ return 0;
1057
+ }
1058
+ const CardDataCtor = CardDataStruct;
1059
+ let buf;
1060
+ if (data instanceof CardDataCtor) {
1061
+ buf = CardDataStruct.raw(data);
1062
+ } else {
1063
+ const cardData = new CardDataCtor();
1064
+ cardData.code = data.code;
1065
+ cardData.alias = data.alias;
1066
+ const targetSetcode = cardData.setcode;
1067
+ targetSetcode.fill(0);
1068
+ if (data.setcode instanceof Uint16Array && data.setcode.length === 16) {
1069
+ targetSetcode.set(data.setcode);
1070
+ } else {
1071
+ for (let i = 0; i < 16 && i < data.setcode.length; i++) {
1072
+ targetSetcode[i] = data.setcode[i];
1073
+ }
1074
+ }
1075
+ cardData.type = data.type;
1076
+ cardData.level = data.level;
1077
+ cardData.attribute = data.attribute;
1078
+ cardData.race = data.race;
1079
+ cardData.attack = data.attack;
1080
+ cardData.defense = data.defense;
1081
+ cardData.lscale = data.lscale;
1082
+ cardData.rscale = data.rscale;
1083
+ cardData.linkMarker = data.linkMarker;
1084
+ buf = CardDataStruct.raw(cardData);
1085
+ }
1086
+ this.heapU8.set(buf, cardDataPtr);
1087
+ return 0;
1088
+ }, "iii");
1089
+ this.ocgcoreModule._set_card_reader(this.cardReaderFunc);
1090
+ this.messageHandlerFunc = this.createFunction((duelPtr, messageType) => {
1091
+ if (!this.logBufferPtr) {
1092
+ this.logBufferPtr = this.ocgcoreModule._malloc(this.logBufferSize);
1093
+ }
1094
+ this.ocgcoreModule._get_log_message(duelPtr, this.logBufferPtr);
1095
+ const message = this.getUTF8String(this.logBufferPtr);
1096
+ const type = messageType === 1 ? "ScriptError" /* ScriptError */ : messageType === 2 ? "DebugMessage" /* DebugMessage */ : messageType;
1097
+ const duel = this.getOrCreateDuel(duelPtr);
1098
+ for (const handler of this.messageHandlers) {
1099
+ try {
1100
+ handler(duel, message, type);
1101
+ } catch {
1102
+ }
1103
+ }
1104
+ }, "iii");
1105
+ this.ocgcoreModule._set_message_handler(this.messageHandlerFunc);
1013
1106
  }
1014
1107
  getUTF8String(ptr) {
1015
1108
  let length = 0;
@@ -1028,7 +1121,10 @@ var OcgcoreWrapper = class {
1028
1121
  const encoded = args.map(
1029
1122
  (item) => typeof item === "string" ? this.encoder.encode(item) : item
1030
1123
  );
1031
- const totalLength = encoded.reduce((acc, bytes) => acc + bytes.length + 1, 0);
1124
+ const totalLength = encoded.reduce(
1125
+ (acc, bytes) => acc + bytes.length + 1,
1126
+ 0
1127
+ );
1032
1128
  if (totalLength > this.tmpStringBufferSize) {
1033
1129
  if (this.tmpStringBufferPtr) {
1034
1130
  this.ocgcoreModule._free(this.tmpStringBufferPtr);
@@ -1071,7 +1167,7 @@ var OcgcoreWrapper = class {
1071
1167
  this.ocgcoreModule._free(ptr);
1072
1168
  return this.getOrCreateDuel(duelPtr);
1073
1169
  }
1074
- defaultScriptReader(namePtr, dataPtr) {
1170
+ _defaultScriptReader(namePtr, dataPtr) {
1075
1171
  return this.ocgcoreModule._default_script_reader(namePtr, dataPtr);
1076
1172
  }
1077
1173
  malloc(size) {
@@ -1080,99 +1176,29 @@ var OcgcoreWrapper = class {
1080
1176
  free(ptr) {
1081
1177
  this.ocgcoreModule._free(ptr);
1082
1178
  }
1083
- _setScriptReader(funcPtr) {
1084
- this.ocgcoreModule._set_script_reader(funcPtr);
1085
- }
1086
- _setCardReader(funcPtr) {
1087
- this.ocgcoreModule._set_card_reader(funcPtr);
1088
- }
1089
- _setMessageHandler(funcPtr) {
1090
- this.ocgcoreModule._set_message_handler(funcPtr);
1091
- }
1092
- stdioExit() {
1179
+ _stdioExit() {
1093
1180
  this.ocgcoreModule.___stdio_exit();
1094
1181
  }
1095
- setScriptReader(reader) {
1096
- if (this.scriptReaderFunc) {
1097
- this.ocgcoreModule.removeFunction(this.scriptReaderFunc);
1182
+ setScriptReader(reader, reset = false) {
1183
+ if (reset) {
1184
+ this.scriptReaders = [];
1098
1185
  }
1099
- if (!this.scriptBufferPtr) {
1100
- this.scriptBufferPtr = this.ocgcoreModule._malloc(this.scriptBufferSize);
1101
- }
1102
- this.scriptReaderFunc = this.createFunction((scriptPtr, lenPtr) => {
1103
- const scriptPath = this.getUTF8String(scriptPtr);
1104
- const content = reader(scriptPath);
1105
- if (content == null) {
1106
- return 0;
1107
- }
1108
- const bytes = typeof content === "string" ? this.encoder.encode(content) : content;
1109
- if (bytes.length > this.scriptBufferSize) {
1110
- this.ocgcoreModule._free(this.scriptBufferPtr);
1111
- this.scriptBufferPtr = this.ocgcoreModule._malloc(bytes.length);
1112
- this.scriptBufferSize = bytes.length;
1113
- }
1114
- this.heapU8.set(bytes, this.scriptBufferPtr);
1115
- this.heapView.setInt32(lenPtr, bytes.length, true);
1116
- return this.scriptBufferPtr;
1117
- }, "iii");
1118
- this._setScriptReader(this.scriptReaderFunc);
1186
+ this.scriptReaders.push(reader);
1187
+ return this;
1119
1188
  }
1120
- setCardReader(reader) {
1121
- if (this.cardReaderFunc) {
1122
- this.ocgcoreModule.removeFunction(this.cardReaderFunc);
1189
+ setCardReader(reader, reset = false) {
1190
+ if (reset) {
1191
+ this.cardReaders = [];
1123
1192
  }
1124
- this.cardReaderFunc = this.createFunction((cardId, cardDataPtr) => {
1125
- const data = reader(cardId);
1126
- if (!data) {
1127
- return 0;
1128
- }
1129
- const CardDataCtor = CardDataStruct;
1130
- let buf;
1131
- if (data instanceof CardDataCtor) {
1132
- buf = CardDataStruct.raw(data);
1133
- } else {
1134
- const cardData = new CardDataCtor();
1135
- cardData.code = data.code;
1136
- cardData.alias = data.alias;
1137
- const targetSetcode = cardData.setcode;
1138
- targetSetcode.fill(0);
1139
- if (data.setcode instanceof Uint16Array && data.setcode.length === 16) {
1140
- targetSetcode.set(data.setcode);
1141
- } else {
1142
- for (let i = 0; i < 16 && i < data.setcode.length; i++) {
1143
- targetSetcode[i] = data.setcode[i];
1144
- }
1145
- }
1146
- cardData.type = data.type;
1147
- cardData.level = data.level;
1148
- cardData.attribute = data.attribute;
1149
- cardData.race = data.race;
1150
- cardData.attack = data.attack;
1151
- cardData.defense = data.defense;
1152
- cardData.lscale = data.lscale;
1153
- cardData.rscale = data.rscale;
1154
- cardData.linkMarker = data.linkMarker;
1155
- buf = CardDataStruct.raw(cardData);
1156
- }
1157
- this.heapU8.set(buf, cardDataPtr);
1158
- return 0;
1159
- }, "iii");
1160
- this._setCardReader(this.cardReaderFunc);
1193
+ this.cardReaders.push(reader);
1194
+ return this;
1161
1195
  }
1162
- setMessageHandler(handler) {
1163
- if (!this.logBufferPtr) {
1164
- this.logBufferPtr = this.ocgcoreModule._malloc(this.logBufferSize);
1165
- }
1166
- if (this.messageHandlerFunc) {
1167
- this.ocgcoreModule.removeFunction(this.messageHandlerFunc);
1196
+ setMessageHandler(handler, reset = false) {
1197
+ if (reset) {
1198
+ this.messageHandlers = [];
1168
1199
  }
1169
- this.messageHandlerFunc = this.createFunction((duelPtr, messageType) => {
1170
- this.ocgcoreModule._get_log_message(duelPtr, this.logBufferPtr);
1171
- const message = this.getUTF8String(this.logBufferPtr);
1172
- const type = messageType === 1 ? "ScriptError" /* ScriptError */ : messageType === 2 ? "DebugMessage" /* DebugMessage */ : messageType;
1173
- handler(this.getOrCreateDuel(duelPtr), message, type);
1174
- }, "iii");
1175
- this._setMessageHandler(this.messageHandlerFunc);
1200
+ this.messageHandlers.push(handler);
1201
+ return this;
1176
1202
  }
1177
1203
  getOrCreateDuel(duelPtr) {
1178
1204
  const existing = this.duels.get(duelPtr);
@@ -1229,10 +1255,86 @@ function normalizeOcgcoreFactory(mod) {
1229
1255
  throw new Error("Invalid ocgcore factory module");
1230
1256
  }
1231
1257
 
1258
+ // src/utility/node-fs.ts
1259
+ function getNodeFs(noThrow = false) {
1260
+ const req = typeof require !== "undefined" && require || Function('return typeof require !== "undefined" && require')();
1261
+ if (!req) {
1262
+ if (noThrow) {
1263
+ return null;
1264
+ }
1265
+ throw new Error("Node.js fs module is not available.");
1266
+ }
1267
+ try {
1268
+ return req("node:fs");
1269
+ } catch {
1270
+ try {
1271
+ return req("fs");
1272
+ } catch {
1273
+ if (noThrow) {
1274
+ return null;
1275
+ }
1276
+ throw new Error("Node.js fs module is not available.");
1277
+ }
1278
+ }
1279
+ }
1280
+
1281
+ // src/utility/node-path.ts
1282
+ function getNodePath(noThrow = false) {
1283
+ const req = typeof require !== "undefined" && require || Function('return typeof require !== "undefined" && require')();
1284
+ if (!req) {
1285
+ if (noThrow) {
1286
+ return null;
1287
+ }
1288
+ throw new Error("Node.js path module is not available.");
1289
+ }
1290
+ try {
1291
+ return req("node:path");
1292
+ } catch {
1293
+ try {
1294
+ return req("path");
1295
+ } catch {
1296
+ if (noThrow) {
1297
+ return null;
1298
+ }
1299
+ throw new Error("Node.js path module is not available.");
1300
+ }
1301
+ }
1302
+ }
1303
+
1232
1304
  // src/load-ocgcore-factory.cjs.ts
1233
1305
  async function loadOcgcoreFactory() {
1234
1306
  const mod = require("./vendor/wasm_cjs/libocgcore.cjs");
1235
- return normalizeOcgcoreFactory(mod);
1307
+ const baseFactory = normalizeOcgcoreFactory(mod);
1308
+ const fs = getNodeFs(true);
1309
+ if (!fs) {
1310
+ return baseFactory;
1311
+ }
1312
+ const pathMod = getNodePath(true);
1313
+ if (!pathMod) {
1314
+ return baseFactory;
1315
+ }
1316
+ let defaultWasmBinary = null;
1317
+ const wasmPath = pathMod.join(
1318
+ __dirname,
1319
+ "vendor",
1320
+ "wasm_cjs",
1321
+ "libocgcore.wasm"
1322
+ );
1323
+ if (fs.existsSync(wasmPath)) {
1324
+ defaultWasmBinary = fs.readFileSync(wasmPath);
1325
+ }
1326
+ if (!defaultWasmBinary) {
1327
+ return baseFactory;
1328
+ }
1329
+ return async (overrides) => {
1330
+ if (!overrides?.wasmBinary && !overrides?.locateFile) {
1331
+ return baseFactory({
1332
+ ...overrides,
1333
+ wasmBinary: defaultWasmBinary.buffer
1334
+ });
1335
+ }
1336
+ return baseFactory(overrides);
1337
+ };
1236
1338
  }
1237
1339
 
1238
1340
  // src/create-ocgcore-wrapper.ts
@@ -1278,13 +1380,47 @@ function buildCandidates(filename) {
1278
1380
  }
1279
1381
  return candidates;
1280
1382
  }
1281
- function MapReader(map) {
1383
+ function joinPath(baseDir, relativePath) {
1384
+ const pathMod = getNodePath();
1385
+ if (pathMod) {
1386
+ return pathMod.join(baseDir, relativePath);
1387
+ }
1388
+ const trimmedBase = baseDir.replace(/[/\\]+$/, "");
1389
+ const trimmedRel = relativePath.replace(/^[/\\]+/, "");
1390
+ return `${trimmedBase}/${trimmedRel}`;
1391
+ }
1392
+ function MapReader(...maps) {
1282
1393
  return (path) => {
1283
1394
  const filename = normalizePath(path);
1395
+ if (!filename.toLowerCase().endsWith(".lua")) {
1396
+ return null;
1397
+ }
1284
1398
  const candidates = buildCandidates(filename);
1285
1399
  for (const candidate of candidates) {
1286
- if (map.has(candidate)) {
1287
- return map.get(candidate) ?? null;
1400
+ for (const map of maps) {
1401
+ if (map.has(candidate)) {
1402
+ return map.get(candidate) ?? null;
1403
+ }
1404
+ }
1405
+ }
1406
+ return null;
1407
+ };
1408
+ }
1409
+ function DirReader(...baseDirs) {
1410
+ const fs = getNodeFs();
1411
+ return (path) => {
1412
+ const filename = normalizePath(path);
1413
+ if (!filename.toLowerCase().endsWith(".lua")) {
1414
+ return null;
1415
+ }
1416
+ const candidates = buildCandidates(filename);
1417
+ for (const baseDir of baseDirs) {
1418
+ for (const candidate of candidates) {
1419
+ const normalized = candidate.startsWith("/") ? candidate.slice(1) : candidate;
1420
+ const fullPath = joinPath(baseDir, normalized);
1421
+ if (fs.existsSync(fullPath)) {
1422
+ return fs.readFileSync(fullPath);
1423
+ }
1288
1424
  }
1289
1425
  }
1290
1426
  return null;
@@ -1299,25 +1435,30 @@ function normalizeZipEntryName(name) {
1299
1435
  }
1300
1436
  return Array.from(names);
1301
1437
  }
1302
- async function ZipReader(data) {
1303
- const zip = await import_jszip.default.loadAsync(data);
1304
- const map = /* @__PURE__ */ new Map();
1305
- const entries = Object.values(zip.files);
1306
- await Promise.all(
1307
- entries.map(async (entry) => {
1308
- if (entry.dir) {
1309
- return;
1310
- }
1311
- if (!entry.name.toLowerCase().endsWith(".lua")) {
1312
- return;
1313
- }
1314
- const content = await entry.async("uint8array");
1315
- for (const name of normalizeZipEntryName(entry.name)) {
1316
- map.set(name, content);
1317
- }
1438
+ async function ZipReader(...inputs) {
1439
+ const maps = await Promise.all(
1440
+ inputs.map(async (data) => {
1441
+ const zip = await import_jszip.default.loadAsync(data);
1442
+ const map = /* @__PURE__ */ new Map();
1443
+ const entries = Object.values(zip.files);
1444
+ await Promise.all(
1445
+ entries.map(async (entry) => {
1446
+ if (entry.dir) {
1447
+ return;
1448
+ }
1449
+ if (!entry.name.toLowerCase().endsWith(".lua")) {
1450
+ return;
1451
+ }
1452
+ const content = await entry.async("uint8array");
1453
+ for (const name of normalizeZipEntryName(entry.name)) {
1454
+ map.set(name, content);
1455
+ }
1456
+ })
1457
+ );
1458
+ return map;
1318
1459
  })
1319
1460
  );
1320
- return MapReader(map);
1461
+ return MapReader(...maps);
1321
1462
  }
1322
1463
 
1323
1464
  // src/vendor/script-constants.ts
@@ -2175,7 +2316,7 @@ function toUint16ArrayFromSetcode(value) {
2175
2316
  }
2176
2317
  function mapRowToCardData(row) {
2177
2318
  const type = (row.type ?? 0) >>> 0;
2178
- let attack = row.atk ?? 0;
2319
+ const attack = row.atk ?? 0;
2179
2320
  let defense = row.def ?? 0;
2180
2321
  let linkMarker = 0;
2181
2322
  if ((type & OcgcoreCommonConstants.TYPE_LINK) >>> 0 !== 0) {
@@ -2367,18 +2508,6 @@ var playYrp = (ocgcoreWrapper, yrpInput) => {
2367
2508
  duel.startDuel(yrp.opt >>> 0);
2368
2509
  while (true) {
2369
2510
  const { raw, status } = duel.process();
2370
- console.log(
2371
- "Duel process status:",
2372
- status,
2373
- "Message length:",
2374
- raw.length,
2375
- "Message:",
2376
- raw[0],
2377
- "Message string:",
2378
- Object.entries(OcgcoreCommonConstants).find(
2379
- ([k, v]) => v === raw[0] && k.startsWith("MSG_")
2380
- )?.[0] ?? "Unknown"
2381
- );
2382
2511
  messages.push(raw);
2383
2512
  if (raw.length > 0 && raw[0] === OcgcoreCommonConstants.MSG_RETRY) {
2384
2513
  throw new Error("Got MSG_RETRY");
@@ -2412,6 +2541,7 @@ if (typeof globalThis !== "undefined" && !globalThis.Buffer) {
2412
2541
  // Annotate the CommonJS export names for ESM import in node:
2413
2542
  0 && (module.exports = {
2414
2543
  CardDataStruct,
2544
+ DirReader,
2415
2545
  LEN_EMPTY,
2416
2546
  LEN_FAIL,
2417
2547
  LEN_HEADER,
@@ -2429,17 +2559,12 @@ if (typeof globalThis !== "undefined" && !globalThis.Buffer) {
2429
2559
  ZipReader,
2430
2560
  createOcgcoreWrapper,
2431
2561
  createSqljsCardReader,
2432
- encodeUtf8,
2433
2562
  normalizeStartDuelOptions,
2434
2563
  parseCardQuery,
2435
2564
  parseFieldCardQuery,
2436
2565
  parseFieldInfo,
2437
2566
  parseRegistryDump,
2438
2567
  parseRegistryKeys,
2439
- playYrp,
2440
- readI32,
2441
- readU16,
2442
- readU32,
2443
- readU8
2568
+ playYrp
2444
2569
  });
2445
2570
  //# sourceMappingURL=index.cjs.map