336 lines
10 KiB
Python
336 lines
10 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Examples of automation patterns using the proposed --exec flag
|
|
|
|
Usage:
|
|
./mcrogueface game.py --exec automation_basic.py
|
|
./mcrogueface game.py --exec automation_stress.py --exec monitor.py
|
|
"""
|
|
|
|
# ===== automation_basic.py =====
|
|
# Basic automation that runs alongside the game
|
|
|
|
import mcrfpy
|
|
from mcrfpy import automation
|
|
import time
|
|
|
|
class GameAutomation:
|
|
"""Automated testing that runs periodically"""
|
|
|
|
def __init__(self):
|
|
self.test_count = 0
|
|
self.test_results = []
|
|
|
|
def run_test_suite(self):
|
|
"""Called by timer - runs one test per invocation"""
|
|
test_name = f"test_{self.test_count}"
|
|
|
|
try:
|
|
if self.test_count == 0:
|
|
# Test main menu
|
|
self.test_main_menu()
|
|
elif self.test_count == 1:
|
|
# Test inventory
|
|
self.test_inventory()
|
|
elif self.test_count == 2:
|
|
# Test combat
|
|
self.test_combat()
|
|
else:
|
|
# All tests complete
|
|
self.report_results()
|
|
return
|
|
|
|
self.test_results.append((test_name, "PASS"))
|
|
except Exception as e:
|
|
self.test_results.append((test_name, f"FAIL: {e}"))
|
|
|
|
self.test_count += 1
|
|
|
|
def test_main_menu(self):
|
|
"""Test main menu interactions"""
|
|
automation.screenshot("test_main_menu_before.png")
|
|
automation.click(400, 300) # New Game button
|
|
time.sleep(0.5)
|
|
automation.screenshot("test_main_menu_after.png")
|
|
|
|
def test_inventory(self):
|
|
"""Test inventory system"""
|
|
automation.hotkey("i") # Open inventory
|
|
time.sleep(0.5)
|
|
automation.screenshot("test_inventory_open.png")
|
|
|
|
# Drag item
|
|
automation.moveTo(100, 200)
|
|
automation.dragTo(200, 200, duration=0.5)
|
|
|
|
automation.hotkey("i") # Close inventory
|
|
|
|
def test_combat(self):
|
|
"""Test combat system"""
|
|
# Move character
|
|
automation.keyDown("w")
|
|
time.sleep(0.5)
|
|
automation.keyUp("w")
|
|
|
|
# Attack
|
|
automation.click(500, 400)
|
|
automation.screenshot("test_combat.png")
|
|
|
|
def report_results(self):
|
|
"""Generate test report"""
|
|
print("\n=== Automation Test Results ===")
|
|
for test, result in self.test_results:
|
|
print(f"{test}: {result}")
|
|
print(f"Total: {len(self.test_results)} tests")
|
|
|
|
# Stop the timer
|
|
mcrfpy.delTimer("automation_suite")
|
|
|
|
# Create automation instance and register timer
|
|
auto = GameAutomation()
|
|
mcrfpy.setTimer("automation_suite", auto.run_test_suite, 2000) # Run every 2 seconds
|
|
|
|
print("Game automation started - tests will run every 2 seconds")
|
|
|
|
|
|
# ===== automation_stress.py =====
|
|
# Stress testing with random inputs
|
|
|
|
import mcrfpy
|
|
from mcrfpy import automation
|
|
import random
|
|
|
|
class StressTester:
|
|
"""Randomly interact with the game to find edge cases"""
|
|
|
|
def __init__(self):
|
|
self.action_count = 0
|
|
self.errors = []
|
|
|
|
def random_action(self):
|
|
"""Perform a random UI action"""
|
|
try:
|
|
action = random.choice([
|
|
self.random_click,
|
|
self.random_key,
|
|
self.random_drag,
|
|
self.random_hotkey
|
|
])
|
|
action()
|
|
self.action_count += 1
|
|
|
|
# Periodic screenshot
|
|
if self.action_count % 50 == 0:
|
|
automation.screenshot(f"stress_test_{self.action_count}.png")
|
|
print(f"Stress test: {self.action_count} actions performed")
|
|
|
|
except Exception as e:
|
|
self.errors.append((self.action_count, str(e)))
|
|
|
|
def random_click(self):
|
|
x = random.randint(0, 1024)
|
|
y = random.randint(0, 768)
|
|
button = random.choice(["left", "right"])
|
|
automation.click(x, y, button=button)
|
|
|
|
def random_key(self):
|
|
key = random.choice([
|
|
"a", "b", "c", "d", "w", "s",
|
|
"space", "enter", "escape",
|
|
"1", "2", "3", "4", "5"
|
|
])
|
|
automation.keyDown(key)
|
|
automation.keyUp(key)
|
|
|
|
def random_drag(self):
|
|
x1 = random.randint(0, 1024)
|
|
y1 = random.randint(0, 768)
|
|
x2 = random.randint(0, 1024)
|
|
y2 = random.randint(0, 768)
|
|
automation.moveTo(x1, y1)
|
|
automation.dragTo(x2, y2, duration=0.2)
|
|
|
|
def random_hotkey(self):
|
|
modifier = random.choice(["ctrl", "alt", "shift"])
|
|
key = random.choice(["a", "s", "d", "f"])
|
|
automation.hotkey(modifier, key)
|
|
|
|
# Create stress tester and run frequently
|
|
stress = StressTester()
|
|
mcrfpy.setTimer("stress_test", stress.random_action, 100) # Every 100ms
|
|
|
|
print("Stress testing started - random actions every 100ms")
|
|
|
|
|
|
# ===== monitor.py =====
|
|
# Performance and state monitoring
|
|
|
|
import mcrfpy
|
|
from mcrfpy import automation
|
|
import json
|
|
import time
|
|
|
|
class PerformanceMonitor:
|
|
"""Monitor game performance and state"""
|
|
|
|
def __init__(self):
|
|
self.samples = []
|
|
self.start_time = time.time()
|
|
|
|
def collect_sample(self):
|
|
"""Collect performance data"""
|
|
sample = {
|
|
"timestamp": time.time() - self.start_time,
|
|
"fps": mcrfpy.getFPS() if hasattr(mcrfpy, 'getFPS') else 60,
|
|
"scene": mcrfpy.currentScene(),
|
|
"memory": self.estimate_memory_usage()
|
|
}
|
|
self.samples.append(sample)
|
|
|
|
# Log every 10 samples
|
|
if len(self.samples) % 10 == 0:
|
|
avg_fps = sum(s["fps"] for s in self.samples[-10:]) / 10
|
|
print(f"Average FPS (last 10 samples): {avg_fps:.1f}")
|
|
|
|
# Save data every 100 samples
|
|
if len(self.samples) % 100 == 0:
|
|
self.save_report()
|
|
|
|
def estimate_memory_usage(self):
|
|
"""Estimate memory usage based on scene complexity"""
|
|
# This is a placeholder - real implementation would use psutil
|
|
ui_count = len(mcrfpy.sceneUI(mcrfpy.currentScene()))
|
|
return ui_count * 1000 # Rough estimate in KB
|
|
|
|
def save_report(self):
|
|
"""Save performance report"""
|
|
with open("performance_report.json", "w") as f:
|
|
json.dump({
|
|
"samples": self.samples,
|
|
"summary": {
|
|
"total_samples": len(self.samples),
|
|
"duration": time.time() - self.start_time,
|
|
"avg_fps": sum(s["fps"] for s in self.samples) / len(self.samples)
|
|
}
|
|
}, f, indent=2)
|
|
print(f"Performance report saved ({len(self.samples)} samples)")
|
|
|
|
# Create monitor and start collecting
|
|
monitor = PerformanceMonitor()
|
|
mcrfpy.setTimer("performance_monitor", monitor.collect_sample, 1000) # Every second
|
|
|
|
print("Performance monitoring started - sampling every second")
|
|
|
|
|
|
# ===== automation_replay.py =====
|
|
# Record and replay user actions
|
|
|
|
import mcrfpy
|
|
from mcrfpy import automation
|
|
import json
|
|
import time
|
|
|
|
class ActionRecorder:
|
|
"""Record user actions for replay"""
|
|
|
|
def __init__(self):
|
|
self.recording = False
|
|
self.actions = []
|
|
self.start_time = None
|
|
|
|
def start_recording(self):
|
|
"""Start recording user actions"""
|
|
self.recording = True
|
|
self.actions = []
|
|
self.start_time = time.time()
|
|
print("Recording started - perform actions to record")
|
|
|
|
# Register callbacks for all input types
|
|
mcrfpy.registerPyAction("record_click", self.record_click)
|
|
mcrfpy.registerPyAction("record_key", self.record_key)
|
|
|
|
# Map all mouse buttons
|
|
for button in range(3):
|
|
mcrfpy.registerInputAction(8192 + button, "record_click")
|
|
|
|
# Map common keys
|
|
for key in range(256):
|
|
mcrfpy.registerInputAction(4096 + key, "record_key")
|
|
|
|
def record_click(self, action_type):
|
|
"""Record mouse click"""
|
|
if not self.recording or action_type != "start":
|
|
return
|
|
|
|
pos = automation.position()
|
|
self.actions.append({
|
|
"type": "click",
|
|
"time": time.time() - self.start_time,
|
|
"x": pos[0],
|
|
"y": pos[1]
|
|
})
|
|
|
|
def record_key(self, action_type):
|
|
"""Record key press"""
|
|
if not self.recording or action_type != "start":
|
|
return
|
|
|
|
# This is simplified - real implementation would decode the key
|
|
self.actions.append({
|
|
"type": "key",
|
|
"time": time.time() - self.start_time,
|
|
"key": "unknown"
|
|
})
|
|
|
|
def stop_recording(self):
|
|
"""Stop recording and save"""
|
|
self.recording = False
|
|
with open("recorded_actions.json", "w") as f:
|
|
json.dump(self.actions, f, indent=2)
|
|
print(f"Recording stopped - {len(self.actions)} actions saved")
|
|
|
|
def replay_actions(self):
|
|
"""Replay recorded actions"""
|
|
print("Replaying recorded actions...")
|
|
|
|
with open("recorded_actions.json", "r") as f:
|
|
actions = json.load(f)
|
|
|
|
start_time = time.time()
|
|
action_index = 0
|
|
|
|
def replay_next():
|
|
nonlocal action_index
|
|
if action_index >= len(actions):
|
|
print("Replay complete")
|
|
mcrfpy.delTimer("replay")
|
|
return
|
|
|
|
action = actions[action_index]
|
|
current_time = time.time() - start_time
|
|
|
|
# Wait until it's time for this action
|
|
if current_time >= action["time"]:
|
|
if action["type"] == "click":
|
|
automation.click(action["x"], action["y"])
|
|
elif action["type"] == "key":
|
|
automation.keyDown(action["key"])
|
|
automation.keyUp(action["key"])
|
|
|
|
action_index += 1
|
|
|
|
mcrfpy.setTimer("replay", replay_next, 10) # Check every 10ms
|
|
|
|
# Example usage - would be controlled by UI
|
|
recorder = ActionRecorder()
|
|
|
|
# To start recording:
|
|
# recorder.start_recording()
|
|
|
|
# To stop and save:
|
|
# recorder.stop_recording()
|
|
|
|
# To replay:
|
|
# recorder.replay_actions()
|
|
|
|
print("Action recorder ready - call recorder.start_recording() to begin") |