脚本作者:大锤八十,小锤四十
import os
import re
import sys
from collections import OrderedDict, defaultdict
def load_script_global(script_global_path):
"""加载ScriptGlobal.lua文件,返回变量到数字的映射字典"""
var_mapping = {}
if not os.path.exists(script_global_path):
print(f"警告: ScriptGlobal.lua文件不存在于路径 {script_global_path}")
return var_mapping
# 尝试不同编码读取文件
encodings = ['utf-8', 'gbk', 'latin-1']
content = None
for encoding in encodings:
try:
with open(script_global_path, 'r', encoding=encoding) as f:
content = f.read()
break
except UnicodeDecodeError:
continue
if content is None:
print(f"错误: 无法解码ScriptGlobal.lua文件")
return var_mapping
# 匹配类似 MD_PETSOULSKILL = 458 --兽魂技能数据 这样的定义
pattern = r'(\w+)\s*=\s*(\d+)\s*(--.*)?'
matches = re.findall(pattern, content)
for match in matches:
var_name = match[0]
var_value = match[1]
var_mapping[var_name] = var_value
return var_mapping
def search_mission_data(folder_path, script_global_path):
# 加载变量映射表
var_mapping = load_script_global(script_global_path)
# 定义正则表达式模式
patterns = [
# 匹配GetMissionData(参数1, 参数2, 参数3)并捕获第三个参数
r'GetMissionData\s*\(\s*[^,]+?\s*,\s*[^,]+?\s*,\s*([^,]+?)\s*\)',
# 匹配SetMissionData(参数1, 参数2, 参数3, 参数4)并捕获第三个参数
r'SetMissionData\s*\(\s*[^,]+?\s*,\s*[^,]+?\s*,\s*([^,]+?)\s*,\s*[^,]+?\s*\)'
]
# 用于存储所有找到的变量信息(包含数值、变量名、位置信息)
results_list = []
# 遍历文件夹中的所有文件
for root, dirs, files in os.walk(folder_path):
for file in files:
# 只处理.lua文件
if not file.endswith('.lua'):
continue
file_path = os.path.join(root, file)
# 尝试读取文件内容
try:
with open(file_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
# 检查每一行是否匹配模式
for line_num, line in enumerate(lines, 1):
stripped_line = line.strip()
if not stripped_line:
continue
for pattern in patterns:
match = re.fullmatch(pattern, stripped_line)
if match:
# 获取第三个参数并去除可能的空格
third_param = match.group(1).strip()
# 判断参数是否为数字
if third_param.isdigit():
param_value = int(third_param)
var_name = None
result_text = f"变量:{param_value}"
else:
# 在映射表中查找变量对应的数字
if third_param in var_mapping:
param_value = int(var_mapping[third_param])
var_name = third_param
result_text = f"变量:{third_param} = {param_value}"
else:
# 未找到对应值的变量不加入排序列表
param_value = None
var_name = third_param
result_text = f"变量:{third_param}(未在ScriptGlobal.lua中找到对应值)"
# 显示当前找到的结果
print(f"文件位置: {file_path} (行号: {line_num})")
print(f"内容: {stripped_line}")
print(f"{result_text}")
print("-" * 50)
# 只将有数值的结果加入排序列表
if param_value is not None:
results_list.append({
'value': param_value,
'var_name': var_name,
'file_path': file_path,
'line_num': line_num,
'content': stripped_line
})
break
except UnicodeDecodeError:
# 尝试其他编码读取Lua文件
try:
with open(file_path, 'r', encoding='gbk') as f:
lines = f.readlines()
# 这里重复检查逻辑
for line_num, line in enumerate(lines, 1):
stripped_line = line.strip()
if not stripped_line:
continue
for pattern in patterns:
match = re.fullmatch(pattern, stripped_line)
if match:
third_param = match.group(1).strip()
if third_param.isdigit():
param_value = int(third_param)
var_name = None
result_text = f"变量:{param_value}"
else:
if third_param in var_mapping:
param_value = int(var_mapping[third_param])
var_name = third_param
result_text = f"变量:{third_param} = {param_value}"
else:
param_value = None
var_name = third_param
result_text = f"变量:{third_param}(未在ScriptGlobal.lua中找到对应值)"
print(f"文件位置: {file_path} (行号: {line_num})")
print(f"内容: {stripped_line}")
print(f"{result_text}")
print("-" * 50)
if param_value is not None:
results_list.append({
'value': param_value,
'var_name': var_name,
'file_path': file_path,
'line_num': line_num,
'content': stripped_line
})
break
except:
continue
except Exception as e:
print(f"读取文件 {file_path} 时出错: {str(e)}")
# 按数值大小排序结果列表(从小到大)
results_list.sort(key=lambda x: x['value'])
# 输出排序后的结果
print("\n" + "=" * 50)
print("按数字大小排序后的结果:")
print("=" * 50)
# 创建有序结果字典并去重(key+value相同的只保留第一个)
result_dict = OrderedDict()
seen_pairs = set()
seen_values = set() # 用于跟踪已出现的数值
# 用于跟踪value对应的非数字key
value_to_non_numeric_keys = defaultdict(list)
for item in results_list:
current_key = item['var_name'] if item['var_name'] else str(item['value'])
current_value = item['value']
pair = (current_key, current_value)
if pair not in seen_pairs:
seen_pairs.add(pair)
seen_values.add(current_value)
result_dict[current_key] = current_value
# 记录非数字key对应的value
if item['var_name'] is not None: # 说明key是变量名而非数字
value_to_non_numeric_keys[current_value].append(current_key)
if item['var_name']:
print(f"变量:{item['var_name']} = {item['value']}")
else:
print(f"变量:{item['value']}")
print(f"位置: {item['file_path']} (行号: {item['line_num']})")
print(f"内容: {item['content']}")
print("-" * 50)
# 找出value重复出现但key不是数字的重复项
duplicate_value_items = {}
for value, keys in value_to_non_numeric_keys.items():
if len(keys) > 1: # 同一个value对应多个非数字key
duplicate_value_items[value] = keys
# 找出0到512之间未出现的数字
missing_numbers = []
for num in range(0, 513): # 包含0和512
if num not in seen_values:
missing_numbers.append(num)
# 输出去重后的有序结果字典
print("\n" + "=" * 50)
print("去重后按数字大小排序的结果字典:")
print("=" * 50)
for key, value in result_dict.items():
print(f"'{key}': {value}")
print("\n字典原始形式:")
print(dict(result_dict))
# 输出value重复但key不是数字的重复项
print("\n" + "=" * 50)
if duplicate_value_items:
print(f"value重复出现但key不是数字的项(共{len(duplicate_value_items)}组):")
print("=" * 50)
for value, keys in duplicate_value_items.items():
print(f"数值 {value} 对应多个变量名: {', '.join(keys)}")
else:
print("没有发现value重复出现但key不是数字的项")
print("=" * 50)
# 输出未出现的数字
print("\n" + "=" * 50)
print(f"0到512之间未出现的数字(共{len(missing_numbers)}个):")
print("=" * 50)
# 按每10个数字一行显示,方便查看
for i in range(0, len(missing_numbers), 10):
print(missing_numbers[i:i + 10])
return results_list, result_dict, missing_numbers, duplicate_value_items
if __name__ == "__main__":
# 直接指定文件夹路径
base_folder = r"C:\Users\W9246\Desktop\fsdownload\tlbb创世\Public\Data\Script"
# ScriptGlobal.lua的路径
script_global_path = os.path.join(base_folder, "ScriptGlobal.lua")
if not os.path.isdir(base_folder):
print(f"错误: {base_folder} 不是一个有效的文件夹路径")
sys.exit(1)
print(f"开始搜索文件夹: {base_folder}")
print(f"使用的ScriptGlobal.lua路径: {script_global_path}")
print("=" * 50)
search_mission_data(base_folder, script_global_path)
print("搜索完成")