mirror of
http://shenjack.top:5100/shenjack/icalingua-python-bot.git
synced 2024-11-23 12:41:05 +08:00
namerena 加上 peek
This commit is contained in:
parent
ed6af04570
commit
3d338b8ba0
|
@ -1,6 +1,6 @@
|
|||
# Python 兼容版本 3.8+
|
||||
|
||||
from typing import Callable, Tuple, NewType, TYPE_CHECKING, TypeVar, Optional
|
||||
from typing import Callable, Tuple, NewType, TYPE_CHECKING, TypeVar, Optional, Union
|
||||
|
||||
"""
|
||||
ica.rs
|
||||
|
@ -270,6 +270,15 @@ class TailchatClient:
|
|||
"""向日志中输出警告信息"""
|
||||
|
||||
|
||||
class ReciveMessage(TailchatReciveMessage, IcaNewMessage):
|
||||
"""
|
||||
继承了两边的消息
|
||||
只是用来类型标记, 不能实例化
|
||||
"""
|
||||
def reply_with(self, message: str) -> Union["IcaReplyMessage", "TailchatSendingMessage"]: # type: ignore
|
||||
...
|
||||
|
||||
|
||||
class ConfigData:
|
||||
def __getitem__(self, key: str):
|
||||
...
|
||||
|
|
213
ica-rs/plugins/name_utils/__init__.py
Normal file
213
ica-rs/plugins/name_utils/__init__.py
Normal file
|
@ -0,0 +1,213 @@
|
|||
import io
|
||||
|
||||
sklname = [
|
||||
"火球术",
|
||||
"冰冻术",
|
||||
"雷击术",
|
||||
"地裂术",
|
||||
"吸血攻击",
|
||||
"投毒",
|
||||
"连击",
|
||||
"会心一击",
|
||||
"瘟疫",
|
||||
"生命之轮",
|
||||
"狂暴术",
|
||||
"魅惑",
|
||||
"加速术",
|
||||
"减速术",
|
||||
"诅咒",
|
||||
"治愈魔法",
|
||||
"苏生术",
|
||||
"净化",
|
||||
"铁壁",
|
||||
"蓄力",
|
||||
"聚气",
|
||||
"潜行",
|
||||
"血祭",
|
||||
"分身",
|
||||
"幻术",
|
||||
"防御",
|
||||
"守护",
|
||||
"伤害反弹",
|
||||
"护身符",
|
||||
"护盾",
|
||||
"反击",
|
||||
"吞噬",
|
||||
"召唤亡灵",
|
||||
"垂死抗争",
|
||||
"隐匿",
|
||||
"sklvoid1",
|
||||
"sklvoid2",
|
||||
"sklvoid3",
|
||||
"sklvoid4",
|
||||
"sklvoid5",
|
||||
]
|
||||
|
||||
prop_names = [
|
||||
"HP",
|
||||
"攻",
|
||||
"防",
|
||||
"速",
|
||||
"敏",
|
||||
"魔",
|
||||
"抗",
|
||||
"智",
|
||||
"八维",
|
||||
]
|
||||
|
||||
|
||||
class Player:
|
||||
def __init__(self) -> None:
|
||||
self.name = ""
|
||||
self.team = ""
|
||||
self.val = [i for i in range(0, 256)]
|
||||
self.name_base = [0] * 128
|
||||
self.name_str = [0] * 256
|
||||
self.team_str = [0] * 256
|
||||
self.name_len = 0
|
||||
self.team_len = 0
|
||||
self.name_prop = [0] * 8
|
||||
self.skl_id = [i for i in range(0, 40)]
|
||||
self.skl_freq = [0] * 40
|
||||
|
||||
def load(self, raw_name: str):
|
||||
if raw_name == "":
|
||||
print("错误:输入不能为空。")
|
||||
return False
|
||||
if raw_name.count("@") > 1:
|
||||
print("错误:无法分割名字与战队名,请检查输入。")
|
||||
return False
|
||||
name_lst = list(raw_name.rpartition("@"))
|
||||
if len(name_lst[0]) > 256 or len(name_lst[2]) > 256:
|
||||
print("错误:名字或战队名长度过大。")
|
||||
return False
|
||||
if name_lst[1] == "@":
|
||||
if name_lst[2] == "":
|
||||
name_lst[2] = name_lst[0]
|
||||
else:
|
||||
name_lst[0] = name_lst[2]
|
||||
name_bytes = name_lst[0].encode()
|
||||
team_bytes = name_lst[2].encode()
|
||||
self.name = name_lst[0]
|
||||
self.team = name_lst[2]
|
||||
self.name_len = len(name_lst[0])
|
||||
self.team_len = len(name_lst[2])
|
||||
for i in range(self.name_len):
|
||||
self.name_str[i + 1] = name_bytes[i]
|
||||
for i in range(self.team_len):
|
||||
self.team_str[i + 1] = team_bytes[i]
|
||||
self.name_len += 1
|
||||
self.team_len += 1
|
||||
|
||||
s = 0
|
||||
for i in range(256):
|
||||
s += self.team_str[i % self.team_len] + self.val[i]
|
||||
s %= 256
|
||||
self.val[i], self.val[s] = self.val[s], self.val[i]
|
||||
|
||||
for i in range(2):
|
||||
s = 0
|
||||
for j in range(256):
|
||||
s += self.name_str[j % self.name_len] + self.val[j]
|
||||
s %= 256
|
||||
self.val[j], self.val[s] = self.val[s], self.val[j]
|
||||
s = 0
|
||||
for i in range(256):
|
||||
m = ((self.val[i] * 181) + 160) % 256
|
||||
if m >= 89 and m < 217:
|
||||
self.name_base[s] = m & 63
|
||||
s += 1
|
||||
|
||||
propcnt = 0
|
||||
r = self.name_base[0:32]
|
||||
for i in range(10, 31, 3):
|
||||
r[i : i + 3] = sorted(r[i : i + 3])
|
||||
self.name_prop[propcnt] = r[i + 1]
|
||||
propcnt += 1
|
||||
r[0:10] = sorted(r[0:10])
|
||||
self.name_prop[propcnt] = 154
|
||||
propcnt += 1
|
||||
for i in range(3, 7):
|
||||
self.name_prop[propcnt - 1] += r[i]
|
||||
for i in range(7):
|
||||
self.name_prop[i] += 36
|
||||
|
||||
self.skl_id = list(range(0, 40))
|
||||
self.skl_freq = [0] * 40
|
||||
a = b = 0
|
||||
randbase = []
|
||||
randbase[:] = self.val[:]
|
||||
|
||||
def randgen():
|
||||
def m():
|
||||
nonlocal a, b, randbase
|
||||
a = (a + 1) % 256
|
||||
b = (b + randbase[a]) % 256
|
||||
randbase[a], randbase[b] = randbase[b], randbase[a]
|
||||
return randbase[(randbase[a] + randbase[b]) & 255]
|
||||
|
||||
return ((m() << 8) | m()) % 40
|
||||
|
||||
s = 0
|
||||
for i in range(2):
|
||||
for j in range(40):
|
||||
rand = randgen()
|
||||
s = (s + rand + self.skl_id[j]) % 40
|
||||
self.skl_id[j], self.skl_id[s] = self.skl_id[s], self.skl_id[j]
|
||||
last = -1
|
||||
j = 0
|
||||
for i in range(64, 128, 4):
|
||||
p = (
|
||||
min(
|
||||
self.name_base[i],
|
||||
self.name_base[i + 1],
|
||||
self.name_base[i + 2],
|
||||
self.name_base[i + 3],
|
||||
)
|
||||
% 256
|
||||
)
|
||||
if p > 10 and self.skl_id[j] < 35:
|
||||
self.skl_freq[j] = p - 10
|
||||
if self.skl_id[j] < 25:
|
||||
last = j
|
||||
j += 1
|
||||
if last != -1:
|
||||
self.skl_freq[last] *= 2
|
||||
if self.skl_freq[14] > 0 and last != 14:
|
||||
self.skl_freq[14] += min(
|
||||
self.name_base[60], self.name_base[61], self.skl_freq[14]
|
||||
)
|
||||
if self.skl_freq[15] > 0 and last != 15:
|
||||
self.skl_freq[15] += min(
|
||||
self.name_base[62], self.name_base[63], self.skl_freq[15]
|
||||
)
|
||||
return True
|
||||
|
||||
def display(self) -> str:
|
||||
cache = io.StringIO()
|
||||
cache.write(f"{self.name}@{self.team}|")
|
||||
full = sum(self.name_prop[0:7]) + round(self.name_prop[7] / 3)
|
||||
datas = [
|
||||
self.name_prop[7],
|
||||
*self.name_prop[0:7],
|
||||
full
|
||||
]
|
||||
cache.write(
|
||||
"|".join(
|
||||
[
|
||||
f"{prop_names[index]}:{value}"
|
||||
for index, value in enumerate(datas)
|
||||
]
|
||||
)
|
||||
)
|
||||
cache.write("\n")
|
||||
cache.write(
|
||||
"|".join(
|
||||
[
|
||||
f"{sklname[self.skl_id[index]]}:{self.skl_freq[index]}"
|
||||
for index, value in enumerate(self.skl_freq)
|
||||
if value > 0
|
||||
]
|
||||
)
|
||||
)
|
||||
return cache.getvalue()
|
|
@ -1,3 +1,5 @@
|
|||
import io
|
||||
import sys
|
||||
import time
|
||||
import traceback
|
||||
import subprocess
|
||||
|
@ -6,31 +8,67 @@ from pathlib import Path
|
|||
|
||||
from typing import TYPE_CHECKING, TypeVar
|
||||
|
||||
if str(Path(__file__).parent.absolute()) not in sys.path:
|
||||
sys.path.append(str(Path(__file__).parent.absolute()))
|
||||
|
||||
import name_utils
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ica_typing import IcaNewMessage, IcaClient, ConfigData
|
||||
from ica_typing import IcaNewMessage, IcaClient, ConfigData, ReciveMessage, TailchatReciveMessage
|
||||
|
||||
CONFIG_DATA: ConfigData
|
||||
else:
|
||||
CONFIG_DATA = None # type: ignore
|
||||
IcaNewMessage = TypeVar("NewMessage")
|
||||
IcaClient = TypeVar("IcaClient")
|
||||
ReciveMessage = TypeVar("ReciveMessage")
|
||||
TailchatReciveMessage = TypeVar("TailchatReciveMessage")
|
||||
|
||||
_version_ = "0.4.2"
|
||||
|
||||
COMMAND = "/namerena"
|
||||
_version_ = "0.5.0"
|
||||
|
||||
def on_ica_message(msg: IcaNewMessage, client: IcaClient) -> None:
|
||||
if not msg.content.startswith("/namerena") or msg.is_reply:
|
||||
return
|
||||
EVAL_PREFIX = "/namerena"
|
||||
CONVERT_PREFIX = "/namer-peek"
|
||||
|
||||
def convert_name(msg: ReciveMessage, client) -> None:
|
||||
# 也是多行
|
||||
if msg.content.find("\n") == -1:
|
||||
client.send_message(
|
||||
msg.reply_with(
|
||||
f"请使用 {COMMAND} 命令,然后换行输入名字,例如:\n{COMMAND}\n张三\n李四\n王五\n"
|
||||
f"请使用 {CONVERT_PREFIX} 命令,然后换行输入名字,例如:\n{CONVERT_PREFIX}\n张三\n李四\n王五\n"
|
||||
)
|
||||
)
|
||||
return
|
||||
# 去掉 /name
|
||||
names = msg.content[len(COMMAND) :]
|
||||
# 去掉 prefix
|
||||
names = msg.content[len(CONVERT_PREFIX) :]
|
||||
# 去掉第一个 \n
|
||||
names = names[names.find("\n") + 1 :]
|
||||
cache = io.StringIO()
|
||||
raw_players = [x for x in names.split("\n") if x != ""]
|
||||
players = [name_utils.Player() for _ in raw_players]
|
||||
for i, player in enumerate(players):
|
||||
if not player.load(raw_players[i]):
|
||||
cache.write(f"{i+1} {raw_players[i]} 无法解析\n")
|
||||
raw_players[i] = ""
|
||||
for i, player in enumerate(players):
|
||||
if raw_players[i] == "":
|
||||
continue
|
||||
cache.write(player.display())
|
||||
cache.write("\n")
|
||||
reply = msg.reply_with(f"{cache.getvalue()}版本:{_version_}")
|
||||
client.send_message(reply)
|
||||
|
||||
|
||||
def eval_fight(msg: ReciveMessage, client) -> None:
|
||||
if msg.content.find("\n") == -1:
|
||||
client.send_message(
|
||||
msg.reply_with(
|
||||
f"请使用 {EVAL_PREFIX} 命令,然后换行输入名字,例如:\n{EVAL_PREFIX}\n张三\n李四\n王五\n"
|
||||
)
|
||||
)
|
||||
return
|
||||
# 去掉 prefix
|
||||
names = msg.content[len(EVAL_PREFIX) :]
|
||||
# 去掉第一个 \n
|
||||
names = names[names.find("\n") + 1 :]
|
||||
|
||||
|
@ -64,6 +102,18 @@ def on_ica_message(msg: IcaNewMessage, client: IcaClient) -> None:
|
|||
reply = msg.reply_with(f"发生错误:{e}\n{traceback.format_exc()}")
|
||||
client.send_message(reply)
|
||||
|
||||
def dispatch_msg(msg: ReciveMessage, client) -> None:
|
||||
if msg.is_reply or msg.is_from_self:
|
||||
return
|
||||
if msg.content.startswith(EVAL_PREFIX):
|
||||
eval_fight(msg, client)
|
||||
elif msg.content.startswith(CONVERT_PREFIX):
|
||||
convert_name(msg, client)
|
||||
|
||||
def on_tailchat_message(msg, client) -> None:
|
||||
on_ica_message(msg, client)
|
||||
|
||||
def on_ica_message(msg: IcaNewMessage, client: IcaClient) -> None:
|
||||
dispatch_msg(msg, client) # type: ignore
|
||||
|
||||
|
||||
def on_tailchat_message(msg: TailchatReciveMessage, client) -> None:
|
||||
dispatch_msg(msg, client) # type: ignore
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use pyo3::prelude::*;
|
||||
use rust_socketio::asynchronous::Client;
|
||||
use tracing::{event, info, warn, Level};
|
||||
|
||||
use crate::data_struct::tailchat::status::BotStatus;
|
||||
use crate::data_struct::{ica, tailchat};
|
||||
use crate::error::PyPluginError;
|
||||
use crate::py::{class, PyPlugin, PyStatus};
|
||||
|
|
|
@ -79,12 +79,13 @@ impl TryFrom<RawPyPlugin> for PyPlugin {
|
|||
type Error = PyErr;
|
||||
fn try_from(value: RawPyPlugin) -> Result<Self, Self::Error> {
|
||||
let (path, changed_time, content) = value;
|
||||
let py_module = py_module_from_code(&content, &path);
|
||||
if let Err(e) = py_module {
|
||||
warn!("加载 Python 插件: {:?} 失败", e);
|
||||
return Err(e);
|
||||
let py_module = match py_module_from_code(&content, &path) {
|
||||
Ok(module) => module,
|
||||
Err(e) => {
|
||||
warn!("加载 Python 插件: {:?} 失败", e);
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
let py_module = py_module.unwrap();
|
||||
Python::with_gil(|py| {
|
||||
let module = py_module.bind(py);
|
||||
if let Ok(config_func) = call::get_func(module, "on_config") {
|
||||
|
|
Loading…
Reference in New Issue
Block a user