mirror of
https://github.com/LiteyukiStudio/nonebot-plugin-marshoai.git
synced 2025-02-07 12:16:12 +08:00
* 新增了萌百插件(meowiki) * 更新萌百搜索 * 删除萌百插件, 结束开发 * 新建MegaKits插件 * 修复 * 摩尔斯电码加密/解码 * 猫语转换/翻译 * 新增了养猫插件 * 数据加密解码处理完成 * 汉明码加密解码处理完成 * 进制转换 * 112位Bit数据解密 * 总解码完成 * 格式微调 * # 112位Bit数据编码 * 总编码完成 * 养猫插件上传 * 新的数据存储方式 * 进制转换 * bool byte转换 * Token解码 * Token编码 * 删除测试语句 * 测试句 * 修复二进制位错乱问题, 删去调试语句 * 添加了try-except异常处理语句 * 将异常返回值规整为变量 * 删去了调试语句 * 重命名pc_code.py为pc_token.py * 修复了length超域问题 * 创建pc_info存储公用数据 * 打印列表 * 修复了加载问题 * 帮助文档 * 不知道更新啥了, commit一下 * 修改了提示词 * 修复了提示词问题 & 新增了token转换日志 & 添加了新的交互 * Log * 将 值/1.27 输出整合为函数 * 修复 * 修复 * 修复 * 修复 * 交互前状态更新, py函数装饰器 * 修改了date生成逻辑 * 修改了接下来的计划
201 lines
5.3 KiB
Python
201 lines
5.3 KiB
Python
# 由于无法直接存储数据, 使用一个字符串记录全部信息
|
|
# 这里作为引用进行编码/解码, 以及公用数据
|
|
|
|
"""猫对象属性存储编码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
|
|
|
|
# 私用列表
|
|
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:
|
|
logger.info(f"开始解码...\n{token}")
|
|
|
|
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]) + 1
|
|
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: str = ""
|
|
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
|
|
|
|
logger.success(f"解码完成, 数据为\n{data}")
|
|
return data
|
|
|
|
|
|
# 数据编码
|
|
def dict_to_token(data: dict) -> str:
|
|
logger.info(f"开始编码...\n{data}")
|
|
|
|
code = [False] * 120
|
|
|
|
# 拆分data
|
|
name_length = len(data["name"])
|
|
if name_length > 8:
|
|
logger.error("name过长")
|
|
return ERROR_TOKEN
|
|
|
|
name = data["name"]
|
|
age = data["age"]
|
|
type = data["type"]
|
|
health = data["health"]
|
|
saturation = data["saturation"]
|
|
energy = data["energy"]
|
|
skill = data["skill"]
|
|
date = data["date"]
|
|
|
|
# 填入code
|
|
code[0:3] = int_to_bool(name_length - 1, 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()
|
|
|
|
logger.success(f"编码完成, token为\n{token}")
|
|
return token
|