此页面尚在编辑中
前言
欢迎来到SRA开发文档。SRA是一个基于Python语言开发的自动化工具,旨在帮助玩家在崩坏星穹铁道游戏中实现自动化操作。
SRA的开发文档旨在为开发者提供详细的指导,帮助了解SRA的基本概念、API使用方法以及插件开发规范。通过阅读文档,开发者可以快速上手SRA,并根据自己的需求进行定制化开发。
感谢您在百忙之中阅读SRA开发文档。这个文档将向你展示从Python基础开始的SRA开发。如果你已经有相关基础,可以跳过这部分然后开始阅读SRA API
学习
环境:
- Python 3.11.5
- PyCharm Community Edition
- 如果你有更喜欢的配置,可以使用自己的配置。
Python 基础
- 第一个Python程序
print("hello world")
- 变量和数据类型
Python 是动态类型语言,无需提前声明变量类型。常见的数据类型有整数(int)、浮点数(float)、字符串(str)、布尔值(bool)等。
# 整数 num = 10
# 浮点数 float_num = 3.14
# 字符串 name = "John"
# 布尔值 is_valid = True - 条件语句
Python 使用
if
、elif
和else
来实现条件判断。age = 18
if age < 18:
print("未成年")
elif age == 18:
print("刚成年")
else:
print("已成年") - 循环语句
Python 有
for
和while
两种循环。for
循环示例:fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)while
循环示例:count = 0
while count < 5:
print(count)
count += 1 - 函数
函数是一段可重复使用的代码块,使用
def
关键字定义。def add(a, b):
return a + b
result = add(3, 5)
print(result) - 列表、字典、集合、元组
Python 中有多种集合类型,包括列表(list)、字典(dict)、集合(set)和元组(tuple)。
列表(list)是一种有序的可变集合,字典(dict)是一种无序的键值对集合。集合(set)是无序且元素唯一的集合,元组(tuple)是有序的不可变集合。
以下是各种集合类型的创建示例和基本操作:
# 列表 (list) # 创建列表 my_list = [1, 2, 3, 'apple', 'banana'] print("列表:", my_list) # 访问列表元素 print("列表的第一个元素:", my_list[0]) # 修改列表元素 my_list[0] = 100 print("修改后的列表:", my_list) # 列表添加元素 my_list.append('cherry') print("添加元素后的列表:", my_list) # 列表删除元素 del my_list[3] print("删除元素后的列表:", my_list) # 字典 (dict) # 创建字典 my_dict = {'name': 'John', 'age': 30, 'city': 'New York'} print("字典:", my_dict) # 访问字典元素 print("姓名:", my_dict['name']) # 修改字典元素 my_dict['age'] = 31 print("修改后的字典:", my_dict) # 添加字典元素 my_dict['job'] = 'Engineer' print("添加元素后的字典:", my_dict) # 删除字典元素 del my_dict['city'] print("删除元素后的字典:", my_dict) # 集合 (set) # 创建集合 my_set = {1, 2, 3, 3, 4} # 重复元素会被自动去除 print("集合:", my_set) # 集合添加元素 my_set.add(5) print("添加元素后的集合:", my_set) # 集合删除元素 my_set.remove(4) print("删除元素后的集合:", my_set) # 元组 (tuple) # 创建元组 my_tuple = (1, 2, 'apple', 'banana') print("元组:", my_tuple) # 访问元组元素 print("元组的第一个元素:", my_tuple[0]) # 元组不可修改,以下代码会报错 # my_tuple[0] = 100
Python 进阶
- 文件操作
Python 使用
open
函数打开文件,使用read
和write
方法读写文件。# 打开一个文件用于读取 file = open('example.txt', 'r') content = file.read() print(content) file.close() # 更安全的文件打开方式,使用 with 语句,它会自动关闭文件 with open('example.txt', 'r') as file: content = file.read() print(content) # 写入文件 with open('output.txt', 'w') as file: file.write('这是写入文件的内容。') # 追加内容到文件 with open('output.txt', 'a') as file: file.write('\n这是追加的内容。')
- 异常处理
在 Python 中,可以使用
try
、except
、finally
和else
语句来处理异常。try: result = 10 / 0 # 会引发 ZeroDivisionError 异常 except ZeroDivisionError: print('错误:除数不能为零。') except Exception as e: print(f'发生未知错误:{e}') else: print('没有发生异常,结果是:', result) finally: print('无论是否发生异常,这里的代码都会执行。')
- 类和对象
Python 是面向对象的编程语言,使用
class
关键字定义类。class Person: def __init__(self, name, age): self.name = name self.age = age def introduce(self): print(f'我叫 {self.name},今年 {self.age} 岁。') # 创建对象 person = Person('张三', 25) person.introduce()
- 继承
Python 支持类的继承,子类可以继承父类的属性和方法。
class Student(Person): def __init__(self, name, age, student_id): super().__init__(name, age) self.student_id = student_id def study(self): print(f'{self.name}(学号:{self.student_id})正在学习。') # 创建 Student 对象 student = Student('李四', 20, '2023001') student.introduce() student.study()
- 模块和包
Python 支持模块和包的概念,使用
import
语句导入模块或包。# 导入整个模块 import math print(math.sqrt(16)) # 输出 4.0 # 导入模块中的特定函数 from math import sqrt print(sqrt(25)) # 输出 5.0 # 导入模块并给模块起别名 import math as m print(m.pow(2, 3)) # 输出 8.0 # 导入包中的模块 # 假设存在一个名为 my_package 的包,里面有一个名为 my_module 的模块 from my_package import my_module my_module.my_function() # 包的 __init__.py 文件可以用于初始化包,也可以导入包内的模块 # 在 my_package 的 __init__.py 中写入: # from .my_module import my_function # 这样就可以直接从包导入函数 from my_package import my_function my_function()
- 装饰器
装饰器是 Python 中一个强大的特性,它允许你在不修改原函数代码的情况下,扩展函数的功能。装饰器本质上是一个函数,它接受一个函数作为参数,并返回一个新的函数。
# 定义一个简单的装饰器 def my_decorator(func): def wrapper(): print("在函数执行前做一些事情") func() print("在函数执行后做一些事情") return wrapper # 使用装饰器 @my_decorator def say_hello(): print("Hello!") say_hello() # 输出: # 在函数执行前做一些事情 # Hello! # 在函数执行后做一些事情
- 生成器
生成器是一种特殊的迭代器,它可以在需要时生成值,而不是一次性生成所有值。这在处理大量数据时非常有用,可以节省内存。生成器有两种创建方式:生成器表达式和生成器函数。
# 生成器表达式 numbers = (x * 2 for x in range(5)) print("生成器表达式输出:") for num in numbers: print(num) # 预期输出: # 0 # 2 # 4 # 6 # 8 # 生成器函数 def my_generator(): yield 1 yield 2 yield 3 gen = my_generator() print("\n生成器函数输出:") for value in gen: print(value) # 预期输出: # 1 # 2 # 3 # 更复杂的生成器函数,生成斐波那契数列的前 n 项 def fibonacci_generator(n): a, b = 0, 1 count = 0 while count < n: yield a a, b = b, a + b count += 1 # 使用斐波那契生成器 fib_gen = fibonacci_generator(10) print("\n斐波那契数列的前 10 项:") for fib_num in fib_gen: print(fib_num) # 预期输出: # 0 # 1 # 1 # 2 # 3 # 5 # 8 # 13 # 21 # 34 # 使用生成器进行文件处理,逐行读取文件内容 def file_line_generator(file_path): try: with open(file_path, 'r', encoding='utf-8') as file: for line in file: yield line.strip() except FileNotFoundError: print(f"文件 {file_path} 未找到。") # 假设存在一个名为 example.txt 的文件,使用文件生成器读取内容 file_gen = file_line_generator('example.txt') print("\n文件 example.txt 的内容:") for line_content in file_gen: print(line_content) # 预期输出取决于 example.txt 文件的实际内容,若文件不存在则输出: # 文件 example.txt 未找到。
- 上下文管理器
上下文管理器用于管理资源的分配和释放,例如文件的打开和关闭、锁的获取和释放等。使用
with
语句可以简化上下文管理的代码。# 自定义上下文管理器 class MyContextManager: def __enter__(self): print("进入上下文") return self def __exit__(self, exc_type, exc_val, exc_tb): print("退出上下文") with MyContextManager() as cm: print("在上下文中执行操作")
- 多线程和多进程
Python 支持多线程和多进程编程,多线程可以提高程序的并发性,多进程可以利用多核处理器。
# 多线程示例,使用 threading 模块 import threading def print_numbers(): for i in range(1, 6): print(f"线程 1: {i}") def print_letters(): for letter in ['a', 'b', 'c', 'd', 'e']: print(f"线程 2: {letter}") # 创建线程对象 thread1 = threading.Thread(target=print_numbers) thread2 = threading.Thread(target=print_letters) # 启动线程 thread1.start() thread2.start() # 等待线程执行完毕 thread1.join() thread2.join() print("多线程执行完毕") # 多进程示例,使用 multiprocessing 模块 import multiprocessing def square_number(num): result = num * num print(f"进程处理结果: {result}") if __name__ == '__main__': numbers = [1, 2, 3, 4, 5] processes = [] # 创建进程对象并启动 for num in numbers: p = multiprocessing.Process(target=square_number, args=(num,)) processes.append(p) p.start() # 等待所有进程执行完毕 for p in processes: p.join() print("多进程执行完毕")
- 异步编程
Python 中的异步编程可以在单线程中实现高效的并发操作,主要使用
asyncio
库。异步函数使用async
关键字定义,await
关键字用于暂停函数的执行,直到等待的协程完成。import asyncio # 定义异步函数 async def hello_world(): print("开始执行异步函数") await asyncio.sleep(1) # 模拟耗时操作 print("异步函数执行完毕") # 定义主函数 async def main(): task = asyncio.create_task(hello_world()) await task # 运行异步程序 asyncio.run(main()) # 多个异步任务并发执行 async def task1(): print("任务 1 开始") await asyncio.sleep(2) print("任务 1 结束") async def task2(): print("任务 2 开始") await asyncio.sleep(1) print("任务 2 结束") async def concurrent_tasks(): tasks = [task1(), task2()] await asyncio.gather(*tasks) asyncio.run(concurrent_tasks())
- 单元测试
单元测试是对程序中的最小可测试单元进行检查和验证,Python 提供了
unittest
模块来编写和运行单元测试。import unittest # 定义一个简单的函数 def add(a, b): return a + b # 创建测试类,继承自 unittest.TestCase class TestAdd(unittest.TestCase): def test_add(self): result = add(3, 5) self.assertEqual(result, 8) # 断言结果是否等于 8 if __name__ == '__main__': unittest.main()
- 文档字符串和类型提示
文档字符串用于为模块、类、函数等添加文档说明,类型提示可以提高代码的可读性和可维护性。
# 文档字符串示例 def multiply(a: int, b: int) -> int: """ 计算两个整数的乘积。 :param a: 第一个整数 :param b: 第二个整数 :return: 两个整数的乘积 """ return a * b # 使用类型提示和文档字符串 help(multiply) # 查看函数的文档说明
约定
为SRA进行开发时,建议遵守下面的约定
- 变量名
变量应当使用英文命名,使用小写字母,且有实际意义。每个单词之间用下划线分隔开,避免出现拼写错误。
例如:
user_name
、is_logged_in
。 - 常量名
常量应当使用英文命名,使用大写字母,且有实际意义。每个单词之间用下划线分隔开,避免出现拼写错误。
例如:
MAX_USER_COUNT
、DEFAULT_TIMEOUT
。 - 函数名
函数名应当使用英文命名,使用小写字母,且有实际意义。每个单词之间用下划线分隔开,避免出现拼写错误。
例如:
calculate_average
、get_user_info
。 - 类名
类名应当使用英文命名,使用单词首字母大写,且有实际意义。
例如:
User
、DatabaseConnection
。 - 模块名
模块名应当使用英文命名,使用小写字母,且有实际意义。每个单词之间用下划线分隔开,避免出现拼写错误。
例如:
math_utils
、database
。 - 包名
包名应当使用英文命名,使用小写字母,且有实际意义。每个单词之间用下划线分隔开,避免出现拼写错误。
例如:
utils
、database
。 - 缩进
缩进应当使用四个空格。
例如:
def calculate_average(numbers): total = 0 for number in numbers: total += number return total / len(numbers)
- 换行
换行应当使用换行符,避免使用空格。行长不建议超过120
例如:
result = calculate_average([1, 2, 3, 4, 5]) print("The average is:", result)
- 空格
空格应当使用空格,避免使用制表符。
例如:
result = calculate_average([1, 2, 3, 4, 5]) print("The average is:", result)
- 引号
引号应当首选使用双引号。
例如:
print("Hello, 'world'!")
SRA API
SRA API在源码中均有详细注释,此处只罗列而不详细介绍
鼠标事件
鼠标事件是SRA的一个重要功能,它可以模拟鼠标的点击、移动等操作。鼠标事件的API如下:
- SRACore.util.SRAOperator.SRAOperator
- click_img(...): 在屏幕上点击对应的图像
- click_point(*args): 在指定的坐标处点击。
- moveTo(*args): 移动光标到指定位置。
- moveRel(x_offset: int, y_offset: int): 相对当前位置移动光标。
- scroll(delta): 模拟鼠标滚轮滚动。
键盘事件
键盘事件是SRA的一个重要功能,它可以模拟键盘的按键、组合键等操作。键盘事件的API如下:
- SRACore.util.SRAOperator.SRAOperator
- press_key(): 模拟键盘按键按下并释放。
- press_key_for_a_while(): 按下按键持续一段时间后释放。
- copy(): 将内容复制到剪切板。
- paste(): 将剪切板内容粘贴到指定位置。
- write(): 向指定位置写入文本。
画面检测
画面检测是SRA的一个重要功能,它可以检测屏幕上的图像,并返回图像的位置。画面检测的API如下:
- SRACore.util.SRAOperator.SRAOperator
- get_screenshot(): 根据指定的窗口标题和区域获取截图,并对截图进行尺寸调整。
- locate(): 在指定标题的窗口截图中定位指定图像的位置。
- locateCenter(): 在指定标题的窗口截图中定位指定图像的中心位置,并根据偏移量进行调整,最后计算出实际屏幕坐标。
- locateAny(): 在截图中依次定位图像列表中的图像,返回第一个匹配成功的图像的索引和位置。
- locateAll(): 在截图中定位图像列表中的所有图像,返回所有匹配成功的图像的索引和位置。
- exist(): 检查指定路径的图像是否存在于画面中。
- existAny(): 检查指定路径的图像列表中是否存在于画面中。
- check(): 按照指定的时间间隔持续检查图像,直到图像出现或者达到最大检查次数。
- checkAny(): 按照指定的时间间隔持续检查图像列表,直到图像出现或者达到最大检查次数。
- get_screen_center(): 获取当前活动窗口的中心点坐标。
电源操作
电源操作是SRA的一个重要功能,它可以模拟电源的操作。电源操作的API如下:
- SRACore.util.WindowsPower
- schedule_shutdown(): 设置Windows延时关机。
- shutdown_cancel(): 取消关机
- hibernate(): 休眠计算机。
进程操作
进程操作是SRA的一个重要功能,它对进程操作。进程操作的API如下:
- SRACore.util.WindowsProcess
- find_window(): 基于窗口标题查找窗口
- check_window(): 激活窗口
- is_process_running(process_name): 基于进程名判断进程是否正在运行
- task_kill(): 关闭指定进程。
- open_normal(): 运行指定exe程序或命令并等待,阻塞当前线程。
- Popen(): 运行指定exe程序或命令并立即返回,不阻塞当前线程。
- set_startup_item(): 设置开机启动项。
- delete_startup_item(): 删除开机启动项。
配置操作
配置操作是SRA的一个重要功能,它对配置进行操作。配置操作的API如下:
- SRACore.util.Configure
- init(): 配置初始化方法。
- load(): 从指定路径加载配置。
- loadConfigByName(): 根据配置名加载配置。
- save(): 保存配置到指定路径。
- remove(): 移除指定配置文件。
- rename(): 将配置文件重命名。
日志操作
日志操作是SRA的一个重要功能。日志操作的API如下:
- SRACore.util.Logger.logger
- info(): 输出信息日志。
- warning(): 输出警告日志。
- error(): 输出错误日志。
- debug(): 输出调试日志。
对话框
对话框是SRA的一个重要功能,它可以显示对话框。对话框的API如下:
- SRACore.util.Dialog
- DownloadDialog: 下载对话框。
- AnnouncementDialog: 公告对话框。
- AnnouncementBoard: 公告栏对话框。
- InputDialog: 输入对话框。
- MessageBox: 消息框对话框。
插件开发指南
仅限0.8.1+
插件介绍
插件是SRA的扩展模块,通过插件可以实现一些特定的功能。插件可以是一个单独的Python文件,也可以是一个包含多个Python文件的文件夹。或用Python调用其他语言。
插件结构
插件的结构如下:
插件名/
├── __init__.py
├── 插件文件1.py
├── 插件文件2.py
├── ...
└── 资源/
├── 资源文件1.png
├── 资源文件2.png
├──...
其中,__init__.py
是插件的入口文件,用于初始化插件。插件文件可以是Python文件,也可以是其他类型的文件。资源文件夹用于存放插件所需的资源文件,如图片、音频等。
插件元数据
插件的元数据是若干用于描述插件的信息,或用于请求与SRA交互。元数据的键值对如下:
- NAME: 插件的名称,必须是字符串类型。
- VERSION: 插件的版本号,必须是字符串类型。
- DESCRIPTION: 插件的描述,必须是字符串类型。
- AUTHOR: 插件的作者,必须是字符串类型。
- UI: 请求SRA的主ui。仅声明即可。
元数据的示例如下:
NAME = "MyPlugin"
VERSION = "1.0.0"
DESCRIPTION = "A plugin for SRA"
AUTHOR = "John Doe"
UI = None
插件API
插件API是用于与SRA进行交互的接口。插件API的方法如下:
- run(): 插件启动时调用的方法。
- PluginBase: 所有插件的基类。插件必须继承此类。
- PluginManager.register(): 注册插件线程。
插件示例
下面是一个简单的无UI插件示例:
__init__.py
from SRACore.util.Plugins import PluginBase, PluginManager
NAME = "MyPlugin"
VERSION = "1.0.0"
DESCRIPTION = "A plugin for SRA"
AUTHOR = "John Doe"
def run():
# 插件启动时调用的方法
plugin = MyPlugin()
plugin.start() # 启动插件线程
PluginManager.register(plugin)
class MyPlugin(PluginBase):
def __init__(self):
super().__init__()
# 初始化插件
pass
def run(self):
# 插件启动时调用的方法
pass
插件开发规范
插件开发时,需要遵循以下规范:
- 插件必须含有__init__.py,并在其中实现run()方法。
- 插件必须含有一个主类, 继承PluginBase类。
- 插件必须使用PluginManager.register()方法注册到多线程运行。
- 使用源码的插件尽量仅使用SRA API或Python标准库中的内容。