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
hide_console()
# ===================================================
# ================== CẤU HÌNH ==================
USERNAME = "nhi1509"
PASSWORD = "abc13579"
INTERVAL_SECONDS = 6 * 60 * 60 # 6 giờ (phù hợp cho Vật nuôi, Điểm danh sẽ tự bỏ qua nếu đã điểm)
TOTAL_CAGES = 3 # Số chuồng hiện tại
HEADLESS = True
# ==============================================
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):
token = await page.evaluate("""() => {
const input = document.querySelector('input[name="farm_csrf"]');
if (input && input.value) return input.value;
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():
print("\n==========================================")
print(f"[*] Đang xử lý tài khoản: {USERNAME}")
async with async_playwright() as p:
browser = await p.chromium.launch(headless=HEADLESS)
context = await browser.new_context()
page = await context.new_page()
page.on("dialog", lambda dialog: dialog.accept()) # Tự bấm OK confirm
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. ĐIỂM DANH ==========
print("[2] Kiểm tra điểm danh hàng ngày...")
await safe_goto(page, "https://1900.fun/profile.php")
await page.wait_for_timeout(1200)
checkin_button = page.locator("button[name='checkin']")
if await checkin_button.count() > 0:
is_disabled = await checkin_button.is_disabled()
if not is_disabled:
print(" → Chưa điểm danh → Đang điểm danh...")
await checkin_button.click()
await page.wait_for_timeout(1800)
print(" → Điểm danh thành công!")
else:
print(" → Đã điểm danh rồi → Bỏ qua")
else:
# Thử selector phụ
alt_button = page.locator("button:has-text('Điểm danh'), button:has-text('Check-in'), .checkin-btn")
if await alt_button.count() > 0:
print(" → Tìm thấy nút điểm danh (selector phụ) → Click...")
await alt_button.first.click()
await page.wait_for_timeout(1800)
print(" → Điểm danh thành công!")
else:
print(" → Không tìm thấy nút điểm danh")
# ========== 3. VẬT NUÔI ==========
print("[3] Vào trang Vật Nuôi...")
await safe_goto(page, "https://1900.fun/nongtrai/vatnuoi.php")
await page.wait_for_timeout(1800)
csrf = await get_csrf(page)
if csrf:
print(f" → CSRF: {csrf[:16]}...")
else:
print(" [!] Không lấy được CSRF")
# 3.1 Thu hoạch từng chuồng
print("[4] Thu hoạch vật nuôi...")
for cage_idx in range(TOTAL_CAGES):
if csrf:
harvest_url = f"https://1900.fun/nongtrai/vatnuoi.php?harvest={cage_idx}&farm_csrf={csrf}"
else:
harvest_url = f"https://1900.fun/nongtrai/vatnuoi.php?harvest={cage_idx}"
print(f" → Thử thu hoạch chuồng {cage_idx + 1}...")
await safe_goto(page, harvest_url)
await page.wait_for_timeout(1600)
# Reload lại để lấy trạng thái mới nhất
await safe_goto(page, "https://1900.fun/nongtrai/vatnuoi.php")
await page.wait_for_timeout(1500)
# 3.2 Kiểm tra chuồng trống + mua
print("[5] Kiểm tra chuồng trống & mua vật nuôi...")
info = await page.evaluate("""() => {
const result = {
animals: typeof animals !== 'undefined' ? animals : [],
userLevel: typeof userLevel !== 'undefined' ? userLevel : 1,
userMoney: typeof userMoney !== 'undefined' ? userMoney : 0,
emptyCages: [],
cageStatus: []
};
const cages = document.querySelectorAll('.cage');
cages.forEach((cage, index) => {
const hasAnimalName = !!cage.querySelector('.animal-name');
const hasTimeLeft = !!cage.querySelector('.time-left');
const hasHarvestBtn = !!cage.querySelector('.harvest-btn, a[href*="harvest="]');
const text = cage.innerText || '';
const isEmpty = cage.classList.contains('empty') ||
(!hasAnimalName && !hasTimeLeft) ||
text.includes('Trống') ||
text.includes('Mua') ||
text.includes('Nuôi');
result.cageStatus.push({
index,
isEmpty,
hasAnimalName,
hasTimeLeft,
text: text.substring(0, 50)
});
if (isEmpty) {
result.emptyCages.push(index);
}
});
return result;
}""")
print(f" → Trạng thái chuồng:")
for st in info.get("cageStatus", []):
status = "TRỐNG" if st["isEmpty"] else "CÓ VẬT NUÔI"
print(f" Chuồng {st['index']+1}: {status} | {st['text']}")
empty_cages = info.get("emptyCages", [])
print(f" → Số chuồng trống: {len(empty_cages)}")
if empty_cages and info.get("animals"):
available = [
a for a in info["animals"]
if a.get("level_required", 1) <= info["userLevel"]
and a.get("price", 0) <= info["userMoney"]
]
if available:
available.sort(key=lambda x: (x.get("level_required", 1), x.get("price", 0)), reverse=True)
best = available[0]
print(f" → Chọn: {best['name']} (Cấp {best['level_required']}) - Giá {best['price']:,} Xu")
for cage_index in empty_cages:
print(f" → Mua vào chuồng {cage_index + 1}...")
await page.evaluate(f"""() => {{
const cageEl = document.getElementById('buyCageIndex');
const animalEl = document.getElementById('buyAnimalId');
if (cageEl) cageEl.value = '{cage_index}';
if (animalEl) animalEl.value = '{best["id"]}';
}}""")
try:
async with page.expect_navigation(wait_until="domcontentloaded", timeout=15000):
await page.eval_on_selector("#buyForm", "form => form.submit()")
print(f" ✓ Đã mua thành công chuồng {cage_index + 1}")
except Exception as e:
print(f" [!] Lỗi mua chuồng {cage_index + 1}: {e}")
await page.wait_for_timeout(1600)
# Trừ tạm tiền để không mua vượt quá
info["userMoney"] -= best["price"]
if info["userMoney"] < best["price"]:
print(" → Hết tiền, dừng mua thêm.")
break
else:
print(" → Không có vật nuôi nào đủ cấp / đủ tiền.")
else:
if not empty_cages:
print(" → Không có chuồng trống (có thể vật nuôi chưa chín hoặc harvest chưa thành công).")
else:
print(" → Không lấy được danh sách animals.")
# ========== 4. ĐĂNG XUẤT ==========
print("[6] Đă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 browser.close()
if __name__ == "__main__":
while True:
try:
print(f"\n==================== [ BẮT ĐẦU VÒNG LẶP ĐIỂM DANH + VẬT NUÔI ] ====================")
asyncio.run(run_automation())
except Exception as err:
print(f"[!] Lỗi ngoài: {err}")
hours = INTERVAL_SECONDS // 3600
print(f"\n[⏳] Hoàn thành. Chờ {hours} giờ để chạy tiếp...")
time.sleep(INTERVAL_SECONDS)