├── image-1.png ├── image.png ├── .gitignore ├── utils ├── banner.js ├── logger.js ├── file.js ├── login.js ├── system.js ├── providers.js └── websocket.js ├── main.js ├── package.json ├── LICENSE ├── README.md ├── setup.js └── autoreff.js /image-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GzGod/oasis-bot/HEAD/image-1.png -------------------------------------------------------------------------------- /image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GzGod/oasis-bot/HEAD/image.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | accounts.txt 2 | node_modules 3 | providers.txt 4 | tokens.txt 5 | proxy.txt 6 | package-lock.json 7 | register.js 8 | emails.txt 9 | accountsReff.txt 10 | -------------------------------------------------------------------------------- /utils/banner.js: -------------------------------------------------------------------------------- 1 | const banner = ` 2 | ╔═╗╔═╦╗─╔╦═══╦═══╦═══╦═══╗ 3 | ╚╗╚╝╔╣║─║║╔══╣╔═╗║╔═╗║╔═╗║ 4 | ─╚╗╔╝║║─║║╚══╣║─╚╣║─║║║─║║ 5 | ─╔╝╚╗║║─║║╔══╣║╔═╣╚═╝║║─║║ 6 | ╔╝╔╗╚╣╚═╝║╚══╣╚╩═║╔═╗║╚═╝║ 7 | ╚═╝╚═╩═══╩═══╩═══╩╝─╚╩═══╝ 8 | 原作者github:github.com/zlkcyber 9 | 我的gihub:github.com/Gzgod 本人仅做了汉化处理 10 | 我的推特:推特雪糕战神@Hy78516012 11 | 12 | ` 13 | export default banner; 14 | -------------------------------------------------------------------------------- /utils/logger.js: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | 3 | export function logger(message, value = '', level = 'info') { 4 | const now = new Date().toISOString(); 5 | const levels = { 6 | info: chalk.greenBright, 7 | warn: chalk.yellowBright, 8 | error: chalk.redBright, 9 | success: chalk.blueBright, 10 | debug: chalk.magentaBright, 11 | }; 12 | 13 | const log = levels[level] || chalk.whiteBright; 14 | console.log(log(`[${now}] [${level.toUpperCase()}]: ${message}`, chalk.yellowBright(value))); 15 | } 16 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | import { readToken, delay } from "./utils/file.js"; 2 | import { createConnection } from "./utils/websocket.js"; 3 | import beddu from "./utils/banner.js"; 4 | import { logger } from "./utils/logger.js"; 5 | 6 | async function start() { 7 | console.log(beddu); 8 | const tokens = await readToken("providers.txt"); 9 | const proxies = await readToken("proxy.txt"); 10 | 11 | if (proxies.length === 0) { 12 | logger("未找到代理 - 无代理运行中...", "", "warn"); 13 | } 14 | 15 | // 使用每个token一个代理创建连接 16 | for (let i = 0; i < tokens.length; i++) { 17 | const token = tokens[i]; 18 | const proxy = proxies[i % proxies.length] || null; 19 | 20 | await createConnection(token, proxy); 21 | await delay(1000); 22 | } 23 | } 24 | 25 | start(); 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "oasisai-bot", 3 | "type": "module", 4 | "version": "1.0.1", 5 | "main": "main.js", 6 | "scripts": { 7 | "start": "node main.js", 8 | "setup": "node setup.js", 9 | "autoreff": "node autoreff.js" 10 | }, 11 | "author": "@zlkcyber", 12 | "license": "MIT", 13 | "description": "oasis ai bot auto create multiple providers", 14 | "dependencies": { 15 | "@cemalgnlts/mailjs": "^3.0.1", 16 | "axios": "^1.7.8", 17 | "chalk": "^5.3.0", 18 | "cheerio": "^1.0.0", 19 | "https-proxy-agent": "^7.0.5", 20 | "ws": "^8.18.0" 21 | }, 22 | "devDependencies": {}, 23 | "repository": { 24 | "type": "git", 25 | "url": "git+https://github.com/Zlkcyber/oasis-bot.git" 26 | }, 27 | "keywords": [ 28 | "oasis-bot", 29 | "oasisbot", 30 | "oasisaibot", 31 | "oasisai-bot", 32 | "https://oasis.ai" 33 | ], 34 | "bugs": { 35 | "url": "https://github.com/Zlkcyber/oasis-bot/issues" 36 | }, 37 | "homepage": "https://github.com/Zlkcyber/oasis-bot#readme" 38 | } 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2024] [zlkcyber] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OASIS AI BETA CLI 版本 2 | **不介意的话走我的链接注册吧~https://r.oasis.ai/xuegaozhanshen** 3 | 4 | ![banner](image-1.png) 5 | 由分布式计算提供支持的AI推理 6 | 7 | # 特性 8 | 9 | ![Banner](image.png) 10 | 11 | - **注册/登录账户** 12 | 13 | - **自动创建提供者** 14 | 15 | - **自动发送心跳** 16 | 17 | - **支持多个账户** 18 | 19 | - **支持代理** 20 | 21 | ## 要求 22 | 23 | - **Node.js**: 请确保已安装 Node.js。 24 | 25 | - **NPM**: 请确保已安装 npm。 26 | 27 | 将你的代理放在文件 `proxy.txt` 中,格式为 `http://username:pass@ip:port`,每个提供者一个代理。 28 | 29 | 所以如果你想创建多个提供者,你需要在文件中放置多个代理。 30 | 31 | ## 设置 32 | 33 | 1. 克隆此仓库: 34 | 35 | ```bash 36 | git clone https://github.com/Gzgod/oasis-bot.git 37 | cd oasis-bot 38 | ``` 39 | 40 | 2. 安装依赖: 41 | 42 | ```bash 43 | npm install 44 | ``` 45 | 46 | 3. 将你的邮箱和密码放入 `accounts.txt` 文件中,格式为 `email|password`,每行一个账户 47 | 48 | ```bash 49 | nano accounts.txt 50 | ``` 51 | 52 | 4. 将你的代理放入 `proxy.txt` 文件中 53 | 54 | ```bash 55 | nano proxy.txt 56 | ``` 57 | 58 | 5. 设置以创建账户/登录并获取令牌: 59 | 60 | ```bash 61 | npm run setup 62 | ``` 63 | 64 | 6. 运行脚本: 65 | 66 | ```bash 67 | npm run start 68 | ``` 69 | 70 | 7. 额外功能:自动推荐 71 | ```bash 72 | npm run autoreff 73 | ``` 74 | 75 | ## ![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg) 76 | 77 | 此项目采用 [MIT License](LICENSE) 许可。 78 | -------------------------------------------------------------------------------- /setup.js: -------------------------------------------------------------------------------- 1 | import { readToken, delay } from "./utils/file.js"; 2 | import beddu from "./utils/banner.js"; 3 | import { loginFromFile } from "./utils/login.js"; 4 | import { createProviders } from "./utils/providers.js"; 5 | import { logger } from "./utils/logger.js"; 6 | import { createInterface } from 'readline'; 7 | import fs from 'fs'; 8 | 9 | const rl = createInterface({ 10 | input: process.stdin, 11 | output: process.stdout 12 | }); 13 | 14 | function askQuestion(query) { 15 | return new Promise(resolve => rl.question(query, resolve)); 16 | } 17 | 18 | async function setup() { 19 | console.log(beddu); 20 | // 询问要创建的提供者数量 21 | const input = await askQuestion('输入您想为每个账户创建的提供者数量 [1-100]: '); 22 | const numProv = parseInt(input, 10); 23 | 24 | if (isNaN(numProv) || numProv < 1 || numProv > 100) { 25 | logger("无效输入。请输入1到100之间的数字。", "", "error"); 26 | rl.close(); 27 | return; 28 | }; 29 | 30 | const accounts = await readToken("accounts.txt"); 31 | if (fs.existsSync('tokens.txt')) { 32 | const tokens = await readToken("tokens.txt"); 33 | 34 | if (accounts.length !== tokens.length) { 35 | fs.unlinkSync('tokens.txt'); 36 | const isLogin = await loginFromFile('accounts.txt'); 37 | if (!isLogin) { 38 | logger("没有账户成功登录。退出...", "", "error"); 39 | rl.close(); 40 | return; 41 | } 42 | } 43 | } 44 | 45 | const isLogin = await loginFromFile('accounts.txt'); 46 | if (!isLogin) { 47 | logger("没有账户成功登录。退出...", "", "error"); 48 | rl.close(); 49 | return; 50 | } 51 | 52 | logger(`创建 ${numProv} 个提供者...`); 53 | await createProviders(numProv); 54 | 55 | rl.close(); 56 | } 57 | 58 | setup(); 59 | -------------------------------------------------------------------------------- /utils/file.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import { logger } from './logger.js'; 3 | 4 | export function readToken(filePath) { 5 | return new Promise((resolve, reject) => { 6 | fs.readFile(filePath, 'utf8', (err, data) => { 7 | if (err) return reject(err); 8 | 9 | const tokens = data.split('\n').map(token => token.trim()).filter(token => token); 10 | resolve(tokens); 11 | }); 12 | }); 13 | } 14 | 15 | export function readAccounts(filePath) { 16 | return new Promise((resolve, reject) => { 17 | fs.readFile(filePath, 'utf8', (err, data) => { 18 | if (err) return reject(err); 19 | 20 | const accounts = data 21 | .split('\n') 22 | .map((line, index) => { 23 | if (!line.includes('|')) { 24 | return null; 25 | } 26 | 27 | const [email, password] = line.split('|').map(part => part?.trim()); 28 | if (!email || !password) { 29 | return null; 30 | } 31 | 32 | return { email, password }; 33 | }) 34 | .filter(account => account !== null); 35 | 36 | if (accounts.length === 0) { 37 | console.warn("在文件中未找到有效的账户。"); 38 | } 39 | 40 | resolve(accounts); 41 | }); 42 | }); 43 | } 44 | 45 | export function saveToken(filePath, token) { 46 | fs.appendFile(filePath, `${token}\n`, (err) => { 47 | if (err) { 48 | logger('保存令牌时出错:', err); 49 | } else { 50 | logger('令牌保存成功。'); 51 | } 52 | }); 53 | } 54 | 55 | export function delay(ms) { 56 | return new Promise(resolve => setTimeout(resolve, ms)); 57 | } 58 | -------------------------------------------------------------------------------- /utils/login.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { readAccounts, saveToken } from './file.js'; 3 | import { logger } from './logger.js'; 4 | 5 | // 用户注册函数 6 | async function registerUser(email, password) { 7 | const url = 'https://api.oasis.ai/internal/auth/signup'; 8 | const payload = { 9 | email: email, 10 | password: password, 11 | referralCode: "xgzs" 12 | } 13 | const headers = { 14 | 'Content-Type': 'application/json', 15 | }; 16 | 17 | try { 18 | const response = await axios.post(url, payload, { headers }); 19 | if (response.data) { 20 | logger('注册成功:', email); 21 | logger('请检查您的邮箱以获取验证邮件'); 22 | return true; 23 | } 24 | } catch (error) { 25 | logger(`注册错误 ${email}:`, error.response ? error.response.data[0] : error.response.statusText, 'error'); 26 | return null; 27 | } 28 | } 29 | 30 | // 用户登录函数 31 | async function loginUser(email, password) { 32 | const url = 'https://api.oasis.ai/internal/auth/login'; 33 | const payload = { 34 | email, 35 | password, 36 | rememberSession: true 37 | } 38 | 39 | const headers = { 40 | 'Content-Type': 'application/json', 41 | }; 42 | 43 | try { 44 | const response = await axios.post(url, payload, { headers }); 45 | logger('登录成功:', email); 46 | return response.data.token; 47 | } catch (error) { 48 | logger(`登录错误 ${email}:`, error.response ? error.response.data[0] : error.response.statusText, 'error'); 49 | logger('请检查您的邮箱以验证您的邮箱', email, 'error'); 50 | return null; 51 | } 52 | } 53 | 54 | // 主函数 55 | export async function loginFromFile(filePath) { 56 | try { 57 | const accounts = await readAccounts(filePath); 58 | let successCount = 0; 59 | 60 | logger(`尝试登录并获取所有账户的令牌...`) 61 | for (const account of accounts) { 62 | logger(`尝试登录 ${account.email}`); 63 | const token = await loginUser(account.email, account.password); 64 | if (token) { 65 | saveToken('tokens.txt', token); 66 | successCount++; 67 | } else { 68 | logger(`尝试注册 ${account.email}`); 69 | await registerUser(account.email, account.password); 70 | } 71 | } 72 | 73 | if (successCount > 0) { 74 | logger(`${successCount}/${accounts.length} 个账户登录成功。`); 75 | return true; 76 | } else { 77 | logger("所有账户登录失败。", "", "error"); 78 | return false; 79 | } 80 | } catch (error) { 81 | logger("读取账户或处理登录时出错:", error, "error"); 82 | return false; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /utils/system.js: -------------------------------------------------------------------------------- 1 | export function generateRandomId(length = 26) { 2 | const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; 3 | let id = ''; 4 | for (let i = 0; i < length; i++) { 5 | id += characters.charAt(Math.floor(Math.random() * characters.length)); 6 | } 7 | return id; 8 | } 9 | 10 | function generateRandomCpuInfo() { 11 | const cpuModels = [ 12 | "AMD Ryzen 5 5600G with Radeon Graphics", 13 | "Intel Core i7-9700K", 14 | "AMD Ryzen 7 5800X", 15 | "Intel Core i9-10900K", 16 | "Intel Core i5-11600K", 17 | "AMD Ryzen 9 5900X", 18 | "Intel Core i7-12700K", 19 | "AMD Ryzen 5 3600X", 20 | "Intel Core i9-11900K", 21 | "AMD Ryzen 3 3200G" 22 | ]; 23 | 24 | const features = ["mmx", "sse", "sse2", "sse3", "ssse3", "sse4_1", "sse4_2", "avx"]; 25 | const numOfProcessors = [4, 8, 16, 32][Math.floor(Math.random() * 4)]; 26 | 27 | let processors = []; 28 | for (let i = 0; i < numOfProcessors; i++) { 29 | processors.push({ 30 | usage: { 31 | idle: Math.floor(Math.random() * 2000000000000), 32 | kernel: Math.floor(Math.random() * 10000000000), 33 | total: Math.floor(Math.random() * 2000000000000), 34 | user: Math.floor(Math.random() * 50000000000) 35 | } 36 | }); 37 | } 38 | 39 | return { 40 | archName: "x86_64", 41 | features: features, 42 | modelName: cpuModels[Math.floor(Math.random() * cpuModels.length)], 43 | numOfProcessors: numOfProcessors, 44 | processors: processors, 45 | temperatures: [] 46 | }; 47 | } 48 | 49 | function generateRandomGpuInfo() { 50 | const renderers = [ 51 | "ANGLE (AMD, AMD Radeon(TM) Graphics (0x00001638) Direct3D11 vs_5_0 ps_5_0, D3D11)", 52 | "ANGLE (NVIDIA, GeForce GTX 1080 Ti Direct3D11 vs_5_0 ps_5_0, D3D11)", 53 | "ANGLE (Intel, Iris Xe Graphics (0x00008086) Direct3D11 vs_5_0 ps_5_0, D3D11)" 54 | ]; 55 | const vendors = ["Google Inc. (AMD)", "NVIDIA", "Intel"]; 56 | return { 57 | renderer: renderers[Math.floor(Math.random() * renderers.length)], 58 | vendor: vendors[Math.floor(Math.random() * vendors.length)] 59 | }; 60 | } 61 | 62 | function generateRandomOperatingSystem() { 63 | const osList = ["windows", "linux", "macOS"]; 64 | return osList[Math.floor(Math.random() * osList.length)]; 65 | } 66 | 67 | export function generateRandomSystemData() { 68 | return { 69 | id: generateRandomId(26), 70 | type: "system", 71 | data: { 72 | gpuInfo: generateRandomGpuInfo(), 73 | memoryInfo: { 74 | availableCapacity: Math.floor(Math.random() * 1000000000) + 1000000000, 75 | capacity: Math.floor(Math.random() * 1000000000) + 2000000000 76 | }, 77 | operatingSystem: generateRandomOperatingSystem(), 78 | machineId: generateRandomId(32).toLowerCase(), 79 | cpuInfo: generateRandomCpuInfo() 80 | } 81 | }; 82 | } 83 | -------------------------------------------------------------------------------- /utils/providers.js: -------------------------------------------------------------------------------- 1 | import { generateRandomId } from "./system.js"; 2 | import { readToken, saveToken } from "./file.js"; 3 | import { logger } from "./logger.js"; 4 | import axios from 'axios'; 5 | import fs from 'fs'; 6 | 7 | async function connectWithToken(token) { 8 | const url = 'https://api.oasis.ai/internal/auth/connect'; 9 | const randomId = generateRandomId(); 10 | const payload = { 11 | "name": randomId, 12 | "platform": "browser" 13 | } 14 | 15 | const headers = { 16 | 'Content-Type': 'application/json', 17 | 'Authorization': token, 18 | }; 19 | 20 | try { 21 | const response = await axios.post(url, payload, { headers }); 22 | const logToken = response.data.token; 23 | logger('创建提供者成功:', logToken); 24 | return logToken; 25 | } catch (error) { 26 | logger('创建提供者错误:', error.response ? error.response.status : error.response.statusText, 'error'); 27 | return null; 28 | } 29 | } 30 | 31 | async function getAllProviders(token) { 32 | const url = 'https://api.oasis.ai/internal/provider/providers?limit=100'; 33 | 34 | const headers = { 35 | 'Authorization': token, 36 | }; 37 | 38 | try { 39 | const response = await axios.get(url, { headers }); 40 | const data = response.data; 41 | logger('获取所有现有提供者成功'); 42 | return data; 43 | } catch (error) { 44 | logger('获取所有现有提供者错误:', error.response ? error.response.status : error.response.statusText, 'error'); 45 | return null; 46 | } 47 | } 48 | 49 | async function deleteProviders(token, nodeId) { 50 | const url = `https://api.oasis.ai/internal/provider/?id=${nodeId}`; 51 | const headers = { 52 | 'Authorization': token, 53 | }; 54 | 55 | try { 56 | const response = await axios.delete(url, { headers }); 57 | const data = response.data; 58 | logger('删除提供者成功'); 59 | return data; 60 | } catch (error) { 61 | logger('删除提供者错误:', error.response ? error.response.status : error.response.statusText, 'error'); 62 | return null; 63 | } 64 | } 65 | 66 | export async function createProviders(numID) { 67 | try { 68 | const tokens = await readToken('tokens.txt'); 69 | const filePath = 'providers.txt'; 70 | 71 | if (fs.existsSync(filePath)) { 72 | try { 73 | fs.unlinkSync(filePath); 74 | logger(`${filePath} 已删除。`); 75 | } catch (err) { 76 | logger(`删除 ${filePath} 时出错:`, 'error'); 77 | } 78 | } 79 | 80 | for (const token of tokens) { 81 | logger(`使用令牌检查所有提供者: ${token}`); 82 | const response = await getAllProviders(token) 83 | const nodeIds = response.results.map(item => item.id); 84 | logger(`找到 ${nodeIds.length} 个现有提供者 - 尝试删除旧提供者...`); 85 | for (const nodeId of nodeIds) { 86 | await deleteProviders(token, nodeId) 87 | } 88 | 89 | logger(`使用令牌创建提供者: ${token}`); 90 | for (let i = 0; i < numID; i++) { 91 | logger(`创建提供者 #${i + 1}....`); 92 | const logToken = await connectWithToken(token); 93 | if (logToken) { 94 | saveToken("providers.txt", logToken) 95 | } else { 96 | logger('创建提供者失败', 'error', 'error'); 97 | continue; 98 | } 99 | }; 100 | 101 | }; 102 | return true; 103 | } catch (error) { 104 | logger("读取令牌或连接时出错:", error, 'error'); 105 | }; 106 | }; 107 | -------------------------------------------------------------------------------- /utils/websocket.js: -------------------------------------------------------------------------------- 1 | import WebSocket from "ws"; 2 | import { HttpsProxyAgent } from "https-proxy-agent"; 3 | import { generateRandomId, generateRandomSystemData } from "./system.js"; 4 | import { delay } from "./file.js"; 5 | import { logger } from "./logger.js"; 6 | 7 | export async function createConnection(token, proxy = null) { 8 | const wsOptions = { 9 | headers: { 10 | 'accept-encoding': 'gzip, deflate, br, zstd', 11 | 'accept-language': 'en-US,en;q=0.9', 12 | 'cache-control': 'no-cache', 13 | connection: 'Upgrade', 14 | host: 'ws.oasis.ai', 15 | origin: 'chrome-extension://knhbjeinoabfecakfppapfgdhcpnekmm', 16 | pragma: 'no-cache', 17 | 'sec-websocket-extensions': 'permessage-deflate; client_max_window_bits', 18 | 'sec-websocket-version': '13', 19 | upgrade: 'websocket', 20 | 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' 21 | } 22 | }; 23 | 24 | if (proxy) { 25 | logger(`使用代理连接: ${proxy}`); 26 | wsOptions.agent = new HttpsProxyAgent(proxy); 27 | } 28 | 29 | const socket = new WebSocket(`wss://ws.oasis.ai/?token=${token}&version=0.1.20&platform=extension`, wsOptions); 30 | 31 | socket.on("open", async () => { 32 | logger(`WebSocket 连接已建立,提供者: ${token}`, "", "success"); 33 | const randomId = generateRandomId(); 34 | const systemData = generateRandomSystemData(); 35 | 36 | socket.send(JSON.stringify(systemData)); 37 | //await delay(1000); 38 | 39 | socket.send( 40 | JSON.stringify({ 41 | id: randomId, 42 | type: "heartbeat", 43 | data: { 44 | inferenceState: true, 45 | version: "0.1.20", 46 | mostRecentModel: "unknown", 47 | status: "active", 48 | }, 49 | }) 50 | ); 51 | 52 | setInterval(() => { 53 | const randomId = generateRandomId(); 54 | socket.send( 55 | JSON.stringify({ 56 | id: randomId, 57 | type: "heartbeat", 58 | data: { 59 | inferenceState: true, 60 | version: "0.1.20", 61 | mostRecentModel: "unknown", 62 | status: "active", 63 | }, 64 | }) 65 | ); 66 | }, 60000); 67 | }); 68 | 69 | socket.on("message", (data) => { 70 | const message = data.toString(); 71 | try { 72 | const parsedMessage = JSON.parse(message); 73 | if (parsedMessage.type === "serverMetrics") { 74 | const { totalEarnings, totalUptime, creditsEarned } = parsedMessage.data; 75 | logger(`发送心跳给提供者: ${token}`); 76 | logger(`总运行时间: ${totalUptime} 秒 | 获得的积分:`, creditsEarned); 77 | } else if (parsedMessage.type === "acknowledged") { 78 | logger("系统已更新:", message, "info"); 79 | } else if (parsedMessage.type === "error" && parsedMessage.data.code === "Invalid body") { 80 | const systemData = generateRandomSystemData(); 81 | socket.send(JSON.stringify(systemData)); 82 | } 83 | } catch (error) { 84 | logger("解析消息时出错:", "error"); 85 | } 86 | }); 87 | 88 | socket.on("close", () => { 89 | logger("WebSocket 连接关闭,token:", token, "warn"); 90 | setTimeout(() => { 91 | logger("尝试重新连接,token:", token, "warn"); 92 | createConnection(token, proxy); 93 | }, 5000); 94 | }); 95 | 96 | socket.on("error", (error) => { 97 | logger("WebSocket 错误,token:", token, "error"); 98 | }); 99 | } 100 | -------------------------------------------------------------------------------- /autoreff.js: -------------------------------------------------------------------------------- 1 | import Mailjs from "@cemalgnlts/mailjs"; 2 | import axios from "axios"; 3 | import fs from 'fs'; 4 | import { HttpsProxyAgent } from 'https-proxy-agent'; 5 | import readline from "readline/promises"; 6 | import { delay } from "./utils/file.js"; 7 | import { logger } from "./utils/logger.js"; 8 | import { showBanner } from "./utils/banner.js"; 9 | 10 | const mailjs = new Mailjs(); 11 | 12 | const rl = readline.createInterface({ 13 | input: process.stdin, 14 | output: process.stdout, 15 | }); 16 | 17 | function extractCodeFromEmail(text) { 18 | const regex = /code=([A-Za-z0-9]+)/; 19 | const match = text.match(regex); 20 | return match ? match[1] : null; 21 | } 22 | 23 | function readProxies(filePath) { 24 | return new Promise((resolve, reject) => { 25 | fs.readFile(filePath, 'utf8', (err, data) => { 26 | if (err) return reject(err); 27 | const proxies = data.split('\n').map(proxy => proxy.trim()).filter(proxy => proxy); 28 | resolve(proxies); 29 | }); 30 | }); 31 | } 32 | 33 | async function verifyEmail(code, proxy) { 34 | const proxyAgent = new HttpsProxyAgent(proxy); 35 | const url = "https://api.oasis.ai/internal/authVerifyEmail?batch=1"; 36 | const payload = { 37 | "0": { 38 | json: { 39 | token: code, 40 | }, 41 | }, 42 | }; 43 | 44 | try { 45 | const response = await axios.post(url, payload, { 46 | headers: { "Content-Type": "application/json" }, 47 | httpsAgent: proxyAgent, 48 | }); 49 | return response.data[0].result.data; 50 | } catch (error) { 51 | logger( 52 | "验证邮箱时出错:", 53 | error.response ? error.response.data : error.message, 54 | 'error' 55 | ); 56 | return null; 57 | } 58 | } 59 | 60 | // 检查新邮件 61 | async function checkForNewEmails(proxy) { 62 | try { 63 | const emailData = await mailjs.getMessages(); 64 | const latestEmail = emailData.data[0]; 65 | 66 | if (latestEmail) { 67 | logger("收到新邮件:", latestEmail.subject); 68 | const msgId = latestEmail.id; 69 | 70 | const emailMessage = await mailjs.getMessage(msgId); 71 | const textContent = emailMessage.data.text; 72 | 73 | if (textContent) { 74 | const verificationCode = extractCodeFromEmail(textContent); 75 | if (verificationCode) { 76 | const verifyResult = await verifyEmail(verificationCode, proxy); 77 | if (verifyResult) { 78 | logger("邮箱验证成功:", verifyResult.json.message, 'success'); 79 | return true; 80 | } else { 81 | await verifyEmail(verificationCode, proxy); 82 | } 83 | } 84 | } else { 85 | logger("邮件中没有文本内容。", '', 'error'); 86 | } 87 | 88 | await mailjs.deleteMessage(msgId); 89 | } 90 | return false; 91 | } catch (error) { 92 | logger("检查新邮件时出错:", error, 'error'); 93 | return false; 94 | } 95 | } 96 | 97 | // 发送注册请求 98 | async function sendSignupRequest(email, password, proxy, referralCode) { 99 | const proxyAgent = new HttpsProxyAgent(proxy); 100 | const url = "https://api.oasis.ai/internal/authSignup?batch=1"; 101 | const payload = { 102 | "0": { 103 | json: { 104 | email, 105 | password, 106 | referralCode, 107 | }, 108 | }, 109 | }; 110 | 111 | try { 112 | const response = await axios.post(url, payload, { 113 | headers: { "Content-Type": "application/json" }, 114 | httpsAgent: proxyAgent, 115 | }); 116 | logger(`注册成功`, email, 'success'); 117 | return { email, status: "success", data: response.data }; 118 | } catch (error) { 119 | const errorMessage = error.response 120 | ? error.response.statusText 121 | : error.message; 122 | logger(`注册时出错 ${email}:`, errorMessage, 'error'); 123 | return null; 124 | } 125 | } 126 | 127 | async function saveAccountToFile(email, password) { 128 | const account = `${email}|${password}\n`; 129 | fs.appendFileSync("accountsReff.txt", account, (err) => { 130 | if (err) { 131 | logger("保存账户时出错:", err, 'error'); 132 | } else { 133 | logger("账户成功保存到 accounts.txt。"); 134 | } 135 | }); 136 | } 137 | 138 | // 主进程 139 | async function main() { 140 | try { 141 | showBanner() 142 | const proxies = await readProxies('proxy.txt'); 143 | if (proxies.length === 0) { 144 | throw new Error('proxy.txt 中没有可用的代理'); 145 | } 146 | const referralCode = await rl.question("输入您的推荐代码: "); 147 | const numAccounts = await rl.question("您想创建多少个账户: "); 148 | const totalAccounts = parseInt(numAccounts); 149 | if (isNaN(totalAccounts) || totalAccounts <= 0) { 150 | logger("请输入有效的账户数量。", '', 'warn'); 151 | return; 152 | } 153 | 154 | for (let i = 1; i <= totalAccounts; i++) { 155 | const proxy = proxies[i % proxies.length]; 156 | logger(`正在创建第 ${i} 个账户,总共 ${totalAccounts} 个...`); 157 | 158 | try { 159 | const account = await mailjs.createOneAccount(); 160 | 161 | if (!account.status || !account.data) { 162 | logger(`创建第 ${i} 个账户时出错:`, account.error || "限速,5秒后重试...", 'error'); 163 | i--; 164 | await delay(5000); 165 | continue; 166 | } 167 | 168 | const username = account.data.username; 169 | const password = account.data.password; 170 | logger(`账户 ${i} 已创建:`, username); 171 | 172 | mailjs.on("open", () => logger(`等待账户 ${i} 的验证邮件...`)); 173 | 174 | let isSignup = await sendSignupRequest(username, password, proxy, referralCode); 175 | while (!isSignup) { 176 | isSignup = await sendSignupRequest(username, password, proxy, referralCode); 177 | await delay(5000); 178 | } 179 | 180 | let isEmailVerified = false; 181 | while (!isEmailVerified) { 182 | isEmailVerified = await checkForNewEmails(proxy); 183 | if (!isEmailVerified) { 184 | await delay(5000); 185 | } 186 | } 187 | 188 | mailjs.on("arrive", () => onNewMessageReceived(i, username, password, proxy)); 189 | await delay(10000); 190 | } catch (error) { 191 | logger(`创建账户 ${i} 时出错:`, error, 'error'); 192 | } 193 | } 194 | 195 | rl.close(); 196 | } catch (error) { 197 | logger("错误:", error.message || error, 'error'); 198 | rl.close(); 199 | } 200 | } 201 | 202 | async function onNewMessageReceived(i, username, password, proxy) { 203 | try { 204 | logger(`账户 ${i} 收到新消息。处理中...`); 205 | await checkForNewEmails(proxy); 206 | 207 | mailjs.off(); 208 | saveAccountToFile(username, password); 209 | } catch (error) { 210 | logger("处理新消息时出错:", error, 'error'); 211 | } 212 | } 213 | 214 | main(); 215 | --------------------------------------------------------------------------------