csx 发表于 2024-1-19 23:32

分享】女朋友被杀戮尖塔气哭了?我只好写个修改器了

本帖最后由 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]
查看完整版本: 分享】女朋友被杀戮尖塔气哭了?我只好写个修改器了