自动使用兑换码归档 (#1575)
6
archive/js/自动使用兑换码/README.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
兑换码支持用非字母数字串隔开,
|
||||||
|
例如输入“DUIHUANMA111 DUIHUANMA222%.&*()DUIHUANMA333#¥”,
|
||||||
|
可以识别出DUIHUANMA111,DUIHUANMA222,DUIHUANMA333三个兑换码,
|
||||||
|
不过还是建议用空格隔开例如“DUIHUANMA111 DUIHUANMA222 DUIHUANMA333”
|
||||||
|
|
||||||
|
不需要关闭该脚本。该脚本自动检测新旧兑换码,无需反复启停该脚本。脚本现在能正确检测兑换码(自定义配置)变化并只在新兑换码(自定义配置)出现时执行。
|
||||||
BIN
archive/js/自动使用兑换码/assets/account.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
archive/js/自动使用兑换码/assets/clear.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
archive/js/自动使用兑换码/assets/confirm.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
archive/js/自动使用兑换码/assets/expired.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
archive/js/自动使用兑换码/assets/go_to_redeem.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
BIN
archive/js/自动使用兑换码/assets/input_code.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
archive/js/自动使用兑换码/assets/invalid.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
archive/js/自动使用兑换码/assets/not_open.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
archive/js/自动使用兑换码/assets/redeem.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
archive/js/自动使用兑换码/assets/settings.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
archive/js/自动使用兑换码/assets/used.png
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
168
archive/js/自动使用兑换码/main.js
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
(async function () {
|
||||||
|
// 定义状态文件路径
|
||||||
|
const STATE_FILE = "redeem_state.json";
|
||||||
|
|
||||||
|
// 1. 检查配置项是否存在
|
||||||
|
if (typeof settings === 'undefined' || typeof settings.redeemCodes === 'undefined') {
|
||||||
|
log.error("兑换码配置项不存在,脚本终止运行");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 获取当前兑换码配置
|
||||||
|
const currentCodesText = settings.redeemCodes || "";
|
||||||
|
const currentCodes = currentCodesText.split(/\s+/).filter(code => code.trim() !== "");
|
||||||
|
|
||||||
|
if (currentCodes.length === 0) {
|
||||||
|
log.info("未检测到兑换码,脚本终止运行");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 读取上次兑换状态(使用 try-catch 替代 existsSync)
|
||||||
|
let lastRunCodes = [];
|
||||||
|
try {
|
||||||
|
// 直接尝试读取文件,如果文件不存在会抛出异常
|
||||||
|
const stateData = file.readTextSync(STATE_FILE);
|
||||||
|
lastRunCodes = JSON.parse(stateData);
|
||||||
|
log.info(`读取到上次兑换码配置: ${lastRunCodes.join(" ")}`);
|
||||||
|
} catch (error) {
|
||||||
|
// 文件不存在是正常情况,不需要警告
|
||||||
|
if (!error.message.includes("文件不存在")) {
|
||||||
|
log.warning(`读取状态文件失败: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 检查兑换码是否变化
|
||||||
|
const hasChanged = !arraysEqual(currentCodes, lastRunCodes);
|
||||||
|
|
||||||
|
if (!hasChanged) {
|
||||||
|
log.info("兑换码配置未变化,脚本终止运行");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info(`检测到新兑换码配置: ${currentCodesText}`);
|
||||||
|
setGameMetrics(1920, 1080, 1);
|
||||||
|
// 5. 返回主界面,等待1秒
|
||||||
|
await genshin.returnMainUi();
|
||||||
|
await sleep(1000);
|
||||||
|
|
||||||
|
// 6. 通过keyPress点按esc键(VK_ESCAPE),等待2秒
|
||||||
|
keyPress("ESCAPE");
|
||||||
|
await sleep(2000);
|
||||||
|
|
||||||
|
const settingsRo = RecognitionObject.TemplateMatch(file.readImageMatSync("assets/settings.png"));
|
||||||
|
const settingsRes = captureGameRegion().find(settingsRo);
|
||||||
|
if (settingsRes.isExist()) {
|
||||||
|
settingsRes.click();
|
||||||
|
}
|
||||||
|
await sleep(2000);
|
||||||
|
|
||||||
|
const accountRo = RecognitionObject.TemplateMatch(file.readImageMatSync("assets/account.png"));
|
||||||
|
const accountRes = captureGameRegion().find(accountRo);
|
||||||
|
if (accountRes.isExist()) {
|
||||||
|
accountRes.click();
|
||||||
|
}
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const goToRedeemRo = RecognitionObject.TemplateMatch(file.readImageMatSync("assets/go_to_redeem.png"));
|
||||||
|
const goToRedeemRes = captureGameRegion().find(goToRedeemRo);
|
||||||
|
if (goToRedeemRes.isExist()) {
|
||||||
|
goToRedeemRes.click();
|
||||||
|
}
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (const code of currentCodes) {
|
||||||
|
log.info(`处理兑换码: ${code}`);
|
||||||
|
|
||||||
|
// b. 识别输入兑换码图片并点击
|
||||||
|
const inputCodeRo = RecognitionObject.TemplateMatch(file.readImageMatSync("assets/input_code.png"));
|
||||||
|
const inputCodeRes = captureGameRegion().find(inputCodeRo);
|
||||||
|
if (inputCodeRes.isExist()) {
|
||||||
|
inputCodeRes.click();
|
||||||
|
}
|
||||||
|
await sleep(300);
|
||||||
|
|
||||||
|
// c. 通过虚拟键代码依次keyPress键入兑换码的每一个字符
|
||||||
|
await inputText(code);
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
// d. 输入完毕后,识别兑换图片并点击,等待1.5秒
|
||||||
|
const redeemRo = RecognitionObject.TemplateMatch(file.readImageMatSync("assets/redeem.png"));
|
||||||
|
const redeemRes = captureGameRegion().find(redeemRo);
|
||||||
|
if (redeemRes.isExist()) {
|
||||||
|
redeemRes.click();
|
||||||
|
}
|
||||||
|
await sleep(1500);
|
||||||
|
|
||||||
|
// e. 识别各种状态图片
|
||||||
|
const invalidRo = RecognitionObject.TemplateMatch(file.readImageMatSync("assets/invalid.png"));
|
||||||
|
const invalidRes = captureGameRegion().find(invalidRo);
|
||||||
|
if (invalidRes.isExist()) {
|
||||||
|
log.info(`兑换码【${code}】无效`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const usedRo = RecognitionObject.TemplateMatch(file.readImageMatSync("assets/used.png"));
|
||||||
|
const usedRes = captureGameRegion().find(usedRo);
|
||||||
|
if (usedRes.isExist()) {
|
||||||
|
log.info(`兑换码【${code}】已使用`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const expiredRo = RecognitionObject.TemplateMatch(file.readImageMatSync("assets/expired.png"));
|
||||||
|
const expiredRes = captureGameRegion().find(expiredRo);
|
||||||
|
if (expiredRes.isExist()) {
|
||||||
|
log.info(`兑换码【${code}】已过期`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const notopenRo = RecognitionObject.TemplateMatch(file.readImageMatSync("assets/not_open.png"));
|
||||||
|
const notopenRes = captureGameRegion().find(notopenRo);
|
||||||
|
if (notopenRes.isExist()) {
|
||||||
|
log.info(`兑换码【${code}】未开启`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmRo = RecognitionObject.TemplateMatch(file.readImageMatSync("assets/confirm.png"));
|
||||||
|
const confirmRes = captureGameRegion().find(confirmRo);
|
||||||
|
if (confirmRes.isExist()) {
|
||||||
|
log.info(`兑换码【${code}】成功兑换`);
|
||||||
|
confirmRes.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
// f. 识别清除图片并点击
|
||||||
|
const clearRo = RecognitionObject.TemplateMatch(file.readImageMatSync("assets/clear.png"));
|
||||||
|
const clearRes = captureGameRegion().find(clearRo);
|
||||||
|
if (clearRes.isExist()) {
|
||||||
|
clearRes.click();
|
||||||
|
}
|
||||||
|
await sleep(4000);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
log.error(`处理兑换码时出错: ${error}`);
|
||||||
|
return; // 出错时不更新状态
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. 所有兑换码兑换完成后返回主界面
|
||||||
|
await genshin.returnMainUi();
|
||||||
|
|
||||||
|
// 8. 保存当前兑换码到状态文件
|
||||||
|
try {
|
||||||
|
file.writeTextSync(STATE_FILE, JSON.stringify(currentCodes));
|
||||||
|
log.info("兑换码状态已更新");
|
||||||
|
} catch (error) {
|
||||||
|
log.error(`保存状态文件失败: ${error}`);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// 辅助函数:比较两个数组是否相同
|
||||||
|
function arraysEqual(a, b) {
|
||||||
|
if (a === b) return true;
|
||||||
|
if (a == null || b == null) return false;
|
||||||
|
if (a.length !== b.length) return false;
|
||||||
|
|
||||||
|
// 创建副本避免修改原数组
|
||||||
|
const sortedA = [...a].sort();
|
||||||
|
const sortedB = [...b].sort();
|
||||||
|
|
||||||
|
for (let i = 0; i < sortedA.length; i++) {
|
||||||
|
if (sortedA[i] !== sortedB[i]) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
14
archive/js/自动使用兑换码/manifest.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"manifest_version": 1,
|
||||||
|
"name": "自动使用多个兑换码",
|
||||||
|
"version": "2.0",
|
||||||
|
"description": "自动使用兑换码,自定义配置里输入兑换码,多个兑换码支持用非字母数字串隔开,建议用空格隔开。自动检测新旧兑换码,无需反复启停该脚本",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "miludelongwang",
|
||||||
|
"links": "https://github.com/miludelongwang"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings_ui": "settings.json",
|
||||||
|
"main": "main.js"
|
||||||
|
}
|
||||||
1
archive/js/自动使用兑换码/redeem_state.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
["DUIHUANMA111","DUIHUANMA222","DUIHUANMA333"]
|
||||||
7
archive/js/自动使用兑换码/settings.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "redeemCodes",
|
||||||
|
"type": "input-text",
|
||||||
|
"label": "兑换码(多个兑换码支持用非字母数字串隔开,建议用空格隔开)"
|
||||||
|
}
|
||||||
|
]
|
||||||
5
archive/js/自动使用兑换码/version.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# 2.0
|
||||||
|
新增自动检测新旧兑换码,无需反复启停该脚本。脚本现在能正确检测兑换码(自定义配置)变化并只在新兑换码(自定义配置)出现时执行。
|
||||||
|
兑换码支持用非字母数字串隔开,例如输入“DUIHUANMA111 DUIHUANMA222%.&*()DUIHUANMA333#¥”,可以识别出DUIHUANMA111,DUIHUANMA222,DUIHUANMA333三个兑换码,不过还是建议用空格隔开例如“DUIHUANMA111 DUIHUANMA222 DUIHUANMA333”
|
||||||
|
# 1.0
|
||||||
|
自动使用兑换码,自定义配置里输入兑换码,多个兑换码间用空格隔开。
|
||||||