koishipro-core.js 1.1.1 → 1.1.3
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 +20 -14
- package/dist/index.cjs +411 -192
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.mjs +438 -228
- package/dist/index.mjs.map +4 -4
- package/dist/src/adapters/index.d.ts +0 -1
- package/dist/src/card-reader/dir-card-reader.d.ts +3 -0
- package/dist/src/card-reader/index.d.ts +2 -0
- package/dist/src/card-reader/sqljs-card-reader.d.ts +5 -0
- package/dist/src/ocgcore-duel.d.ts +2 -1
- package/dist/src/play-yrp.d.ts +11 -0
- package/dist/src/script-reader/dir-script-reader-ex.d.ts +2 -0
- package/dist/src/script-reader/index.d.ts +2 -0
- package/dist/src/script-reader/script-readers.d.ts +10 -0
- package/dist/src/utility/index.d.ts +1 -0
- package/dist/src/utility/node-fs.d.ts +11 -0
- package/dist/src/utility/search-zips.d.ts +6 -0
- package/index.ts +2 -1
- package/package.json +1 -1
- package/dist/src/adapters/script-readers.d.ts +0 -4
- package/dist/src/sqljs-card-reader.d.ts +0 -3
package/dist/index.mjs
CHANGED
|
@@ -499,6 +499,7 @@ var OcgcoreDuel = class {
|
|
|
499
499
|
this.duelPtr = duelPtr;
|
|
500
500
|
this.returnPtr = 0;
|
|
501
501
|
this.returnSize = 512;
|
|
502
|
+
this.ended = false;
|
|
502
503
|
}
|
|
503
504
|
startDuel(options) {
|
|
504
505
|
if (!this.returnPtr) {
|
|
@@ -508,6 +509,8 @@ var OcgcoreDuel = class {
|
|
|
508
509
|
this.ocgcoreWrapper.ocgcoreModule._start_duel(this.duelPtr, optionValue);
|
|
509
510
|
}
|
|
510
511
|
endDuel() {
|
|
512
|
+
if (this.ended) return;
|
|
513
|
+
this.ended = true;
|
|
511
514
|
this.ocgcoreWrapper.ocgcoreModule._end_duel(this.duelPtr);
|
|
512
515
|
if (this.returnPtr) {
|
|
513
516
|
this.ocgcoreWrapper.free(this.returnPtr);
|
|
@@ -628,6 +631,10 @@ var OcgcoreDuel = class {
|
|
|
628
631
|
this.ocgcoreWrapper.ocgcoreModule._set_responsei(this.duelPtr, value);
|
|
629
632
|
}
|
|
630
633
|
setResponse(response) {
|
|
634
|
+
if (typeof response === "number") {
|
|
635
|
+
this.setResponseInt(response);
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
631
638
|
if (response.length > this.returnSize) {
|
|
632
639
|
this.ocgcoreWrapper.free(this.returnPtr);
|
|
633
640
|
this.returnPtr = this.ocgcoreWrapper.malloc(response.length);
|
|
@@ -1097,150 +1104,6 @@ async function createOcgcoreWrapper(options = {}) {
|
|
|
1097
1104
|
return new OcgcoreWrapper(moduleInstance);
|
|
1098
1105
|
}
|
|
1099
1106
|
|
|
1100
|
-
// src/adapters/script-readers.ts
|
|
1101
|
-
import JSZip from "jszip";
|
|
1102
|
-
|
|
1103
|
-
// src/utility/load-node-module.ts
|
|
1104
|
-
function loadNodeModule(id, altId) {
|
|
1105
|
-
const req = typeof module.require !== "undefined" ? module.require : void 0;
|
|
1106
|
-
if (!req) {
|
|
1107
|
-
return null;
|
|
1108
|
-
}
|
|
1109
|
-
try {
|
|
1110
|
-
return req(id);
|
|
1111
|
-
} catch {
|
|
1112
|
-
if (!altId) return null;
|
|
1113
|
-
try {
|
|
1114
|
-
return req(altId);
|
|
1115
|
-
} catch {
|
|
1116
|
-
return null;
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
|
|
1121
|
-
// src/utility/node-fs.ts
|
|
1122
|
-
function getNodeFs(noThrow = false) {
|
|
1123
|
-
const mod = loadNodeModule("node:fs", "fs");
|
|
1124
|
-
if (mod) return mod;
|
|
1125
|
-
if (noThrow) return null;
|
|
1126
|
-
throw new Error("Node.js fs module is not available.");
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
// src/utility/node-path.ts
|
|
1130
|
-
function getNodePath(noThrow = false) {
|
|
1131
|
-
const mod = loadNodeModule("node:path", "path");
|
|
1132
|
-
if (mod) return mod;
|
|
1133
|
-
if (noThrow) return null;
|
|
1134
|
-
throw new Error("Node.js path module is not available.");
|
|
1135
|
-
}
|
|
1136
|
-
|
|
1137
|
-
// src/adapters/script-readers.ts
|
|
1138
|
-
var SCRIPT_PREFIX = "./script/";
|
|
1139
|
-
function normalizePath(input) {
|
|
1140
|
-
let path = input.replace(/\\/g, "/");
|
|
1141
|
-
if (path.startsWith(SCRIPT_PREFIX)) {
|
|
1142
|
-
path = path.slice(SCRIPT_PREFIX.length);
|
|
1143
|
-
}
|
|
1144
|
-
return path;
|
|
1145
|
-
}
|
|
1146
|
-
function buildCandidates(filename) {
|
|
1147
|
-
const entries = [
|
|
1148
|
-
filename,
|
|
1149
|
-
`specials/${filename}`,
|
|
1150
|
-
`expansions/script/${filename}`,
|
|
1151
|
-
`script/${filename}`
|
|
1152
|
-
];
|
|
1153
|
-
const candidates = [];
|
|
1154
|
-
for (const entry of entries) {
|
|
1155
|
-
candidates.push(entry);
|
|
1156
|
-
if (!entry.startsWith("./")) {
|
|
1157
|
-
const dotEntry = entry.startsWith("/") ? `./${entry.slice(1)}` : `./${entry}`;
|
|
1158
|
-
candidates.push(dotEntry);
|
|
1159
|
-
}
|
|
1160
|
-
}
|
|
1161
|
-
return candidates;
|
|
1162
|
-
}
|
|
1163
|
-
function joinPath(baseDir, relativePath) {
|
|
1164
|
-
const pathMod = getNodePath();
|
|
1165
|
-
if (pathMod) {
|
|
1166
|
-
return pathMod.join(baseDir, relativePath);
|
|
1167
|
-
}
|
|
1168
|
-
const trimmedBase = baseDir.replace(/[/\\]+$/, "");
|
|
1169
|
-
const trimmedRel = relativePath.replace(/^[/\\]+/, "");
|
|
1170
|
-
return `${trimmedBase}/${trimmedRel}`;
|
|
1171
|
-
}
|
|
1172
|
-
function MapReader(...maps) {
|
|
1173
|
-
return (path) => {
|
|
1174
|
-
const filename = normalizePath(path);
|
|
1175
|
-
if (!filename.toLowerCase().endsWith(".lua")) {
|
|
1176
|
-
return null;
|
|
1177
|
-
}
|
|
1178
|
-
const candidates = buildCandidates(filename);
|
|
1179
|
-
for (const candidate of candidates) {
|
|
1180
|
-
for (const map of maps) {
|
|
1181
|
-
if (map.has(candidate)) {
|
|
1182
|
-
return map.get(candidate) ?? null;
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1185
|
-
}
|
|
1186
|
-
return null;
|
|
1187
|
-
};
|
|
1188
|
-
}
|
|
1189
|
-
function DirReader(...baseDirs) {
|
|
1190
|
-
const fs = getNodeFs();
|
|
1191
|
-
return (path) => {
|
|
1192
|
-
const filename = normalizePath(path);
|
|
1193
|
-
if (!filename.toLowerCase().endsWith(".lua")) {
|
|
1194
|
-
return null;
|
|
1195
|
-
}
|
|
1196
|
-
const candidates = buildCandidates(filename);
|
|
1197
|
-
for (const baseDir of baseDirs) {
|
|
1198
|
-
for (const candidate of candidates) {
|
|
1199
|
-
const normalized = candidate.startsWith("/") ? candidate.slice(1) : candidate;
|
|
1200
|
-
const fullPath = joinPath(baseDir, normalized);
|
|
1201
|
-
if (fs.existsSync(fullPath)) {
|
|
1202
|
-
return fs.readFileSync(fullPath);
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
}
|
|
1206
|
-
return null;
|
|
1207
|
-
};
|
|
1208
|
-
}
|
|
1209
|
-
function normalizeZipEntryName(name) {
|
|
1210
|
-
const normalized = name.replace(/\\/g, "/").replace(/^\.?\//, "");
|
|
1211
|
-
const names = /* @__PURE__ */ new Set();
|
|
1212
|
-
names.add(normalized);
|
|
1213
|
-
if (normalized.startsWith("script/")) {
|
|
1214
|
-
names.add(normalized.slice("script/".length));
|
|
1215
|
-
}
|
|
1216
|
-
return Array.from(names);
|
|
1217
|
-
}
|
|
1218
|
-
async function ZipReader(...inputs) {
|
|
1219
|
-
const maps = await Promise.all(
|
|
1220
|
-
inputs.map(async (data) => {
|
|
1221
|
-
const zip = await JSZip.loadAsync(data);
|
|
1222
|
-
const map = /* @__PURE__ */ new Map();
|
|
1223
|
-
const entries = Object.values(zip.files);
|
|
1224
|
-
await Promise.all(
|
|
1225
|
-
entries.map(async (entry) => {
|
|
1226
|
-
if (entry.dir) {
|
|
1227
|
-
return;
|
|
1228
|
-
}
|
|
1229
|
-
if (!entry.name.toLowerCase().endsWith(".lua")) {
|
|
1230
|
-
return;
|
|
1231
|
-
}
|
|
1232
|
-
const content = await entry.async("uint8array");
|
|
1233
|
-
for (const name of normalizeZipEntryName(entry.name)) {
|
|
1234
|
-
map.set(name, content);
|
|
1235
|
-
}
|
|
1236
|
-
})
|
|
1237
|
-
);
|
|
1238
|
-
return map;
|
|
1239
|
-
})
|
|
1240
|
-
);
|
|
1241
|
-
return MapReader(...maps);
|
|
1242
|
-
}
|
|
1243
|
-
|
|
1244
1107
|
// src/vendor/script-constants.ts
|
|
1245
1108
|
var OcgcoreScriptConstants = {
|
|
1246
1109
|
ACTIVITY_ATTACK: 5,
|
|
@@ -2079,7 +1942,243 @@ var OcgcoreScriptConstants = {
|
|
|
2079
1942
|
TYPE_XYZ: 8388608
|
|
2080
1943
|
};
|
|
2081
1944
|
|
|
2082
|
-
// src/
|
|
1945
|
+
// src/script-reader/script-readers.ts
|
|
1946
|
+
import JSZip from "jszip";
|
|
1947
|
+
|
|
1948
|
+
// src/utility/load-node-module.ts
|
|
1949
|
+
function loadNodeModule(id, altId) {
|
|
1950
|
+
const req = typeof module.require !== "undefined" ? module.require : void 0;
|
|
1951
|
+
if (!req) {
|
|
1952
|
+
return null;
|
|
1953
|
+
}
|
|
1954
|
+
try {
|
|
1955
|
+
return req(id);
|
|
1956
|
+
} catch {
|
|
1957
|
+
if (!altId) return null;
|
|
1958
|
+
try {
|
|
1959
|
+
return req(altId);
|
|
1960
|
+
} catch {
|
|
1961
|
+
return null;
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
// src/utility/node-fs.ts
|
|
1967
|
+
function getNodeFs(noThrow = false) {
|
|
1968
|
+
const mod = loadNodeModule("node:fs", "fs");
|
|
1969
|
+
if (mod) return mod;
|
|
1970
|
+
if (noThrow) return null;
|
|
1971
|
+
throw new Error("Node.js fs module is not available.");
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1974
|
+
// src/utility/node-path.ts
|
|
1975
|
+
function getNodePath(noThrow = false) {
|
|
1976
|
+
const mod = loadNodeModule("node:path", "path");
|
|
1977
|
+
if (mod) return mod;
|
|
1978
|
+
if (noThrow) return null;
|
|
1979
|
+
throw new Error("Node.js path module is not available.");
|
|
1980
|
+
}
|
|
1981
|
+
|
|
1982
|
+
// src/script-reader/script-readers.ts
|
|
1983
|
+
var SCRIPT_PREFIX = "./script/";
|
|
1984
|
+
function normalizePath(input) {
|
|
1985
|
+
let path = input.replace(/\\/g, "/");
|
|
1986
|
+
if (path.startsWith(SCRIPT_PREFIX)) {
|
|
1987
|
+
path = path.slice(SCRIPT_PREFIX.length);
|
|
1988
|
+
}
|
|
1989
|
+
return path;
|
|
1990
|
+
}
|
|
1991
|
+
function buildCandidates(filename) {
|
|
1992
|
+
const entries = [
|
|
1993
|
+
filename,
|
|
1994
|
+
`specials/${filename}`,
|
|
1995
|
+
`expansions/script/${filename}`,
|
|
1996
|
+
`script/${filename}`
|
|
1997
|
+
];
|
|
1998
|
+
const candidates = [];
|
|
1999
|
+
for (const entry of entries) {
|
|
2000
|
+
candidates.push(entry);
|
|
2001
|
+
if (!entry.startsWith("./")) {
|
|
2002
|
+
const dotEntry = entry.startsWith("/") ? `./${entry.slice(1)}` : `./${entry}`;
|
|
2003
|
+
candidates.push(dotEntry);
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
return candidates;
|
|
2007
|
+
}
|
|
2008
|
+
function joinPath(baseDir, relativePath) {
|
|
2009
|
+
const pathMod = getNodePath();
|
|
2010
|
+
if (pathMod) {
|
|
2011
|
+
return pathMod.join(baseDir, relativePath);
|
|
2012
|
+
}
|
|
2013
|
+
const trimmedBase = baseDir.replace(/[/\\]+$/, "");
|
|
2014
|
+
const trimmedRel = relativePath.replace(/^[/\\]+/, "");
|
|
2015
|
+
return `${trimmedBase}/${trimmedRel}`;
|
|
2016
|
+
}
|
|
2017
|
+
function MapScriptReader(...maps) {
|
|
2018
|
+
return (path) => {
|
|
2019
|
+
const filename = normalizePath(path);
|
|
2020
|
+
if (!filename.toLowerCase().endsWith(".lua")) {
|
|
2021
|
+
return null;
|
|
2022
|
+
}
|
|
2023
|
+
const candidates = buildCandidates(filename);
|
|
2024
|
+
for (const candidate of candidates) {
|
|
2025
|
+
for (const map of maps) {
|
|
2026
|
+
if (map.has(candidate)) {
|
|
2027
|
+
return map.get(candidate) ?? null;
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
return null;
|
|
2032
|
+
};
|
|
2033
|
+
}
|
|
2034
|
+
function DirScriptReader(...baseDirs) {
|
|
2035
|
+
const fs = getNodeFs();
|
|
2036
|
+
return (path) => {
|
|
2037
|
+
const filename = normalizePath(path);
|
|
2038
|
+
if (!filename.toLowerCase().endsWith(".lua")) {
|
|
2039
|
+
return null;
|
|
2040
|
+
}
|
|
2041
|
+
const candidates = buildCandidates(filename);
|
|
2042
|
+
for (const baseDir of baseDirs) {
|
|
2043
|
+
for (const candidate of candidates) {
|
|
2044
|
+
const normalized = candidate.startsWith("/") ? candidate.slice(1) : candidate;
|
|
2045
|
+
const fullPath = joinPath(baseDir, normalized);
|
|
2046
|
+
if (fs.existsSync(fullPath)) {
|
|
2047
|
+
return fs.readFileSync(fullPath);
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
return null;
|
|
2052
|
+
};
|
|
2053
|
+
}
|
|
2054
|
+
function normalizeZipEntryName(name) {
|
|
2055
|
+
const normalized = name.replace(/\\/g, "/").replace(/^\.?\//, "");
|
|
2056
|
+
const names = /* @__PURE__ */ new Set();
|
|
2057
|
+
names.add(normalized);
|
|
2058
|
+
if (normalized.startsWith("script/")) {
|
|
2059
|
+
names.add(normalized.slice("script/".length));
|
|
2060
|
+
}
|
|
2061
|
+
return Array.from(names);
|
|
2062
|
+
}
|
|
2063
|
+
async function ZipScriptReader(...inputs) {
|
|
2064
|
+
const maps = await Promise.all(
|
|
2065
|
+
inputs.map(async (data) => {
|
|
2066
|
+
const zip = await JSZip.loadAsync(data);
|
|
2067
|
+
const map = /* @__PURE__ */ new Map();
|
|
2068
|
+
const entries = Object.values(zip.files);
|
|
2069
|
+
await Promise.all(
|
|
2070
|
+
entries.map(async (entry) => {
|
|
2071
|
+
if (entry.dir) {
|
|
2072
|
+
return;
|
|
2073
|
+
}
|
|
2074
|
+
if (!entry.name.toLowerCase().endsWith(".lua")) {
|
|
2075
|
+
return;
|
|
2076
|
+
}
|
|
2077
|
+
const content = await entry.async("uint8array");
|
|
2078
|
+
for (const name of normalizeZipEntryName(entry.name)) {
|
|
2079
|
+
map.set(name, content);
|
|
2080
|
+
}
|
|
2081
|
+
})
|
|
2082
|
+
);
|
|
2083
|
+
return map;
|
|
2084
|
+
})
|
|
2085
|
+
);
|
|
2086
|
+
return MapScriptReader(...maps);
|
|
2087
|
+
}
|
|
2088
|
+
function MapReader(...maps) {
|
|
2089
|
+
return MapScriptReader(...maps);
|
|
2090
|
+
}
|
|
2091
|
+
function DirReader(...baseDirs) {
|
|
2092
|
+
return DirScriptReader(...baseDirs);
|
|
2093
|
+
}
|
|
2094
|
+
async function ZipReader(...inputs) {
|
|
2095
|
+
return ZipScriptReader(...inputs);
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2098
|
+
// src/utility/search-zips.ts
|
|
2099
|
+
function joinPath2(pathMod, baseDir, rel) {
|
|
2100
|
+
if (pathMod) {
|
|
2101
|
+
return pathMod.join(baseDir, rel);
|
|
2102
|
+
}
|
|
2103
|
+
const trimmedBase = baseDir.replace(/[/\\]+$/, "");
|
|
2104
|
+
const trimmedRel = rel.replace(/^[/\\]+/, "");
|
|
2105
|
+
return `${trimmedBase}/${trimmedRel}`;
|
|
2106
|
+
}
|
|
2107
|
+
async function safeReadDir(fs, dirPath) {
|
|
2108
|
+
try {
|
|
2109
|
+
return await fs.promises.readdir(dirPath);
|
|
2110
|
+
} catch {
|
|
2111
|
+
return [];
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
async function searchZips(fs, pathMod, baseDir) {
|
|
2115
|
+
const results = [];
|
|
2116
|
+
const rootEntries = await safeReadDir(fs, baseDir);
|
|
2117
|
+
for (const entry of rootEntries) {
|
|
2118
|
+
const lower = entry.toLowerCase();
|
|
2119
|
+
if (!lower.endsWith(".zip") && !lower.endsWith(".ypk")) {
|
|
2120
|
+
continue;
|
|
2121
|
+
}
|
|
2122
|
+
const fullPath = joinPath2(pathMod, baseDir, entry);
|
|
2123
|
+
try {
|
|
2124
|
+
const stats = await fs.promises.stat(fullPath);
|
|
2125
|
+
if (stats.isFile()) {
|
|
2126
|
+
results.push(fullPath);
|
|
2127
|
+
}
|
|
2128
|
+
} catch {
|
|
2129
|
+
continue;
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
const expansionsDir = joinPath2(pathMod, baseDir, "expansions");
|
|
2133
|
+
const expansionEntries = await safeReadDir(fs, expansionsDir);
|
|
2134
|
+
for (const entry of expansionEntries) {
|
|
2135
|
+
const lower = entry.toLowerCase();
|
|
2136
|
+
if (!lower.endsWith(".zip") && !lower.endsWith(".ypk")) {
|
|
2137
|
+
continue;
|
|
2138
|
+
}
|
|
2139
|
+
const fullPath = joinPath2(pathMod, expansionsDir, entry);
|
|
2140
|
+
try {
|
|
2141
|
+
const stats = await fs.promises.stat(fullPath);
|
|
2142
|
+
if (stats.isFile()) {
|
|
2143
|
+
results.push(fullPath);
|
|
2144
|
+
}
|
|
2145
|
+
} catch {
|
|
2146
|
+
continue;
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
return results;
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2152
|
+
// src/script-reader/dir-script-reader-ex.ts
|
|
2153
|
+
function getNodeModuleOrThrow(value, label) {
|
|
2154
|
+
if (!value) {
|
|
2155
|
+
throw new Error(`${label} is not supported in this runtime.`);
|
|
2156
|
+
}
|
|
2157
|
+
return value;
|
|
2158
|
+
}
|
|
2159
|
+
async function DirScriptReaderEx(...baseDirs) {
|
|
2160
|
+
const fs = getNodeModuleOrThrow(getNodeFs(), "DirScriptReaderEx");
|
|
2161
|
+
const pathMod = getNodeModuleOrThrow(getNodePath(), "DirScriptReaderEx");
|
|
2162
|
+
const fsReader = DirScriptReader(...baseDirs);
|
|
2163
|
+
const zipInputs = [];
|
|
2164
|
+
for (const baseDir of baseDirs) {
|
|
2165
|
+
const zipPaths = await searchZips(fs, pathMod, baseDir);
|
|
2166
|
+
for (const zipPath of zipPaths) {
|
|
2167
|
+
try {
|
|
2168
|
+
zipInputs.push(await fs.promises.readFile(zipPath));
|
|
2169
|
+
} catch {
|
|
2170
|
+
continue;
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
if (zipInputs.length === 0) {
|
|
2175
|
+
return fsReader;
|
|
2176
|
+
}
|
|
2177
|
+
const zipReader = await ZipScriptReader(...zipInputs);
|
|
2178
|
+
return (path) => fsReader(path) ?? zipReader(path);
|
|
2179
|
+
}
|
|
2180
|
+
|
|
2181
|
+
// src/card-reader/sqljs-card-reader.ts
|
|
2083
2182
|
function toUint16ArrayFromSetcode(value) {
|
|
2084
2183
|
let raw = typeof value === "bigint" ? value : BigInt(value >>> 0);
|
|
2085
2184
|
const list = new Uint16Array(16);
|
|
@@ -2160,7 +2259,7 @@ function queryOne(db, cardId) {
|
|
|
2160
2259
|
attribute: row[8]
|
|
2161
2260
|
});
|
|
2162
2261
|
}
|
|
2163
|
-
function
|
|
2262
|
+
function SqljsCardReader(...dbs) {
|
|
2164
2263
|
return (cardId) => {
|
|
2165
2264
|
for (const db of dbs) {
|
|
2166
2265
|
const data = queryOne(db, cardId);
|
|
@@ -2171,6 +2270,105 @@ function createSqljsCardReader(...dbs) {
|
|
|
2171
2270
|
return null;
|
|
2172
2271
|
};
|
|
2173
2272
|
}
|
|
2273
|
+
function createSqljsCardReader(...dbs) {
|
|
2274
|
+
return SqljsCardReader(...dbs);
|
|
2275
|
+
}
|
|
2276
|
+
|
|
2277
|
+
// src/card-reader/dir-card-reader.ts
|
|
2278
|
+
import JSZip2 from "jszip";
|
|
2279
|
+
function joinPath3(pathMod, baseDir, rel) {
|
|
2280
|
+
if (pathMod) {
|
|
2281
|
+
return pathMod.join(baseDir, rel);
|
|
2282
|
+
}
|
|
2283
|
+
const trimmedBase = baseDir.replace(/[/\\]+$/, "");
|
|
2284
|
+
const trimmedRel = rel.replace(/^[/\\]+/, "");
|
|
2285
|
+
return `${trimmedBase}/${trimmedRel}`;
|
|
2286
|
+
}
|
|
2287
|
+
function getNodeModuleOrThrow2(value, label) {
|
|
2288
|
+
if (!value) {
|
|
2289
|
+
throw new Error(`${label} is not supported in this runtime.`);
|
|
2290
|
+
}
|
|
2291
|
+
return value;
|
|
2292
|
+
}
|
|
2293
|
+
async function safeReadDir2(fs, dirPath) {
|
|
2294
|
+
try {
|
|
2295
|
+
return await fs.promises.readdir(dirPath);
|
|
2296
|
+
} catch {
|
|
2297
|
+
return [];
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
async function collectFsDbPaths(fs, pathMod, baseDir) {
|
|
2301
|
+
const results = [];
|
|
2302
|
+
const baseDb = joinPath3(pathMod, baseDir, "cards.cdb");
|
|
2303
|
+
try {
|
|
2304
|
+
const stats = await fs.promises.stat(baseDb);
|
|
2305
|
+
if (stats.isFile()) {
|
|
2306
|
+
results.push(baseDb);
|
|
2307
|
+
}
|
|
2308
|
+
} catch {
|
|
2309
|
+
}
|
|
2310
|
+
const expansionsDir = joinPath3(pathMod, baseDir, "expansions");
|
|
2311
|
+
const entries = await safeReadDir2(fs, expansionsDir);
|
|
2312
|
+
for (const entry of entries) {
|
|
2313
|
+
if (!entry.toLowerCase().endsWith(".cdb")) {
|
|
2314
|
+
continue;
|
|
2315
|
+
}
|
|
2316
|
+
const fullPath = joinPath3(pathMod, expansionsDir, entry);
|
|
2317
|
+
try {
|
|
2318
|
+
const stats = await fs.promises.stat(fullPath);
|
|
2319
|
+
if (stats.isFile()) {
|
|
2320
|
+
results.push(fullPath);
|
|
2321
|
+
}
|
|
2322
|
+
} catch {
|
|
2323
|
+
continue;
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
return results;
|
|
2327
|
+
}
|
|
2328
|
+
function isRootCdbEntry(entryName) {
|
|
2329
|
+
const normalized = entryName.replace(/\\/g, "/").replace(/^\.?\//, "");
|
|
2330
|
+
return !normalized.includes("/") && normalized.toLowerCase().endsWith(".cdb");
|
|
2331
|
+
}
|
|
2332
|
+
async function DirCardReader(sqljs, ...baseDirs) {
|
|
2333
|
+
const fs = getNodeModuleOrThrow2(getNodeFs(), "DirCardReader");
|
|
2334
|
+
const pathMod = getNodeModuleOrThrow2(getNodePath(), "DirCardReader");
|
|
2335
|
+
const dbs = [];
|
|
2336
|
+
for (const baseDir of baseDirs) {
|
|
2337
|
+
const dbPaths = await collectFsDbPaths(fs, pathMod, baseDir);
|
|
2338
|
+
for (const dbPath of dbPaths) {
|
|
2339
|
+
try {
|
|
2340
|
+
const bytes = await fs.promises.readFile(dbPath);
|
|
2341
|
+
dbs.push(new sqljs.Database(bytes));
|
|
2342
|
+
} catch {
|
|
2343
|
+
continue;
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
for (const baseDir of baseDirs) {
|
|
2348
|
+
const zipPaths = await searchZips(fs, pathMod, baseDir);
|
|
2349
|
+
for (const zipPath of zipPaths) {
|
|
2350
|
+
try {
|
|
2351
|
+
const bytes = await fs.promises.readFile(zipPath);
|
|
2352
|
+
const zip = await JSZip2.loadAsync(bytes);
|
|
2353
|
+
const entries = Object.values(zip.files);
|
|
2354
|
+
for (const entry of entries) {
|
|
2355
|
+
if (entry.dir || !isRootCdbEntry(entry.name)) {
|
|
2356
|
+
continue;
|
|
2357
|
+
}
|
|
2358
|
+
try {
|
|
2359
|
+
const content = await entry.async("uint8array");
|
|
2360
|
+
dbs.push(new sqljs.Database(content));
|
|
2361
|
+
} catch {
|
|
2362
|
+
continue;
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2365
|
+
} catch {
|
|
2366
|
+
continue;
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
return SqljsCardReader(...dbs);
|
|
2371
|
+
}
|
|
2174
2372
|
|
|
2175
2373
|
// src/play-yrp.ts
|
|
2176
2374
|
import { YGOProYrp } from "ygopro-yrp-encode";
|
|
@@ -2181,14 +2379,6 @@ function normalizeYrp(input) {
|
|
|
2181
2379
|
}
|
|
2182
2380
|
return new YGOProYrp().fromYrp(input);
|
|
2183
2381
|
}
|
|
2184
|
-
function createReplayDuel(wrapper, yrp) {
|
|
2185
|
-
const header = yrp.header;
|
|
2186
|
-
const seedSequence = header?.seedSequence ?? [];
|
|
2187
|
-
if (seedSequence.length > 0) {
|
|
2188
|
-
return wrapper.createDuelV2(seedSequence);
|
|
2189
|
-
}
|
|
2190
|
-
return wrapper.createDuel(header?.seed ?? 0);
|
|
2191
|
-
}
|
|
2192
2382
|
function loadDeck(duel, deck, owner, player) {
|
|
2193
2383
|
if (!deck) return;
|
|
2194
2384
|
for (const code of deck.main ?? []) {
|
|
@@ -2232,86 +2422,97 @@ function loadTagDeck(duel, deck, owner) {
|
|
|
2232
2422
|
function setRegistryValue(duel, key, value) {
|
|
2233
2423
|
duel.setRegistryValue(key, value);
|
|
2234
2424
|
}
|
|
2235
|
-
function
|
|
2425
|
+
function createDuelFromYrp(wrapper, yrpInput) {
|
|
2236
2426
|
const yrp = normalizeYrp(yrpInput);
|
|
2237
|
-
const
|
|
2238
|
-
const
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2427
|
+
const header = yrp.header;
|
|
2428
|
+
const seedSequence = header?.seedSequence ?? [];
|
|
2429
|
+
const duel = seedSequence.length > 0 ? wrapper.createDuelV2(seedSequence) : wrapper.createDuel(header?.seed ?? 0);
|
|
2430
|
+
setRegistryValue(duel, "duel_mode", yrp.isTag ? "tag" : "single");
|
|
2431
|
+
setRegistryValue(duel, "start_lp", String(yrp.startLp));
|
|
2432
|
+
setRegistryValue(duel, "start_hand", String(yrp.startHand));
|
|
2433
|
+
setRegistryValue(duel, "draw_count", String(yrp.drawCount));
|
|
2434
|
+
const playerNames = yrp.isTag ? [
|
|
2435
|
+
yrp.hostName,
|
|
2436
|
+
yrp.tagHostName ?? "",
|
|
2437
|
+
yrp.tagClientName ?? "",
|
|
2438
|
+
yrp.clientName
|
|
2439
|
+
] : [yrp.hostName, yrp.clientName];
|
|
2440
|
+
for (let i = 0; i < playerNames.length; i++) {
|
|
2441
|
+
setRegistryValue(duel, `player_name_${i}`, playerNames[i] ?? "");
|
|
2442
|
+
}
|
|
2443
|
+
setRegistryValue(duel, "player_type_0", "0");
|
|
2444
|
+
setRegistryValue(duel, "player_type_1", "1");
|
|
2445
|
+
duel.setPlayerInfo({
|
|
2446
|
+
player: 0,
|
|
2447
|
+
lp: yrp.startLp,
|
|
2448
|
+
startHand: yrp.startHand,
|
|
2449
|
+
drawCount: yrp.drawCount
|
|
2450
|
+
});
|
|
2451
|
+
duel.setPlayerInfo({
|
|
2452
|
+
player: 1,
|
|
2453
|
+
lp: yrp.startLp,
|
|
2454
|
+
startHand: yrp.startHand,
|
|
2455
|
+
drawCount: yrp.drawCount
|
|
2456
|
+
});
|
|
2457
|
+
duel.preloadScript("./script/patches/entry.lua");
|
|
2458
|
+
duel.preloadScript("./script/special.lua");
|
|
2459
|
+
duel.preloadScript("./script/init.lua");
|
|
2460
|
+
if (yrp.isSingleMode && yrp.singleScript) {
|
|
2461
|
+
duel.preloadScript(`./single/${yrp.singleScript}`);
|
|
2462
|
+
} else if (yrp.isTag) {
|
|
2463
|
+
loadDeck(duel, yrp.hostDeck, 0, 0);
|
|
2464
|
+
loadTagDeck(duel, yrp.tagHostDeck, 0);
|
|
2465
|
+
loadDeck(duel, yrp.clientDeck, 1, 1);
|
|
2466
|
+
loadTagDeck(duel, yrp.tagClientDeck, 1);
|
|
2467
|
+
} else {
|
|
2468
|
+
loadDeck(duel, yrp.hostDeck, 0, 0);
|
|
2469
|
+
loadDeck(duel, yrp.clientDeck, 1, 1);
|
|
2470
|
+
}
|
|
2471
|
+
duel.startDuel(yrp.opt >>> 0);
|
|
2472
|
+
return { yrp, duel };
|
|
2473
|
+
}
|
|
2474
|
+
function consumeResponseFromOcgcoreProcess(duel, result, responses) {
|
|
2475
|
+
if (result.raw.length > 0 && result.raw[0] === OcgcoreCommonConstants.MSG_RETRY) {
|
|
2476
|
+
throw new Error("Got MSG_RETRY");
|
|
2477
|
+
}
|
|
2478
|
+
if (result.status === 0) {
|
|
2479
|
+
return false;
|
|
2480
|
+
}
|
|
2481
|
+
if (result.status === 1) {
|
|
2482
|
+
if (result.raw.length === 0) {
|
|
2483
|
+
return false;
|
|
2258
2484
|
}
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
player: 0,
|
|
2263
|
-
lp: yrp.startLp,
|
|
2264
|
-
startHand: yrp.startHand,
|
|
2265
|
-
drawCount: yrp.drawCount
|
|
2266
|
-
});
|
|
2267
|
-
duel.setPlayerInfo({
|
|
2268
|
-
player: 1,
|
|
2269
|
-
lp: yrp.startLp,
|
|
2270
|
-
startHand: yrp.startHand,
|
|
2271
|
-
drawCount: yrp.drawCount
|
|
2272
|
-
});
|
|
2273
|
-
duel.preloadScript("./script/patches/entry.lua");
|
|
2274
|
-
duel.preloadScript("./script/special.lua");
|
|
2275
|
-
duel.preloadScript("./script/init.lua");
|
|
2276
|
-
if (yrp.isSingleMode && yrp.singleScript) {
|
|
2277
|
-
duel.preloadScript(`./single/${yrp.singleScript}`);
|
|
2278
|
-
} else if (yrp.isTag) {
|
|
2279
|
-
loadDeck(duel, yrp.hostDeck, 0, 0);
|
|
2280
|
-
loadTagDeck(duel, yrp.tagHostDeck, 0);
|
|
2281
|
-
loadDeck(duel, yrp.clientDeck, 1, 1);
|
|
2282
|
-
loadTagDeck(duel, yrp.tagClientDeck, 1);
|
|
2283
|
-
} else {
|
|
2284
|
-
loadDeck(duel, yrp.hostDeck, 0, 0);
|
|
2285
|
-
loadDeck(duel, yrp.clientDeck, 1, 1);
|
|
2485
|
+
const response = responses.shift();
|
|
2486
|
+
if (!response) {
|
|
2487
|
+
return true;
|
|
2286
2488
|
}
|
|
2287
|
-
duel.
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
continue;
|
|
2303
|
-
}
|
|
2304
|
-
const response = responses.shift();
|
|
2305
|
-
if (!response) {
|
|
2306
|
-
break;
|
|
2307
|
-
}
|
|
2308
|
-
duel.setResponse(response);
|
|
2309
|
-
continue;
|
|
2310
|
-
}
|
|
2489
|
+
duel.setResponse(response);
|
|
2490
|
+
return false;
|
|
2491
|
+
}
|
|
2492
|
+
return true;
|
|
2493
|
+
}
|
|
2494
|
+
function* processYrpDuelStep(duel, yrp) {
|
|
2495
|
+
const responses = yrp.responses.slice();
|
|
2496
|
+
while (true) {
|
|
2497
|
+
const result = duel.process();
|
|
2498
|
+
yield {
|
|
2499
|
+
duel,
|
|
2500
|
+
result,
|
|
2501
|
+
responses
|
|
2502
|
+
};
|
|
2503
|
+
if (consumeResponseFromOcgcoreProcess(duel, result, responses)) {
|
|
2311
2504
|
break;
|
|
2312
2505
|
}
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2508
|
+
function* playYrpStep(ocgcoreWrapper, yrpInput) {
|
|
2509
|
+
const { yrp, duel } = createDuelFromYrp(ocgcoreWrapper, yrpInput);
|
|
2510
|
+
try {
|
|
2511
|
+
for (const stepResult of processYrpDuelStep(duel, yrp)) {
|
|
2512
|
+
yield stepResult;
|
|
2513
|
+
}
|
|
2313
2514
|
} finally {
|
|
2314
|
-
endDuel();
|
|
2515
|
+
duel.endDuel();
|
|
2315
2516
|
}
|
|
2316
2517
|
}
|
|
2317
2518
|
var playYrp = (ocgcoreWrapper, yrpInput) => {
|
|
@@ -2371,12 +2572,16 @@ if (typeof globalThis !== "undefined" && !globalThis.Buffer) {
|
|
|
2371
2572
|
}
|
|
2372
2573
|
export {
|
|
2373
2574
|
CardDataStruct,
|
|
2575
|
+
DirCardReader,
|
|
2374
2576
|
DirReader,
|
|
2577
|
+
DirScriptReader,
|
|
2578
|
+
DirScriptReaderEx,
|
|
2375
2579
|
LEN_EMPTY,
|
|
2376
2580
|
LEN_FAIL,
|
|
2377
2581
|
LEN_HEADER,
|
|
2378
2582
|
MESSAGE_BUFFER_SIZE,
|
|
2379
2583
|
MapReader,
|
|
2584
|
+
MapScriptReader,
|
|
2380
2585
|
OcgcoreCommonConstants,
|
|
2381
2586
|
OcgcoreDuel,
|
|
2382
2587
|
OcgcoreDuelOptionFlag,
|
|
@@ -2386,7 +2591,11 @@ export {
|
|
|
2386
2591
|
OcgcoreWrapper,
|
|
2387
2592
|
QUERY_BUFFER_SIZE,
|
|
2388
2593
|
REGISTRY_BUFFER_SIZE,
|
|
2594
|
+
SqljsCardReader,
|
|
2389
2595
|
ZipReader,
|
|
2596
|
+
ZipScriptReader,
|
|
2597
|
+
consumeResponseFromOcgcoreProcess,
|
|
2598
|
+
createDuelFromYrp,
|
|
2390
2599
|
createOcgcoreWrapper,
|
|
2391
2600
|
createSqljsCardReader,
|
|
2392
2601
|
normalizeStartDuelOptions,
|
|
@@ -2397,6 +2606,7 @@ export {
|
|
|
2397
2606
|
parseRegistryKeys,
|
|
2398
2607
|
playYrp,
|
|
2399
2608
|
playYrpStep,
|
|
2609
|
+
processYrpDuelStep,
|
|
2400
2610
|
testCard
|
|
2401
2611
|
};
|
|
2402
2612
|
//# sourceMappingURL=index.mjs.map
|