分享】女朋友被杀戮尖塔气哭了?我只好写个修改器了
本帖最后由 csx 于 2024-1-19 23:33 编辑简介
[*]语言 : python
[*]游戏 : 蒸汽- 杀戮尖塔
女朋友说杀戮尖塔她就没打通过, 太难了, 商店的东西也买不起, 牌组还总是凑不齐就寄了, 非常生气, 于是我写了一款修改器帮她爽一下修改器
[*]因为我比较懒, 没有去创建ui
[*]使用方法:
[*]关键文件列表 [ 游戏自己的autosave文档, 游戏的卡组json文件, 游戏的遗物json文件]
[*]autosave通常在\SlayTheSpire\saves\*.autosave 这个路径里面
[*]所有卡组和遗物的json在\SlayTheSpire\desktop-1.0.jar 可以得到
[*]有需要成品,后面再发吧
使用方法
[*]运行程序后, 选择对应的.autosave 游戏存档载入程序
[*]根据弹出的功能列表输入功能ID
[*]修改后请执行保存
[*]进游戏实现效果
代码:# _*_encoding:UTF-8_*_
# .autosave 是保存的文件
from tkinter.filedialog import askopenfilename
from base64 import b64decode, b64encode
from time import sleep
import json
from ast import literal_eval
'''
--功能列表 :
1. 修改血量上限 1
2. 查看当前血量上限 1
3. 修改能量点上限1
4. 查看当前已有卡组及其说明1
6. 添加卡组1
7. 查看当前遗物 1
9. 增加指定遗物1
10. 获取所有遗物 1
11. 查看当前金币 1
12. 修改金币 1
13. 修改手牌上限 1
14. 一键清空所有卡组1
15. 一键清空所有遗物1
16. 保存存档1
16. 导入常用的流派, 并保存 None
17. 支持调用流派 None
5. 删除卡组 1
8. 删除指定遗物 1
'''
class SlayAid:
"""
杀戮尖塔辅助器
"""
def __init__(self) -> None:
# 玩家存档
self.user_card_data = None
# 游戏卡组
self.original_cards = None
# 游戏遗物
self.original_relics = None
# autosave_path 自动存档的路径
self.autosave_path = None
# menu
self.menu_list = {
0: ['展示基础信息', self.show_player_status],
1: ['修改血量上限', self.modify_blood],
2: ['修改能量点上限', self.modify_red],
3: ['修改金币', self.modify_gold],
4: ['修改手牌上限', self.modify_hand_size],
5: ['加牌', self.add_one_card],
6: ['删除指定牌', self.del_one_card],
7: ['加遗物', self.add_one_relic],
8: ['删除一个遗物:', self.del_one_relic],
9: ['一键清空遗物', self.clear_all_relics],
10: ['一键清空牌组', self.clear_all_crads],
66: ['保存修改到存档', self.save_to_game],
88: ['退出程序', self.stop]
}
def select_storage_file(self):
storage_file_path = askopenfilename(title="请选择autosave文件", filetypes=[('游戏存档', '.autosave')])
if not storage_file_path:
print(f"用户未选择任何文件, 3s后程序自动退出...")
sleep(3)
exit()
else:
print(f"文件载入中,{storage_file_path}")
self.autosave_path = storage_file_path
with open(storage_file_path, mode="rb") as f:
data = f.read()
# 解密文件会return一个json
self.decode_encryption(data=data)
# 解密存档
def decode_encryption(self, data):
# 定义密钥
key = "key"
# Base64解码
data = b64decode(data)
# 解密数据
result = ''.join(chr(byte ^ ord(key)) for index, byte in enumerate(data))
# 解析JSON
json_result = json.loads(result)
# 存储原始存档信息到实例属性
self.user_card_data = json_result
# 获取当前手牌
def get_cards(self):
try:
with open('cards.json', 'r', encoding='utf-8') as f:
original_data = json.load(f)
self.original_cards = original_data
except Exception as e:
print(f"文件原始卡组信息导入失败, 错误信息:{e}")
else:
card_data = self.user_card_data['cards']
# 把原始数据original_data映射到user_card_data
card_data_cn = [
{**item, 'misc': original_data]['DESCRIPTION'], 'id': original_data]['NAME']} for
item in card_data]
return card_data_cn
# 获取当前遗物
def get_relics(self):
try:
with open('./relics.json', mode='r', encoding='utf-8') as f:
original_relic = json.load(f)
self.original_relics = original_relic
except Exception as e:
print(f"遗物原始卡组导入失败! 错误信息:{e}")
else:
tran_relic = self.user_card_data['relics']
# 原始relics遗物映射到user_card_data
tran_relic_name_cn = [{original_relic['NAME']: original_relic['DESCRIPTIONS']} for key in
tran_relic if key in original_relic]
return tran_relic_name_cn
# 展示玩家存档信息
def show_player_status(self):
# 调用实例方法
current_cards_cn = self.get_cards()
current_relic_cn = self.get_relics()
# 展示当前血量上限
print(f"玩家血量上限:{self.user_card_data['max_health']}")
# 展示玩家手牌上限
print(f"玩家当前手牌上限:{self.user_card_data['hand_size']}")
# 展示当前金币数
print(f"玩家金币:{self.user_card_data['gold']} 元")
# 展示玩家遗物组
print(f"玩家当前遗物:{current_relic_cn}")
# 展示玩家当前牌组
print(f"玩家当前牌组:{current_cards_cn}")
# 修改血量
def modify_blood(self):
"""
修改血量上限
"""
wanna_blood = input("输入你需要修改到的血量上限(int):")
try:
wanna_blood_num = int(wanna_blood)
if wanna_blood_num > 0:
print("验证数字成功, 修改存档...")
# change max_blood
self.user_card_data['max_health'] = wanna_blood_num
else:
print("请校验你的输入是否为正整数!!!")
except Exception as e:
print(f"血量上限修改异常,错误信息{e}")
# 修改手牌上限
def modify_hand_size(self):
"""
修改手牌上限
"""
wanna_size = input("输入你需要修改到的手牌上限(int):")
try:
wanna_size_num = int(wanna_size)
if wanna_size_num >= 5:
print("验证数字成功, 修改存档...")
# change max_blood
self.user_card_data['hand_size'] = wanna_size_num
else:
print("请校验你的输入是否为正整数,不少于5!!!")
except Exception as e:
print(f"修改手牌上限异常,错误信息{e}")
# 修改能量点上限
def modify_red(self):
"""
修改能量点上限
"""
wanna_red = input("输入你需要修改到的能量点上限(int):")
try:
wanna_red_num = int(wanna_red)
if wanna_red_num >= 3:
print("验证数字成功, 修改存档...")
# change max_blood
self.user_card_data['red'] = wanna_red_num
else:
print("请校验你的输入是否为正整数,不少于3!!!")
except Exception as e:
print(f"能量点输入异常,错误信息:{e}")
# 修改金币
def modify_gold(self):
"""
修改金币
"""
wanna_gold = input("输入你需要修改的金币数:(int):")
try:
wanna_gold_num = int(wanna_gold)
if wanna_gold_num >= 0:
print("验证数字成功, 修改存档...")
# change max_blood
self.user_card_data['gold'] = wanna_gold_num
else:
print("请校验你的输入是否为正整数!!!")
except Exception as e:
print(f"修改金币失败,错误信息:{e}")
# 一键清空牌组
def clear_all_crads(self):
self.user_card_data["cards"] = []# 清空卡组列表
# 一键清空遗物
def clear_all_relics(self):
self.user_card_data["relics"] = []# 清空遗物列表
# 添加指定卡片
def add_one_card(self):
wanna_card = input("输入你需要的卡片('中文名',等级=0或1,张数>=1):")
try:
# 第一步把输入的内容转换为元组
wanna_card_tuple = literal_eval(wanna_card)
if isinstance(wanna_card_tuple, tuple):
if isinstance(wanna_card_tuple, str) and isinstance(wanna_card_tuple, int) and 0 <= \
wanna_card_tuple <= 1 and wanna_card_tuple >= 1:
for key, sub_dict in self.original_cards.items():
if sub_dict.get('NAME') == wanna_card_tuple:
print(f"您需要添加的卡组{key}")
_ = 0
card_template = {
'upgrades': wanna_card_tuple,
'misc': 0,
'id': key
}
while _ < wanna_card_tuple:
self.user_card_data['cards'].append(card_template)
_ += 1
break
else:
print("你输入的卡组也许不存在,请检查")
else:
print(f"{wanna_card}卡片非中文字符串,或卡片等级不合理...")
else:
print("请输入元组,例如('壁垒',1)")
except Exception as e:
print(f"输入异常,请输入元组格式,错误信息:{e}")
# 添加指定遗物
def add_one_relic(self):
wanna_relic = input("请输入你需要的遗物:")
for key, sub_set in self.original_relics.items():
if sub_set.get('NAME') == wanna_relic:
# 添加到遗物列表
self.user_card_data['relics'].append(key)
break
else:
print("你输入的遗物不存在,请检查")
# 删除指定卡片
def del_one_card(self):
wanna_del_card = input('请输入你需要删除的卡名称("中文名",张数):')
wanna_del_card_tuple = literal_eval(wanna_del_card)
if isinstance(wanna_del_card_tuple, tuple):
if isinstance(wanna_del_card_tuple, str) and isinstance(wanna_del_card_tuple, int):
for key, sub_dict in self.original_cards.items():
if sub_dict.get("NAME") == wanna_del_card_tuple:
print(f"你需要删除的卡片:{key}")
_ = 0
while _ < wanna_del_card_tuple:
for i, d in enumerate(self.user_card_data['cards']):
if d.get('id') == key:
del self.user_card_data['cards']
break
_ += 1
print("删除完毕")
else:
print("未能找到你需要删除的卡片,请检查卡片名称是否存在于卡组中...")
else:
print("用户输入不合理,请输入元组形式(卡片名,张),例如('打击',3)")
else:
print("用户输入非元组格式,请检查,例如('打击',3)")
# 删除指定遗物
def del_one_relic(self):
del_relic = input("请输入你想删除的遗物:")
for key, sub_set in self.original_relics.items():
if sub_set.get('NAME') == del_relic:
self.user_card_data['relics'] = if _ != del_relic]
print("删除成功...")
break
else:
print("你输入的遗物不存在,请检查")
# 重新加密
def encode_save_file(self):
encrytion_data = json.dumps(self.user_card_data)
result = ""
key = "key"
for index, i in enumerate(encrytion_data.encode()):
result += chr(i ^ ord(key))
result = b64encode(result.encode()).decode()
return result
# 保存存档
def save_to_game(self):
if self.user_card_data is not None:
try:
result = self.encode_save_file()
with open(self.autosave_path, 'w') as f:
f.write(result)
print("保存成功...")
except Exception as e:
print(f"用户自定义数据异常,覆写游戏存档失败:{e}")
else:
print("用户自定义为空,不主张覆写游戏存档")
# show_menu
def show_menu(self):
print("_" * 30)
print("〖Welcome〗v0.0.1杀戮尖塔修改器")
self.show_player_status()
print("_" * 30)
for k, v in self.menu_list.items():
print(f"{k}:{v}")
print("*" * 30)
user_func_select = input("你好,请输入功能id:")
try:
user_funcn = int(user_func_select)
if user_funcn in self.menu_list:
fun = self.menu_list.get(user_funcn)
return fun()# 这里不用加self
except Exception as e:
print(f"输入错误或功能暂未开发,错误信息{e}")
# get_start
def start(self):
while True:
self.show_menu()
sleep(3)
# 退出程序
@staticmethod
def stop():
check_save = input("如果你已经修改某些参数,请先执行保存,是否继续退出(y/n)")
if check_save == 'y':
print("3s后自动退出本程序")
sleep(3)
exit()
if __name__ == "__main__":
slayaid = SlayAid()
slayaid.select_storage_file()
slayaid.start()
页:
[1]