From 1423b63c035753872ec3080f0040bf4bb95ac75a Mon Sep 17 00:00:00 2001 From: thuanle Date: Tue, 5 Aug 2025 12:36:10 +0700 Subject: [PATCH] Enhance agent.user.js by implementing a timer system for session management, including start, pause, and stop functionalities. Introduce new session keys for timer state and accumulated time, and update the dashboard overlay to display timer information. Refactor task handling to improve clarity and maintainability. --- agent.user.js | 518 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 395 insertions(+), 123 deletions(-) diff --git a/agent.user.js b/agent.user.js index 5cff284..e3eed9e 100644 --- a/agent.user.js +++ b/agent.user.js @@ -34,10 +34,14 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); SESSION_ID: 'aRah9OhHeijee6sho3baequu9phoovah', SESSION_BINDED: 'Oos2uoth2thae8Ir8iakahj1OohaMahb', SESSION_TOKEN: 'ThiegiecohViuZ1Iecio7gahphiechub', + SESSION_INITIALIZED: 'iR4choo2Ieg2ew0ogheeyaer8Aisheet', BOT_STATUS: 'wiethie3boGhoh3iegh3ohnezei2tauj', CURRENT_TASK: 'Reebo1eitahh2aotumai5jae1neetoh3', CURRENT_TASK_DATA: 'cheishailoh5keePoo6oe2Quie1gaxah', CURRENT_STEP: 'eDusaidu2hooweiMoonahng3fua7aoso', + TIMER_START_TIME: 'einguh3eshuiqua7Ux7thaNgai5Axahy', + TIMER_IS_RUNNING: 'iengoose3vie2aikePhooCaPheeceizu', + TIMER_ACCUMULATED: 'aeMaiwae3PohB5Soshaech8eegh5quoo', } if (!sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_ID)) { @@ -50,13 +54,13 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); DASHBOARD_UPDATE_INTERVAL: 500, // Update dashboard overlay every 0.5 seconds TASK_INTERVAL: 10_000, // Check for new task every 10 seconds REQUEST_TIMEOUT: 10_000, // Request timeout in milliseconds (10 seconds) + DEBUG_MILESTONE: true, // Show milestone debug logs SERVERS: { local: { label: '🏠 Local', url: 'http://localhost:3000' }, prod: { label: '🌐 Prod', url: 'https://baf.thuanle.me' }, }, }; - const AppSession = { SESSION_ID: sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_ID), @@ -66,11 +70,14 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); getSessionToken: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_TOKEN), setSessionToken: token => sessionStorage.setItem(SESSION_STORAGE_KEYS.SESSION_TOKEN, token), - getSessionStatus: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.BOT_STATUS) || AppEnums.BOT_STATUS.STOP, + getSessionStatus: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.BOT_STATUS), setSessionStatus: status => sessionStorage.setItem(SESSION_STORAGE_KEYS.BOT_STATUS, status), + getSessionInitialized: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_INITIALIZED) === 'true', + setSessionInitialized: initialized => sessionStorage.setItem(SESSION_STORAGE_KEYS.SESSION_INITIALIZED, initialized ? 'true' : 'false'), + // Task state - Trạng thái task hiện tại (lưu trong sessionStorage) - getCurrentTask: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.CURRENT_TASK) || BAF_TASKS.NO_TASK, + getCurrentTask: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.CURRENT_TASK), setCurrentTask: task => sessionStorage.setItem(SESSION_STORAGE_KEYS.CURRENT_TASK, task), getCurrentTaskData: () => { @@ -79,15 +86,35 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); }, setCurrentTaskData: data => sessionStorage.setItem(SESSION_STORAGE_KEYS.CURRENT_TASK_DATA, JSON.stringify(data)), - getCurrentStep: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.CURRENT_STEP) || BAF_TASKS.NO_STEP, + getCurrentStep: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.CURRENT_STEP), setCurrentStep: step => sessionStorage.setItem(SESSION_STORAGE_KEYS.CURRENT_STEP, step), + + initialize: async () => { + try { + const isInitialized = AppSession.getSessionInitialized(); + + if (!isInitialized) { + AppSession.setSessionStatus(AppEnums.BOT_STATUS.INITIALIZING); + AppSession.setCurrentTask(BAF_TASKS.NO_TASK); + AppSession.setCurrentStep(BAF_TASKS.NO_STEP); + AppSession.setSessionInitialized(true); + } else { + } + } catch (error) { + TL.error('APP-SESSION', '1.2.4. Error during session initialization:', error); + throw error; + } + }, } // ====== APP ENUMS ====== const AppEnums = { BOT_STATUS: { + INITIALIZING: 'initializing', STOP: 'stop', - RUNNING: 'running', + PAUSE: 'pause', + WAITING_FOR_TASK: 'waiting_for_task', + PERFORMING_TASK: 'performing_task', ERROR: 'error', }, BOT_STARTUP_MODE: { @@ -115,7 +142,6 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); // Session flags - Flags cho session hiện tại (reset khi reload) menuCreated: false, // Menu đã được tạo popupInitialized: false, // Popup đã được khởi tạo - appInitialized: false // App đã được khởi tạo hoàn toàn }; this.observers = new Map(); // Observer pattern cho state changes @@ -166,7 +192,6 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); getIsLoggedIn() { return this.data.is_logged_in; } getMenuCreated() { return this.data.menuCreated; } getPopupInitialized() { return this.data.popupInitialized; } - getAppInitialized() { return this.data.appInitialized; } /** * Cập nhật state với partial update @@ -284,6 +309,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); */ const TL = { debug: (tag, msg, ...args) => AppSettings.getDebug() && GM_log(`[TL] [DEBUG] [${new Date().toLocaleString()}] [${tag}] \n${msg}`, ...args), + milestone: (tag, msg, ...args) => CONFIG.DEBUG_MILESTONE && GM_log(`[TL] [MILESTONE] [${new Date().toLocaleString()}] [${tag}] 🎯\n${msg}`, ...args), log: (tag, msg, ...args) => GM_log(`[TL] [LOG] [${new Date().toLocaleString()}] [${tag}] \n${msg}`, ...args), warn: (tag, msg, ...args) => GM_log(`[TL] [WARN] [${new Date().toLocaleString()}] [${tag}] ⚠️\n${msg}`, ...args), error: (tag, msg, ...args) => GM_log(`[TL] [ERROR] [${new Date().toLocaleString()}] [${tag}] ❌\n${msg}`, ...args), @@ -352,7 +378,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); * Navigate to URL với option forceReload * @param {string} url - URL cần navigate */ - navigate: (url) => { + navigateTo: (url) => { window.location.href = url; } }, @@ -419,11 +445,16 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); const BAF_TASKS = { NO_TASK: 'no_task', - + LOGIN: 'login', + WALLET_SPOT: 'wallet_spot', + WALLET_FUNDING: 'wallet_funding', + WALLET_EARN: 'wallet_earn', + ALPHA_SWAP: 'alpha_swap', + ALPHA_ORDER_HISTORY: 'alpha_order_history', NO_STEP: 'no_step', }; - + const BAF = { _getHost: () => AppState.getServer()?.url, @@ -630,7 +661,10 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); // Create dashboard overlay element create: () => { + + if (AppUi.dashboardOverlay.element) { + document.body.removeChild(AppUi.dashboardOverlay.element); } @@ -655,6 +689,36 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); user-select: none; `; + // Add close button (X) + const closeBtn = document.createElement('div'); + closeBtn.style.cssText = ` + position: absolute; + top: -8px; + left: -8px; + width: 20px; + height: 20px; + background: #dc3545; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + font-size: 12px; + color: white; + border: 2px solid rgba(255, 255, 255, 0.2); + transition: all 0.2s ease; + font-weight: bold; + `; + closeBtn.innerHTML = '×'; + closeBtn.title = 'Close popup'; + closeBtn.addEventListener('click', () => { + AppUi.dashboardOverlay.hide(); + AppSettings.setPopupVisible(false); + }); + TL.dom.setHover(closeBtn, 'mouseenter', { scale: 1.5, background: '#c82333' }); + TL.dom.setHover(closeBtn, 'mouseleave', { scale: 1, background: '#dc3545' }); + overlay.appendChild(closeBtn); + // Add position toggle button const positionBtn = document.createElement('div'); positionBtn.style.cssText = ` @@ -679,15 +743,18 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); positionBtn.addEventListener('click', () => { const newPosition = (AppSettings.getPopupPosition() % 4) + 1; AppSettings.setPopupPosition(newPosition); - AppUi.statusOverlay.updatePosition(); + AppUi.dashboardOverlay.updatePosition(); }); TL.dom.setHover(positionBtn, 'mouseenter', { scale: 1.5, background: '#0056b3' }); TL.dom.setHover(positionBtn, 'mouseleave', { scale: 1, background: '#007bff' }); overlay.appendChild(positionBtn); + AppUi.dashboardOverlay.element = overlay; + document.body.appendChild(overlay); + return overlay; }, @@ -703,20 +770,37 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); // Update overlay content updateContent: () => { try { + + + + if (!AppUi.dashboardOverlay.element) { + AppUi.dashboardOverlay.create(); + } // Get status display let statusDisplay = ''; - switch (AppSession.getSessionStatus()) { - case AppEnums.BOT_STATUS.RUNNING: - statusDisplay = '▶️ Running'; + const currentStatus = AppSession.getSessionStatus(); + + switch (currentStatus) { + case AppEnums.BOT_STATUS.INITIALIZING: + statusDisplay = '🔄 Initializing'; break; case AppEnums.BOT_STATUS.STOP: statusDisplay = '⏹️ Stop'; break; + case AppEnums.BOT_STATUS.PAUSE: + statusDisplay = '⏸️ Pause'; + break; + case AppEnums.BOT_STATUS.WAITING_FOR_TASK: + statusDisplay = '⏳ Waiting for Task'; + break; + case AppEnums.BOT_STATUS.PERFORMING_TASK: + statusDisplay = '▶️ Performing Task'; + break; case AppEnums.BOT_STATUS.ERROR: statusDisplay = '❌ Error'; break; default: - statusDisplay = '❌ Error'; + statusDisplay = '❓ Unknown'; break; } @@ -741,16 +825,16 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
BAF Agent Dashboard
- 🛟 Safety: ${safetyStatus.enabled ? '🛡️ Safe' : '🚨 Blocked'} + 🛟 Safety: ${safetyStatus.enabled ? '🛡️ Safe' : '🚨 Blocked'}
🆔 Tab: ${AppSession.SESSION_ID.slice(-12)}
- 🤖 Bot Status: ${statusDisplay} + 🤖 Bot Status: ${statusDisplay}
- 🚀 Startup Mode: ${AppSettings.getBotStartupMode() === AppEnums.BOT_STARTUP_MODE.AUTO ? '🔄 Auto' : '✋ Manual'} + 🚀 Startup Mode: ${AppSettings.getBotStartupMode() === AppEnums.BOT_STARTUP_MODE.AUTO ? '🔄 Auto' : '✋ Manual'}
📋 Task: ${AppSession.getCurrentTask() || 'None'} @@ -765,14 +849,32 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); Page: ${pageDisplay}
- 🌐 Server: ${serverLabel} ${serverConnected} + 🌐 Server: ${serverLabel} ${serverConnected}
- 🐛 Debug: ${AppSettings.getDebug() ? '🔈 ON' : '🔇 OFF'} + 🐛 Debug: ${AppSettings.getDebug() ? '🔈 ON' : '🔇 OFF'} +
+
+ 🎯 Milestone: ${CONFIG.DEBUG_MILESTONE ? '🔈 ON' : '🔇 OFF'} +
+
+
+ ⏱️ ${AppServices.Timer.getDisplay()} +
+
+ ▶️ + ⏸️ + ⏹️ +
`; // Update content (excluding position button) + if (!AppUi.dashboardOverlay.element) { + TL.error('DASHBOARD-OVERLAY', '8.1. Element is null!'); + return; + } + const contentDiv = AppUi.dashboardOverlay.element.querySelector('.baf-content') || document.createElement('div'); contentDiv.className = 'baf-content'; contentDiv.innerHTML = content; @@ -782,7 +884,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); } // Add event listener for safety toggle button - const safetyToggleBtn = contentDiv.querySelector('#safety-toggle-btn'); + const safetyToggleBtn = contentDiv.querySelector('#safety-toggle-btn-AithaiG2'); if (safetyToggleBtn) { safetyToggleBtn.onclick = () => { const currentStatus = { @@ -800,7 +902,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); } // Add event listener for debug toggle button - const debugToggleBtn = contentDiv.querySelector('#debug-toggle-btn'); + const debugToggleBtn = contentDiv.querySelector('#debug-toggle-btn-Tai5guto'); if (debugToggleBtn) { debugToggleBtn.onclick = () => { const newDebugState = !AppSettings.getDebug(); @@ -810,29 +912,47 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); }; } - // Add event listener for bot status toggle button - const botStatusToggleBtn = contentDiv.querySelector('#bot-status-toggle-btn'); - if (botStatusToggleBtn) { - botStatusToggleBtn.onclick = () => { - const currentBotStatus = AppSession.getSessionStatus(); - let newBotStatus; - - // Logic: stop/error -> start, start -> stop - if (currentBotStatus === AppEnums.BOT_STATUS.RUNNING) { - newBotStatus = AppEnums.BOT_STATUS.STOP; - } else { - // STOP or ERROR -> RUNNING - newBotStatus = AppEnums.BOT_STATUS.RUNNING; - } - - AppSession.setSessionStatus(newBotStatus); - // Update the content to reflect the change + // Add event listeners for control buttons + const playBtn = contentDiv.querySelector('#play-btn-uPha3Mah'); + if (playBtn) { + playBtn.onclick = () => { + AppServices.Status.play(); AppUi.dashboardOverlay.updateContent(); }; } + const pauseBtn = contentDiv.querySelector('#pause-btn-Gai2quie'); + if (pauseBtn) { + pauseBtn.onclick = () => { + AppServices.Status.pause(); + AppUi.dashboardOverlay.updateContent(); + }; + } + + const stopBtn = contentDiv.querySelector('#stop-btn-jooK6che'); + if (stopBtn) { + stopBtn.onclick = () => { + AppServices.Status.stop(); + AppUi.dashboardOverlay.updateContent(); + }; + } + + // Add hover effects for control buttons + if (playBtn) { + TL.dom.setHover(playBtn, 'mouseenter', { scale: 1.2, background: 'rgba(40, 167, 69, 0.2)' }); + TL.dom.setHover(playBtn, 'mouseleave', { scale: 1, background: 'rgba(40, 167, 69, 0.1)' }); + } + if (pauseBtn) { + TL.dom.setHover(pauseBtn, 'mouseenter', { scale: 1.2, background: 'rgba(255, 193, 7, 0.2)' }); + TL.dom.setHover(pauseBtn, 'mouseleave', { scale: 1, background: 'rgba(255, 193, 7, 0.1)' }); + } + if (stopBtn) { + TL.dom.setHover(stopBtn, 'mouseenter', { scale: 1.2, background: 'rgba(220, 53, 69, 0.2)' }); + TL.dom.setHover(stopBtn, 'mouseleave', { scale: 1, background: 'rgba(220, 53, 69, 0.1)' }); + } + // Add event listener for startup mode toggle button - const startupModeToggleBtn = contentDiv.querySelector('#startup-mode-toggle-btn'); + const startupModeToggleBtn = contentDiv.querySelector('#startup-mode-toggle-btn-tha9ieCa'); if (startupModeToggleBtn) { startupModeToggleBtn.onclick = () => { const currentStartupMode = AppSettings.getBotStartupMode(); @@ -844,7 +964,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); } // Add event listener for server toggle button - const serverToggleBtn = contentDiv.querySelector('#server-toggle-btn'); + const serverToggleBtn = contentDiv.querySelector('#server-toggle-btn-Youx4pho'); if (serverToggleBtn) { serverToggleBtn.onclick = async () => { const currentServerType = AppSettings.getServerType(); @@ -894,8 +1014,16 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); // Initialize dashboard overlay init: () => { - if (AppSettings.getPopupVisible()) { - AppUi.dashboardOverlay.show(); + try { + const popupVisible = AppSettings.getPopupVisible(); + + if (popupVisible) { + AppUi.dashboardOverlay.show(); + } else { + } + } catch (error) { + TL.error('DASHBOARD-OVERLAY', '1.4.4. Error initializing dashboard overlay:', error); + throw error; } } }, @@ -944,85 +1072,98 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); GM_registerMenuCommand("👁️ Toggle Popup", () => { AppUi.dashboardOverlay.toggle(); }); - } catch (error) { - TL.error('MENU', 'Failed to create menu:', error); + TL.error('MENU', '1.3.5. Failed to create menu:', error); throw error; } } }, }; + // ====== APP TASKS ====== + const AppTasks = { + login: async (step, data) => { + if (!AppServices.isReadyToRun()) { + TL.debug('APP-TASKS', 'Bot is not ready to run'); + return; + } + + TL.debug('APP-TASKS', `Login task ${step}`); + //set steps + switch (step) { + case "start": + AppSession.setSessionStatus(AppEnums.BOT_STATUS.PERFORMING_TASK); + AppSession.setCurrentStep("navigating-to-login-page"); + TL.browser.navigateTo(BINANCE.page.getLoginUrl()); + break; + } + }, + }; + // ====== APP SERVICE ====== const AppServices = { initialize: async () => { - await AppState.initialize(); + try { + await AppState.initialize(); + await AppSession.initialize(); - await AppUi.menu.create(); + // Khởi tạo timer + AppServices.Timer.initialize(); - AppUi.dashboardOverlay.init(); + await AppUi.menu.create(); + AppUi.dashboardOverlay.init(); + await AppServices.registerSession(); - // Setup observers for dashboard overlay updates - AppServices.initObservers(); + const status = AppSession.getSessionStatus(); + if (status === AppEnums.BOT_STATUS.INITIALIZING) { + const startupMode = AppSettings.getBotStartupMode(); + if (startupMode === AppEnums.BOT_STARTUP_MODE.AUTO) { + AppSession.setSessionStatus(AppEnums.BOT_STATUS.WAITING_FOR_TASK); + } else { + AppSession.setSessionStatus(AppEnums.BOT_STATUS.STOP); + } + } - await AppServices.registerSession(); - - // Set bot status based on startup mode - const startupMode = AppSettings.getBotStartupMode(); - if (startupMode === AppEnums.BOT_STARTUP_MODE.AUTO) { - AppSession.setSessionStatus(AppEnums.BOT_STATUS.RUNNING); - TL.debug('APP-SERVICES', 'Auto startup mode: Bot status set to RUNNING'); - } else { - AppSession.setSessionStatus(AppEnums.BOT_STATUS.STOP); - TL.debug('APP-SERVICES', 'Manual startup mode: Bot status set to STOP'); + AppServices.initInterval(); + } catch (error) { + TL.error('APP-SERVICES', 'Error during initialization:', error); + throw error; } - - // Setup interval services - AppServices.initInterval(); - - AppState.update({ appInitialized: true }); - - TL.debug('APP-SERVICES', 'AppServices initialized'); }, - initObservers: () => { - // AppState.subscribe('server_last_seen', () => { - // if (AppSettings.getPopupVisible()) { - // AppUi.dashboardOverlay.updateContent(); - // } - // }); - - // AppState.subscribe('is_logged_in', () => { - // if (AppSettings.getPopupVisible()) { - // AppUi.dashboardOverlay.updateContent(); - // } - // }); - - // AppState.subscribe('current_page', () => { - // if (AppSettings.getPopupVisible()) { - // AppUi.dashboardOverlay.updateContent(); - // } - // }); - }, registerSession: async () => { - const msg = await BAF.register({ session_id: AppSession.SESSION_ID }); - //if ok, set session token - if (msg.ok) { - AppSession.setSessionToken(msg.data.token); - AppSession.setSessionBinded(true); - TL.debug('APP-SERVICES', `Session token: ${AppSession.getSessionToken()}`); - } else { + try { + const msg = await BAF.register({ session_id: AppSession.SESSION_ID }); + + if (msg.ok) { + AppSession.setSessionToken(msg.data.token); + AppSession.setSessionBinded(true); + } else { + AppSession.setSessionBinded(false); + TL.error('APP-SERVICES', `1.5.3. Failed to register session: ${msg.error}`); + } + } catch (error) { + TL.error('APP-SERVICES', '1.5.3. Error during session registration:', error); AppSession.setSessionBinded(false); - TL.error('APP-SERVICES', `Failed to register session: ${msg.error}`); + throw error; } }, - // Setup interval services initInterval: () => { - setInterval(() => AppServices.heartbeat(), CONFIG.HEARTBEAT_INTERVAL); - setInterval(() => AppUi.dashboardOverlay.updateContent(), CONFIG.DASHBOARD_UPDATE_INTERVAL); + try { + setInterval(() => AppServices.heartbeat(), CONFIG.HEARTBEAT_INTERVAL); + setInterval(() => AppUi.dashboardOverlay.updateContent(), CONFIG.DASHBOARD_UPDATE_INTERVAL); - TL.debug('APP-SERVICES', 'Interval services started'); + // Timer update interval - cập nhật timer mỗi giây + setInterval(() => { + const timerDisplay = document.querySelector('#timer-display-ohr1Youj'); + if (timerDisplay) { + timerDisplay.textContent = `⏱️ ${AppServices.Timer.getDisplay()}`; + } + }, 1000); + } catch (error) { + throw error; + } }, isConnected: () => { @@ -1030,9 +1171,86 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); return serverLastSeen && new Date() - serverLastSeen < 60000; }, - isReadyToRun: () => { - return AppSession.getSessionBinded() && AppSettings.getSafetyGuard() && AppSession.getSessionStatus() === AppEnums.BOT_STATUS.RUNNING; + return AppSession.getSessionBinded() && AppSettings.getSafetyGuard() && AppSession.getSessionStatus() === AppEnums.BOT_STATUS.WAITING_FOR_TASK; + }, + + // ====== TIMER SYSTEM ====== + Timer: { + // Timer state management - Quản lý trạng thái timer + getStartTime: () => { + const time = sessionStorage.getItem(SESSION_STORAGE_KEYS.TIMER_START_TIME); + return time ? parseInt(time) : null; + }, + setStartTime: time => { + if (time === null || time === undefined) { + sessionStorage.removeItem(SESSION_STORAGE_KEYS.TIMER_START_TIME); + } else { + sessionStorage.setItem(SESSION_STORAGE_KEYS.TIMER_START_TIME, time.toString()); + } + }, + + isRunning: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.TIMER_IS_RUNNING) === 'true', + setRunning: running => sessionStorage.setItem(SESSION_STORAGE_KEYS.TIMER_IS_RUNNING, running ? 'true' : 'false'), + + getAccumulated: () => { + const time = sessionStorage.getItem(SESSION_STORAGE_KEYS.TIMER_ACCUMULATED); + return time ? parseInt(time) : 0; + }, + setAccumulated: time => sessionStorage.setItem(SESSION_STORAGE_KEYS.TIMER_ACCUMULATED, time.toString()), + + // Timer control methods + start: () => { + if (!AppServices.Timer.isRunning()) { + AppServices.Timer.setStartTime(Date.now()); + AppServices.Timer.setRunning(true); + TL.debug('TIMER', 'Timer started'); + } + }, + + pause: () => { + if (AppServices.Timer.isRunning()) { + const startTime = AppServices.Timer.getStartTime(); + const currentTime = Date.now(); + const elapsed = currentTime - startTime; + const accumulated = AppServices.Timer.getAccumulated(); + AppServices.Timer.setAccumulated(accumulated + elapsed); + AppServices.Timer.setRunning(false); + AppServices.Timer.setStartTime(null); + } + }, + + stop: () => { + AppServices.Timer.pause(); + AppServices.Timer.setAccumulated(0); + }, + + getDisplay: () => { + let totalTime = AppServices.Timer.getAccumulated(); + + if (AppServices.Timer.isRunning()) { + const startTime = AppServices.Timer.getStartTime(); + if (startTime) { + const currentTime = Date.now(); + totalTime += (currentTime - startTime); + } + } + + const hours = Math.floor(totalTime / 3600000); + const minutes = Math.floor((totalTime % 3600000) / 60000); + const seconds = Math.floor((totalTime % 60000) / 1000); + + const display = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; + TL.debug('TIMER', `Display: ${display}, Running: ${AppServices.Timer.isRunning()}, Accumulated: ${totalTime}`); + return display; + }, + + initialize: () => { + AppServices.Timer.setAccumulated(0); + AppServices.Timer.setRunning(false); + AppServices.Timer.setStartTime(null); + TL.debug('TIMER', 'Timer initialized'); + } }, // ====== HEARTBEAT SYSTEM ====== @@ -1066,7 +1284,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); } }, - getTask: async () => { + handleNewTask: async () => { const data = { logged_in: AppState.getIsLoggedIn(), current_page: AppState.getCurrentPage(), @@ -1075,38 +1293,89 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); current_task_data: AppSession.getCurrentTaskData(), current_step: AppSession.getCurrentStep(), }; - const task = await BAF.getTask(data); - return task; + + const taskResponse = await BAF.getTask(data); + TL.debug('APP-SERVICES', `Task: ${JSON.stringify(taskResponse, null, 2)}`); + + if (taskResponse.ok) { + const task = taskResponse.data; + AppSession.setCurrentTask(task.type); + AppSession.setCurrentTaskData(task.data || null); + + switch (task.type) { + case BAF_TASKS.NO_TASK: + TL.debug('APP-TASK', "No task. Sleep now"); + break; + case BAF_TASKS.LOGIN: + AppTasks.login("start", task.data); + break; + default: + TL.debug('APP-TASK', `Unknown task 🛑`); + AppSession.setSessionStatus(AppEnums.BOT_STATUS.ERROR); + break; + } + } }, - handleTask: (task) => { - TL.debug('APP-SERVICES', `Task: ${JSON.stringify(task, null, 2)}`); + resumeTask: async () => { + TL.debug('APP-SERVICES', 'Resume task'); - AppSession.setCurrentTask(task.task); - AppSession.setCurrentTaskData(task.data || null); - AppSession.setCurrentStep(task.step || null); + const task = AppSession.getCurrentTask(); + const data = AppSession.getCurrentTaskData(); + const step = AppSession.getCurrentStep(); - switch (task.task) { - case BAF_TASKS.NO_TASK: - TL.debug('APP-TASK', "No task. Sleep now"); - break; - default: - TL.debug('APP-TASK', `Unknown task 🛑`); - AppSession.setSessionStatus(AppEnums.BOT_STATUS.ERROR); + switch (task) { + case BAF_TASKS.LOGIN: + AppTasks.login(step, data); break; + }; + }, + + // ====== BOT STATUS CONTROL ====== + Status: { + play: () => { + AppServices.Timer.start(); + AppSession.setSessionStatus(AppEnums.BOT_STATUS.WAITING_FOR_TASK); + }, + + pause: () => { + AppServices.Timer.pause(); + AppSession.setSessionStatus(AppEnums.BOT_STATUS.PAUSE); + }, + + stop: () => { + AppServices.Timer.stop(); + AppSession.setCurrentTask(BAF_TASKS.NO_TASK); + AppSession.setCurrentTaskData(null); + AppSession.setCurrentStep(BAF_TASKS.NO_STEP); + AppSession.setSessionStatus(AppEnums.BOT_STATUS.STOP); } }, start: async () => { while (true) { - //checking bot status: running? - if (AppSession.getSessionStatus() === AppEnums.BOT_STATUS.RUNNING) { - const task = await AppServices.getTask(); - if (task.ok) { - AppServices.handleTask(task.data); - } - } else { - TL.debug('APP-SERVICES', 'Bot is stopped, skipping task check'); + switch (AppSession.getSessionStatus()) { + case AppEnums.BOT_STATUS.INITIALIZING: + TL.debug('APP-SERVICES', 'Bot is initializing, waiting...'); + break; + case AppEnums.BOT_STATUS.STOP: + TL.debug('APP-SERVICES', 'Bot is stopped, skipping task check'); + break; + case AppEnums.BOT_STATUS.PAUSE: + TL.debug('APP-SERVICES', 'Bot is paused, skipping task check'); + break; + case AppEnums.BOT_STATUS.WAITING_FOR_TASK: + await AppServices.handleNewTask(); + break; + case AppEnums.BOT_STATUS.PERFORMING_TASK: + await AppServices.resumeTask(); + break; + case AppEnums.BOT_STATUS.ERROR: + TL.debug('APP-SERVICES', 'Bot is in error state, skipping task check'); + break; + default: + TL.debug('APP-SERVICES', 'Bot is in unknown state, skipping task check'); + break; } await TL.delay(CONFIG.TASK_INTERVAL); @@ -1116,9 +1385,12 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.'); // Start the application try { + await AppServices.initialize(); + } catch (error) { TL.error('MAIN', 'Failed to initialize app:', error); + TL.error('MAIN', 'Error stack:', error.stack); } TL.log('MAIN', 'App started');