Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.0.5 pre #12

Merged
merged 1 commit into from
Jan 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions database.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,14 @@

from loguru import logger

from singleton import singleton


# 2b queue没法获取返回值

@singleton
class BotDatabase:
_instance = None

def __new__(cls, *args, **kw):
if cls._instance is None:
cls._instance = object.__new__(cls, *args, **kw)
return cls._instance

def __init__(self):
super().__init__()

self.database = sqlite3.connect('userpoints.db', check_same_thread=False) # 连接数据库
self.wxid_list = self._get_wxid_list() # 获取已有用户列表

Expand Down
7 changes: 4 additions & 3 deletions main_config.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#Version 0.0.4
#Version 0.0.5 pre
bot_version: "v0.0.5 pre"

#如果不知道自己在干什么请别动这两行
ip: 127.0.0.1
port: 5555

admins: [ "" ]

# 建议:(cpu核心数)*5-4
max_thread: 16
max_worker: 25

command_prefix: "/"

Expand Down
2 changes: 2 additions & 0 deletions plans_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
import os

from plans_interface import PlansInterface
from singleton import singleton


@singleton
class PlansManager:
def __init__(self):
self.plans = {}
Expand Down
1 change: 0 additions & 1 deletion plugin_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#
# This program is licensed under the GNU General Public License v3.0.

# plugin_interface.py
class PluginInterface:
def run(self, recv):
raise NotImplementedError("Subclasses must implement the 'run' method.")
26 changes: 10 additions & 16 deletions plugin_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
# This program is licensed under the GNU General Public License v3.0.
#
# This program is licensed under the GNU General Public License v3.0.
#
# This program is licensed under the GNU General Public License v3.0.

import importlib
import os
Expand All @@ -13,19 +11,12 @@
from loguru import logger

from plugin_interface import PluginInterface
from singleton import singleton


@singleton
class PluginManager:
_instance = None

def __new__(cls, *args, **kw):
if cls._instance is None:
cls._instance = object.__new__(cls, *args, **kw)
return cls._instance

def __init__(self):
super().__init__()

self.plugins = {}
self.keywords = {}

Expand Down Expand Up @@ -62,7 +53,8 @@ def get_keywords(self):
return self.keywords

def load_plugin(self, plugin_name):
if plugin_name not in self.plugins:
if plugin_name not in self.plugins and plugin_name not in self.excluded_plugins and plugin_name != [
'manage_plugins']:
module = importlib.import_module(f'plugins.{plugin_name}')
plugin_class = getattr(module, plugin_name)
if issubclass(plugin_class, PluginInterface):
Expand All @@ -79,11 +71,10 @@ def load_plugins(self, plugin_dir):
for plugin_file in os.listdir(plugin_dir):
if plugin_file.endswith(".py") and plugin_file != "__init__.py" and not plugin_file.startswith('_'):
plugin_name = os.path.splitext(plugin_file)[0]
if plugin_name not in self.excluded_plugins:
self.load_plugin(plugin_name)
self.load_plugin(plugin_name)

def unload_plugin(self, plugin_name):
if plugin_name in self.plugins and plugin_name not in ['manage_plugins']:
if plugin_name in self.plugins and plugin_name != ['manage_plugins']:
del self.plugins[plugin_name]
self.refresh_keywords()
logger.debug('- 已卸载插件:{plugin_name}'.format(plugin_name=plugin_name))
Expand All @@ -92,13 +83,16 @@ def unload_plugin(self, plugin_name):
return False

def reload_plugin(self, plugin_name):
if self.unload_plugin(plugin_name):
if self.unload_plugin(plugin_name) and plugin_name != ['manage_plugins']:
if self.load_plugin(plugin_name):
logger.debug('! 已重载插件:{plugin_name}'.format(plugin_name=plugin_name))
return True
else:
logger.debug('! 重载插件失败:{plugin_name}'.format(plugin_name=plugin_name))
return False
else:
logger.debug('! 重载插件失败:{plugin_name}'.format(plugin_name=plugin_name))
return False


# 实例化插件管理器
Expand Down
3 changes: 1 addition & 2 deletions plugins/admin_points.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@ def __init__(self):
self.bot = pywxdll.Pywxdll(self.ip, self.port) # 机器人api

self.admin_list = main_config['admins']

def run(self, recv):
self.db = BotDatabase()

def run(self, recv):
if recv['id1']: # 用于判断是否为管理员
admin_wxid = recv['id1'] # 是群
else:
Expand Down
3 changes: 2 additions & 1 deletion plugins/bot_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ def __init__(self):
config = yaml.load(f.read(), Loader=yaml.FullLoader)

self.status_message = config['status_message']
self.bot_version = config['bot_version']

current_directory = os.path.dirname(os.path.abspath(__file__))
main_config_path = os.path.join(current_directory, '../main_config.yml')
with open(main_config_path, 'r', encoding='utf-8') as f: # 读取设置
main_config = yaml.load(f.read(), Loader=yaml.FullLoader)

self.bot_version = main_config['bot_version']

self.ip = main_config['ip']
self.port = main_config['port']
self.bot = pywxdll.Pywxdll(self.ip, self.port) # 机器人api
Expand Down
3 changes: 1 addition & 2 deletions plugins/bot_status.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
keywords: ["机器人状态","bottest"]
plugin_name: "bot_status"

status_message: "Bot Running😊"
bot_version: "v0.0.4"
status_message: "Bot Running😊"
2 changes: 0 additions & 2 deletions plugins/gpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
# This program is licensed under the GNU General Public License v3.0.
#
# This program is licensed under the GNU General Public License v3.0.
#
# This program is licensed under the GNU General Public License v3.0.

import os

Expand Down
2 changes: 0 additions & 2 deletions plugins/gpt4.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
# This program is licensed under the GNU General Public License v3.0.
#
# This program is licensed under the GNU General Public License v3.0.
#
# This program is licensed under the GNU General Public License v3.0.

import os

Expand Down
140 changes: 112 additions & 28 deletions plugins/lucky_draw.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def __init__(self):
config = yaml.load(f.read(), Loader=yaml.FullLoader)

self.lucky_draw_probability = config['lucky_draw_probability']
self.max_draw = config['max_draw']

current_directory = os.path.dirname(os.path.abspath(__file__))
main_config_path = os.path.join(current_directory, '../main_config.yml')
Expand All @@ -35,6 +36,10 @@ def __init__(self):
self.db = database.BotDatabase()

def run(self, recv):
global draw_count, draw_name

# -----初始化与消息格式监测-----

if recv['id1']: # 用于判断是否为管理员
target_wxid = recv['id1'] # 是群
else:
Expand All @@ -45,47 +50,84 @@ def run(self, recv):
target_points = self.db.get_points(target_wxid)

error = ''
if len(command) != 2:
error = '-----XYBot-----\n❌命令格式错误!请查看菜单获取正确命令格式'
else:

if len(command) == 2:
draw_name = command[1]
draw_count = 1

if not draw_name in self.lucky_draw_probability.keys():
if draw_name not in self.lucky_draw_probability.keys():
error = '-----XYBot-----\n❌抽奖种类未知或者无效'
elif draw_name in self.lucky_draw_probability.keys() and target_points < \
self.lucky_draw_probability[draw_name][
'cost']:
error = '-----XYBot-----\n❌积分不足!'

elif len(command) == 3:
draw_name = command[1]
draw_count = int(command[2])

if draw_name not in self.lucky_draw_probability.keys():
error = '-----XYBot-----\n❌抽奖种类未知或者无效'
elif draw_name in self.lucky_draw_probability.keys() and target_points < \
self.lucky_draw_probability[draw_name][
'cost'] * draw_count:
error = '-----XYBot-----\n❌积分不足!'
else:
error = '-----XYBot-----\n❌命令格式错误!请查看菜单获取正确命令格式'

if not error:

# -----抽奖核心部分-----

draw_probability = self.lucky_draw_probability[draw_name]['probability']
draw_cost = self.lucky_draw_probability[draw_name]['cost']
draw_cost = self.lucky_draw_probability[draw_name]['cost'] * draw_count

wins = []

self.db.add_points(target_wxid, -1 * draw_cost)

random_num = random.uniform(0, 1)
cumulative_probability = 0
for probability, prize_dict in draw_probability.items():
cumulative_probability += float(probability)
if random_num <= cumulative_probability:
win_name = prize_dict['name']
win_points = prize_dict['points']

logger.info(
'[抽奖] {target_wxid}在{draw_name}抽奖中抽到了{win_name} 抽到了{win_points}点积分'.format(
target_wxid=target_wxid, draw_name=draw_name, win_name=win_name, win_points=win_points))
self.db.add_points(target_wxid, win_points)
out_message = '-----XYBot-----\n🥳恭喜你在 {draw_name}抽奖 中抽到了 {win_name}!✌️你抽到了 {win_points} 点积分!\n🙏🏻谢谢惠顾!\n\n🥳你在抽 {draw_name}抽奖 ,{draw_name}抽奖 需要{draw_cost}点积分💰,中奖概率如下❗️\n\n'.format(
draw_name=draw_name, draw_cost=draw_cost, win_name=win_name, win_points=win_points)

for probability, prize_info in draw_probability.items():
message = '🤑{prize_name}:概率为{probability}%,奖励为{prize_points}点积分\n'.format(
prize_name=prize_info['name'], probability=int(float(probability) * 100),
prize_points=prize_info['points'])
out_message += message
self.send_friend_or_group(recv, out_message)

break
# 保底抽奖
min_guaranteed = draw_count // 10
for _ in range(min_guaranteed):
random_num = random.uniform(0, 0.4)
cumulative_probability = 0
for probability, prize_dict in draw_probability.items():
cumulative_probability += float(probability)
if random_num <= cumulative_probability:
win_name = prize_dict['name']
win_points = prize_dict['points']
win_symbol = prize_dict['symbol']

wins.append((win_name, win_points, win_symbol))
break

# 正常抽奖
for _ in range(draw_count - min_guaranteed):
random_num = random.uniform(0, 1)
cumulative_probability = 0
for probability, prize_dict in draw_probability.items():
cumulative_probability += float(probability)
if random_num <= cumulative_probability:
win_name = prize_dict['name']
win_points = prize_dict['points']
win_symbol = prize_dict['symbol']

wins.append((win_name, win_points, win_symbol))
break

# -----消息组建-----

total_win_points = 0
for win_name, win_points, win_symbol in wins:
total_win_points += win_points

self.db.add_points(target_wxid, total_win_points)
logger.info(
f'[抽奖] wxid: {target_wxid} | 抽奖名: {draw_name} | 次数: {draw_count} | 赢取积分: {total_win_points}')

message = self.make_message(wins, draw_name, draw_count, total_win_points, draw_cost)

self.send_friend_or_group(recv, message)

else:
self.send_friend_or_group(recv, error)
Expand All @@ -98,3 +140,45 @@ def send_friend_or_group(self, recv, out_message='null'):
else:
logger.info('[发送信息]{out_message}| [发送到] {wxid}'.format(out_message=out_message, wxid=recv['wxid']))
self.bot.send_txt_msg(recv['wxid'], out_message) # 发送

@staticmethod
def make_message(wins, draw_name, draw_count, total_win_points, draw_cost):
name_max_len = 0
for win_name, win_points, win_symbol in wins:
if len(win_name) > name_max_len:
name_max_len = len(win_name)

begin_message = f"----XYBot抽奖----\n🥳恭喜你在 {draw_count}次 {draw_name}抽奖 中抽到了:\n\n"
lines = []
for _ in range(name_max_len + 2):
lines.append('')

begin_line = 0

one_line_length = 0

for win_name, win_points, win_symbol in wins:
if one_line_length >= 10:
begin_line += name_max_len + 2
for _ in range(name_max_len + 2):
lines.append('')
one_line_length = 0

lines[begin_line] += win_symbol
for i in range(begin_line + 1, begin_line + name_max_len + 1):
if i % (name_max_len + 2) <= len(win_name):
lines[i] += "\u2004" + win_name[i % (name_max_len + 2) - 1]
else:
lines[i] += win_symbol
lines[begin_line + name_max_len + 1] += win_symbol

one_line_length += 1

message = ''
message += begin_message
for line in lines:
message += line + '\n'

message += f"\n\n🎉总计赢取积分: {total_win_points}🎉\n🎉共计消耗积分:{draw_cost}🎉\n\n概率请自行查询菜单⚙️"

return message
Loading