mirror of
https://github.com/tiennm99/WPlace-AutoBOT.git
synced 2026-05-30 12:22:57 +00:00
Fixed situation, when bot are waiting for charges to restore, when there another acc with charges, by simply switching acc when done with painting
This commit is contained in:
@@ -7517,38 +7517,16 @@
|
||||
return;
|
||||
}
|
||||
|
||||
swapAccountTrigger(nextToken);
|
||||
|
||||
let maxRetries = 20;
|
||||
let retryCount = 0;
|
||||
let swapSuccess = false;
|
||||
|
||||
while (!swapSuccess && retryCount < maxRetries) {
|
||||
console.log(`⏳ Waiting for account swap... (Attempt ${retryCount + 1}/${maxRetries})`);
|
||||
|
||||
// Wait for a short period before checking.
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
try {
|
||||
await fetchAccount();
|
||||
|
||||
console.log("✅ Account swap confirmed.");
|
||||
swapSuccess = true;
|
||||
} catch (error) {
|
||||
console.warn("❌ Account swap not yet successful. Retrying...", error);
|
||||
retryCount++;
|
||||
}
|
||||
}
|
||||
const swapSuccess = await swapAccountTrigger(nextToken);
|
||||
|
||||
if (swapSuccess) {
|
||||
|
||||
const { charges, cooldown } = await WPlaceService.getCharges();
|
||||
state.currentCharges = Math.floor(charges);
|
||||
state.cooldown = cooldown;
|
||||
Utils.performSmartSave();
|
||||
updateStats();
|
||||
} else {
|
||||
console.error("❌ Failed to swap account after multiple retries. Stopping loop.");
|
||||
console.error("❌ Failed to swap account after confirmation timeout. Stopping loop.");
|
||||
state.stopFlag = true;
|
||||
}
|
||||
}
|
||||
@@ -7800,7 +7778,7 @@
|
||||
const token = accountsTokens[i];
|
||||
|
||||
console.log(`🔄 Refreshing account ${i + 1}/${accountsTokens.length} for data collection only...`);
|
||||
swapAccountTrigger(token);
|
||||
await swapAccountTrigger(token);
|
||||
|
||||
let retries = 0;
|
||||
let swapped = false;
|
||||
@@ -7834,7 +7812,7 @@
|
||||
|
||||
if (originalToken) {
|
||||
console.log("🔄 Switching back to original account after data collection...");
|
||||
swapAccountTrigger(originalToken);
|
||||
await swapAccountTrigger(originalToken);
|
||||
}
|
||||
await Utils.sleep(1000);
|
||||
|
||||
@@ -8486,15 +8464,44 @@
|
||||
console.error("An error occurred during the purchase:", e);
|
||||
}
|
||||
}
|
||||
function swapAccountTrigger(token) {
|
||||
async function waitForCookieSet(timeout = 10000) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const onMessage = (event) => {
|
||||
if (event.source !== window) return;
|
||||
const data = event.data || {};
|
||||
if (data.type === 'cookieSet') {
|
||||
window.removeEventListener('message', onMessage);
|
||||
clearTimeout(timer);
|
||||
resolve(true);
|
||||
}
|
||||
};
|
||||
const timer = setTimeout(() => {
|
||||
window.removeEventListener('message', onMessage);
|
||||
reject(new Error('cookieSet timeout'));
|
||||
}, timeout);
|
||||
window.addEventListener('message', onMessage);
|
||||
});
|
||||
}
|
||||
async function swapAccountTrigger(token) {
|
||||
localStorage.removeItem("lp");
|
||||
if (!token) return;
|
||||
if (!token) {
|
||||
console.error('❌ Cannot swap account: token is null or undefined');
|
||||
return false;
|
||||
}
|
||||
console.log("Sending token to extension...");
|
||||
window.postMessage({
|
||||
source: 'my-userscript',
|
||||
type: 'setCookie',
|
||||
value: token
|
||||
}, '*');
|
||||
try {
|
||||
await waitForCookieSet(10000);
|
||||
console.log('✅ Cookie set confirmed');
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.warn('⚠️ No cookieSet confirmation:', e.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async function getAccounts() {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
+259
-177
@@ -1777,8 +1777,9 @@ function getText(key, params) {
|
||||
|
||||
async getCharges() {
|
||||
try {
|
||||
const res = await fetch("https://backend.wplace.live/me", {
|
||||
const res = await fetch(`https://backend.wplace.live/me?_=${Date.now()}` , {
|
||||
credentials: "include",
|
||||
cache: 'no-store'
|
||||
})
|
||||
const data = await res.json()
|
||||
return {
|
||||
@@ -1802,8 +1803,9 @@ function getText(key, params) {
|
||||
|
||||
async fetchCheck() {
|
||||
try {
|
||||
const res = await fetch("https://backend.wplace.live/me", {
|
||||
const res = await fetch(`https://backend.wplace.live/me?_=${Date.now()}` , {
|
||||
credentials: "include",
|
||||
cache: 'no-store'
|
||||
})
|
||||
const data = await res.json()
|
||||
return {
|
||||
@@ -8606,72 +8608,19 @@ function getText(key, params) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Debug current state
|
||||
const totalAccounts = accountManager.getAccountCount();
|
||||
console.log(`📊 Account Status - Current index: ${accountManager.currentIndex}, Total accounts: ${totalAccounts}`);
|
||||
|
||||
// Check if we're at the last account in the sequence
|
||||
const isLastAccount = accountManager.currentIndex >= totalAccounts - 1;
|
||||
console.log(`🔍 Is last account? ${isLastAccount} (index ${accountManager.currentIndex} of ${totalAccounts})`);
|
||||
|
||||
if (!isLastAccount && totalAccounts > 1) {
|
||||
// Update current account status before switching
|
||||
console.log('📊 Updating current account status before switch...');
|
||||
await updateCurrentAccountInList();
|
||||
|
||||
// Switch to next account immediately (no cooldown) - only if we have multiple accounts
|
||||
const nextAccount = accountManager.getNextAccount();
|
||||
console.log(`🔄 Switching to next account: ${nextAccount?.displayName} (${accountManager.currentIndex + 2}/${totalAccounts})`);
|
||||
const switchResult = await switchToNextAccount(accounts);
|
||||
if (!switchResult) {
|
||||
console.log('❌ Account switch failed, stopping');
|
||||
state.stopFlag = true;
|
||||
break;
|
||||
}
|
||||
// Continue painting with new account immediately
|
||||
continue;
|
||||
} else if (totalAccounts === 1) {
|
||||
// Only one account available - use cooldown and continue with same account
|
||||
console.log('ℹ️ Only one account available, entering cooldown period');
|
||||
const cooldownResult = await executeCooldownPeriod();
|
||||
if (cooldownResult === 'stopped') break;
|
||||
console.log('✅ Cooldown complete, continuing with same account');
|
||||
continue;
|
||||
} else {
|
||||
// Last account reached - use cooldown then switch to first account
|
||||
console.log('⏱️ Last account reached, entering cooldown period');
|
||||
console.log(`📊 Current account: index ${accountManager.currentIndex}, Last account: index ${totalAccounts - 1}`);
|
||||
|
||||
const cooldownResult = await executeCooldownPeriod();
|
||||
if (cooldownResult === 'stopped') break;
|
||||
|
||||
// After cooldown, switch to first account
|
||||
console.log('🔁 Cooldown complete, switching to first account');
|
||||
console.log(`🔄 Before switch - Current index: ${accountManager.currentIndex}, Target: index 0`);
|
||||
|
||||
const firstAccountInfo = accountManager.getAccountByIndex(0);
|
||||
const firstAccountToken = firstAccountInfo?.token;
|
||||
|
||||
if (!firstAccountToken) {
|
||||
console.log('❌ First account token not found, stopping');
|
||||
state.stopFlag = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Reset to first position
|
||||
accountManager.setCurrentIndex(0);
|
||||
|
||||
const switchResult = await switchToSpecificAccount(firstAccountToken, firstAccountInfo.displayName);
|
||||
if (!switchResult) {
|
||||
console.log('❌ Switch to ID 1 failed, stopping');
|
||||
state.stopFlag = true;
|
||||
break;
|
||||
}
|
||||
|
||||
console.log(`✅ Successfully switched to ID 1 (${firstAccountInfo.displayName}). Cycle restarted.`);
|
||||
// Continue painting with first account
|
||||
// Try to find an account with enough charges to continue painting
|
||||
const minRequired = Math.max(1, state.cooldownChargeThreshold || 1);
|
||||
console.log(`🔎 Searching for account with ≥${minRequired} charges...`);
|
||||
const switched = await selectAndSwitchToAccountWithCharges(minRequired);
|
||||
if (switched) {
|
||||
console.log('✅ Switched to an account with sufficient charges, continuing painting immediately');
|
||||
continue;
|
||||
}
|
||||
// If none had enough charges, enter cooldown on the best available account
|
||||
console.log('🕒 No accounts have enough charges. Entering cooldown on the account with the soonest recharge...');
|
||||
const cooldownResult = await executeCooldownPeriod();
|
||||
if (cooldownResult === 'stopped') break;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9976,13 +9925,43 @@ function getText(key, params) {
|
||||
type: 'setCookie',
|
||||
value: token
|
||||
}, '*');
|
||||
|
||||
console.log('✅ setCookie message sent successfully');
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to send setCookie message:', error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wait for background confirmation that cookie was set
|
||||
const confirmed = await new Promise((resolve) => {
|
||||
let settled = false;
|
||||
const timer = setTimeout(() => {
|
||||
if (!settled) {
|
||||
settled = true;
|
||||
console.warn('⚠️ cookieSet confirmation timeout');
|
||||
resolve(false);
|
||||
}
|
||||
}, 10000);
|
||||
function onMessage(event) {
|
||||
if (event.source !== window) return;
|
||||
const data = event.data || {};
|
||||
if (data.type === 'cookieSet') {
|
||||
if (!settled) {
|
||||
settled = true;
|
||||
clearTimeout(timer);
|
||||
window.removeEventListener('message', onMessage);
|
||||
resolve(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
window.addEventListener('message', onMessage);
|
||||
});
|
||||
|
||||
if (confirmed) {
|
||||
console.log('✅ Cookie set confirmed');
|
||||
} else {
|
||||
console.warn('⚠️ Proceeding without cookie confirmation');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
async function getAccounts() {
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -10114,10 +10093,16 @@ function getText(key, params) {
|
||||
await switchToSpecificAccount(originalCurrentAccount.token, originalCurrentAccount.displayName);
|
||||
//await Utils.sleep(300);
|
||||
|
||||
// Mark it as current again
|
||||
// Mark it as current again and sync index
|
||||
accountManager.updateAccountData(originalCurrentAccount.token, {
|
||||
isCurrent: true
|
||||
});
|
||||
const list = accountManager.getAllAccounts();
|
||||
const idxOriginal = list.findIndex(acc => acc.token === originalCurrentAccount.token);
|
||||
if (idxOriginal !== -1 && typeof accountManager.setCurrentIndex === 'function') {
|
||||
accountManager.setCurrentIndex(idxOriginal);
|
||||
state.accountIndex = idxOriginal;
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`⚠️ [FETCH] Failed to switch back to original account:`, error);
|
||||
}
|
||||
@@ -10147,95 +10132,78 @@ function getText(key, params) {
|
||||
async function updateCurrentAccountInList() {
|
||||
if (accountManager.getAccountCount() === 0) return;
|
||||
|
||||
// Find current account in the list and update its charges
|
||||
const currentAccount = accountManager.getCurrentAccount();
|
||||
if (currentAccount) {
|
||||
const { charges, cooldown, droplets } = await WPlaceService.getCharges();
|
||||
state.displayCharges = Math.floor(charges);
|
||||
state.preciseCurrentCharges = charges;
|
||||
try {
|
||||
// Always trust backend /me and then map by ID to avoid mixing data between tokens
|
||||
const me = await WPlaceService.getCharges();
|
||||
state.displayCharges = Math.floor(me.charges);
|
||||
state.preciseCurrentCharges = me.charges;
|
||||
await updateStats();
|
||||
|
||||
// Update the current account data in AccountManager
|
||||
accountManager.updateAccountData(currentAccount.token, {
|
||||
Charges: Math.floor(state.displayCharges || state.preciseCurrentCharges || 0),
|
||||
Max: state.maxCharges,
|
||||
Droplets: Math.floor(droplets)
|
||||
});
|
||||
const accounts = accountManager.getAllAccounts();
|
||||
const idx = accounts.findIndex(acc => acc.ID === me.id);
|
||||
const targetToken = idx !== -1 ? accounts[idx].token : accountManager.getCurrentAccount()?.token;
|
||||
|
||||
// Re-render the account list to show updated charges
|
||||
renderAccountsList();
|
||||
if (targetToken) {
|
||||
accountManager.updateAccountData(targetToken, {
|
||||
Charges: Math.floor(state.displayCharges || 0),
|
||||
Max: Math.floor(me.max || state.maxCharges || 0),
|
||||
Droplets: Math.floor(me.droplets)
|
||||
});
|
||||
|
||||
// Keep manager index in sync with reality when possible
|
||||
if (idx !== -1 && typeof accountManager.setCurrentIndex === 'function') {
|
||||
accountManager.setCurrentIndex(idx);
|
||||
state.accountIndex = idx;
|
||||
}
|
||||
|
||||
// Re-render the account list to show updated charges
|
||||
renderAccountsList();
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('⚠️ updateCurrentAccountInList failed:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// Function to update current account spotlight when switching during painting
|
||||
async function updateCurrentAccountSpotlight() {
|
||||
if (accountManager.getAccountCount() === 0) return;
|
||||
// await Utils.sleep(500); // Wait a bit for the switch to take effect
|
||||
try {
|
||||
const currentAccountData = await WPlaceService.getCharges();
|
||||
console.log("Current account after switch:", currentAccountData);
|
||||
console.log(`🔍 Switched to account with ID: ${currentAccountData.id}`);
|
||||
const me = await WPlaceService.getCharges();
|
||||
console.log("Current account after switch:", me);
|
||||
console.log(`🔍 Switched to account with ID: ${me.id}`);
|
||||
|
||||
// Find the current account in AccountManager and update it
|
||||
const accounts = accountManager.getAllAccounts();
|
||||
const currentAccount = accounts.find(acc => acc.ID === currentAccountData.id);
|
||||
const idx = accounts.findIndex(acc => acc.ID === me.id);
|
||||
|
||||
if (currentAccount) {
|
||||
const currentAccountInfo = await WPlaceService.fetchCheck();
|
||||
if (idx !== -1) {
|
||||
const currentAccount = accounts[idx];
|
||||
const info = await WPlaceService.fetchCheck();
|
||||
|
||||
// Sync manager index and flags to actual account
|
||||
if (typeof accountManager.setCurrentIndex === 'function') {
|
||||
accountManager.setCurrentIndex(idx);
|
||||
} else {
|
||||
accounts.forEach((acc, i) => (acc.isCurrent = i === idx));
|
||||
}
|
||||
|
||||
// Update account data in AccountManager
|
||||
accountManager.updateAccountData(currentAccount.token, {
|
||||
isCurrent: true,
|
||||
Charges: Math.floor(currentAccountData.charges),
|
||||
Max: Math.floor(currentAccountData.max),
|
||||
Droplets: Math.floor(currentAccountData.droplets),
|
||||
displayName: currentAccountInfo.Username || currentAccountInfo.name || currentAccount.displayName
|
||||
Charges: Math.floor(me.charges),
|
||||
Max: Math.floor(me.max),
|
||||
Droplets: Math.floor(me.droplets),
|
||||
displayName: info.Username || info.name || currentAccount.displayName
|
||||
});
|
||||
|
||||
console.log(`🎯 Updated current account spotlight: ${currentAccount.displayName}`);
|
||||
// Mirror to UI state for consistency
|
||||
state.displayCharges = Math.floor(me.charges);
|
||||
state.preciseCurrentCharges = me.charges;
|
||||
state.cooldown = me.cooldown;
|
||||
state.accountIndex = idx;
|
||||
|
||||
// Check for autobuy after account is loaded
|
||||
if (CONFIG.autoBuyToggle && Math.floor(currentAccountData.droplets) > 500) {
|
||||
console.log(`💰 Account has ${Math.floor(currentAccountData.droplets)} droplets (>500), triggering autobuy...`);
|
||||
try {
|
||||
const purchaseResult = await purchase(CONFIG.autoBuy);
|
||||
if (purchaseResult == 2) {
|
||||
console.log('✅ Autobuy successful after account switch');
|
||||
// Update charges after purchase
|
||||
const updatedCharges = await WPlaceService.getCharges();
|
||||
accountManager.updateAccountData(currentAccount.token, {
|
||||
Charges: Math.floor(updatedCharges.charges),
|
||||
Droplets: Math.floor(updatedCharges.droplets)
|
||||
});
|
||||
// Re-render account list to show updated status after purchase
|
||||
renderAccountsList();
|
||||
} else {
|
||||
console.log('❌ Autobuy failed after account switch');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ Error during autobuy after account switch:', error);
|
||||
}
|
||||
} else if (CONFIG.autoBuyToggle) {
|
||||
console.log(`💰 Account has ${Math.floor(currentAccountData.droplets)} droplets (≤500), skipping autobuy`);
|
||||
}
|
||||
|
||||
// Re-render the account list to show new current account
|
||||
renderAccountsList();
|
||||
|
||||
console.log(`🔒 PRESERVING currentActiveIndex: ${state.currentActiveIndex} (do not recalculate from isCurrent flag)`);
|
||||
console.log(`� Account at currentActiveIndex ${state.currentActiveIndex}: ${state.originalAccountOrder[state.currentActiveIndex]?.displayName} (ID ${state.originalAccountOrder[state.currentActiveIndex]?.orderId})`);
|
||||
|
||||
// Update accountIndex to match original array position
|
||||
const originalArrayIndex = state.allAccountsInfo.findIndex(acc => acc.isCurrent);
|
||||
if (originalArrayIndex !== -1) {
|
||||
state.accountIndex = originalArrayIndex;
|
||||
}
|
||||
|
||||
console.log(`📊 Final state: activeIndex=${state.currentActiveIndex}, accountIndex=${state.accountIndex}, orderId=${newCurrentAccount.orderId}`);
|
||||
|
||||
console.warn(`⚠️ Could not find account ID ${newCurrentAccount.orderId} in switching order`);
|
||||
|
||||
console.warn(`⚠️ Could not find switched account with ID ${currentAccountData.id} in account list`);
|
||||
console.log(`🎯 Updated current account spotlight: ${currentAccount.displayName}`);
|
||||
} else {
|
||||
console.warn(`⚠️ Could not find switched account with ID ${me.id} in account list`);
|
||||
}
|
||||
|
||||
// Re-render the account list to show new current account
|
||||
@@ -10359,6 +10327,10 @@ function getText(key, params) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Capture the pre-switch (current) account to detect stale reads
|
||||
const preSwitchAccount = accountManager.getCurrentAccount();
|
||||
const previousKnownId = preSwitchAccount?.ID || null;
|
||||
|
||||
// Get next account using simplified manager
|
||||
const nextAccount = accountManager.switchToNext();
|
||||
if (!nextAccount) {
|
||||
@@ -10385,8 +10357,46 @@ function getText(key, params) {
|
||||
|
||||
console.log(`✅ [SWITCH] Successfully switched to ${nextAccount.displayName}`);
|
||||
|
||||
// Wait a moment for the switch to fully complete
|
||||
// await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
// Verify backend reflects the new account to avoid stale reads
|
||||
// Strategy: poll /me until we see an ID different from the pre-switch account's ID
|
||||
// Only then accept and (if needed) assign the next account's ID.
|
||||
let verifiedId = null;
|
||||
for (let attempt = 1; attempt <= 8 && !verifiedId; attempt++) {
|
||||
try {
|
||||
const me = await WPlaceService.getCharges();
|
||||
const curId = me?.id;
|
||||
if (!curId) {
|
||||
await Utils.sleep(500);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (previousKnownId && curId === previousKnownId) {
|
||||
console.log(`⏳ [SWITCH] Still seeing previous ID ${curId} (attempt ${attempt}/8), waiting...`);
|
||||
await Utils.sleep(500);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we had a stored ID for the target and it's different from what we see now,
|
||||
// prefer the live value (curId) and update the stored ID.
|
||||
if (nextAccount.ID && nextAccount.ID !== curId) {
|
||||
console.log(`🔁 [SWITCH] Updating stored ID for ${nextAccount.displayName}: ${nextAccount.ID} → ${curId}`);
|
||||
}
|
||||
|
||||
verifiedId = curId;
|
||||
break;
|
||||
} catch (e) {
|
||||
await Utils.sleep(500);
|
||||
}
|
||||
}
|
||||
|
||||
if (!verifiedId) {
|
||||
console.warn('⚠️ [SWITCH] Could not verify account change via /me after cookie set; skipping ID update but proceeding cautiously.');
|
||||
} else {
|
||||
// Persist verified ID for the next account
|
||||
if (nextAccount.ID !== verifiedId) {
|
||||
accountManager.updateAccountData(nextAccount.token, { ID: verifiedId });
|
||||
}
|
||||
}
|
||||
|
||||
// Update the account status and UI after successful switch
|
||||
await updateCurrentAccountInList();
|
||||
@@ -10401,54 +10411,77 @@ function getText(key, params) {
|
||||
// SIMPLIFIED helper function for specific account switching
|
||||
async function switchToSpecificAccount(token, accountName) {
|
||||
console.log(`🔄 [SPECIFIC SWITCH] Attempting to switch to account: ${accountName}`);
|
||||
if (!token) {
|
||||
console.error('❌ [SPECIFIC SWITCH] Missing token');
|
||||
return false;
|
||||
}
|
||||
console.log(`🔑 [SPECIFIC SWITCH] Using token: ${token.substring(0, 20)}...`);
|
||||
|
||||
await swapAccountTrigger(token);
|
||||
// Capture previous account ID to detect stale responses
|
||||
let previousId = null;
|
||||
try {
|
||||
const prev = await WPlaceService.getCharges();
|
||||
previousId = prev?.id || null;
|
||||
} catch {}
|
||||
|
||||
let maxRetries = 20;
|
||||
let retryCount = 0;
|
||||
let swapSuccess = false;
|
||||
|
||||
while (!swapSuccess && retryCount < maxRetries) {
|
||||
console.log(`⏳ [SPECIFIC SWITCH] Waiting for account swap... (Attempt ${retryCount + 1}/${maxRetries})`);
|
||||
//await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
const ok = await swapAccountTrigger(token);
|
||||
if (!ok) {
|
||||
console.error('❌ [SPECIFIC SWITCH] Cookie confirmation failed');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Poll /me until it reflects a different ID than the previous account
|
||||
let verifiedId = null;
|
||||
for (let attempt = 1; attempt <= 8 && !verifiedId; attempt++) {
|
||||
try {
|
||||
// await fetchAccount();
|
||||
console.log('✅ [SPECIFIC SWITCH] Account swap confirmed.');
|
||||
swapSuccess = true;
|
||||
} catch (error) {
|
||||
console.warn('❌ [SPECIFIC SWITCH] Account swap not yet successful. Retrying...', error);
|
||||
retryCount++;
|
||||
|
||||
if (retryCount % 5 === 0) {
|
||||
console.log('🔄 [SPECIFIC SWITCH] Re-triggering account swap...');
|
||||
await swapAccountTrigger(token);
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
const me = await WPlaceService.getCharges();
|
||||
const curId = me?.id;
|
||||
if (!curId) {
|
||||
await Utils.sleep(500);
|
||||
continue;
|
||||
}
|
||||
if (previousId && curId === previousId) {
|
||||
console.log(`⏳ [SPECIFIC SWITCH] Still seeing previous ID ${curId} (attempt ${attempt}/8), waiting...`);
|
||||
await Utils.sleep(500);
|
||||
continue;
|
||||
}
|
||||
verifiedId = curId;
|
||||
break;
|
||||
} catch {
|
||||
await Utils.sleep(500);
|
||||
}
|
||||
}
|
||||
|
||||
if (swapSuccess) {
|
||||
const { charges, cooldown } = await WPlaceService.getCharges();
|
||||
state.displayCharges = Math.floor(charges);
|
||||
state.preciseCurrentCharges = charges;
|
||||
state.cooldown = cooldown;
|
||||
Utils.performSmartSave();
|
||||
await updateStats();
|
||||
|
||||
// Update account data in manager
|
||||
accountManager.updateAccountData({ charges, cooldown });
|
||||
|
||||
// Update the account status and UI after successful switch
|
||||
await updateCurrentAccountSpotlight();
|
||||
|
||||
console.log(`✅ [SPECIFIC SWITCH] Successfully switched to ${accountName} with ${Math.floor(charges)} charges`);
|
||||
return true;
|
||||
if (!verifiedId) {
|
||||
console.warn('⚠️ [SPECIFIC SWITCH] Could not verify account change via /me; proceeding.');
|
||||
} else {
|
||||
console.error(`❌ [SPECIFIC SWITCH] Failed to swap to ${accountName} after multiple retries.`);
|
||||
return false;
|
||||
// Persist ID and mark as current in AccountManager
|
||||
accountManager.updateAccountData(token, { ID: verifiedId, isCurrent: true });
|
||||
}
|
||||
|
||||
// Sync manager index to the token we explicitly switched to
|
||||
try {
|
||||
const list = accountManager.getAllAccounts();
|
||||
const idxByToken = list.findIndex(acc => acc.token === token);
|
||||
if (idxByToken !== -1 && typeof accountManager.setCurrentIndex === 'function') {
|
||||
accountManager.setCurrentIndex(idxByToken);
|
||||
state.accountIndex = idxByToken;
|
||||
}
|
||||
} catch {}
|
||||
|
||||
// Fetch fresh stats for UI/state
|
||||
const { charges, cooldown, droplets, max } = await WPlaceService.getCharges();
|
||||
state.displayCharges = Math.floor(charges);
|
||||
state.preciseCurrentCharges = charges;
|
||||
state.cooldown = cooldown;
|
||||
Utils.performSmartSave();
|
||||
await updateStats();
|
||||
|
||||
// Update the account status and UI after successful switch
|
||||
await updateCurrentAccountSpotlight();
|
||||
|
||||
console.log(`✅ [SPECIFIC SWITCH] Switched to ${accountName} with ${Math.floor(charges)} charges`);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Wait for dependencies before initializing UI
|
||||
@@ -10492,6 +10525,55 @@ function getText(key, params) {
|
||||
return createUI();
|
||||
}
|
||||
|
||||
// Helper: iterate over accounts to find one with enough charges; otherwise pick best cooldown
|
||||
async function selectAndSwitchToAccountWithCharges(minRequired = 1) {
|
||||
try {
|
||||
const total = accountManager.getAccountCount();
|
||||
if (total <= 1) return false;
|
||||
|
||||
const startIdx = accountManager.currentIndex;
|
||||
let best = { cooldown: Infinity, token: null, name: null, idx: -1 };
|
||||
|
||||
for (let step = 1; step <= total - 1; step++) {
|
||||
const idx = (startIdx + step) % total;
|
||||
const acc = accountManager.getAccountByIndex(idx);
|
||||
if (!acc || !acc.token) continue;
|
||||
|
||||
console.log(`🔄 [SEARCH] Switching temporarily to ${acc.displayName} (${idx + 1}/${total}) to check charges...`);
|
||||
const ok = await switchToSpecificAccount(acc.token, acc.displayName);
|
||||
if (!ok) {
|
||||
console.warn(`⚠️ [SEARCH] Failed to switch to ${acc.displayName}, trying next...`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const me = await WPlaceService.getCharges();
|
||||
const charges = Math.floor(me?.charges || 0);
|
||||
const cooldown = Math.max(0, Number(me?.cooldown || 0));
|
||||
if (charges >= minRequired) {
|
||||
console.log(`✅ [SEARCH] Found account with sufficient charges: ${acc.displayName} (⚡${charges})`);
|
||||
return true;
|
||||
}
|
||||
|
||||
console.log(`⏳ [SEARCH] ${acc.displayName} has no charges (⚡${charges}), cooldown ${cooldown}ms`);
|
||||
if (cooldown < best.cooldown) {
|
||||
best = { cooldown, token: acc.token, name: acc.displayName, idx };
|
||||
}
|
||||
}
|
||||
|
||||
// None had enough charges: switch to the one with the soonest recharge and return false
|
||||
if (best.token && best.idx !== accountManager.currentIndex) {
|
||||
console.log(`🎯 [SEARCH] Switching to account with soonest recharge: ${best.name} (~${Utils.msToTimeText(best.cooldown)})`);
|
||||
await switchToSpecificAccount(best.token, best.name);
|
||||
} else {
|
||||
console.log('🎯 [SEARCH] Staying on current account for cooldown.');
|
||||
}
|
||||
return false;
|
||||
} catch (e) {
|
||||
console.warn('⚠️ selectAndSwitchToAccountWithCharges failed:', e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
waitForDependenciesAndInitialize().then(() => {
|
||||
// Generate token automatically after UI is ready
|
||||
setTimeout(initializeTokenGenerator, 1000);
|
||||
|
||||
Reference in New Issue
Block a user