Hướng dẫn
LDPlayer macro loop: vòng lặp, điều kiện dừng và lập lịch
Lặp macro trên LDPlayer hoặc BlueStacks với điều kiện dừng, giữ tiến độ giữa các lần chạy, thoát bằng mã trạng thái, và lập lịch chạy hằng ngày trong MAS.
- Windows
- Mac
- Giả lập
- Studio
- Python SDK
Trong trang này
- Trước khi bắt đầu
- Mẫu LDPlayer macro loop và BlueStacks
- Điều kiện dừng của macro loop
- Khoảng nghỉ và nhịp giống người
- Lưu tiến độ bằng bộ nhớ
- Thoát bằng mã để webhook báo trạng thái
- Một ví dụ hoàn chỉnh
- Lập lịch macro trong Bộ lập lịch MAS trên BlueStacks hoặc LDPlayer
- Chạy trên nhóm
- Điều gì có thể sai
- Vòng lặp không bao giờ kết thúc
- Lịch không kích hoạt
- Time slot is occupied on this port
- Lần chạy hiển thị Thất bại nhưng macro đã xong
Một macro chạy không cần trông chừng cần ba thứ: một vòng lặp biết khi nào dừng, một cách nhớ nó đã đi tới đâu, và một lịch khởi động nó mà không cần bạn. Hướng dẫn này bao cả ba cho một LDPlayer macro loop hoặc macro BlueStacks trong Macro Automation Studio (MAS). Bạn có các mẫu vòng lặp, điều kiện dừng, lưu trữ giữa các lần chạy, mã thoát mà webhook báo được, và Bộ lập lịch. Trang dành cho bất kỳ ai đưa macro từ “tôi nhấn Chạy” sang “nó tự chạy mỗi sáng”.
Trước khi bắt đầu
- MAS đã cài và đăng nhập. Nó là bản tải miễn phí để dùng thử.
- Một dự án Code-Based chạy được trên giả lập từ Code Editor. Xem Bắt đầu.
- Giả lập đã thêm làm thiết bị với cổng bạn tìm được trên thẻ của nó. Xem Thiết bị.
- Ảnh mẫu và vùng của bạn đã chụp. Xem hướng dẫn nhận diện hình ảnh.
Mẫu LDPlayer macro loop và BlueStacks
Ba hình dạng bao gần như mọi macro.
While, với điều kiện dừng. Vòng lặp chạy cho đến khi thứ gì đó trên màn hình hoặc trong bộ đếm của bạn bảo dừng.
import mas
images = mas.images({"collect": 401, "done": 402})
collected = 0
while collected < 50:
if mas.find_object(images.done):
break
button = mas.find_object_retry(images.collect, total_tries=3, time_sleep=2.0)
if button is None:
continue
mas.click(button.x, button.y, delay_ms=1000)
collected += 1For với số lần cố định. Bạn biết cần làm việc đó bao nhiêu lần.
for round_no in range(1, 11):
mas.log(f"Round {round_no} of 10")
button = mas.find_object_retry(images.collect)
if button is None:
mas.log("Nothing to collect, stopping early", level="warning")
break
mas.click(button.x, button.y)Cho đến khi một ảnh mẫu xuất hiện. Một lần chờ có hạn chót, dùng cho màn hình tải và đồng hồ dài.
import time
def wait_for(image, timeout_s=120, every_s=3.0):
deadline = time.monotonic() + timeout_s
while time.monotonic() < deadline:
match = mas.find_object(image)
if match:
return match
time.sleep(every_s)
return NoneMọi vòng lặp ở trên đều có lối ra. find_object trả về None khi trượt và không bao giờ ném lỗi, nên một ảnh mẫu thiếu tự nó không kết thúc được while True. Hãy cho mọi vòng lặp một giới hạn.
Điều kiện dừng của macro loop
Kết hợp ít nhất hai trong số này. Một cái đề phòng game, cái kia đề phòng lỗi của chính bạn.
- Một bộ đếm.
while collected < 50. Rẻ và dễ đoán. - Ngân sách thời gian.
time.monotonic()đếm giây và không bao giờ nhảy khi đồng hồ đổi. Dùng nó cho vòng lặp ngoài để một lần chạy theo lịch luôn kết thúc trước khi lần tiếp theo bắt đầu. - Trạng thái màn hình. Một ảnh mẫu như “hết năng lượng”, “kho đầy” hoặc thông báo giới hạn hằng ngày. Chụp trong Asset Lab như mọi ảnh mẫu khác và kiểm tra ở đầu mỗi lượt.
- Trượt liên tiếp. Đếm bao nhiêu lượt liên tiếp không tìm thấy gì và bỏ cuộc sau năm lượt. Một màn hình bạn không lường trước trông y hệt như vậy.
started = time.monotonic()
misses = 0
while time.monotonic() - started < 20 * 60:
if mas.find_object(images.out_of_energy):
break
button = mas.find_object_retry(images.collect)
if button is None:
misses += 1
if misses >= 5:
break
continue
misses = 0
mas.click(button.x, button.y)Khoảng nghỉ và nhịp giống người
click đã chờ delay_ms=1000 sau cú chạm và swipe kéo dài duration_ms=1000 theo mặc định. Giữa các lượt, thêm một khoảng nghỉ thay đổi.
import random
def pause(low=0.8, high=2.5):
time.sleep(random.uniform(low, high))Khoảng cách cố định trông máy móc và cũng chạy đua với game. Một popup xuất hiện 900 ms sau cú chạm lọt qua độ trễ cố định 1000 ms vào một ngày máy chậm. Khoảng nghỉ ngẫu nhiên làm mượt cả hai. Giữ delay_ms trên click cho thời gian phản ứng của chính ứng dụng và dùng pause() cho nhịp của con người.
Lưu tiến độ bằng bộ nhớ
Một lần chạy theo lịch dừng giữa chừng nên tiếp tục từ chỗ đã dừng ở lần sau. Các hàm lưu trữ giữ một tài liệu JSON nhỏ cho mỗi tác vụ, khóa theo máy tính này, cổng của thiết bị và tên tác vụ bạn chọn.
TASK = "daily_collect"
state = mas.retrieve(TASK) # {} on the first run
collected = state.get("collected", 0)
last_day = state.get("day")
mas.save(TASK, {"collected": collected, "day": today}) # after each pass of the loop
if collected >= 50:
mas.clear(TASK) # start fresh next timesave(task_name, data) ghi hoặc thay thế mục; retrieve(task_name) trả về từ điển hoặc một từ điển rỗng; clear(task_name) xóa nó. data phải tuần tự hóa được sang JSON. Vì cổng là một phần của khóa, hai instance giả lập chạy cùng macro không bao giờ dùng chung bộ đếm. retrieve_all(task_name) trả về mục của mọi instance khi bạn muốn tổng. Xem Lưu trữ.
Thoát bằng mã để webhook báo trạng thái
MAS đọc mã thoát của tiến trình khi mã của bạn kết thúc. Không nghĩa là lần chạy hoàn thành; bất kỳ giá trị nào khác đánh dấu là thất bại. Bên đăng ký webhook nhận macro.completed hoặc macro.failed tương ứng, kèm exit_code trong payload.
import sys
if energy is None:
mas.log("Could not read energy", level="error")
sys.exit(2) # macro.failed, exit_code 2
mas.log("All done")
sys.exit(0) # macro.completedNgoại lệ không được xử lý cũng thoát với mã khác 0, nên một lần sập được báo là thất bại mà không cần thêm mã. Với các sự kiện chỉ mã của bạn biết, mas.webhook("level.reached", {"level": 40}) gửi sự kiện custom.level.reached tới các điểm cuối đăng ký sự kiện tùy chỉnh. Thiết lập điểm cuối trên trang Webhook; xem Webhook.
Một ví dụ hoàn chỉnh
Macro nhận tối đa năm mươi phần thưởng mỗi ngày, nhớ số đã nhận, dừng khi “hết năng lượng” hoặc sau hai mươi phút, và báo cáo qua mã thoát. Thay ID bằng của bạn.
import datetime
import random
import sys
import time
import mas
images = mas.images({
"collect": 401,
"close_popup": 402,
"out_of_energy": 403,
})
TASK = "daily_collect"
DAILY_LIMIT = 50
TIME_BUDGET_S = 20 * 60
def pause(low=0.8, high=2.5):
time.sleep(random.uniform(low, high))
def main():
today = datetime.date.today().isoformat()
state = mas.retrieve(TASK)
collected = state.get("collected", 0) if state.get("day") == today else 0
mas.log(f"{today}: starting at {collected} of {DAILY_LIMIT}")
started = time.monotonic()
misses = 0
while collected < DAILY_LIMIT:
if time.monotonic() - started > TIME_BUDGET_S:
mas.log("Time budget reached", level="warning")
break
popup = mas.find_object(images.close_popup)
if popup:
mas.click(popup.x, popup.y, delay_ms=800)
continue
if mas.find_object(images.out_of_energy):
mas.log("Out of energy")
break
button = mas.find_object_retry(images.collect, total_tries=3, time_sleep=2.0)
if button is None:
misses += 1
if misses >= 5:
mas.log("Five misses in a row, giving up", level="error")
mas.save(TASK, {"collected": collected, "day": today})
sys.exit(2)
continue
misses = 0
mas.click(button.x, button.y, delay_ms=1000)
collected += 1
mas.save(TASK, {"collected": collected, "day": today})
pause()
mas.log(f"Finished at {collected} of {DAILY_LIMIT}")
sys.exit(0)
if __name__ == "__main__":
main()Chạy một lần từ Code Editor bằng Chạy (F5) và xác nhận nó tự kết thúc trước khi bạn lập lịch.
Lập lịch macro trong Bộ lập lịch MAS trên BlueStacks hoặc LDPlayer
Bộ lập lịch nằm bên trong ứng dụng máy tính và khởi động macro trên giả lập của bạn vào thời điểm bạn đặt.
- Mở Lập lịch và nhấn Tạo lịch mới.
- Nhập Tên (3 đến 100 ký tự) và chọn Macro.
- Dưới Cổng giả lập, nhấn Quét và chọn cổng của instance, hoặc gõ vào.
- Đặt Ngày và Giờ. Giờ là giờ địa phương của máy tính bạn.
- Đặt Chu kỳ: Không cho một lần chạy, Hằng ngày, Hằng tuần với Ngày trong tuần đã tích, hoặc Hằng tháng.
- Để Số lần lặp ở 1 trừ khi bạn muốn macro chạy nhiều lần liên tiếp ở mỗi lần kích hoạt.
- Giữ Hoạt động bật và nhấn Tạo lịch.
Những điều cần biết trước khi bạn dựa vào nó:
- Ứng dụng phải mở và đã đăng nhập. Bộ lập lịch không phải dịch vụ hệ thống và không có cú pháp cron.
- Công việc được kiểm tra mỗi 30 giây, nên một lần chạy có thể bắt đầu muộn tới nửa phút so với giờ đặt.
- Một lịch nhắm vào một cổng. Nếu cổng đang bận với lần chạy khác khi tới giờ, bộ lập lịch bỏ qua chu kỳ đó và thử lại ở chu kỳ tiếp theo.
- Hai lịch không thể dùng chung một khung giờ trên cùng cổng; ứng dụng từ chối với “Time slot is occupied on this port”.
- Tối đa 20 công việc theo lịch chạy được cùng lúc.
- Với Số lần lặp trên 1, một lần chạy thất bại (mã thoát khác 0) dừng các lần lặp còn lại và đánh dấu công việc là Thất bại.
- Các lần chạy theo lịch dùng tham số đã lưu trên thẻ thiết bị, hoặc hồ sơ cài đặt mà thiết bị đi theo. Xem Hồ sơ cài đặt.
- Xem lịch sử trên một công việc hiển thị mọi lần chạy kèm trạng thái và nhật ký.
Trang Bộ lập lịch nói về sửa, bỏ qua và hủy công việc.
Chạy trên nhóm
Để chạy cùng macro trên nhiều instance bằng tay, đặt chúng vào một nhóm thiết bị, gán macro cho từng thiết bị và nhấn Bắt đầu tất cả. Thiết bị bắt đầu lần lượt, cách nhau nửa giây, và mỗi cái có lần chạy, nhật ký và mã thoát riêng. Để lập lịch cho nhóm, tạo một công việc theo lịch cho mỗi cổng với cùng macro và giờ. Hướng dẫn đa nhiệm nói về tham số, proxy và lưu trữ cho từng thiết bị.
Điều gì có thể sai
Vòng lặp không bao giờ kết thúc
Một while True không có giới hạn, hoặc một điều kiện dừng phụ thuộc vào ảnh mẫu không bao giờ xuất hiện. Thêm ngân sách thời gian bằng time.monotonic() và bộ đếm trượt liên tiếp; hai thứ đó kết thúc mọi vòng lặp.
Lịch không kích hoạt
Ứng dụng đã đóng hoặc máy ngủ vào lúc đó, cổng đang bận, hoặc công việc không Hoạt động. Kiểm tra Xem lịch sử để tìm mục bị bỏ qua hoặc thất bại, và giữ máy tính thức trong khung giờ đã lên lịch.
Time slot is occupied on this port
Một công việc khác trên cùng cổng đã giữ giờ đó. Dời một công việc vài phút, hoặc đặt macro thứ hai vào trong macro thứ nhất bằng Số lần lặp.
Lần chạy hiển thị Thất bại nhưng macro đã xong
Mã kết thúc với mã thoát khác 0 hoặc một ngoại lệ không được xử lý sau hành động cuối. Đọc các dòng cuối của nhật ký; một sys.exit(1) trong đường dọn dẹp hoặc một KeyError trên trạng thái đã lưu là nguyên nhân thường gặp.
Không có công cụ tự động hóa nào an toàn 100%, vì vậy hãy tự động hóa một cách có trách nhiệm và theo quyết định của riêng bạn.
Bước tiếp theo
Trang liên quan
Cảm ơn bạn. Nếu có gì chưa đúng, hãy nói với chúng tôi trên Discord.
Có câu hỏi? Hỏi trên Discord