elon_py/test/aola.py

310 lines
13 KiB
Python
Raw Normal View History

2025-05-09 08:40:07 +08:00
import sqlite3
import tkinter as tk
from tkinter import ttk
import os
import json
class TeamSwitchPacketGenerator:
def __init__(self):
# 检查数据库文件是否存在
db_file = 'aola.sqlite'
if not os.path.exists(db_file):
raise FileNotFoundError(f"数据库文件 {db_file} 未找到,请确保文件在 {os.getcwd()} 目录下!")
print(f"数据库文件路径: {os.path.abspath(db_file)}")
self.conn = sqlite3.connect(db_file)
self.cursor = self.conn.cursor()
self.root = tk.Tk()
self.root.title("阵容切换封包生成器")
2025-05-09 10:53:51 +08:00
# 获取所有阵容名称和 spell_code
2025-05-09 13:29:51 +08:00
self.team_data = self.get_team_data()
self.team_names = [item[0] for item in self.team_data]
self.last_filtered_teams = self.team_names
2025-05-09 10:53:51 +08:00
# 创建可搜索的下拉框
2025-05-09 13:29:51 +08:00
tk.Label(self.root, text="选择或搜索阵容(输入拼音缩写):").pack(anchor=tk.W, padx=5)
self.team_var = tk.StringVar(value="请选择阵容")
2025-05-09 08:40:07 +08:00
self.team_dropdown = ttk.Combobox(self.root, textvariable=self.team_var)
2025-05-09 10:53:51 +08:00
self.team_dropdown['values'] = self.team_names
2025-05-09 08:40:07 +08:00
self.team_dropdown.pack(pady=10)
2025-05-09 13:29:51 +08:00
# 防抖定时器和状态
self.debounce_timer = None
self.debounce_delay = 150
self.last_search_text = ""
self.has_typed = False
self.is_dropdown_open = False # 跟踪下拉框状态
# 绑定事件
self.team_dropdown.bind('<KeyRelease>', self.schedule_update_combobox)
self.team_dropdown.bind('<FocusIn>', self.clear_default_text)
self.team_dropdown.bind('<FocusOut>', self.close_dropdown)
self.team_dropdown.bind('<<ComboboxSelected>>', self.on_combobox_select)
# 获取 Combobox 的内部 Entry 控件
self.entry = self.team_dropdown # ttk.Combobox 本身支持 Entry 方法
# 绑定下拉框展开/收起事件
self.team_dropdown.bind('<Button-1>', self.toggle_dropdown_state)
2025-05-09 08:40:07 +08:00
# 创建按钮框架,包含“刷新”和“生成封包”按钮
button_frame = tk.Frame(self.root)
button_frame.pack(pady=5)
2025-05-11 09:22:33 +08:00
tk.Button(button_frame, text="Set1", command=self.set_1).pack(side=tk.LEFT, padx=5)
2025-05-09 08:40:07 +08:00
tk.Button(button_frame, text="刷新", command=self.refresh_dropdown).pack(side=tk.LEFT, padx=5)
tk.Button(button_frame, text="生成封包(第一次生成请先解锁二级密码)", command=self.generate_packets).pack(side=tk.LEFT, padx=5)
2025-05-09 13:29:51 +08:00
# 创建封包输出和复制按钮框架
2025-05-09 08:40:07 +08:00
output_frame = tk.Frame(self.root)
output_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
tk.Label(output_frame, text="封包输出:").pack(anchor=tk.W)
self.output_text = tk.Text(output_frame, height=15, width=60)
self.output_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
tk.Button(output_frame, text="复制脚本", command=self.copy_output).pack(side=tk.RIGHT, padx=5)
# 信息提示框
tk.Label(self.root, text="提示信息:").pack(anchor=tk.W)
self.info_text = tk.Text(self.root, height=5, width=80, fg="red")
self.info_text.pack(pady=5)
2025-05-11 09:22:33 +08:00
def set_1(self):
try:
self.cursor.execute("UPDATE aolaer_id SET is_set = 1")
self.conn.commit()
self.info_text.insert(tk.END, f"set1 ok\n")
return
except sqlite3.Error:
self.info_text.insert(tk.END, f"set1失败\n")
return
2025-05-09 10:53:51 +08:00
def get_team_data(self):
2025-05-09 08:40:07 +08:00
try:
2025-05-09 10:53:51 +08:00
self.cursor.execute("SELECT team_name, spell_code FROM aolaer_team ORDER BY team_name")
2025-05-09 13:29:51 +08:00
return [(row[0], row[1] or "") for row in self.cursor.fetchall()]
2025-05-09 08:40:07 +08:00
except sqlite3.Error as e:
2025-05-09 10:53:51 +08:00
self.info_text.insert(tk.END, f"获取阵容数据失败: {e}\n")
2025-05-09 08:40:07 +08:00
return []
2025-05-09 13:29:51 +08:00
def clear_default_text(self, event):
if self.team_var.get() == "请选择阵容":
self.team_var.set("")
self.has_typed = True
self.entry.focus_set()
self.entry.icursor(tk.END)
def schedule_update_combobox(self, event):
if event.keysym in ('Shift', 'Control', 'Alt', 'Return', 'Tab', 'Left', 'Right', 'Up', 'Down'):
return
self.has_typed = True
if self.debounce_timer is not None:
self.root.after_cancel(self.debounce_timer)
self.debounce_timer = self.root.after(self.debounce_delay, self.update_combobox)
def toggle_dropdown_state(self, event):
"""跟踪下拉框的展开/收起状态"""
# 简单假设点击切换状态(实际可能需要更复杂的状态检测)
self.is_dropdown_open = not self.is_dropdown_open
def update_combobox(self):
"""优化后的更新下拉框逻辑"""
search_text = self.team_var.get().strip().lower()
if search_text == self.last_search_text:
return
self.last_search_text = search_text
if not search_text or search_text == "请选择阵容":
filtered_teams = self.team_names
2025-05-09 10:53:51 +08:00
else:
filtered_teams = [
team_name for team_name, spell_code in self.team_data
if spell_code and search_text in spell_code.lower()
]
2025-05-09 13:29:51 +08:00
if not filtered_teams:
filtered_teams = ["无匹配阵容"]
# 更新下拉框选项
if filtered_teams != self.last_filtered_teams:
2025-05-09 10:53:51 +08:00
self.team_dropdown['values'] = filtered_teams
2025-05-09 13:29:51 +08:00
self.last_filtered_teams = filtered_teams
# 打开下拉框(仅在有输入且未打开时)
if self.has_typed and search_text and not self.is_dropdown_open:
self.team_dropdown.event_generate('<Down>')
self.is_dropdown_open = True
# 延迟设置焦点和光标位置
def set_focus_and_cursor():
self.entry.focus_set()
self.entry.icursor(tk.END)
# 调试日志
self.info_text.insert(tk.END, f"焦点设置: {self.root.focus_get() == self.entry}\n")
self.root.after(10, set_focus_and_cursor)
def close_dropdown(self, event):
self.has_typed = False
if self.is_dropdown_open:
self.team_dropdown.event_generate('<Up>')
self.is_dropdown_open = False
def on_combobox_select(self, event):
self.has_typed = False
self.is_dropdown_open = False
self.entry.focus_set()
self.entry.icursor(tk.END)
2025-05-09 10:53:51 +08:00
2025-05-09 08:40:07 +08:00
def refresh_dropdown(self):
2025-05-09 10:53:51 +08:00
self.team_data = self.get_team_data()
self.team_names = [item[0] for item in self.team_data]
self.team_dropdown['values'] = self.team_names
2025-05-09 13:29:51 +08:00
self.last_filtered_teams = self.team_names
self.team_var.set("请选择阵容")
self.last_search_text = ""
self.has_typed = False
self.is_dropdown_open = False
2025-05-09 08:40:07 +08:00
self.info_text.insert(tk.END, "下拉框数据已刷新!\n")
def copy_output(self):
content = self.output_text.get(1.0, tk.END).strip()
if content:
self.root.clipboard_clear()
self.root.clipboard_append(content)
self.info_text.insert(tk.END, "脚本内容已复制到剪贴板!\n")
else:
self.info_text.insert(tk.END, "脚本输出框为空,无法复制!\n")
def validate_ids(self, ids_str):
try:
ids = json.loads(ids_str)
if not isinstance(ids, list) or len(ids) != 5:
return False, "ids 必须是长度为 5 的数组"
for x in ids:
if not isinstance(x, int) or x < 0:
return False, "ids 中的值必须是非负整数"
return True, ids
except json.JSONDecodeError:
return False, "ids 格式不正确"
def generate_packets(self):
self.output_text.delete(1.0, tk.END)
self.info_text.delete(1.0, tk.END)
packets = []
selected_team = self.team_var.get()
2025-05-09 10:53:51 +08:00
if not selected_team or selected_team in ["请选择阵容", "无匹配阵容"]:
self.info_text.insert(tk.END, "请先选择一个有效阵容!\n")
2025-05-09 08:40:07 +08:00
return
try:
self.cursor.execute("SELECT team_code, team_set FROM aolaer_team WHERE team_name = ?", (selected_team,))
result = self.cursor.fetchone()
if not result:
self.info_text.insert(tk.END, f"未找到阵容 {selected_team} 的 team_code\n")
return
team_code, team_set = result
packets.append(f'|#send={{"id":13,"param":{{"pms":"{team_code}"}},"cmd":"1222"}}|')
self.cursor.execute("SELECT id FROM aolaer_id WHERE is_set = 1")
set_ids = [row[0] for row in self.cursor.fetchall()]
for set_id in set_ids:
packets.append(
2025-05-09 13:29:51 +08:00
f'|#send={{"id":42,"param":{{"bk":1,"petId":{set_id},"ids":[0,0,0,0,0]}},"cmd":"ASC221104_2"}}|#time=10|')
2025-05-09 08:40:07 +08:00
self.cursor.execute("UPDATE aolaer_id SET is_set = 0 WHERE id = ?", (set_id,))
self.conn.commit()
team_ids = team_code.split('#')
team_ids = [id for id in team_ids if id]
team_set_codes = None
if team_set:
team_set_codes = team_set.split('#')
if len(team_set_codes) != len(team_ids):
self.info_text.insert(tk.END,
f"警告team_set 的长度 ({len(team_set_codes)}) 与 team_code 的 ID 数量 ({len(team_ids)}) 不匹配!\n")
return
self.cursor.execute(
"SELECT id, div_weapon, aolaer_typecode FROM aolaer_id WHERE id IN ({})".format(
','.join('?' for _ in team_ids)
),
team_ids
)
id_to_typecode = {row[0]: row for row in self.cursor.fetchall()}
sub_pet_packets = []
soul_art_packets = []
soul_card_packets = []
for idx, id in enumerate(team_ids):
id = int(id)
if id not in id_to_typecode:
self.info_text.insert(tk.END, f"警告ID {id} 在 aolaer_id 表中不存在!\n")
continue
div_weapon = id_to_typecode[id][1]
typecode = id_to_typecode[id][2]
if team_set_codes and team_set_codes[idx] != '0':
typecode = team_set_codes[idx]
2025-05-09 10:53:51 +08:00
if div_weapon and str(div_weapon).strip():
2025-05-09 08:40:07 +08:00
sub_pet_packets.append(
2025-05-09 14:19:43 +08:00
f'|#send={{"id":42,"param":{{"subPetId":{id},"petId":{div_weapon}}},"cmd":"ASBS230623_con"}}|#time=10|')
2025-05-09 08:40:07 +08:00
else:
2025-05-09 10:53:51 +08:00
self.info_text.insert(tk.END, f"提示ID {id} 的 div_weapon 为空,跳过生成子宠物封包!\n")
2025-05-09 08:40:07 +08:00
self.cursor.execute("SELECT soul_art, soul_card FROM aolaer_type WHERE aolaer_typecode = ?",
(typecode,))
result = self.cursor.fetchone()
if not result:
self.info_text.insert(tk.END, f"警告typecode {typecode} 在 aolaer_type 表中不存在!\n")
continue
soul_art, soul_card = result
if soul_art and soul_art.strip():
try:
sid1, sid2 = soul_art.split(',')
soul_art_packets.append(
2025-05-09 14:19:43 +08:00
f'|#send={{"id":42,"param":{{"ui":{sid1},"petId":{id}}},"cmd":"ATT231229_1"}}|#time=10|')
2025-05-09 08:40:07 +08:00
soul_art_packets.append(
2025-05-09 14:19:43 +08:00
f'|#send={{"id":42,"param":{{"ui":{sid2},"petId":{id}}},"cmd":"ATT231229_1"}}|#time=10|')
2025-05-09 08:40:07 +08:00
except ValueError:
self.info_text.insert(tk.END, f"错误soul_art 格式不正确 for typecode {typecode}\n")
continue
else:
self.info_text.insert(tk.END,
2025-05-09 10:53:51 +08:00
f"提示typecode {typecode} 的 soul_art 为空,跳过生成魂艺封包!\n")
2025-05-09 08:40:07 +08:00
if soul_card and soul_card.strip():
is_valid, ids_or_error = self.validate_ids(soul_card)
if is_valid:
soul_card_packets.append(
2025-05-09 13:29:51 +08:00
f'|#send={{"id":42,"param":{{"bk":1,"petId":{id},"ids":{soul_card}}},"cmd":"ASC221104_2"}}|#time=10|')
2025-05-09 08:40:07 +08:00
self.cursor.execute("UPDATE aolaer_id SET is_set = 1 WHERE id = ?", (id,))
self.conn.commit()
else:
self.info_text.insert(tk.END,
f"警告typecode {typecode} 的 soul_card {soul_card} 无效({ids_or_error}),已跳过处理!\n")
else:
self.info_text.insert(tk.END, f"提示typecode {typecode} 的 soul_card 为空,已跳过处理!\n")
packets.extend(sub_pet_packets)
packets.extend(soul_art_packets)
packets.extend(soul_card_packets)
if packets:
self.output_text.insert(tk.END, '\n'.join(packets))
else:
self.info_text.insert(tk.END, "未生成任何封包,请检查数据!\n")
except sqlite3.Error as e:
self.info_text.insert(tk.END, f"数据库操作失败: {e}\n")
def run(self):
self.root.mainloop()
def __del__(self):
self.conn.close()
if __name__ == "__main__":
app = TeamSwitchPacketGenerator()
app.run()