From 841b3e0d4e48e0379cb486fd4761da64463dcd22 Mon Sep 17 00:00:00 2001 From: Nya_Twisuki <100500860+Twisuki@users.noreply.github.com> Date: Wed, 1 Jan 2025 12:41:38 +0800 Subject: [PATCH] =?UTF-8?q?petcat=E6=8F=92=E4=BB=B6token=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E9=83=A8=E5=88=86=20(#32)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 新增了萌百插件(meowiki) * 更新萌百搜索 * 删除萌百插件, 结束开发 * 新建MegaKits插件 * 修复 * 摩尔斯电码加密/解码 * 猫语转换/翻译 * 新增了养猫插件 * 数据加密解码处理完成 * 汉明码加密解码处理完成 * 进制转换 * 112位Bit数据解密 * 总解码完成 * 格式微调 * # 112位Bit数据编码 * 总编码完成 * 养猫插件上传 * 新的数据存储方式 * 进制转换 * bool byte转换 * Token解码 * Token编码 * 删除测试语句 * 测试句 * 修复二进制位错乱问题, 删去调试语句 * 添加了try-except异常处理语句 * 将异常返回值规整为变量 * 删去了调试语句 * 重命名pc_code.py为pc_token.py --- .../plugins/twisuki_petcat/__init__.py | 13 ++ .../plugins/twisuki_petcat/pc_cat.py | 1 + .../plugins/twisuki_petcat/pc_shop.py | 1 + .../plugins/twisuki_petcat/pc_token.py | 193 ++++++++++++++++++ 4 files changed, 208 insertions(+) create mode 100644 nonebot_plugin_marshoai/plugins/twisuki_petcat/__init__.py create mode 100644 nonebot_plugin_marshoai/plugins/twisuki_petcat/pc_cat.py create mode 100644 nonebot_plugin_marshoai/plugins/twisuki_petcat/pc_shop.py create mode 100644 nonebot_plugin_marshoai/plugins/twisuki_petcat/pc_token.py diff --git a/nonebot_plugin_marshoai/plugins/twisuki_petcat/__init__.py b/nonebot_plugin_marshoai/plugins/twisuki_petcat/__init__.py new file mode 100644 index 00000000..02123ca2 --- /dev/null +++ b/nonebot_plugin_marshoai/plugins/twisuki_petcat/__init__.py @@ -0,0 +1,13 @@ +from nonebot_plugin_marshoai.plugin import ( + Integer, + Parameter, + PluginMetadata, + String, + on_function_call, +) + +__marsho_meta__ = PluginMetadata( + name="养猫插件", + description="在Marsho这里赛博养猫", + author="Twisuki", +) diff --git a/nonebot_plugin_marshoai/plugins/twisuki_petcat/pc_cat.py b/nonebot_plugin_marshoai/plugins/twisuki_petcat/pc_cat.py new file mode 100644 index 00000000..069efed9 --- /dev/null +++ b/nonebot_plugin_marshoai/plugins/twisuki_petcat/pc_cat.py @@ -0,0 +1 @@ +# 主交互 diff --git a/nonebot_plugin_marshoai/plugins/twisuki_petcat/pc_shop.py b/nonebot_plugin_marshoai/plugins/twisuki_petcat/pc_shop.py new file mode 100644 index 00000000..2ec9919f --- /dev/null +++ b/nonebot_plugin_marshoai/plugins/twisuki_petcat/pc_shop.py @@ -0,0 +1 @@ +# 商店 diff --git a/nonebot_plugin_marshoai/plugins/twisuki_petcat/pc_token.py b/nonebot_plugin_marshoai/plugins/twisuki_petcat/pc_token.py new file mode 100644 index 00000000..40ee1583 --- /dev/null +++ b/nonebot_plugin_marshoai/plugins/twisuki_petcat/pc_token.py @@ -0,0 +1,193 @@ +# 由于无法直接存储数据, 使用一个字符串记录全部信息 +# 这里作为引用进行编码/解码, 以及公用数据 + +"""猫对象属性存储编码Token +名字: 3位长度 + 8位ASCII字符 - 67b +年龄: 0 ~ 15 - 4b +种类: 8种 - 3b +生命值: 0 ~ 127 - 7b +饱食度: 0 ~ 127 - 7b +活力值: 0 ~ 127 - 7b +技能: 8种任选 - 8b +时间: 0 ~ 131017d > 2025-1-1 - 17b + +总计120b有效数据 +总计120b数据, 15字节, 每3字节(utf-8一个字符)转换为4个Base64字符 +总计20个Base64字符的字符串 +""" + +"""定义变量 +存储字符串: Token: str +对象数据: data: dict +名字: name: str +年龄: age: int +种类: type: int # 代表TYPE_LIST中的序号 +生命值: health: int # 0 - 127, 显示时转换为100% +饱食度: saturation: int # 0 - 127, 显示时转换为100% +活力值: energy: int # 0 - 127, 显示时转换为100% +技能: skill: List[bool] # 8元素bool数组 +时间: date: int # 到2025-1-1按日的时间戳 +""" + +import base64 +from datetime import datetime +from typing import List + +from nonebot.log import logger + +# 公用列表 +TYPE_LIST = ["猫1", "猫2", "猫3", "猫4", "猫5", "猫6", "猫7", "猫8"] +SKILL_LIST = ["s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8"] + +# 私用列表 +ERROR_DICT = { + "name": "ERROR!", + "age": 0, + "type": 0, + "health": 0, + "saturation": 0, + "energy": 0, + "skill": [False, False, False, False, False, False, False, False], + "date": 0, +} +ERROR_TOKEN = "yKpKSepEIAAAAAAAAAAA" + + +# bool数组/int数据转换 +def bool_to_int(bool_array: List[bool]) -> int: + result = 0 + for index, bit in enumerate(bool_array[::-1]): + if bit: + result |= 1 << index + return result + + +def int_to_bool(integer: int, length: int = 0) -> List[bool]: + bit_length = integer.bit_length() + bool_array = [False] * bit_length + for i in range(bit_length): + if integer & (1 << i): + bool_array[bit_length - 1 - i] = True + if len(bool_array) >= length: + return bool_array + else: + return [*([False] * (length - len(bool_array))), *bool_array] + + +# bool数组/byte数据转换 +def bool_to_byte(bool_array: List[bool]) -> bytes: + byte_data = bytearray() + for i in range(0, len(bool_array), 8): + byte = 0 + for j in range(8): + if i + j < len(bool_array) and bool_array[i + j]: + byte |= 1 << (7 - j) + byte_data.append(byte) + return bytes(byte_data) + + +def byte_to_bool(byte_data: bytes, length: int = 0) -> List[bool]: + bool_array = [] + for byte in byte_data: + for bit in format(byte, "08b"): + bool_array.append(bit == "1") + if len(bool_array) >= length: + return bool_array + else: + return [*([False] * (length - len(bool_array))), *bool_array] + + +# 数据解码 +def token_to_dict(token: str) -> dict: + data = { + "name": "Default0", + "age": 0, + "type": 0, + "health": 0, + "saturation": 0, + "energy": 0, + "skill": [False] * 8, + "date": 0, + } + + # 转换token + try: + token_byte = base64.b64decode(token.encode()) + code = byte_to_bool(token_byte) + except ValueError: + logger.error("token b64解码错误!") + return ERROR_DICT + + # 拆分code + name_length = bool_to_int(code[0:3]) + name_code = code[3:67] + age = bool_to_int(code[67:71]) + type = bool_to_int(code[71:74]) + health = bool_to_int(code[74:81]) + saturation = bool_to_int(code[81:88]) + energy = bool_to_int(code[88:95]) + skill = code[95:103] + date = bool_to_int(code[103:120]) + + # 解析code + name = "" + try: + for i in range(name_length): + character_code = bool_to_byte(name_code[8 * i : 8 * i + 8]) + name += character_code.decode("ASCII") + except UnicodeDecodeError: + logger.error("token ASCII解析错误!") + return ERROR_DICT + + data["name"] = name + data["age"] = age + data["type"] = type + data["health"] = health + data["saturation"] = saturation + data["energy"] = energy + data["skill"] = skill + data["date"] = date + + return data + + +# 数据编码 +def dict_to_token(data: dict) -> str: + code = [False] * 120 + + # 拆分data + name_length = len(data["name"]) + name = data["name"] + age = data["age"] + type = data["type"] + health = data["health"] + saturation = data["saturation"] + energy = data["energy"] + skill = data["skill"] + date = (datetime(2025, 1, 1) - datetime.now()).days + + # 填入code + code[0:3] = int_to_bool(name_length, 3) + name_code = [False] * 64 + try: + for i in range(name_length): + character_code = byte_to_bool(name[i].encode("ASCII"), 8) + name_code[8 * i : 8 * i + 8] = character_code + except UnicodeEncodeError: + # "name": "ERROR!" + logger.error("name内含有非法字符!") + return ERROR_TOKEN + + code[3:67] = name_code + code[67:71] = int_to_bool(age, 4) + code[71:74] = int_to_bool(type, 3) + code[74:81] = int_to_bool(health, 7) + code[81:88] = int_to_bool(saturation, 7) + code[88:95] = int_to_bool(energy, 7) + code[95:103] = skill + code[103:120] = int_to_bool(date, 17) + + # 转换token + token_byte = bool_to_byte(code) + token = base64.b64encode(token_byte).decode() + return token