import asyncio
import os
import ctypes
import time
from playwright.async_api import async_playwright
# ================== ẨN CỬA SỔ CMD ==================
def hide_console():
try:
hwnd = ctypes.windll.kernel32.GetConsoleWindow()
if hwnd:
ctypes.windll.user32.ShowWindow(hwnd, 0) # 0 = SW_HIDE
except Exception:
pass
# Gọi hàm ẩn cửa sổ ngay lập tức khi khởi chạy
hide_console()
# ===================================================
# CẤU HÌNH
# -------------------------------------------------------------
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
ACCOUNTS_FILE = os.path.join(BASE_DIR, "accounts.txt")
INTERVAL_SECONDS = 1 * 60 * 60 # 1 giờ
HEADLESS = True
# -------------------------------------------------------------
def load_accounts(file_path):
accounts = []
if not os.path.exists(file_path):
print(f"[-] File {file_path} không tồn tại!")
return accounts
with open(file_path, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if not line or line.startswith("#"):
continue
if "|" in line:
user, pwd = line.split("|", 1)
elif ":" in line:
user, pwd = line.split(":", 1)
else:
continue
accounts.append((user.strip(), pwd.strip()))
return accounts
async def safe_goto(page, url, retries=3):
for attempt in range(1, retries + 1):
try:
await page.goto(url, wait_until="domcontentloaded", timeout=60000)
return True
except Exception as e:
print(f" [!] Lỗi tải trang ({attempt}/{retries}): {e}")
if attempt < retries:
await asyncio.sleep(2)
else:
raise e
async def get_csrf(page):
"""Lấy farm_csrf từ trang"""
token = await page.evaluate("""() => {
const input = document.querySelector('input[name="farm_csrf"]');
if (input && input.value) return input.value;
// Tìm trong onclick / href
const els = Array.from(document.querySelectorAll('[onclick*="farm_csrf"], a[href*="farm_csrf"]'));
for (const el of els) {
const text = el.getAttribute('onclick') || el.getAttribute('href') || '';
const match = text.match(/farm_csrf=([a-f0-9]+)/i);
if (match) return match[1];
}
return null;
}""")
return token
async def run_automation():
accounts = load_accounts(ACCOUNTS_FILE)
if not accounts:
print("[-] Danh sách tài khoản trống!")
return
async with async_playwright() as p:
browser = await p.chromium.launch(headless=HEADLESS)
for username, password in accounts:
print("\n==========================================")
print(f"[*] Đang xử lý tài khoản: {username}")
context = await browser.new_context()
page = await context.new_page()
page.set_default_timeout(60000)
page.set_default_navigation_timeout(60000)
try:
# ========== 1. ĐĂNG NHẬP ==========
print("[1] Đăng nhập...")
await safe_goto(page, "https://1900.fun/login.php")
await page.fill("input[name='username']", username)
await page.fill("input[name='password']", password)
async with page.expect_navigation(wait_until="domcontentloaded"):
await page.click("button[type='submit']")
await page.wait_for_timeout(1500)
# ========== 2. VƯỜN ==========
print("[2] Vào trang Vườn...")
await safe_goto(page, "https://1900.fun/nongtrai/index.php")
await page.wait_for_timeout(1500)
csrf = await get_csrf(page)
if csrf:
print(f" → CSRF: {csrf[:16]}...")
else:
print(" [!] Không lấy được CSRF")
# 2.1 Thu hoạch tất cả
print("[3] Thu hoạch nhanh tất cả...")
harvest_url = f"https://1900.fun/nongtrai/index.php?harvest_all=1&farm_csrf={csrf}" if csrf else \
"https://1900.fun/nongtrai/index.php?harvest_all=1"
await safe_goto(page, harvest_url)
await page.wait_for_timeout(2000)
# 2.2 Gieo hạt nhanh
print("[4] Gieo hạt nhanh...")
await safe_goto(page, "https://1900.fun/nongtrai/index.php")
await page.wait_for_timeout(1500)
best_crop = await page.evaluate("""() => {
if (typeof cropsData !== 'undefined' && typeof userLevel !== 'undefined') {
const available = cropsData.filter(c => c.level_required <= userLevel);
if (available.length > 0) {
available.sort((a, b) => b.level_required - a.level_required);
return available[0];
}
}
return null;
}""")
if best_crop and await page.locator("#quickPlantForm").count() > 0:
crop_id = str(best_crop['id'])
print(f" → Chọn cây: {best_crop['name']} (ID {crop_id})")
await page.evaluate(f"""() => {{
const el = document.getElementById('quickCropId');
if (el) el.value = '{crop_id}';
}}""")
try:
async with page.expect_navigation(wait_until="domcontentloaded", timeout=15000):
await page.eval_on_selector("#quickPlantForm", "form => form.submit()")
except:
pass
await page.wait_for_timeout(2000)
else:
print(" → Không có đất trống hoặc không tìm thấy form.")
# ========== 3. HỒ CÁ ==========
print("[5] Vào Hồ Cá...")
await safe_goto(page, "https://1900.fun/nongtrai/hoca.php")
await page.wait_for_timeout(1500)
csrf_fish = await get_csrf(page)
if csrf_fish:
print(f" → CSRF Hồ Cá: {csrf_fish[:16]}...")
# 3.1 Bán tất cả cá
print("[6] Bán tất cả cá...")
if csrf_fish:
sell_url = f"https://1900.fun/nongtrai/hoca.php?sell_all_fish=1&farm_csrf={csrf_fish}"
else:
sell_url = "https://1900.fun/nongtrai/hoca.php?sell_all_fish=1"
await safe_goto(page, sell_url)
await page.wait_for_timeout(2000)
# Thử thêm cách bán qua nút nếu có
try:
sell_btn = page.locator("button.sell-all, .action-btn.sell-all, a[onclick*='sell_all']")
if await sell_btn.count() > 0:
await sell_btn.first.click()
await page.wait_for_timeout(1500)
except:
pass
# 3.2 Mua cá (dùng form Mua nhanh nếu có)
print("[7] Mua cá cấp cao nhất...")
await safe_goto(page, "https://1900.fun/nongtrai/hoca.php")
await page.wait_for_timeout(1500)
fish_data = await page.evaluate("""() => {
const current = typeof currentFish !== 'undefined' ? currentFish : 0;
const max = typeof maxFish !== 'undefined' ? maxFish : 0;
let best = null;
if (typeof fishList !== 'undefined' && typeof userLevel !== 'undefined' && typeof userMoney !== 'undefined') {
const available = fishList.filter(f => f.level_required <= userLevel && f.price <= userMoney);
if (available.length > 0) {
available.sort((a, b) => b.level_required - a.level_required);
best = available[0];
}
}
return { current, max, best };
}""")
needed = fish_data['max'] - fish_data['current']
print(f" → Hồ hiện tại: {fish_data['current']}/{fish_data['max']} (cần mua: {needed})")
if needed > 0 and fish_data['best']:
best = fish_data['best']
fish_id = str(best['id'])
fish_name = best.get('name', 'Cá')
print(f" → Mua: {fish_name} (ID {fish_id}) × {needed}")
# Ưu tiên dùng form Mua nhanh (quickBuyForm)
has_quick = await page.locator("#quickBuyForm").count() > 0
if has_quick:
await page.evaluate(f"""() => {{
document.getElementById('quickBuyFishType').value = '{fish_id}';
document.getElementById('quickBuyQuantity').value = '{needed}';
}}""")
try:
async with page.expect_navigation(wait_until="domcontentloaded", timeout=15000):
await page.eval_on_selector("#quickBuyForm", "form => form.submit()")
print(" → Đã gửi form Mua nhanh")
except Exception as e:
print(f" [!] Lỗi submit quickBuy: {e}")
else:
# Fallback: mua từng con bằng buyForm
for i in range(needed):
await page.evaluate(f"""() => {{
const el = document.getElementById('buyFishType');
if (el) el.value = '{fish_id}';
}}""")
try:
async with page.expect_navigation(wait_until="domcontentloaded", timeout=12000):
await page.eval_on_selector("#buyForm", "form => form.submit()")
except:
pass
await page.wait_for_timeout(1000)
else:
if needed <= 0:
print(" → Hồ đã đầy.")
else:
print(" → Không tìm thấy cá phù hợp hoặc không đủ xu.")
# ========== 4. ĐĂNG XUẤT ==========
print("[8] Đăng xuất...")
await safe_goto(page, "https://1900.fun/logout.php")
await page.wait_for_timeout(1000)
print(f"[+] Hoàn tất: {username}")
except Exception as e:
print(f"[-] Lỗi với {username}: {e}")
finally:
await context.close()
await asyncio.sleep(2)
await browser.close()
if __name__ == "__main__":
while True:
try:
print(f"\n==================== [ BẮT ĐẦU VÒNG LẶP NÔNG TRẠI ] ====================")
asyncio.run(run_automation())
except Exception as err:
print(f"[!] Lỗi ngoài: {err}")
print(f"\n[⏳] Hoàn thành. Chờ {INTERVAL_SECONDS // 3600} giờ để chạy tiếp...")
time.sleep(INTERVAL_SECONDS)