Archived
1
0
Fork 0
This commit is contained in:
yzhh 2021-02-01 23:13:11 +08:00
parent b4dfd3dcb7
commit 0322600068
60 changed files with 2072 additions and 1885 deletions

4
.gitignore vendored
View file

@ -9,4 +9,6 @@ mcvrss.txt
assets/usercard/*.png
test.py
assets/Favicon/**/*.png
assets/cache/*
assets/cache/*
save.db
cache/*

View file

@ -1,100 +0,0 @@
import re
ignorelist = []
from commandlist import commandlist
clist = commandlist()
async def findcommand(str1, group=0):
str1 = re.sub(r'^', '~', str1)
q = re.match(r'^.*(:\n~)(.*)', str1)
if q:
return q.group(2)
q = re.match(r'^~(.*)', str1)
if q:
return q.group(1)
q = re.match(r'^!(.*\-.*)', str1)
if q:
q = str.upper(q.group(1))
return 'bug ' + q
async def command(text, group=0):
result = await findcommand(text, group)
c = result
if c != None:
try:
d = result.split(' ')
d = d[0]
except Exception:
d = c
if d in clist:
k = clist.get(d)
k1 = re.match(r'from (.*) import (.*)\|(.*)', k)
if k1:
cmd = eval(
f'__import__("modules.{k1.group(1)}", fromlist=["{k1.group(1)}"]).{k1.group(2)}().{k1.group(3)}')
if d == c:
return await cmd()
else:
c = re.sub(r'^'+d+' ','',c)
return await cmd(c)
else:
k2 = re.match(r'from (.*) import (.*)', k)
if k2:
cmd = eval(f'__import__("modules.{k2.group(1)}", fromlist=["{k2.group(1)}"]).{k2.group(2)}')
if d == c:
return await cmd()
else:
c = re.sub(r'^' + d + ' ', '', c)
return await cmd(c)
else:
a = __import__('modules.' + k, fromlist=[k])
if d == c:
return await a.main()
else:
c = re.sub(r'^' + d + ' ', '', c)
return await a.main(c)
async def ttext(text, group=0):
if text.find('[Webhook]') != -1:
pass
else:
w = re.findall(r'\[\[(.*?)\]\]', text, re.I)
w2 = re.findall(r'\{\{(.*?)\}\}', text, re.I)
z = []
c = '\n'
if w:
from modules.wiki import im
wi1 = []
if str(w) != '['']' or str(w) != '[]':
for x in w:
if x == '' or x in wi1:
pass
else:
wi1.append(x)
if wi1 != []:
z.append(await im(wi1))
if w2:
from modules.wiki import imt
wi2 = []
if str(w2) != '['']' or str(w2) != '[]':
for x in w2:
if x == '' or x in wi2:
pass
else:
wi2.append(x)
if wi2 != []:
z.append(await imt(wi2))
w3 = re.findall(r'(https://bugs.mojang.com/browse/.*?-\d*)', text)
for link in w3:
matchbug = re.match(r'https://bugs.mojang.com/browse/(.*?-\d*)',link)
if matchbug:
import modules.bug
z.append(await modules.bug.main(matchbug.group(1)))
if str(z):
v = c.join(z)
if v != '':
return v

View file

@ -1,154 +0,0 @@
import asyncio
import os
import random
import re
import traceback
from os.path import abspath
import graia.application.interrupt as inter
from graia.application.message.chain import MessageChain
from graia.application.message.elements.internal import Plain, Image, Source
from modules.findimage import findimage
try:
cachepath = abspath('./assets/cache/')
cachefile = os.listdir(cachepath)
for file in cachefile:
os.remove(f'{cachepath}/{file}')
except Exception:
pass
async def gen(bcc, app, message, target1, target2='0', msgtype='None', runfun='command'):
im = inter.InterruptControl(bcc)
command = __import__('CommandGen', fromlist=[runfun])
command = getattr(command, runfun)
if msgtype == 'Group':
run = await command(message.asDisplay(), target1.id)
else:
run = await command(message.asDisplay())
# print(run)
if run != None:
await msgproc(run, app, im, command, message, target1, target2, msgtype)
async def msgproc(resultmsgraw, app, im, command, message, target1, target2='0', msgtype='None'):
print(resultmsgraw)
msgchain = await makemsgchain(resultmsgraw)
send = await sendmessage(app, msgchain, target1, target2, msgtype,
message[Source][0] if msgtype == 'Group' else 0)
uimgcs = re.findall(r'\[\[uimgc:.*\]\]', resultmsgraw, re.I | re.M)
for uimgc in uimgcs:
uimgc = re.match(r'\[\[uimgc:(.*)\]\]', uimgc)
if uimgc:
await uimgsend(app, message, target1, target2, msgtype, uimgc.group(1))
r = re.findall(r'(https?://.*?/File:.*?\.(?:png|gif|jpg|jpeg|webp|bmp|ico))', resultmsgraw, re.I)
for d in r:
d1 = await findimage(d)
if d1 is not None:
await linkimgsend(app, d1, target1, target2, msgtype)
await afterproc(resultmsgraw, app, im, command, send, message, target1, target2, msgtype)
async def makemsgchain(msg):
msg = re.sub('\[wait\]', '', msg)
msgbase = re.sub(r'\[\[uimgc:.*\]\]', '', msg)
msgchain = MessageChain.create([Plain(msgbase)])
return msgchain
async def afterproc(resultmsgraw, app, im, command, send, message, target1, target2='0', msgtype='None'):
if resultmsgraw.find('[一分钟后撤回本消息]') != -1:
await asyncio.sleep(60)
await app.revokeMessage(send)
if resultmsgraw.find('[30秒后撤回本消息]') != -1:
await asyncio.sleep(30)
await app.revokeMessage(send)
if resultmsgraw.find('[wait]') != -1:
ranint = random.randint(1, 3)
if ranint == 2:
waitmsg = await makemsgchain('提示:你可以发送“是”字来将所有无效结果再次查询。(考虑到实现复杂性,恕不提供选择性查询)')
await sendmessage(app, waitmsg, target1, target2, msgtype)
MessageEventImport = __import__('graia.application', fromlist=[f'{msgtype}Message'])
MessageEvent = getattr(MessageEventImport, f'{msgtype}Message')
InterruptImport = __import__('graia.application.interrupt.interrupts',
fromlist=[f'{msgtype}MessageInterrupt'])
Interrupt = getattr(InterruptImport, f'{msgtype}MessageInterrupt')
if msgtype == 'Friend':
event: MessageEvent = await im.wait(Interrupt(target1.id))
else:
event: MessageEvent = await im.wait(Interrupt(target1, target2))
print(event)
if event.messageChain.asDisplay() == '':
msg2 = await command(resultmsgraw)
await msgproc(msg2, app, im, command, message, target1, target2, msgtype)
else:
pass
async def uimgsend(app, message, target1, target2, msgtype, link):
exec('from graia.application.message.elements.internal import UploadMethods')
mth = eval(f'UploadMethods.{msgtype}')
try:
msgchain = MessageChain.create(
[Image.fromLocalFile(filepath=abspath(link), method=mth)])
print('Sending Image...')
await sendmessage(app, msgchain, target1, target2, msgtype,
message[Source][0] if msgtype == 'Group' else 0)
except Exception:
traceback.print_exc()
msgchain = MessageChain.create(
[Plain('上传过程中遇到了问题,图片发送失败。')])
await sendmessage(app, msgchain, target1, target2, msgtype,
message[Source][0] if msgtype == 'Group' else 0)
async def linkimgsend(app, sendlink, target1, target2, msgtype):
exec('from graia.application.message.elements.internal import UploadMethods')
mth = eval(f'UploadMethods.{msgtype}')
try:
msgchain = MessageChain.create([Image.fromNetworkAddress(url=sendlink, method=mth)])
print('Sending Image...')
await sendmessage(app, msgchain, target1, target2, msgtype)
except Exception:
traceback.print_exc()
msgchain = MessageChain.create(
[Plain('上传过程中遇到了问题,图片发送失败。')])
await sendmessage(app, msgchain, target1, target2, msgtype)
async def sendmessage(app, msgchain, target1, target2, msgtype, quoteid=0):
if msgtype == 'Friend':
friend = target1
send = await app.sendFriendMessage(friend, msgchain.asSendable())
if msgtype == 'Group':
group = target1
send = await app.sendGroupMessage(group, msgchain.asSendable(), quote=quoteid if quoteid != 0 else None)
if msgtype == 'Temp':
group = target1
member = target2
send = await app.sendTempMessage(group=group, target=member, message=msgchain.asSendable())
return send
"""
if msgtype == 'Group':
voice = re.findall(r'https?://.*?/File:.*?\.(?:ogg|m4a|mp3|flac|wav)', run, re.I)
for voicelink in voice:
try:
findvoicename = re.match(r'(https?://.*?/)File:(.*?\.(?:ogg|m4a|mp3|flac|wav))', voicelink, re.I)
downloadfile = await dfile(findvoicename.group(1), findvoicename.group(2))
print(downloadfile)
conventamr = await camr(downloadfile)
print(conventamr)
readfile = open(conventamr, 'rb+')
uploadvoice = await app.uploadVoice(readfile.read())
voicemsgchain = MessageChain.create([uploadvoice])
await app.sendGroupMessage(target1, voicemsgchain)
readfile.close()
os.remove(downloadfile)
os.remove(conventamr)
except Exception:
traceback.print_exc()
"""

Binary file not shown.

BIN
assets/chromedriver.exe Normal file

Binary file not shown.

15
assets/infoboxfix.css Normal file
View file

@ -0,0 +1,15 @@
html body {
margin-top: 0px !important;
}
div.infobox div.notaninfobox {
width: 100% !important;
float: none !important;
margin: 0 0 0 0 !important;
}
table.infobox {
width: 100% !important;
float: unset !important;
margin: 0 0 0 0 !important;
}

View file

@ -0,0 +1,4 @@
21w03a
1.16.5
Future Version - 1.17+

93
bot.py
View file

@ -1,80 +1,43 @@
import asyncio
from graia.application import GraiaMiraiApplication, Session
from graia.application.event.mirai import NewFriendRequestEvent, BotInvitedJoinGroupRequestEvent
from graia.application import GraiaMiraiApplication
from graia.application.friend import Friend
from graia.application.group import Group, Member
from graia.application.message.chain import MessageChain
from graia.broadcast import Broadcast
from MessageGen import gen
from core.broadcast import bcc, app
from core.loader import rss_loader
from core.parser import parser
import os
loop = asyncio.get_event_loop()
cache_path = os.path.abspath('./cache/')
if os.path.exists(cache_path):
for x in os.listdir(cache_path):
os.remove(cache_path + x)
os.removedirs(cache_path)
os.mkdir(cache_path)
else:
os.mkdir(cache_path)
bcc = Broadcast(loop=loop, debug_flag=True)
app = GraiaMiraiApplication(
broadcast=bcc,
enable_chat_log=False,
connect_info=Session(
host="http://localhost:11919", # 填入 httpapi 服务运行的地址
authKey='1145141919810', # 填入 authKey
account=2926887640, # 你的机器人的 qq 号
websocket=True # Graia 已经可以根据所配置的消息接收的方式来保证消息接收部分的正常运作.
)
)
@bcc.receiver('GroupMessage')
async def group_message_handler(message: MessageChain, group: Group, member: Member):
kwargs = {MessageChain: message, Group: group, Member: member}
await parser(kwargs)
@bcc.receiver("GroupMessage")
async def group_message_handler(app: GraiaMiraiApplication, message: MessageChain, group: Group, member: Member):
await gen(bcc, app, message, group, member, msgtype='Group')
@bcc.receiver('FriendMessage')
async def group_message_handler(message: MessageChain, friend: Friend):
kwargs = {MessageChain: message, Friend: friend}
await parser(kwargs)
@bcc.receiver("GroupMessage")
async def group_message_handler1(app: GraiaMiraiApplication, message: MessageChain, group: Group, member: Member):
await gen(bcc, app, message, group, member, msgtype='Group', runfun='ttext')
@bcc.receiver("FriendMessage")
async def friend_message_handler(app: GraiaMiraiApplication, message: MessageChain, friend: Friend):
await gen(bcc, app, message, friend, msgtype='Friend')
@bcc.receiver("FriendMessage")
async def friend_message_handler1(app: GraiaMiraiApplication, message: MessageChain, friend: Friend):
await gen(bcc, app, message, friend, msgtype='Friend', runfun='ttext')
@bcc.receiver("TempMessage")
async def temp_message_handler(app: GraiaMiraiApplication, message: MessageChain, group: Group, member: Member):
await gen(bcc, app, message, group, member, msgtype='Temp')
@bcc.receiver("TempMessage")
async def temp_message_handler1(app: GraiaMiraiApplication, message: MessageChain, group: Group, member: Member):
await gen(bcc, app, message, group, member, msgtype='Temp', runfun='ttext')
@bcc.receiver("NewFriendRequestEvent")
async def NFriend(event: NewFriendRequestEvent):
await event.accept()
@bcc.receiver("BotInvitedJoinGroupRequestEvent")
async def NGroup(event: BotInvitedJoinGroupRequestEvent):
await event.accept()
import subbot
@bcc.receiver("ApplicationLaunched")
async def subbot1(app: GraiaMiraiApplication):
await subbot.ver(app)
@bcc.receiver("ApplicationLaunched")
async def subbot2(app: GraiaMiraiApplication):
await subbot.newbie(app)
@bcc.receiver('ApplicationLaunched')
async def message_handler(app: GraiaMiraiApplication):
rss_list = rss_loader()
gather_list = []
for x in rss_list:
gather_list.append(asyncio.ensure_future(rss_list[x](app)))
await asyncio.gather(*gather_list)
app.launch_blocking()

View file

@ -1,37 +0,0 @@
def commandlist():
clist = {}
import os
path = os.path.abspath('./modules')
dirs = os.listdir(path)
import re
for file in dirs:
filename = os.path.abspath(f'./modules/{file}')
a1 = None
a2 = None
if os.path.isdir(filename):
if file == '__pycache__':
pass
else:
a1 = file
a2 = file
if os.path.isfile(filename):
b = re.match(r'(.*)(.py)', file)
if b:
a1 = b.group(1)
a2 = b.group(1)
try:
if a1 is not None:
a = __import__('modules.' + a1, fromlist=[a2])
if isinstance(a.command, dict):
clist.update(a.command)
print(f'Successful loaded {a2} from {a1}! command = {a.command}')
elif isinstance(a.command, tuple):
for x in a.command:
if isinstance(x, dict):
clist.update(x)
print(f'Successful loaded {x.keys()}! command = {x}')
except Exception as e:
print(str(e) + ', skip!')
return clist

View file

@ -1,9 +1,13 @@
from configparser import ConfigParser
from os.path import abspath
def config(q):
def config(path, q):
cp = ConfigParser()
cp.read(abspath("./config/config.cfg"))
cp.read(path)
section = cp.sections()[0]
return (cp.get(section, q))
value = cp.get(section, q)
if value.upper() == 'TRUE':
return True
if value.upper() == 'FALSE':
return False
return value

28
core/broadcast.py Normal file
View file

@ -0,0 +1,28 @@
import asyncio
from os.path import abspath
from graia.application import GraiaMiraiApplication, Session
from graia.broadcast import Broadcast
from config import config
loop = asyncio.get_event_loop()
config_filename = 'config.cfg'
config_path = abspath('./config/' + config_filename)
def c(q):
return config(config_path, q)
bcc = Broadcast(loop=loop, debug_flag=c('debug_flag'))
app = GraiaMiraiApplication(
broadcast=bcc,
enable_chat_log=c('enable_chat_log'),
connect_info=Session(
host=c('host'), # 填入 httpapi 服务运行的地址
authKey=c('authkey'), # 填入 authKey
account=c('account'), # 你的机器人的 qq 号
websocket=c('websocket') # Graia 已经可以根据所配置的消息接收的方式来保证消息接收部分的正常运作.
)
)

View file

@ -3,6 +3,7 @@ import datetime
import hashlib
import hmac
import json
import os.path
import time
from urllib.parse import urlencode
@ -22,11 +23,13 @@ def computeMD5hash(my_string):
return m.hexdigest()
accessKeyId = config("accessKeyId")
accessKeySecret = config("accessKeySecret")
async def pbc(text):
async def check(text):
try:
config_path = os.path.abspath('config/config.cfg')
accessKeyId = config(config_path, "Check_accessKeyId")
accessKeySecret = config(config_path, "Check_accessKeySecret")
except Exception:
return ''
print('hello')
body = {
"scenes": [
@ -38,7 +41,7 @@ async def pbc(text):
}, text))
}
print(urlencode({
'test': 123
'we': 123
}))
clientInfo = '{}'
root = 'https://green.cn-shanghai.aliyuncs.com'
@ -81,6 +84,7 @@ async def pbc(text):
async with session.post('{}{}'.format(root, url), data=json.dumps(body)) as resp:
if resp.status == 200:
result = await resp.json()
print(result)
resultUsers = []
for item in result['data']:
content = item['content']
@ -93,13 +97,7 @@ async def pbc(text):
else:
content = "<全部吃掉了>"
resultUsers.append(content)
return (resultUsers)
return ''.join(resultUsers)
else:
return (await resp.text())
async def pbc1(newUsers):
Users = []
Users.append(newUsers)
return await pbc(Users)

116
core/loader.py Normal file
View file

@ -0,0 +1,116 @@
import importlib
import os
import re
import traceback
def command_loader():
fun_file = None
admin_list = {}
essential_list = {}
command_list = {}
help_list = {}
regex_list = {}
self_options_list = []
options_list = []
load_dir_path = os.path.abspath('./modules/')
dir_list = os.listdir(load_dir_path)
for file_name in dir_list:
file_path = f'{load_dir_path}/{file_name}'
print(file_path)
if os.path.isdir(file_path):
if file_path != '__pycache__':
fun_file = file_name
if os.path.isfile(file_path):
b = re.match(r'(.*)(.py)', file_path)
if b:
fun_file = b.group(1)
print(fun_file)
try:
if fun_file is not None:
import_fun = importlib.__import__('modules.' + fun_file, fromlist=[fun_file])
try:
admins = import_fun.admin
if isinstance(admins, dict):
admin_list.update(admins)
print(admins)
except:
traceback.print_exc()
try:
essentials = import_fun.essential
if isinstance(essentials, dict):
essential_list.update(essentials)
print(essentials)
except:
traceback.print_exc()
try:
fun_commands = import_fun.command
if isinstance(fun_commands, dict):
command_list.update(fun_commands)
print(fun_commands)
except:
traceback.print_exc()
try:
fun_help = import_fun.help
if isinstance(fun_help, dict):
help_list.update(fun_help)
print(fun_help)
except:
traceback.print_exc()
try:
fun_regex = import_fun.regex
if isinstance(fun_regex, dict):
regex_list.update(fun_regex)
print(fun_regex)
except:
traceback.print_exc()
try:
fun_self_options = import_fun.self_options
if isinstance(fun_self_options, list):
for x in fun_self_options:
self_options_list.append(x)
print(fun_self_options)
except:
traceback.print_exc()
try:
fun_options = import_fun.options
if isinstance(fun_options, list):
for x in fun_options:
self_options_list.append(x)
print(fun_options)
except:
traceback.print_exc()
except:
traceback.print_exc()
return admin_list, essential_list, command_list, help_list, regex_list, self_options_list, options_list
def rss_loader():
fun_file = None
rss_list = {}
load_dir_path = os.path.abspath('./modules/')
dir_list = os.listdir(load_dir_path)
for file_name in dir_list:
file_path = f'{load_dir_path}/{file_name}'
print(file_path)
if os.path.isdir(file_path):
if file_path != '__pycache__':
fun_file = file_name
if os.path.isfile(file_path):
b = re.match(r'(.*)(.py)', file_path)
if b:
fun_file = b.group(1)
print(fun_file)
try:
if fun_file is not None:
import_fun = importlib.__import__('modules.' + fun_file, fromlist=[fun_file])
try:
rss = import_fun.rss
if isinstance(rss, dict):
rss_list.update(rss)
print(rss)
except:
traceback.print_exc()
except:
traceback.print_exc()
return rss_list

79
core/parser.py Normal file
View file

@ -0,0 +1,79 @@
import re
from graia.application import Friend
from graia.application.group import Group, Member
from graia.application.message.chain import MessageChain
import database
from core.loader import command_loader
from core.template import sendMessage
admin_list, essential_list, command_list, help_list, regex_list, self_options_list, options_list = command_loader()
print(essential_list)
function_list = []
for command in command_list:
function_list.append(command)
for reg in regex_list:
function_list.append(reg)
for options in self_options_list:
function_list.append(options)
for options in options_list:
function_list.append(options)
print(function_list)
async def parser(kwargs: dict):
display = kwargs[MessageChain].asDisplay()
command_prefix = ['~', '']
if Group in kwargs:
trigger = kwargs[Member].id
if Friend in kwargs:
trigger = kwargs[Friend].id
if database.check_black_list(trigger):
if not database.check_white_list(trigger):
return
if display[0] in command_prefix:
command = re.sub(r'^' + display[0], '', display)
command_first_word = command.split(' ')[0]
if command_first_word in command_list:
if Group in kwargs:
check_command_enable = database.check_enable_modules(kwargs[Group].id, command_first_word)
if check_command_enable:
check_command_enable_self = database.check_enable_modules_self(kwargs[Member].id,
command_first_word)
if check_command_enable_self:
kwargs['trigger_msg'] = command
await command_list[command_first_word](kwargs)
else:
await sendMessage(kwargs, f'此模块未启用,请管理员在群内发送~enable {command_first_word}启用本模块。')
else:
check_command_enable_self = database.check_enable_modules_self(kwargs[Friend].id, command_first_word)
if check_command_enable_self:
kwargs['trigger_msg'] = command
await command_list[command_first_word](kwargs)
elif command_first_word in essential_list:
kwargs['trigger_msg'] = command
kwargs['function_list'] = function_list
kwargs['help_list'] = help_list
await essential_list[command_first_word](kwargs)
elif command_first_word in admin_list:
if database.check_superuser(kwargs):
kwargs['trigger_msg'] = command
kwargs['function_list'] = function_list
await admin_list[command_first_word](kwargs)
else:
await sendMessage(kwargs, '权限不足')
# regex
if Group in kwargs:
for regex in regex_list:
check_command_enable = database.check_enable_modules(kwargs[Group].id,
regex)
if check_command_enable:
check_command_enable_self = database.check_enable_modules_self(kwargs[Member].id, regex)
if check_command_enable_self:
await regex_list[regex](kwargs)
if Friend in kwargs:
for regex in regex_list:
check_command_enable_self = database.check_enable_modules_self(kwargs[Friend].id, regex)
if check_command_enable_self:
await regex_list[regex](kwargs)

98
core/template.py Normal file
View file

@ -0,0 +1,98 @@
import eventlet
from graia.application import MessageChain, GroupMessage, FriendMessage
from graia.application.friend import Friend
from graia.application.group import Group, Member
from graia.application.message.elements.internal import Plain, Image, Source
from graia.broadcast.interrupt import InterruptControl
from graia.broadcast.interrupt.waiter import Waiter
from core.broadcast import app, bcc
from database import check_superuser
async def sendMessage(kwargs: dict, msgchain):
if isinstance(msgchain, str):
msgchain = MessageChain.create([Plain(msgchain)])
if Group in kwargs:
try:
eventlet.monkey_patch()
with eventlet.Timeout(15):
send = await app.sendGroupMessage(kwargs[Group], msgchain, quote=kwargs[MessageChain][Source][0].id)
return send
except eventlet.timeout.Timeout:
split_msg = msgchain.get(Plain)
sent_msgs = []
for msgs in split_msg:
send = await app.sendGroupMessage(kwargs[Group], MessageChain.create([msgs]), quote=kwargs[MessageChain][Source][0].id)
sent_msgs.append(send)
split_img = msgchain.get(Image)
for imgs in split_img:
send = await app.sendGroupMessage(kwargs[Group], MessageChain.create([imgs]), quote=kwargs[MessageChain][Source][0].id)
sent_msgs.append(send)
return sent_msgs
if Friend in kwargs:
try:
eventlet.monkey_patch()
with eventlet.Timeout(15):
send = await app.sendFriendMessage(kwargs[Friend], msgchain)
return send
except eventlet.timeout.Timeout:
split_msg = msgchain.get(Plain)
sent_msgs = []
for msgs in split_msg:
send = await app.sendFriendMessage(kwargs[Friend], MessageChain.create([msgs]))
sent_msgs.append(send)
split_img = msgchain.get(Image)
for imgs in split_img:
send = await app.sendFriendMessage(kwargs[Friend], MessageChain.create([imgs]))
sent_msgs.append(send)
return sent_msgs
async def wait_confirm(kwargs: dict):
inc = InterruptControl(bcc)
confirm_command = ["", "", 'yes', 'y']
if Group in kwargs:
@Waiter.create_using_function([GroupMessage])
def waiter(waiter_group: Group,
waiter_member: Member, waiter_message: MessageChain):
if all([
waiter_group.id == kwargs[Group].id,
waiter_member.id == kwargs[Member].id,
]):
print(111)
if waiter_message.asDisplay() in confirm_command:
return True
else:
return False
if Friend in kwargs:
@Waiter.create_using_function([FriendMessage])
def waiter(waiter_friend: Friend, waiter_message: MessageChain):
if all([
waiter_friend.id == kwargs[Friend].id,
]):
if waiter_message.asDisplay() in confirm_command:
return True
else:
return False
return await inc.wait(waiter)
async def revokeMessage(msgchain):
if isinstance(msgchain, list):
for msg in msgchain:
await app.revokeMessage(msg)
else:
await app.revokeMessage(msgchain)
def check_permission(kwargs):
if Group in kwargs:
if str(kwargs[Member].permission) in ['MemberPerm.Administrator', 'MemberPerm.Owner'] or check_superuser(
kwargs[Member].id):
return True
if Friend in kwargs:
if check_superuser(kwargs[Friend].id):
return True
return False

277
database/__init__.py Normal file
View file

@ -0,0 +1,277 @@
import os
import sqlite3
import traceback
from graia.application import Group, Friend, Member
dbpath = os.path.abspath('./database/save.db')
def initialize():
a = open(dbpath, 'w')
a.close()
conn = sqlite3.connect(dbpath)
c = conn.cursor()
c.execute('''CREATE TABLE group_permission
(ID INT PRIMARY KEY NOT NULL,
ENABLE_MODULES TEXT);''')
c.execute('''CREATE TABLE self_permission
(ID INT PRIMARY KEY NOT NULL,
DISABLE_MODULES TEXT);''')
c.execute('''CREATE TABLE black_list
(ID INT PRIMARY KEY NOT NULL);''')
c.execute('''CREATE TABLE white_list
(ID INT PRIMARY KEY NOT NULL);''')
c.execute('''CREATE TABLE warn
(ID INT PRIMARY KEY NOT NULL,
WARN TEXT);''')
c.execute('''CREATE TABLE superuser
(ID INT PRIMARY KEY NOT NULL);''')
c.close()
def connect_db(path):
conn = sqlite3.connect(path)
c = conn.cursor()
return c
def update_modules(do, id, modules_name, table='group_permission', value='ENABLE_MODULES'):
if not os.path.exists(dbpath):
initialize()
conn = sqlite3.connect(dbpath)
c = conn.cursor()
a = c.execute(f"SELECT * FROM {table} WHERE ID={id}").fetchone()
if do == 'add':
if a:
enabled_split = a[1].split('|')
if modules_name in enabled_split:
return '失败:模块已被启用:' + modules_name
else:
enabled_split.append(modules_name)
c.execute(f"UPDATE {table} SET {value}='{'|'.join(enabled_split)}' WHERE ID='{id}'")
conn.commit()
return '成功:启用模块:' + modules_name
else:
c.execute(f"INSERT INTO {table} (ID, {value}) VALUES (?, ?)", (id, modules_name))
conn.commit()
return '成功:启用模块:' + modules_name
elif do == 'del':
if a:
enabled_split = a[1].split('|')
if modules_name in enabled_split:
enabled_split.remove(modules_name)
c.execute(f"UPDATE {table} SET {value}='{'|'.join(enabled_split)}' WHERE ID='{id}'")
conn.commit()
return '成功:禁用模块:' + modules_name
else:
return '失败:未启用过该模块:' + modules_name
else:
return '失败:未启用过该模块:' + modules_name
def update_modules_self(do, id, modules_name, table='self_permission', value='DISABLE_MODULES'):
if not os.path.exists(dbpath):
initialize()
conn = sqlite3.connect(dbpath)
c = conn.cursor()
a = c.execute(f"SELECT * FROM {table} WHERE ID={id}").fetchone()
if do == 'del':
if a:
enabled_split = a[1].split('|')
if modules_name in enabled_split:
return '失败:模块已被禁用:' + modules_name
else:
enabled_split.append(modules_name)
c.execute(f"UPDATE {table} SET {value}='{'|'.join(enabled_split)}' WHERE ID='{id}'")
conn.commit()
return '成功:禁用模块:' + modules_name
else:
c.execute(f"INSERT INTO {table} (ID, {value}) VALUES (?, ?)", (id, modules_name))
conn.commit()
return '成功:禁用模块:' + modules_name
elif do == 'add':
if a:
enabled_split = a[1].split('|')
if modules_name in enabled_split:
enabled_split.remove(modules_name)
c.execute(f"UPDATE {table} SET {value}='{'|'.join(enabled_split)}' WHERE ID='{id}'")
conn.commit()
return '成功:启用模块:' + modules_name
else:
return '失败:未禁用过该模块:' + modules_name
else:
return '失败:未禁用过该模块:' + modules_name
def check_enable_modules(kwargs, modules_name, table='group_permission'):
if not os.path.exists(dbpath):
initialize()
if isinstance(kwargs, int):
target = kwargs
else:
if Group in kwargs:
table == 'group_permission'
target = kwargs[Group].id
if Friend in kwargs:
table == 'self_permission'
target = kwargs[Friend].id
if table == 'group_permission':
conn = sqlite3.connect(dbpath)
c = conn.cursor()
a = c.execute(f"SELECT * FROM {table} WHERE ID='{target}'").fetchone()
if a:
enabled_split = a[1].split('|')
if modules_name in enabled_split:
return True
else:
return False
else:
return False
if table == 'self_permission':
conn = sqlite3.connect(dbpath)
c = conn.cursor()
a = c.execute(f"SELECT * FROM {table} WHERE ID='{target}'").fetchone()
if a:
enabled_split = a[1].split('|')
if modules_name in enabled_split:
return False
else:
return True
else:
return True
def check_enable_modules_self(id, modules_name, table='self_permission'):
if not os.path.exists(dbpath):
initialize()
if table == 'self_permission':
conn = sqlite3.connect(dbpath)
c = conn.cursor()
a = c.execute(f"SELECT * FROM {table} WHERE ID='{id}'").fetchone()
if a:
enabled_split = a[1].split('|')
if modules_name in enabled_split:
return False
else:
return True
else:
return True
def check_enable_modules_all(table, modules_name):
# 检查表中所有匹配的对象返回一个list
if not os.path.exists(dbpath):
initialize()
enable_target = []
conn = sqlite3.connect(dbpath)
c = conn.cursor()
a = c.execute(f"SELECT * FROM {table}").fetchall()
for x in a:
enabled_split = x[1].split('|')
if modules_name in enabled_split:
enable_target.append(x[0])
return enable_target
def add_black_list(id):
if not os.path.exists(dbpath):
initialize()
conn = sqlite3.connect(dbpath)
c = conn.cursor()
c.execute(f"INSERT INTO black_list (ID) VALUES ('{id}')")
conn.commit()
c.close()
def add_white_list(id):
if not os.path.exists(dbpath):
initialize()
conn = sqlite3.connect(dbpath)
c = conn.cursor()
c.execute(f"INSERT INTO white_list (ID) VALUES ('{id}')")
conn.commit()
c.close()
def check_black_list(id):
if not os.path.exists(dbpath):
initialize()
conn = sqlite3.connect(dbpath)
c = conn.cursor()
a = c.execute(f"SELECT * FROM black_list WHERE ID={id}").fetchone()
if a:
return True
else:
return False
def check_white_list(id):
if not os.path.exists(dbpath):
initialize()
conn = sqlite3.connect(dbpath)
c = conn.cursor()
a = c.execute(f"SELECT * FROM white_list WHERE ID={id}").fetchone()
if a:
return True
else:
return False
def check_superuser(kwargs: dict):
if not os.path.exists(dbpath):
initialize()
if Group in kwargs:
id = kwargs[Member].id
if Friend in kwargs:
id = kwargs[Friend].id
conn = sqlite3.connect(dbpath)
c = conn.cursor()
a = c.execute(f"SELECT * FROM superuser WHERE ID={id}").fetchone()
if a:
return True
else:
return False
def add_superuser(id):
if not os.path.exists(dbpath):
initialize()
conn = sqlite3.connect(dbpath)
c = conn.cursor()
try:
c.execute(f"INSERT INTO superuser (ID) VALUES ('{id}')")
except:
traceback.print_exc()
conn.commit()
c.close()
return '成功?我也不知道成没成,懒得写判断了('
def del_superuser(id):
if not os.path.exists(dbpath):
initialize()
conn = sqlite3.connect(dbpath)
c = conn.cursor()
try:
c.execute(f"DELETE FROM superuser WHERE ID='{id}'")
except:
traceback.print_exc()
conn.commit()
c.close()
return '成功?我也不知道成没成,懒得写判断了('
def warn_someone(id):
if not os.path.exists(dbpath):
initialize()
conn = sqlite3.connect(dbpath)
c = conn.cursor()
a = c.execute(f"SELECT * FROM warn WHERE ID={id}").fetchone()
if a:
c.execute(f"UPDATE warn SET WARN='{int(a[1]) + 1}' WHERE ID='{id}'")
else:
c.execute(f"INSERT INTO warn (ID, WARN) VALUES (?, ?)", (id, 0,))
conn.commit()
if int(a[1]) > 5:
add_black_list(id)

View file

View file

@ -1,32 +0,0 @@
# -*- coding:utf-8 -*-
import json
import aiohttp
from modules.UTC8 import UTC8
from modules.pbc import pbc
async def main():
url = 'https://minecraft-zh.gamepedia.com/api.php?action=query&list=abuselog&aflprop=user|title|action|result|filter|timestamp&format=json'
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=5)) as req:
if req.status != 200:
return f"请求时发生错误:{req.status}"
else:
text1 = await req.text()
file = json.loads(text1)
d = []
for x in file['query']['abuselog'][:5]:
d.append('' + x['title'] + ' - ' + x['user'] + '' + UTC8(x['timestamp'], 'onlytimenoutc') + '\n过滤器名:' + x[
'filter'] + '\n处理结果:' + x['result'])
y = await pbc(d)
space = '\n'
f = space.join(y)
if f.find('<吃掉了>') != -1 or f.find('<全部吃掉了>') != -1:
return f + '\n...仅显示前5条内容\n检测到外来信息介入请前往滥用日志查看所有消息。Special:滥用日志\n[一分钟后撤回本消息]'
else:
return f + '\n...仅显示前5条内容\n[一分钟后撤回本消息]'
command = {'ab': 'ab'}

View file

@ -1,12 +0,0 @@
import re
from .bugtracker import bug
async def main(name):
q = re.match(r'(.*)\-(.*)', name)
if q:
return (await bug(q.group(1) + '-' + q.group(2)))
command = {'bug': 'bug'}

View file

@ -0,0 +1,41 @@
import re
from graia.application import MessageChain
from graia.application.message.elements.internal import Plain
from core.template import sendMessage
from .bugtracker import bug
async def bugtracker(kwargs: dict):
msg = kwargs['trigger_msg']
msg = re.sub('bug ', '', msg)
q = re.match(r'(.*)\-(.*)', msg)
if q:
result = await bug(q.group(1) + '-' + q.group(2))
msgchain = MessageChain.create([Plain(result)])
await sendMessage(kwargs, msgchain)
async def regex_bugtracker(kwargs: dict):
msg = kwargs[MessageChain].asDisplay()
if msg[0] == '!':
msg = re.sub('!', '', msg)
msg = re.sub('bug ', '', msg)
q = re.match(r'(.*)\-(.*)', msg)
if q:
result = await bug(q.group(1) + '-' + q.group(2))
msgchain = MessageChain.create([Plain(result)])
await sendMessage(kwargs, msgchain)
findlink = re.findall(r'(https://bugs.mojang.com/browse/.*?-\d*)', msg)
for link in findlink:
print(link)
matchbug = re.match(r'https://bugs.mojang.com/browse/(.*?-\d*)', link)
if matchbug:
await sendMessage(kwargs, await bug(matchbug.group(1)))
command = {'bug': bugtracker}
regex = {'bug_regex': regex_bugtracker}
help = {'bug': {'module': '查询Mojira上的漏洞编号。', 'help': '~bug <mojiraid> 查询Mojira上的漏洞编号。'},
'bug_regex': {'module': '正则自动查询Mojira上的漏洞编号。', 'help': '提示正则自动查询Mojira漏洞已开启所有消息开头为!<mojiraid>和来自Mojira的链接将会被自动查询并发送梗概内容。'}}

View file

@ -1,11 +0,0 @@
from os.path import abspath
import ffmpy
async def camr(filename):
ff = ffmpy.FFmpeg(
inputs={abspath(filename): None},
outputs={abspath(filename + '.amr'): '-ar 8000 -ab 12.2k -filter_complex channelsplit=channel_layout=mono'})
ff.run()
return filename + '.amr'

View file

@ -1,13 +0,0 @@
import json
import requests
def checkuser(path, username):
url = 'https://' + path + '.gamepedia.com/api.php?action=query&list=users&ususers=' + username + '&usprop=groups%7Cblockinfo%7Cregistration%7Ceditcount%7Cgender&format=json'
q = requests.get(url)
file = json.loads(q.text)
if ('missing' in file['query']['users'][0]):
return False
else:
return True

180
modules/core/__init__.py Normal file
View file

@ -0,0 +1,180 @@
from graia.application import Group, MessageChain, Member, Friend
from graia.application.message.elements.internal import Plain
import database
from core.template import sendMessage, check_permission
async def enable_modules(kwargs: dict):
"""
~enable [self] <modules/all>"""
command = kwargs['trigger_msg'].split(' ')
function_list = kwargs['function_list']
if not len(command) > 1:
await sendMessage(kwargs, '命令格式错误。' + enable_modules.__doc__)
return
command_second_word = command[1]
if Group in kwargs:
if command_second_word == 'self':
if not len(command) > 2:
await sendMessage(kwargs, '命令格式错误。' + enable_modules.__doc__)
return
command_third_word = command[2]
if command_third_word in function_list:
msg = database.update_modules_self('add', kwargs[Member].id, command_third_word)
await sendMessage(kwargs, msg)
else:
await sendMessage(kwargs, '此模块不存在。')
elif command_second_word == 'all':
if check_permission(kwargs):
msglist = []
for function in function_list:
msg = database.update_modules('add', kwargs[Group].id, function)
msglist.append(msg)
await sendMessage(kwargs, '\n'.join(msglist))
else:
await sendMessage(kwargs, '你没有使用该命令的权限。')
elif command_second_word in function_list:
if check_permission(kwargs):
msg = database.update_modules('add', kwargs[Group].id, command_second_word)
await sendMessage(kwargs, msg)
else:
await sendMessage(kwargs, '你没有使用该命令的权限。')
else:
msgchain = MessageChain.create([Plain('此模块不存在。')])
await sendMessage(kwargs, msgchain)
elif Friend in kwargs:
if command_second_word == 'self':
if not len(command) > 2:
await sendMessage(kwargs, '命令格式错误。' + enable_modules.__doc__)
return
command_second_word = command[2]
do = 'add'
if command_second_word == 'all':
msglist = []
for function in function_list:
msg = database.update_modules_self(do, kwargs[Friend].id, function)
msglist.append(msg)
await sendMessage(kwargs, '\n'.join(msglist))
elif command_second_word in function_list:
msg = database.update_modules_self(do, kwargs[Friend].id, command_second_word)
await sendMessage(kwargs, msg)
else:
await sendMessage(kwargs, '此模块不存在。')
async def disable_modules(kwargs: dict):
"""
~disable [self] <modules/all>"""
command = kwargs['trigger_msg'].split(' ')
if not len(command) > 1:
await sendMessage(kwargs, '命令格式错误。' + disable_modules.__doc__)
return
function_list = kwargs['function_list']
command_second_word = command[1]
if Group in kwargs:
if command_second_word == 'self':
if not len(command) > 2:
await sendMessage(kwargs, '命令格式错误。' + disable_modules.__doc__)
return
command_third_word = command[2]
if command_third_word in function_list:
msg = database.update_modules_self('del', kwargs[Member].id, command_third_word)
await sendMessage(kwargs, msg)
else:
await sendMessage(kwargs, '此模块不存在。')
elif command_second_word == 'all':
if check_permission(kwargs):
msglist = []
for function in function_list:
msg = database.update_modules('del', kwargs[Group].id, function)
msglist.append(msg)
await sendMessage(kwargs, '\n'.join(msglist))
else:
await sendMessage(kwargs, '你没有使用该命令的权限。')
elif command_second_word in function_list:
if check_permission(kwargs):
msg = database.update_modules('del', kwargs[Group].id, command_second_word)
await sendMessage(kwargs, msg)
else:
await sendMessage(kwargs, '你没有使用该命令的权限。')
else:
await sendMessage(kwargs, '此模块不存在。')
elif Friend in kwargs:
if command_second_word == 'self':
if not len(command) > 2:
await sendMessage(kwargs, '命令格式错误。' + disable_modules.__doc__)
return
command_second_word = command[2]
do = 'del'
if command_second_word == 'all':
msglist = []
for function in function_list:
msg = database.update_modules_self(do, kwargs[Friend].id, function)
msglist.append(msg)
await sendMessage(kwargs, '\n'.join(msglist))
elif command_second_word in function_list:
msg = database.update_modules_self(do, kwargs[Friend].id, command_second_word)
await sendMessage(kwargs, msg)
else:
await sendMessage(kwargs, '此模块不存在。')
async def bot_help(kwargs: dict):
help_list = kwargs['help_list']
print(help_list)
help_msg = []
help_msg.append('基础命令:')
for x in help_list:
if 'essential' in help_list[x]:
help_msg.append(help_list[x]['help'])
help_msg.append('模块扩展命令:')
for x in help_list:
if Group in kwargs:
if database.check_enable_modules(kwargs, x):
if 'help' in help_list[x]:
help_msg.append(help_list[x]['help'])
if 'depend' in help_list[x]:
if database.check_enable_modules(kwargs, help_list[x]['depend']):
if help_list[x]['help'] not in help_msg:
help_msg.append(help_list[x]['help'])
elif Friend in kwargs:
if 'help' in help_list[x]:
help_msg.append(help_list[x]['help'])
if 'depend' in help_list[x]:
if help_list[x]['help'] not in help_msg:
help_msg.append(help_list[x]['help'])
await sendMessage(kwargs, '\n'.join(help_msg))
async def modules_help(kwargs: dict):
help_list = kwargs['help_list']
help_msg = []
help_msg.append('当前可用的模块有:')
for x in help_list:
if 'module' in help_list[x]:
help_msg.append(x+ '' + help_list[x]['module'])
await sendMessage(kwargs, '\n'.join(help_msg))
async def add_su(kwargs: dict):
command = kwargs['trigger_msg'].split(' ')
if database.check_superuser(kwargs):
await sendMessage(kwargs, database.add_superuser(command[1]))
else:
await sendMessage(kwargs, '权限不足。')
async def del_su(kwargs: dict):
command = kwargs['trigger_msg'].split(' ')
if database.check_superuser(kwargs):
await sendMessage(kwargs, database.del_superuser(command[1]))
else:
await sendMessage(kwargs, '权限不足。')
essential = {'enable': enable_modules, 'disable': disable_modules, 'help': bot_help, 'modules': modules_help}
admin = {'add_su': add_su, 'del_su': del_su}
help = {'enable': {'module': '开启一个模块', 'help': '~enable <模块名> - 开启一个模块', 'essential': True},
'disable': {'module': '关闭一个模块', 'help': '~disable <模块名> - 关闭一个模块', 'essential': True},
'module': {'help': '~modules - 查询所有可用模块。'}}

View file

@ -1,15 +0,0 @@
async def main():
return '''===============
主开发者 OasisAkari
_LittleC_
代码贡献 Dianliang233
wyapx
资金支持 WDLJT
2020 Teahouse Studios
===============
此机器人的源代码已于https://github.com/Teahouse-Studios/bot仓库与母项目Graia采用相同协议AGPL-3.0 License进行开源
[30秒后撤回本消息]'''
command = 'credits'

View file

@ -1,46 +0,0 @@
import os
import re
import uuid
from os.path import abspath
import aiohttp
from bs4 import BeautifulSoup as bs
async def dfile(link, filename):
suffix = re.match(r'.*(\..*)$', filename)
async with aiohttp.ClientSession() as session:
async with session.get(link + 'File:' + filename) as req:
if req.status != 200:
return f"请求时发生错误:{req.status}"
else:
q = await req.text()
soup = bs(q, 'html.parser')
aa = soup.find('div', id='mw-content-text')
aaa = aa.find('div', class_='fullImageLink', id='file')
aaaa = aaa.find('audio')
print(aaaa)
z = re.match('.*<.*src="(.*)".*><.*', str(aaa), re.S)
url = z.group(1)
print(url)
d = abspath('./assets/cache/')
if not os.path.exists(d):
os.makedirs(d)
print(suffix.group(1))
path = d + '/' + str(uuid.uuid4()) + suffix.group(1)
print(path)
try:
if not os.path.exists(d):
os.mkdir(d)
if not os.path.exists(path):
async with aiohttp.ClientSession() as session:
async with session.get(url) as r:
with open(path, "wb") as fp:
chunk = await r.content.read()
fp.write(chunk)
return path
else:
print("已存在")
return path
except Exception as e:
print(str(e))

View file

@ -1,25 +0,0 @@
import re
import traceback
import aiohttp
from bs4 import BeautifulSoup as bs
async def findimage(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as req:
if req.status != 200:
return None
else:
q = await req.text()
try:
soup = bs(q, 'html.parser')
aa = soup.find('div', id='mw-content-text')
src = aa.find_all('div', class_='fullImageLink')
z = re.match('.*<a href="(.*)"><.*', str(src), re.S)
find = re.sub(r'\?.*', '', z.group(1))
return find
except Exception:
traceback.print_exc()
return None

View file

@ -1,35 +0,0 @@
path = '~'
async def main():
return f'''{path}ab - 查看Minecraft Wiki过滤器日志。
{path}bug <JiraID> - 从Mojira中获取此Bug的信息
{path}credits - 展示制作人员列表
{path}mcv - 获取当前Minecraft Java版最新版本
{path}mcbv - 获取当前Minecraft基岩版最新版本
{path}mcdv - 获取当前Minecraft Dungeons最新版本
{path}rc - 查看Minecraft Wiki最近更改
{path}server -h
{path}user -h
{path}wiki -h
! - 用于快捷查bug!mc-4
[[]] - 用于快捷查wiki[[海晶石]]
{{{{}}}} - 用于快捷查wiki模板{{{{v}}}}
[30秒后撤回本消息]'''
def wikihelp():
return f'''{path}wiki ~<site> <pagename> - 从指定Gamepedia站点中输出条目链接。
{path}wiki <lang>:<pagename>, {path}wiki-<lang> <pagename> - 从指定语言中的Minecraft Wiki中输出条目链接
{path}wiki <pagename> - 从Minecraft Wiki英文中输出条目链接'''
def userhelp():
return f'''{path}user ~<site> <pagename> - 从指定Gamepedia站点中输出用户信息。
{path}user <lang>:<pagename>, {path}user-<lang> <pagename> - 从指定语言中的Minecraft Wiki中输出用户信息
{path}user <pagename> - 从Minecraft Wiki英文中输出用户信息
[-r] - 输出详细信息
[-p] - 输出一张用户信息的图片不包含用户组'''
command = {'help': 'help'}

View file

@ -1,26 +0,0 @@
from configparser import ConfigParser
from os.path import abspath
path = abspath("./modules/interwikilist/")
print(path)
def iwlist():
cp = ConfigParser()
cp.read(path+"/list.cfg")
print(path)
section = cp.sections()[0]
return (cp.options(section))
def iwlink(iw):
cp = ConfigParser()
cp.read(path+"/list.cfg")
section = cp.sections()[0]
return (cp.get(section, iw))
def iwalllink():
links = []
for x in iwlist():
links.append(iwlink(x))
return links

View file

@ -1,36 +0,0 @@
[list]
aether = https://aether.gamepedia.com/
ftb = https://ftb.gamepedia.com/
gphelp = https://help.gamepedia.com/
gphelpzh = https://help-zh.gamepedia.com/
mw = https://www.mediawiki.org/w/
mwphab = https://phabricator.wikimedia.org/
wikimedia = https://commons.wikimedia.org/w/
wikisource = http://wikisource.org/wiki/
wiktionary = http://en.wiktionary.org/wiki/
cs = https://minecraft-cs.gamepedia.com/
de = https://minecraft-de.gamepedia.com/
el = https://minecraft-el.gamepedia.com/
en = https://minecraft.gamepedia.com/
es = https://minecraft-es.gamepedia.com/
fr = https://minecraft-fr.gamepedia.com/
hu = https://minecraft-hu.gamepedia.com/
it = https://minecraft-it.gamepedia.com/
ja = https://minecraft-ja.gamepedia.com/
ko = https://minecraft-ko.gamepedia.com/
nl = https://minecraft-nl.gamepedia.com/
pl = https://minecraft-pl.gamepedia.com/
pt = https://minecraft-pt.gamepedia.com/
ru = https://minecraft-ru.gamepedia.com/
th = https://minecraft-th.gamepedia.com/
tr = https://minecraft-tr.gamepedia.com/
uk = https://minecraft-uk.gamepedia.com/
zh = https://minecraft-zh.gamepedia.com/
moegirl = https://zh.moegirl.org.cn/
enmoe = https://en.moegirl.org.cn/
jamoe = https://ja.moegirl.org.cn/
moe = https://zh.moegirl.org.cn/
arc = https://wiki.arcaea.cn/index.php/
arcaea = https://wiki.arcaea.cn/index.php/
lakeus = https://files.lakejason0.ml/
adodoz = https://wiki.adodoz.cn/

View file

@ -1,34 +0,0 @@
import re
import aiohttp
async def get_data(url: str, fmt: str):
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=20)) as req:
if hasattr(req, fmt):
return await getattr(req, fmt)()
else:
raise ValueError(f"NoSuchMethod: {fmt}")
async def main():
try:
data = await get_data('https://bugs.mojang.com/rest/api/2/project/10200/versions', "json")
except (ConnectionError, OSError): # Probably...
return "发生错误:土豆熟了"
beta = []
release = []
for v in data:
if not v['archived']:
match = re.match(r"(.*Beta)$", v["name"])
if match:
beta.append(match.group(1))
else:
release.append(v["name"])
prefix = " | "
return f'Beta{prefix.join(beta)}Release{prefix.join(release)}\n' \
f'数据来源于MoJira可能会比官方发布要早一段时间。信息仅供参考。'
command = {'mcbv': 'mcbv'}

View file

@ -1,24 +0,0 @@
import aiohttp
async def get_data(url: str, fmt: str):
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=20)) as req:
if hasattr(req, fmt):
return await getattr(req, fmt)()
else:
raise ValueError(f"NoSuchMethod: {fmt}")
async def main():
try:
data = await get_data('https://bugs.mojang.com/rest/api/2/project/11901/versions', "json")
except (ConnectionError, OSError): # Probably...
return "发生错误:土豆熟了"
for v in data:
if not v['archived']:
return f'最新版:{v.get("name")} \n数据来源于MoJira可能会比官方发布要早一段时间。信息仅供参考。'
return "出了点问题快去锤develop"
command = {'mcdv': 'mcdv'}

33
modules/mcv/__init__.py Normal file
View file

@ -0,0 +1,33 @@
from graia.application import MessageChain
from graia.application.message.elements.internal import Plain
from core.template import sendMessage
from .mcv import mcv, mcbv, mcdv
async def mcv_loader(kwargs: dict):
run = await mcv()
msgchain = MessageChain.create([Plain(run)])
await sendMessage(kwargs, msgchain)
async def mcbv_loader(kwargs: dict):
run = await mcbv()
msgchain = MessageChain.create([Plain(run)])
await sendMessage(kwargs, msgchain)
async def mcdv_loader(kwargs: dict):
run = await mcdv()
msgchain = MessageChain.create([Plain(run)])
await sendMessage(kwargs, msgchain)
command = {'mcv': mcv_loader, 'mcbv': mcbv_loader, 'mcdv': mcdv_loader}
help = {'mcv': {'module': '查询当前Minecraft Java版启动器内最新版本。',
'help': '~mcv - 查询当前Minecraft Java版启动器内最新版本。'},
'mcbv': {'module': '查询当前Minecraft基岩版Jira上记录的最新版本。',
'help': '~mcbv - 查询当前Minecraft基岩版Jira上记录的最新版本。'},
'mcdv': {'module': '查询当前Minecraft Dungeons Jira上记录的最新版本。',
'help': '~mcdv - 查询当前Minecraft Dungeons Jira上记录的最新版本。'}
}

View file

@ -1,3 +1,5 @@
import re
import aiohttp
@ -10,7 +12,7 @@ async def get_data(url: str, fmt: str):
raise ValueError(f"NoSuchMethod: {fmt}")
async def main():
async def mcv():
try:
data = await get_data('http://launchermeta.mojang.com/mc/game/version_manifest.json', "json")
message1 = f"最新版:{data['latest']['release']},最新快照:{data['latest']['snapshot']}"
@ -33,4 +35,31 @@ Mojira上所记录最新版本为
以启动器内最新版本为准Mojira仅作版本号预览用"""
command = {'mcv': 'mcv'}
async def mcbv():
try:
data = await get_data('https://bugs.mojang.com/rest/api/2/project/10200/versions', "json")
except (ConnectionError, OSError): # Probably...
return "发生错误:土豆熟了"
beta = []
release = []
for v in data:
if not v['archived']:
match = re.match(r"(.*Beta)$", v["name"])
if match:
beta.append(match.group(1))
else:
release.append(v["name"])
prefix = " | "
return f'Beta{prefix.join(beta)}Release{prefix.join(release)}\n' \
f'数据来源于MoJira可能会比官方发布要早一段时间。信息仅供参考。'
async def mcdv():
try:
data = await get_data('https://bugs.mojang.com/rest/api/2/project/11901/versions', "json")
except (ConnectionError, OSError): # Probably...
return "发生错误:土豆熟了"
for v in data:
if not v['archived']:
return f'最新版:{v.get("name")} \n数据来源于MoJira可能会比官方发布要早一段时间。信息仅供参考。'
return "出了点问题快去锤develop"

View file

@ -0,0 +1,99 @@
import asyncio
import traceback
from os.path import abspath
from graia.application import MessageChain
from graia.application.message.elements.internal import Plain
from database import check_enable_modules_all
from modules.mcv.mcv import get_data
def mcversion():
w = open(abspath('./assets/mcversion.txt'), 'r+')
s = w.read().split('\n')
w.close()
return s
def mcversion_jira():
w = open(abspath('./assets/mcversion_jira.txt'), 'r+')
s = w.read().split('\n')
w.close()
return s
async def mcv_rss(app):
url = 'http://launchermeta.mojang.com/mc/game/version_manifest.json'
print('subbot ver launched')
while True:
try:
verlist = mcversion()
file = await get_data(url, 'json')
release = file['latest']['release']
snapshot = file['latest']['snapshot']
if release not in verlist:
print(release)
for qqgroup in check_enable_modules_all('group_permission', 'mcv_rss'):
try:
await app.sendGroupMessage(int(qqgroup), MessageChain.create(
[Plain('启动器已更新' + file['latest']['release'] + '正式版。')]))
await asyncio.sleep(0.5)
except Exception:
traceback.print_exc()
addversion = open('./assets/mcversion.txt', 'a')
addversion.write('\n' + release)
addversion.close()
verlist = mcversion()
if snapshot not in verlist:
print(snapshot)
for qqgroup in check_enable_modules_all('group_permission', 'mcv_rss'):
try:
await app.sendGroupMessage(int(qqgroup), MessageChain.create(
[Plain('启动器已更新' + file['latest']['snapshot'] + '快照。')]))
await asyncio.sleep(0.5)
except Exception:
traceback.print_exc()
addversion = open('./assets/mcversion.txt', 'a')
addversion.write('\n' + snapshot)
addversion.close()
await asyncio.sleep(10)
except Exception:
traceback.print_exc()
await asyncio.sleep(5)
async def mcv_jira_rss(app):
url = 'https://bugs.mojang.com/rest/api/2/project/10400/versions'
print('subbot jira launched')
while True:
try:
verlist = mcversion_jira()
file = await get_data(url, 'json')
release = []
for v in file:
if not v['archived']:
release.append(v['name'])
for x in release:
if x not in verlist:
print(x)
for qqgroup in check_enable_modules_all('group_permission', 'mcv_jira_rss'):
try:
await app.sendGroupMessage(int(qqgroup), MessageChain.create(
[Plain(f'Jira已更新{x}\nJira上的信息仅作版本号预览用不代表启动器已更新此版本')]))
await asyncio.sleep(0.5)
except Exception:
traceback.print_exc()
addversion = open('./assets/mcversion_jira.txt', 'a')
addversion.write('\n' + x)
addversion.close()
await asyncio.sleep(10)
except Exception:
traceback.print_exc()
await asyncio.sleep(5)
rss = {'mcv_rss': mcv_rss, 'mcv_jira_rss': mcv_jira_rss}
options = ['mcv_rss', 'mcv_jira_rss']
help = {'mcv_rss': {'module': '订阅Minecraft Java版游戏版本检测。仅群聊'},
'mcv_jira_rss': {'module': '订阅Minecraft Java版游戏版本检测Jira记录仅作预览用仅群聊'}}

View file

@ -1,8 +0,0 @@
from os.path import abspath
def mcversion():
w = open(abspath('./assets/mcversion.txt'), 'r')
s = w.read().split('\n')
w.close()
return (s)

View file

@ -1,42 +0,0 @@
import os
import re
from os.path import abspath
def mcvrss():
w = open(abspath('./mcvrss.txt'), 'r')
s = w.read().split('\n')
if '' in s:
s.remove('')
w.close()
return (s)
def mcvrssa(group):
q = mcvrss()
if group in q:
return ('该群已在订阅列表中。')
else:
wr = open('../mcvrss.txt', 'a+')
wr.write(re.sub(r'\n$', '', '\n' + group))
wr.close()
return ('已订阅。')
def mcvrssr(group):
q = mcvrss()
if group in q:
q.remove(group)
os.remove('../mcvrss.txt')
wr = open('../mcvrss.txt', 'a')
y = []
h = ''
for x in q:
y.append(x + '\n')
g = h.join(y)
k = re.sub(r'\n$', '', g)
wr.write(k)
wr.close()
return ('已移除订阅。')
else:
return ('此群不在订阅列表中。')

View file

@ -1,529 +0,0 @@
#Copied from kurisu(https://github.com/nh-server/Kurisu/blob/port/cogs/err.py)
import binascii
import re
class Err():
"""
Parses CTR error codes.
"""
# CTR Error Codes
summaries = {
0: 'Success',
1: 'Nothing happened',
2: 'Would block',
3: 'Out of resource',
4: 'Not found',
5: 'Invalid state',
6: 'Not supported',
7: 'Invalid argument',
8: 'Wrong argument',
9: 'Canceled',
10: 'Status changed',
11: 'Internal',
63: 'Invalid result value'
}
levels = {
0: "Success",
1: "Info",
25: "Status",
26: "Temporary",
27: "Permanent",
28: "Usage",
29: "Reinitialize",
30: "Reset",
31: "Fatal"
}
modules = {
0: 'Common',
1: 'Kernel',
2: 'Util',
3: 'File server',
4: 'Loader server',
5: 'TCB',
6: 'OS',
7: 'DBG',
8: 'DMNT',
9: 'PDN',
10: 'GSP',
11: 'I2C',
12: 'GPIO',
13: 'DD',
14: 'CODEC',
15: 'SPI',
16: 'PXI',
17: 'FS',
18: 'DI',
19: 'HID',
20: 'CAM',
21: 'PI',
22: 'PM',
23: 'PM_LOW',
24: 'FSI',
25: 'SRV',
26: 'NDM',
27: 'NWM',
28: 'SOC',
29: 'LDR',
30: 'ACC',
31: 'RomFS',
32: 'AM',
33: 'HIO',
34: 'Updater',
35: 'MIC',
36: 'FND',
37: 'MP',
38: 'MPWL',
39: 'AC',
40: 'HTTP',
41: 'DSP',
42: 'SND',
43: 'DLP',
44: 'HIO_LOW',
45: 'CSND',
46: 'SSL',
47: 'AM_LOW',
48: 'NEX',
49: 'Friends',
50: 'RDT',
51: 'Applet',
52: 'NIM',
53: 'PTM',
54: 'MIDI',
55: 'MC',
56: 'SWC',
57: 'FatFS',
58: 'NGC',
59: 'CARD',
60: 'CARDNOR',
61: 'SDMC',
62: 'BOSS',
63: 'DBM',
64: 'Config',
65: 'PS',
66: 'CEC',
67: 'IR',
68: 'UDS',
69: 'PL',
70: 'CUP',
71: 'Gyroscope',
72: 'MCU',
73: 'NS',
74: 'News',
75: 'RO',
76: 'GD',
77: 'Card SPI',
78: 'EC',
79: 'Web Browser',
80: 'Test',
81: 'ENC',
82: 'PIA',
83: 'ACT',
84: 'VCTL',
85: 'OLV',
86: 'NEIA',
87: 'NPNS',
90: 'AVD',
91: 'L2B',
92: 'MVD',
93: 'NFC',
94: 'UART',
95: 'SPM',
96: 'QTM',
97: 'NFP (amiibo)',
254: 'Application',
255: 'Invalid result value'
}
descriptions = {
0: 'Success',
2: 'Invalid memory permissions (kernel)',
4: 'Invalid ticket version (AM)',
5: 'Invalid string length. This error is returned when service name length is greater than 8 or zero. (srv)',
6: 'Access denied. This error is returned when you request a service that you don\'t have access to. (srv)',
7: 'String size does not match string contents. This error is returned when service name contains an unexpected null byte. (srv)',
8: 'Camera already in use/busy (qtm).',
10: 'Not enough memory (os)',
26: 'Session closed by remote (os)',
32: 'Empty CIA? (AM)',
37: 'Invalid NCCH? (AM)',
39: 'Invalid title version (AM)',
43: 'Database doesn\'t exist/failed to open (AM)',
44: 'Trying to uninstall system-app (AM)',
47: 'Invalid command header (OS)',
101: 'Archive not mounted/mount-point not found (fs)',
105: 'Request timed out (http)',
106: 'Invalid signature/CIA? (AM)',
120: 'Title/object not found? (fs)',
141: 'Gamecard not inserted? (fs)',
190: 'Object does already exist/failed to create object.',
230: 'Invalid open-flags / permissions? (fs)',
250: 'FAT operation denied (fs?)',
271: 'Invalid configuration (mvd).',
335: '(No permission? Seemed to appear when JKSM was being used without its XML.)',
391: 'NCCH hash-check failed? (fs)',
392: 'RSA/AES-MAC verification failed? (fs)',
393: 'Invalid database? (AM)',
395: 'RomFS/Savedata hash-check failed? (fs)',
630: 'Command not allowed / missing permissions? (fs)',
702: 'Invalid path? (fs)',
740: '(Occurred when NDS card was inserted and attempting to use AM_GetTitleCount on MEDIATYPE_GAME_CARD.) (fs)',
761: 'Incorrect read-size for ExeFS? (fs)',
1000: 'Invalid selection',
1001: 'Too large',
1002: 'Not authorized',
1003: 'Already done',
1004: 'Invalid size',
1005: 'Invalid enum value',
1006: 'Invalid combination',
1007: 'No data',
1008: 'Busy',
1009: 'Misaligned address',
1010: 'Misaligned size',
1011: 'Out of memory',
1012: 'Not implemented',
1013: 'Invalid address',
1014: 'Invalid pointer',
1015: 'Invalid handle',
1016: 'Not initialized',
1017: 'Already initialized',
1018: 'Not found',
1019: 'Cancel requested',
1020: 'Already exists',
1021: 'Out of range',
1022: 'Timeout',
1023: 'Invalid result value'
}
# Nintendo Error Codes
errcodes = {
# Nintendo 3DS
'001-0502': 'Some sort of network error related to friend presence. "Allow Friends to see your online status" might fix this.',
'001-0803': 'Could not communicate with authentication server.',
'002-0102': 'System is permanently banned by Nintendo. You cannot ask how to fix this issue here.',
'002-0107': 'System is temporarily(?) banned by Nintendo. You cannot ask how to fix this issue here.',
'002-0119': 'System update required (outdated friends-module)',
'002-0120': 'Title update required (outdated title version)',
'002-0121': 'Local friend code SEED has invalid signature.\n\nThis should not happen unless it is modified. The only use case for modifying this file is for system unbanning, so you cannot ask how to fix this issue here.',
'002-0123': 'System is generally banned by Nintendo. You cannot ask how to fix this issue here.',
'022-2502': 'Region settings between the console and Nintendo Network ID do not match. The console region must be fixed to use the NNID. If you want to use a different region, the NNID must be unlinked from the system or deleted.',
'022-2932': 'Unable to agree to the Nintendo Network Services Agreement. Usually found on region-changed devices.',
'003-1099': 'Access point could not be found with the given SSID.',
'003-2001': 'DNS error. If using a custom DNS server, make sure the settings are correct.',
'005-7000': 'Base error code for most other error codes. No error occured.',
'005-2008': 'This error is caused by installing a game or game update from an unofficial source, as it contains a bad ticket.\nThe only solution is to delete the unofficial game or update as well as its ticket\nin FBI, and install the game or update legitimately. If the title was uninstalled\nalready, remove the ticket in FBI.',
'005-4800': 'HTTP Status 500 (Internal Error), unknown cause(?). eShop servers might have issues.',
'005-5602': 'Unable to connect to the eShop. This error is most likely the result of an incorrect region setting.\nMake sure your region is correctly set in System Settings. If you encounter this error after region-changing your system, make sure you followed all the steps properly.',
'005-5958': 'Unknown eShop error. Usually seen on region-changed devices.',
'005-5964': 'Your Nintendo Network ID has been banned from accessing the eShop.\nIf you think this was unwarranted, you will have to contact Nintendo Support to have it reversed.',
'005-7550': 'Replace SD card(?). Occurs on Nintendo eShop.',
'006-0102': 'Unexpected error. Could probably happen trying to play an out-of-region title online?',
'006-0332': 'Disconnected from the game server.',
'006-0502': 'Could not connect to the server.\n\n• Check the [network status page](http://support.nintendo.com/networkstatus)\n• Move closer to your wireless router\n• Verify DNS settings. If "Auto-Obtain" doesn\'t work, try Google\'s Public DNS (8.8.8.8, 8.8.4.4) and try again.',
'006-0612': 'Failed to join the session.',
'007-0200': 'Could not access SD card.',
'007-2001': 'Usually the result after region-changing the system. New 3DS cannot fix this issue right now.',
'007-2100': 'The connection to the Nintendo eShop timed out.\nThis may be due to an ongoing server maintenance, check <https://support.nintendo.com/networkstatus> to make sure the servers are operating normally. You may also encounter this error if you have a weak internet connection.',
'007-2404': 'An error occurred while attempting to connect to the Nintendo eShop.\nMake sure you are running the latest firmware, since this error will appear if you are trying to access the eShop on older versions.',
'007-2670': 'Generic connection error.',
'007-2720': 'SSL error?',
'007-2916': 'HTTP error, server is probably down. Try again later?',
'007-2920': 'This error is caused by installing a game or game update from an unofficial source, as it contains a bad ticket.\nThe only solution is to delete the unofficial game or update as well as its ticket\nin FBI, and install the game or update legitimately. If the title was uninstalled\nalready, remove the ticket in FBI.',
'007-2913': 'HTTP error, server is probably down. Try again later?',
'007-2923': 'The Nintendo Servers are currently down for maintenance. Please try again later.',
'007-3102': 'Cannot find title on Nintendo eShop. Probably pulled.',
'007-6054': 'Occurs when ticket database is full (8192 tickets).',
'009-1000': 'System update required. (friends module?)',
'009-2916': 'NIM HTTP error, server is probably down. Try again later?',
'009-2913': 'NIM HTTP error, server is probably down. Try again later?',
'009-2920': 'This error is caused by installing a game or game update from an unofficial source, as it contains a bad ticket.\nThe only solution is to delete the unofficial game or update as well as its ticket\nin FBI, and install the game or update legitimately. If the title was uninstalled\nalready, remove the ticket in FBI.',
'009-4079': 'Could not access SD card. General purpose error.',
'009-4998': '"Local content is newer."\nThe actual cause of this error is unknown.',
'009-6106': '"AM error in NIM."\nProbably a bad ticket.',
'009-8401': 'Update data corrupted. Delete and re-install.',
'011-3021': 'Cannot find title on Nintendo eShop. Probably incorrect region, or never existed.',
'011-3136': 'Nintendo eShop is currently unavailable. Try again later.',
'011-6901': 'System is banned by Nintendo, this error code description is oddly Japanese, generic error code. You cannot ask how to fix this issue here.',
'012-1511': 'Certificate warning.',
'014-0016': 'Both systems have the same movable.sed key. Format the target and try system transfer again.',
'014-0062': 'Error during System Transfer. Move closer to the wireless router and keep trying.',
'022-2452': 'Occurs when trying to use Nintendo eShop with UNITINFO patches enabled.',
'022-2501': 'Attempting to use a Nintendo Network ID on one system when it is linked on another. This can be the result of using System Transfer, then restoring the source system\'s NAND and attempting to use services that require a Nintendo Network ID.\n\nIn a System Transfer, all Nintendo Network ID accounts associated with the system are transferred over, whether they are currently linked or not.',
'022-2511': 'System update required (what causes this? noticed while opening Miiverse, probably not friends module)',
'022-2613': 'Incorrect e-mail or password when trying to link an existing Nintendo Network ID. Make sure there are no typos, and the given e-mail is the correct one for the given ID.\nIf you forgot the password, reset it at <https://id.nintendo.net/account/forgotten-password>',
'022-2631': 'Nintendo Network ID deleted, or not usable on the current system. If you used System Transfer, the Nintendo Network ID will only work on the target system.',
'022-2633': 'Nintendo Network ID temporarily locked due to too many incorrect password attempts. Try again later.',
'022-2634': 'Nintendo Network ID is not correctly linked on the system. This can be a result of formatting the SysNAND using System Settings to unlink it from the EmuNAND.\nTo fix, boot GodMode9 and [follow these steps.](https://3ds.hacks.guide/godmode9-usage#removing-an-nnid-without-formatting-your-device)\nAfterwards, reboot and sign into your NNID again.',
'022-2812': 'System is permanently banned by Nintendo for illegally playing the Pokemon Sun & Moon ROM leak online before release. You cannot ask how to fix this issue here.',
'022-2815': 'System is banned by Nintendo from Miiverse access.',
'022-5515': 'Network timeout.',
'032-1820': 'Browser error that asks whether you want to go on to a potentially dangerous website. Can be bypassed by touching "yes".',
'090-0212': 'Game is permanently banned from Pokémon Global Link. This is most likely as a result of using altered or illegal save data.',
# Wii U
# these all mean different things technically and maybe i should list them
'102-2802': 'NNID is permanently banned by Nintendo. You cannot ask how to fix this issue here.',
'102-2805': 'System is banned from accessing Nintendo eShop. You cannot ask how to fix this issue here.',
'102-2812': 'System + linked NNID and access to online services are permanently banned by Nintendo. You cannot ask how to fix this issue here.',
'102-2813': 'System is banned by Nintendo. You cannot ask how to fix this issue here.',
'102-2814': 'System is permanently banned from online multiplayer in a/multiple game(s) (preferably Splatoon). You cannot ask how to fix this issue here.',
'102-2815': 'System is banned from accessing the Nintendo eShop. You cannot ask how to fix this issue here.',
'102-2816': 'System is banned for a/multiple game(s) (preferably Splatoon) for an unknown duration, by attempting to use modified static.pack/+ game files online. You cannot ask how to fix this issue here.',
'106-0306': 'NNID is temporarily banned from a/multiple games (preferably Splatoon) online multiplayer. You cannot ask how to fix this issue here.',
'106-0346': 'NNID is permanently banned from a/multiple games (preferably Splatoon) online multiplayer. You cannot ask how to fix this issue here.',
'112-1037': 'Incorrect permissions for the default index.html file which prevents the Internet Browser from reading it. This can be fixed by following [this guide](https://wiiu.hacks.guide/#/fix-errcode-112-1037).',
'115-1009': 'System is permanently banned from Miiverse.',
'121-0902': 'Permissions missing for the action you are trying to perfrom (Miiverse error).',
'126-9622': 'Error when attempting to add funds. Maybe try again after a while, or make sure there is no issue with the payment method.',
'150-1031': 'Disc could not be read. Either the disc is dirty, the lens is dirty, or the disc is unsupported (i.e. not a Wii or Wii U game).',
'150-2031': 'Disc could not be read. Either the disc is dirty, the lens is dirty, or the disc is unsupported (i.e. not a Wii or Wii U game).',
'160-0101': '"Generic error". Can happen when formatting a system with CBHC.',
'160-0102': 'Error in SLC/MLC or USB.',
'160-0103': '"The system memory is corrupted (MLC)."',
'160-0104': '"The system memory is corrupted (SLC)."',
'160-0105': 'USB storage corrupted?',
'199-9999': 'Usually occurs when trying to run an unsigned title without signature patches, or something unknown(?) is corrupted.',
}
switch_errcodes = {
# Switch
'007-1037': ['Could not detect an SD card.', None],
'2001-0125': ['Executed svcCloseHandle on main-thread handle (No known support page)', None],
'2002-6063': ['Attempted to read eMMC CID from browser? (No known support page)', None],
'2005-0003': ['You are unable to download software.', 'https://en-americas-support.nintendo.com/app/answers/detail/a_id/22393/kw/2005-0003'],
'2016-2101': ['Inserted Tencent-Nintendo (Chinese model) cartridge into regular Switch, which is region locked.', 'https://nintendoswitch.com.cn/support/'],
'2110-3400': ['This error code indicates the Internet connection you are attempting to use likely requires some type of authentication through a web browser (such as agreeing to terms of service or entering a username and password).', 'https://en-americas-support.nintendo.com/app/answers/detail/a_id/22569/kw/2110-3400'],
'2124-4007': ['System + Nintendo Account are permanently banned by Nintendo. You cannot ask how to fix this issue here.', 'https://en-americas-support.nintendo.com/app/answers/detail/a_id/28046/kw/2124-4007'],
'2124-4025': ['Game Card is banned, this "COULD" happen to legal users if so contact Nintendo to allow them to whitelist the Game Card. Otherwise, You cannot ask how to fix this issue here.', None],
'2124-4027': ['System + Nintendo Account are banned from a game (preferably Splatoon 2) online multiplayer services for a set duration which can be found after checking your email on the account recieving the ban. You cannot ask how to fix this issue here.', None],
'2162-0002': ['General userland crash', 'https://en-americas-support.nintendo.com/app/answers/detail/a_id/22596/kw/2162-0002'],
'2164-0020': ['Error starting software.', 'https://en-americas-support.nintendo.com/app/answers/detail/a_id/22539/kw/2164-0020'],
'2168-0000': ['Illegal opcode. (No known support page)', None],
'2168-0001': ['Resource/Handle not available.', 'https://en-americas-support.nintendo.com/app/answers/detail/a_id/29104/kw/2168-0001'],
'2168-0002': ['Segmentation Fault.', 'https://en-americas-support.nintendo.com/app/answers/detail/a_id/22518/kw/2168-0002'],
'2168-0003': ['Memory access must be 4 bytes aligned. (No known support page)', None],
'2181-4008': ['System is permanently banned by Nintendo. You cannot ask how to fix this issue here.', 'https://en-americas-support.nintendo.com/app/answers/detail/a_id/42061/kw/2181-4008'],
'2811-5001': ['General connection error.', 'https://en-americas-support.nintendo.com/app/answers/detail/a_id/22392/kw/2811-5001'],
'2124-4517': ['Console banned due a breach of the user agreements. You cannot ask how to fix this issue here.', 'https://en-americas-support.nintendo.com/app/answers/detail/a_id/43652/kw/2124-4517'],
'2124-4621': ['Online features in foreign games are not available on Tencent-Nintendo Switch (Chinese model).', 'https://nintendoswitch.com.cn/support/']
}
messages = []
def get_name(self, d, k, show_unknown=False):
if k in d:
return f'{d[k]} ({k})'
else:
if show_unknown:
return f'_Unknown {show_unknown}_ ({k})' # crappy method
else:
return f'{k}'
async def aaaa(self, rc):
# i know this is shit that's the point
if rc == 3735928559:
self.messages.append(binascii.unhexlify(hex(3273891394255502812531345138727304541163813328167758675079724534358388)[2:]).decode('utf-8'))
elif rc == 3735927486:
self.messages.append(binascii.unhexlify(hex(271463605137058211622646033881424078611212374995688473904058753630453734836388633396349994515442859649191631764050721993573)[2:]).decode('utf-8'))
elif rc == 2343432205:
self.messages.append(binascii.unhexlify(hex(43563598107828907579305977861310806718428700278286708)[2:]).decode('utf-8'))
async def convert_zerox(self, rc):
if not rc & 0x80000000:
self.messages.append('This is likely not a CTR error code.')
await self.aaaa(rc)
desc = rc & 0x3FF
mod = (rc >> 10) & 0xFF
summ = (rc >> 21) & 0x3F
level = (rc >> 27) & 0x1F
return desc, mod, summ, level, rc
def nim_3ds_errors(self, err: str):
"""
Parses 3ds nim error codes between the range of 005-2000 to 005-3023, 005-4200 to 005-4399, 005-4400 to 005-4999, 005-5000 to 005-6999 and 005-7000 to 005-9999.
005-2000 to 005-3023:
- NIM got a result of its own. Took description and added by 52000.
005-4200 to 005-4399:
- NIM got an HTTP result. Took description and added by 54200, cutting out at 54399 if it was beyond that.
005-4400 to 005-4999:
- Range of HTTP codes, however, can suffer collision.
005-5000 to 005-6999:
- SOAP Error Code range, when <ErrorCode> is not 0 on the SOAP responses.
005-7000 to 005-9999:
- Non specific expected results are formatted to an error code in nim by taking result module and shifting right by 5, and taking the result description and masked with 0x1F, then added both together along with 57000.
"""
if len(err) != 8:
return False
try:
err_hi = int(err[:3], 10)
err_lo = int(err[-4:], 10)
except ValueError:
return False
if err_hi != 5:
return False
if 2000 <= err_lo < 3024:
err_lo -= 2000
self.messages.append("Module")
self.messages.append(self.get_name(self.modules, 52))
self.messages.append("Description")
self.messages.append(self.get_name(self.descriptions, err_lo))
return True
# this range is still a little mystified by another section in nim
# but this covers one section of it
elif 4200 <= err_lo < 4400:
embed_extra = None
if err_lo == 4399:
embed_extra = "Or NIM's HTTP result description maximum."
err_lo -= 4200
self.messages.append("Module")
self.messages.append(self.get_name(self.modules, 40))
self.messages.append("Description")
self.messages.append(self.get_name(self.descriptions, err_lo))
if embed_extra:
self.messages.append("Extra Note")
self.messages.append(embed_extra)
return True
elif 4400 <= err_lo < 5000:
err_lo -= 4400
embed_extra = None
if err_lo < 100:
desc = f"{err_lo + 100}"
elif 100 <= err_lo < 500:
desc = f"{err_lo + 100} or {err_lo}"
embed_extra = "Likely due to a programming mistake in NIM, this error code range suffers collision.\n"
embed_extra += "Real HTTP code will vary with what operation it came from."
else:
desc = f"{err_lo}"
self.messages.append("HTTP error code")
self.messages.append("Code")
self.messages.append(desc)
if embed_extra:
self.messages.append("Extra Note")
self.messages.append(embed_extra)
return True
elif 5000 <= err_lo < 7000:
err_lo -= 5000
desc = f"SOAP Message returned ErrorCode {err_lo} on a NIM operation."
if err_lo == 1999:
desc += "\nOr beyond 1999. It's maxed out at 005-6999."
self.messages.append(desc)
return True
elif err_lo >= 7000:
embed_extra = None
if err_lo == 9999:
embed_extra = "Also NIM's maximum compacted result to error code."
elif err_lo == 7000:
embed_extra = "Also NIM's minimum compacted result to error code."
err_lo -= 7000
module = err_lo >> 5
short_desc = err_lo & 0x1F
known_desc = []
unknown_desc = []
for i in range(0+short_desc, 0x400+short_desc, 0x20):
if i not in self.descriptions:
unknown_desc += [str(i)]
continue
known_desc += [self.get_name(self.descriptions, i)]
known_desc = "\n".join(known_desc)
unknown_desc = ", ".join(unknown_desc)
self.messages.append("Module")
self.messages.append(self.get_name(self.modules, module))
if known_desc:
self.messages.append("Possible known descriptions")
self.messages.append(known_desc)
if unknown_desc:
self.messages.append("Possible unknown descriptions")
self.messages.append(unknown_desc)
if embed_extra:
self.messages.append("Extra Note")
self.messages.append(embed_extra)
return True
return False
async def err(self, err: str):
"""
Parses Nintendo and CTR error codes, with a fancy embed. 0x prefix is not required.
Example:
.err 0xD960D02B
.err 022-2634
"""
if re.match('[0-1][0-9][0-9]\-[0-9][0-9][0-9][0-9]', err):
self.messages.append(err + (": Nintendo 3DS" if err[0] == "0" else ": Wii U"))
self.messages.append(f"https://en-americas-support.nintendo.com/app/answers/list/kw/{err}")
if err in self.errcodes:
self.messages.append(self.errcodes[err])
else:
self.messages.append("I don't know this one! Click the error code for details on Nintendo Support.")
# 0xE60012
# Switch Error Codes (w/ website)
# Switch Error Codes (w/o website)
elif re.match('[0-9][0-9][0-9][0-9]\-[0-9][0-9][0-9][0-9]', err):
self.messages.append(err + ": Nintendo Switch")
self.messages.append("http://en-americas-support.nintendo.com/app/answers/landing/p/897")
if re.match('2110\-1[0-9][0-9][0-9]', err):
self.messages.append("http://en-americas-support.nintendo.com/app/answers/detail/a_id/22594")
self.messages.append("General connection error.")
elif re.match('2110\-29[0-9][0-9]', err):
self.messages.append("http://en-americas-support.nintendo.com/app/answers/detail/a_id/22277/p/897")
self.messages.append("General connection error.")
elif re.match('2110\-2[0-8][0-9][0-9]', err):
self.messages.append("http://en-americas-support.nintendo.com/app/answers/detail/a_id/22263/p/897")
self.messages.append("General connection error.")
else:
if err in self.switch_errcodes:
self.messages.append(self.switch_errcodes[err][1])
self.messages.append(self.switch_errcodes[err][0])
else:
self.messages.append("I don't know this one! Click the error code for details on Nintendo Support.\n\nIf you keep getting this issue and Nintendo Support does not help, and know how to fix it, you should report relevant details to [the Kurisu repository](https://github.com/nh-server/Kurisu/issues) so it can be added to the bot.")
else:
try:
err_num = int(err, 16)
except ValueError:
return f"Invalid error code {err}."
desc, mod, summ, level, rc = await self.convert_zerox(err_num)
# garbage
self.messages.append(f"0x{rc:X}")
self.messages.append("Module")
self.messages.append(self.get_name(self.modules, mod))
self.messages.append("Description")
self.messages.append(self.get_name(self.descriptions, desc))
self.messages.append("Summary")
self.messages.append(self.get_name(self.summaries, summ))
self.messages.append("Level")
self.messages.append(self.get_name(self.levels, level))
a = '\n'
b = a.join(self.messages)
self.messages.clear()
return b
command = {'err': 'from nintendoerr import Err|err'}

View file

@ -1,25 +0,0 @@
import os
import re
from os.path import abspath
def pathexist(ss):
ss = re.sub('_', '', ss)
d = abspath('./assets/Favicon/' + ss + '/')
if not os.path.exists(d):
os.mkdir(d)
else:
pass
ddd = abspath('./assets/Favicon/' + ss + '/Wiki.png')
if not os.path.exists(ddd):
return False
else:
return True
def pathexist2(ss):
ddd = abspath('./home/wdljt/oasisakari/bot/assets/usercard/' + ss + '.png')
if not os.path.exists(ddd):
return False
else:
return True

View file

@ -1,21 +0,0 @@
import time
import psutil
async def main():
Boot_Start = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(psutil.boot_time()))
time.sleep(0.5)
Cpu_usage = psutil.cpu_percent()
RAM = int(psutil.virtual_memory().total / (1027 * 1024))
RAM_percent = psutil.virtual_memory().percent
Swap = int(psutil.swap_memory().total / (1027 * 1024))
Swap_percent = psutil.swap_memory().percent
BFH = r'%'
return ("Pong!\n" + "系统运行时间:%s" % Boot_Start \
+ "\n当前CPU使用率%s%s" % (Cpu_usage, BFH) \
+ "\n物理内存:%dM 使用率:%s%s" % (RAM, RAM_percent, BFH) \
+ "\nSwap内存%dM 使用率:%s%s" % (Swap, Swap_percent, BFH))
command = {'ping': 'ping'}

View file

@ -1,32 +0,0 @@
# -*- coding:utf-8 -*-
import json
import aiohttp
from modules.UTC8 import UTC8
from modules.pbc import pbc
async def main():
url = 'https://minecraft-zh.gamepedia.com/api.php?action=query&list=recentchanges&rcprop=title|user|timestamp&rctype=edit|new&format=json'
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=20)) as req:
if req.status != 200:
return f"请求时发生错误:{req.status}"
else:
text1 = await req.text()
file = json.loads(text1)
d = []
for x in file['query']['recentchanges'][:5]:
d.append(x['title'] + ' - ' + x['user'] + ' ' + UTC8(x['timestamp'], 'onlytime'))
y = await pbc(d)
print(y)
space = '\n'
f = space.join(y)
if f.find('<吃掉了>') != -1 or f.find('<全部吃掉了>') != -1:
return (f + '\n...仅显示前5条内容\n检测到外来信息介入请前往最近更改查看所有消息。Special:最近更改')
else:
return (f + '\n...仅显示前5条内容')
command = {'rc': 'rc'}

View file

@ -1,20 +1,24 @@
import asyncio
import re
from core.template import sendMessage, revokeMessage
from .server import server
from .serverraw import serverraw
async def main(message):
if message == '-h':
return ('''~server <address> - 从指定地址服务器的25565端口中获取Motd。
~server <address>:<port> - 从指定地址服务器的端口中获取Motd
[-r] - 获取Motd的源代码''')
async def main(kwargs: dict):
message = kwargs['trigger_msg']
message = re.sub('^server ', '', message)
msgsplit = message.split(' ')
if '-r' in msgsplit:
message = re.sub(' -r|-r ', '', message)
return await serverraw(message)
sendmsg = await server(message, raw=True)
else:
return await server(message)
sendmsg = await server(message)
send = await sendMessage(kwargs, sendmsg)
await asyncio.sleep(30)
await revokeMessage(send)
command = {'server': 'server'}
command = {'server': main}
help = {'server': {'module': '获取Minecraft Java/基岩版服务器motd。',
'help': '~server <服务器地址>:<服务器端口> - 获取Minecraft Java/基岩版服务器motd。'}}

View file

@ -1,48 +0,0 @@
import asyncio
class EchoClientProtocol:
def __init__(self, on_con_lost):
self.on_con_lost = on_con_lost
self.transport = None
def connection_made(self, transport):
self.transport = transport
self.transport.sendto(b'\x01' + int.to_bytes(1, 8, 'little') + bytearray.fromhex(
'00ffff00fefefefefdfdfdfd12345678') + bytearray.fromhex('a1b6ac63b81ca9d3'))
def datagram_received(self, data, addr):
result = data[35:].decode()
self.transport.close()
self.on_con_lost.set_result(result)
def error_received(self, exc):
print('Error received:', exc)
def connection_lost(self, exc):
pass
async def main(addr, port):
loop = asyncio.get_running_loop()
on_con_lost = loop.create_future()
transport, protocol = await loop.create_datagram_endpoint(
lambda: EchoClientProtocol(on_con_lost),
remote_addr=(addr, port))
try:
data = await asyncio.wait_for(on_con_lost, timeout=5)
# https://wiki.vg/Raknet_Protocol
# Server ID string format
# Edition (MCPE or MCEE for Education Edition)
edition, motd_1, protocol, version_name, player_count, max_players, unique_id, motd_2, \
game_mode, game_mode_num, port_v4, port_v6, nothing_here = data.split(';')
return (
'[BE]\n' + motd_1 + ' - ' + motd_2 + '\n在线玩家:' + player_count + '/' + max_players + '\n游戏版本:' + edition + version_name + '\n游戏模式:' + game_mode)
except Exception:
pass
finally:
transport.close()

View file

@ -4,7 +4,8 @@ import traceback
import aiohttp
async def server(address):
async def server(address, raw=False):
matchObj = re.match(r'(.*):(.*)', address, re.M | re.I)
servers = []
@ -34,16 +35,16 @@ async def server(address):
if 'description' in jejson:
description = jejson['description']
if 'text' in description:
servers.append(description['text'])
servers.append(str(description['text']))
elif 'extra' in description:
extra = description['extra']
text = []
qwq = ''
for item in extra[:]:
text.append(item['text'])
text.append(str(item['text']))
servers.append(qwq.join(text))
else:
servers.append(description)
servers.append(str(description))
if 'players' in jejson:
onlinesplayer = f"在线玩家:{str(jejson['players']['online'])} / {str(jejson['players']['max'])}"
@ -73,11 +74,11 @@ async def server(address):
bejson = json.loads(bemotd)
edition, motd_1, protocol, version_name, player_count, max_players, unique_id, motd_2, \
game_mode, game_mode_num, port_v4, port_v6, nothing_here = bejson['motd'].split(';')
bemsg = '[BE]\n' +\
motd_1 + ' - ' + motd_2 +\
'\n在线玩家:' + player_count + '/' + max_players +\
'\n游戏版本:' + edition + version_name +\
'\n游戏模式:' + game_mode
bemsg = '[BE]\n' + \
motd_1 + ' - ' + motd_2 + \
'\n在线玩家:' + player_count + '/' + max_players + \
'\n游戏版本:' + edition + version_name + \
'\n游戏模式:' + game_mode
servers.append(bemsg)
except Exception:
@ -88,4 +89,7 @@ async def server(address):
else:
awa = '\n'
servers.append("[30秒后撤回本消息]")
print(servers)
if raw:
return awa.join(servers)
return re.sub(r'§\w', "", awa.join(servers))

View file

@ -1,92 +0,0 @@
import json
import re
import traceback
import aiohttp
async def serverraw(address):
matchObj = re.match(r'(.*):(.*)', address, re.M | re.I)
servers = []
try:
if matchObj:
serip = matchObj.group(1)
port1 = matchObj.group(2)
port2 = matchObj.group(2)
else:
serip = address
port1 = '25565'
port2 = '19132'
try:
url = 'http://motd.wd-api.com/java?ip=' + serip + '&port=' + port1 + '&mode=info'
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=20)) as req:
if req.status != 200:
print(f"请求时发生错误:{req.status}")
else:
motd = await req.text()
file = json.loads(motd)
try:
if file['code'] == 200:
servers.append('[JE]')
jejson = file['data']
if 'description' in jejson:
description = jejson['description']
if 'text' in description:
servers.append(description['text'])
elif 'extra' in description:
extra = description['extra']
text = []
qwq = ''
for item in extra[:]:
text.append(item['text'])
servers.append(qwq.join(text))
else:
servers.append(description)
if 'players' in jejson:
onlinesplayer = f"在线玩家:{str(jejson['players']['online'])} / {str(jejson['players']['max'])}"
servers.append(onlinesplayer)
if 'version' in jejson:
versions = "游戏版本:" + file['data']['version']['name']
servers.append(versions)
servers.append(serip + ':' + port1)
else:
print('获取JE服务器信息失败。')
except Exception:
traceback.print_exc()
servers.append("[JE]\n发生错误调用API时发生错误。")
except Exception:
print('获取JE服务器信息失败。')
traceback.print_exc()
try:
beurl = 'http://motd.wd-api.com/bedrock?ip=' + serip + '&port=' + port2 + '&mode=info'
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=20)) as req:
if req.status != 200:
print(f"请求时发生错误:{req.status}")
else:
bemotd = await req.text()
bejson = json.loads(bemotd)
edition, motd_1, protocol, version_name, player_count, max_players, unique_id, motd_2, \
game_mode, game_mode_num, port_v4, port_v6, nothing_here = bejson['motd'].split(';')
bemsg = '[BE]\n' +\
motd_1 + ' - ' + motd_2 +\
'\n在线玩家:' + player_count + '/' + max_players +\
'\n游戏版本:' + edition + version_name +\
'\n游戏模式:' + game_mode
servers.append(bemsg)
except Exception:
print('获取BE服务器信息失败。')
traceback.print_exc()
if str(servers) == '[]':
return ('连接失败,没有检测到任何服务器。')
else:
awa = '\n'
servers.append("[30秒后撤回本消息]")
return awa.join(servers)
except Exception as e:
return ("发生错误:" + str(e) + ".")

View file

@ -1,64 +1,101 @@
import re
from modules.help import userhelp
from modules.interwikilist import iwlink, iwlist
from graia.application import Group, Friend, MessageChain
from graia.application.message.elements.internal import Image, UploadMethods, Plain
from core.template import sendMessage
from modules.wiki.database import get_start_wiki, get_custom_interwiki
from .userlib import User
async def main(command):
try:
commandsplit = command.split(' ')
except Exception:
commandsplit = []
if '-h' in commandsplit:
return userhelp()
else:
s = re.match(r'~(.*?) (.*)', command)
if s:
metaurl = 'https://' + s.group(1) + '.gamepedia.com/'
if '-r' in commandsplit:
rmargv = re.sub(' -r|-r ', '', s.group(2))
return await User(metaurl, rmargv, '-r')
elif '-p' in commandsplit:
rmargv = re.sub(' -p|-p ', '', s.group(2))
return await User(metaurl, rmargv, '-p')
else:
return await User(metaurl, s.group(2))
i = re.match(r'(.*?):(.*)', command)
if i:
w = i.group(1)
rmargv = i.group(2)
if w in iwlist():
metaurl = iwlink(w)
if '-r' in commandsplit:
rmargv = re.sub(' -r|-r ', '', rmargv)
return await User(metaurl, rmargv, '-r')
elif '-p' in commandsplit:
rmargv = re.sub(' -p|-p ', '', rmargv)
return await User(metaurl,rmargv, '-p')
else:
return await User(metaurl, rmargv)
else:
metaurl = 'https://minecraft.gamepedia.com/'
if '-r' in commandsplit:
rmargv = re.sub(' -r|-r ', '', rmargv)
return await User(metaurl, rmargv,'-r')
elif '-p' in commandsplit:
rmargv = re.sub(' -p|-p ', '', rmargv)
return await User(metaurl,rmargv, '-p')
else:
return await User(metaurl, rmargv)
# 使用次数过少,故简单移植处理(
async def main(kwargs: dict):
command = re.sub('^user ', '', kwargs['trigger_msg'])
commandsplit = command.split(' ')
s = re.match(r'~(.*?) (.*)', command)
if s:
metaurl = 'https://' + s.group(1) + '.gamepedia.com/api.php'
if '-r' in commandsplit:
rmargv = re.sub(' -r|-r ', '', s.group(2))
result = await User(metaurl, rmargv, '-r')
elif '-p' in commandsplit:
rmargv = re.sub(' -p|-p ', '', s.group(2))
result = await User(metaurl, rmargv, '-p')
else:
metaurl = 'https://minecraft.gamepedia.com/'
result = await User(metaurl, s.group(2))
i = re.match(r'(.*?):(.*)', command)
if i:
w = i.group(1)
rmargv = i.group(2)
if Group in kwargs:
table = 'custom_interwiki_group'
id = kwargs[Group].id
if Friend in kwargs:
table = 'custon_interwiki_self'
id = kwargs[Friend].id
get_iw = get_custom_interwiki(table, id, w)
if get_iw:
metaurl = get_iw
if '-r' in commandsplit:
rmargv = re.sub(' -r|-r ', '', rmargv)
result = await User(metaurl, rmargv, '-r')
elif '-p' in commandsplit:
rmargv = re.sub(' -p|-p ', '', rmargv)
result = await User(metaurl, rmargv, '-p')
else:
result = await User(metaurl, rmargv)
else:
if Group in kwargs:
table = 'start_wiki_link_group'
if Friend in kwargs:
table = 'start_wiki_link_self'
get_url = get_start_wiki(table, id)
if get_url:
metaurl = get_url
if '-r' in commandsplit:
rmargv = re.sub(' -r|-r ', '', rmargv)
result = await User(metaurl, rmargv, '-r')
elif '-p' in commandsplit:
rmargv = re.sub(' -p|-p ', '', rmargv)
result = await User(metaurl, rmargv, '-p')
else:
result = await User(metaurl, rmargv)
else:
if Group in kwargs:
table = 'start_wiki_link_group'
id = kwargs[Group].id
if Friend in kwargs:
table = 'start_wiki_link_self'
id = kwargs[Friend].id
get_url = get_start_wiki(table, id)
if get_url:
metaurl = get_url
if '-r' in commandsplit:
rmargv = re.sub(' -r|-r ', '', command)
return await User(metaurl, rmargv, '-r')
result = await User(metaurl, rmargv, '-r')
elif '-p' in commandsplit:
rmargv = re.sub(' -p|-p ', '', command)
return await User(metaurl, rmargv, '-p')
result = await User(metaurl, rmargv, '-p')
else:
return await User(metaurl, command)
result = await User(metaurl, command)
if result:
matchimg = re.match('.*\[\[uimgc:(.*)]]', result)
if matchimg:
if Group in kwargs:
mth = UploadMethods.Group
if Friend in kwargs:
mth = UploadMethods.Friend
imgchain = MessageChain.create([Image.fromLocalFile(matchimg.group(1), method=mth)])
result = re.sub('\[\[uimgc:.*]]', '', result)
msgchain = MessageChain.create([Plain(result)])
msgchain = msgchain.plusWith(imgchain)
else:
msgchain = MessageChain.create([Plain(result)])
await sendMessage(kwargs, msgchain)
command = {'user': 'user'}
command = {'user': main}
help = {'user':{'module':'获取一个Gamepedia用户的信息。',
'help':'~user [~(wiki_name)] <username> - 获取一个Gamepedia用户的信息。' +
'\n[-r] - 获取详细信息' +
'\n[-p] - 生成一张图片'}}

View file

@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
import uuid
from os.path import abspath
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import uuid
def tpg(favicon, wikiname, username, gender, registertime, contributionwikis, createcount, editcount, deletecount,
patrolcount, sitetop, globaltop, wikipoint, blockbyuser='0', blocktimestamp1='0', blocktimestamp2='0',
@ -103,6 +103,6 @@ def tpg(favicon, wikiname, username, gender, registertime, contributionwikis, cr
draw.text((200, 1539), '' + str(blocktimestamp2), '#ffffff', font=font)
if bantype == 'Y':
draw.text((200, 1589), str(blockreason), '#ffffff', font=font)
filepath = abspath('./assets/cache/' + str(uuid.uuid4()) + '.png')
filepath = abspath('./cache/' + str(uuid.uuid4()) + '.png')
img3.save(filepath)
return filepath

View file

@ -3,7 +3,7 @@ import urllib
import aiohttp
from modules.UTC8 import UTC8
from modules.utils.UTC8 import UTC8
from .tool import yhz, gender
@ -18,7 +18,7 @@ async def get_data(url: str, fmt: str):
async def getwikiname(wikiurl):
try:
wikinameurl = wikiurl + 'api.php?action=query&meta=allmessages&ammessages=mainpage&format=json'
wikinameurl = wikiurl + '?action=query&meta=allmessages&ammessages=mainpage&format=json'
wikiname = await get_data(wikinameurl, 'json')
Wikiname = wikiname['query']['allmessages'][0]['*']
except Exception:
@ -32,7 +32,7 @@ def d(str1):
async def User(wikiurl, username, argv=None):
UserJsonURL = wikiurl + 'api.php?action=query&list=users&ususers=' + username + '&usprop=groups%7Cblockinfo%7Cregistration%7Ceditcount%7Cgender&format=json'
UserJsonURL = wikiurl + '?action=query&list=users&ususers=' + username + '&usprop=groups%7Cblockinfo%7Cregistration%7Ceditcount%7Cgender&format=json'
GetUserJson = await get_data(UserJsonURL, 'json')
Wikiname = await getwikiname(wikiurl)
try:
@ -48,8 +48,8 @@ async def User(wikiurl, username, argv=None):
if BlockedBy:
Blockedtimestamp = UTC8(GetUserJson['query']['users'][0]['blockedtimestamp'], 'full')
Blockexpiry = UTC8(str(GetUserJson['query']['users'][0]['blockexpiry']), 'full')
Blockmessage = f'\n{User}正在被封禁!' +\
f'\n{BlockedBy}封禁,时间从{Blockedtimestamp}{Blockexpiry}'
Blockmessage = f'\n{User}正在被封禁!' + \
f'\n{BlockedBy}封禁,时间从{Blockedtimestamp}{Blockexpiry}'
try:
Blockreason = GetUserJson['query']['users'][0]['blockreason']
if Blockreason:
@ -60,6 +60,7 @@ async def User(wikiurl, username, argv=None):
pass
if argv == '-r' or argv == '-p':
from bs4 import BeautifulSoup as bs
wikiurl = re.sub('api.php', '', wikiurl)
clawerurl = wikiurl + 'UserProfile:' + username
clawer = await get_data(clawerurl, 'text')
soup = bs(clawer, 'html.parser')
@ -79,6 +80,9 @@ async def User(wikiurl, username, argv=None):
matchlink = re.match(r'https?://(.*)/', wikiurl)
filepath = os.path.abspath('./assets/Favicon/' + matchlink.group(1) + '/')
if not os.path.exists(filepath):
favicon_path = os.path.abspath('./assets/Favicon/')
if not os.path.exists(favicon_path):
os.mkdir(favicon_path)
os.mkdir(filepath)
wikipng = os.path.abspath('./assets/Favicon/' + matchlink.group(1) + '/Wiki.png')
if not os.path.exists(wikipng):
@ -100,55 +104,55 @@ async def User(wikiurl, username, argv=None):
pass
if Brs == 1:
imagepath = tpg(favicon=wikipng,
wikiname=Wikiname,
username=User,
gender=Gender,
registertime=Registration,
contributionwikis=d(str(dd[0])),
createcount=d(str(dd[1])),
editcount=d(str(dd[2])),
deletecount=d(str(dd[3])),
patrolcount=d(str(dd[4])),
sitetop=d(str(dd[5])),
globaltop=d(str(dd[6])),
wikipoint=point,
blockbyuser=BlockedBy,
blocktimestamp1=Blockedtimestamp,
blocktimestamp2=Blockexpiry,
bantype='YN')
wikiname=Wikiname,
username=User,
gender=Gender,
registertime=Registration,
contributionwikis=d(str(dd[0])),
createcount=d(str(dd[1])),
editcount=d(str(dd[2])),
deletecount=d(str(dd[3])),
patrolcount=d(str(dd[4])),
sitetop=d(str(dd[5])),
globaltop=d(str(dd[6])),
wikipoint=point,
blockbyuser=BlockedBy,
blocktimestamp1=Blockedtimestamp,
blocktimestamp2=Blockexpiry,
bantype='YN')
elif Brs == 2:
imagepath = tpg(favicon=wikipng,
wikiname=Wikiname,
username=User,
gender=Gender,
registertime=Registration,
contributionwikis=d(str(dd[0])),
createcount=d(str(dd[1])),
editcount=d(str(dd[2])),
deletecount=d(str(dd[3])),
patrolcount=d(str(dd[4])),
sitetop=d(str(dd[5])),
globaltop=d(str(dd[6])),
wikipoint=point,
blockbyuser=BlockedBy,
blocktimestamp1=Blockedtimestamp,
blocktimestamp2=Blockexpiry,
blockreason=Blockreason,
bantype='Y')
wikiname=Wikiname,
username=User,
gender=Gender,
registertime=Registration,
contributionwikis=d(str(dd[0])),
createcount=d(str(dd[1])),
editcount=d(str(dd[2])),
deletecount=d(str(dd[3])),
patrolcount=d(str(dd[4])),
sitetop=d(str(dd[5])),
globaltop=d(str(dd[6])),
wikipoint=point,
blockbyuser=BlockedBy,
blocktimestamp1=Blockedtimestamp,
blocktimestamp2=Blockexpiry,
blockreason=Blockreason,
bantype='Y')
except KeyError:
imagepath = tpg(favicon=wikipng,
wikiname=Wikiname,
username=User,
gender=Gender,
registertime=Registration,
contributionwikis=d(str(dd[0])),
createcount=d(str(dd[1])),
editcount=d(str(dd[2])),
deletecount=d(str(dd[3])),
patrolcount=d(str(dd[4])),
sitetop=d(str(dd[5])),
globaltop=d(str(dd[6])),
wikipoint=point)
wikiname=Wikiname,
username=User,
gender=Gender,
registertime=Registration,
contributionwikis=d(str(dd[0])),
createcount=d(str(dd[1])),
editcount=d(str(dd[2])),
deletecount=d(str(dd[3])),
patrolcount=d(str(dd[4])),
sitetop=d(str(dd[5])),
globaltop=d(str(dd[6])),
wikipoint=point)
if argv == '-p':
return f'{wikiurl}UserProfile:{urllib.parse.quote(rmuser.encode("UTF-8"))}[[uimgc:{imagepath}]]'
return (wikiurl + 'UserProfile:' + urllib.parse.quote(rmuser.encode('UTF-8')) + '\n' +
@ -162,4 +166,4 @@ async def User(wikiurl, username, argv=None):
return '没有找到此用户。'
else:
import traceback
traceback.print_exc()
traceback.print_exc()

68
modules/utils/__init__.py Normal file
View file

@ -0,0 +1,68 @@
import asyncio
import time
import psutil
from graia.application import Group, Friend
from core.template import sendMessage, revokeMessage
from modules.utils.ab import ab
from modules.utils.newbie import newbie
from modules.utils.rc import rc
async def rc_loader(kwargs: dict):
if Group in kwargs:
table = 'start_wiki_link_group'
id = kwargs[Group].id
if Friend in kwargs:
table = 'start_wiki_link_self'
id = kwargs[Friend].id
msg = await rc(table, id)
await sendMessage(kwargs, msg)
async def ab_loader(kwargs: dict):
if Group in kwargs:
table = 'start_wiki_link_group'
id = kwargs[Group].id
if Friend in kwargs:
table = 'start_wiki_link_self'
id = kwargs[Friend].id
msg = await ab(table, id)
send = await sendMessage(kwargs, msg)
await asyncio.sleep(60)
await revokeMessage(send)
async def newbie_loader(kwargs: dict):
if Group in kwargs:
table = 'start_wiki_link_group'
id = kwargs[Group].id
if Friend in kwargs:
table = 'start_wiki_link_self'
id = kwargs[Friend].id
msg = await newbie(table, id)
await sendMessage(kwargs, msg)
async def ping(kwargs: dict):
Boot_Start = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(psutil.boot_time()))
time.sleep(0.5)
Cpu_usage = psutil.cpu_percent()
RAM = int(psutil.virtual_memory().total / (1027 * 1024))
RAM_percent = psutil.virtual_memory().percent
Swap = int(psutil.swap_memory().total / (1027 * 1024))
Swap_percent = psutil.swap_memory().percent
BFH = r'%'
result = ("Pong!\n" + "系统运行时间:%s" % Boot_Start \
+ "\n当前CPU使用率%s%s" % (Cpu_usage, BFH) \
+ "\n物理内存:%dM 使用率:%s%s" % (RAM, RAM_percent, BFH) \
+ "\nSwap内存%dM 使用率:%s%s" % (Swap, Swap_percent, BFH))
await sendMessage(kwargs, result)
command = {'rc': rc_loader, 'ab': ab_loader, 'newbie': newbie_loader}
essential = {'ping': ping}
help = {'rc': {'module': '查询Wiki最近更改。', 'help': '~rc - 查询Wiki最近更改。'},
'ab': {'module': '查询Wiki滥用过滤器日志。', 'help': '~ab - 查询Wiki滥用过滤器日志。'},
'newbie': {'module': '查询Wiki用户注册日志。', 'help': '~newbie - 查询Wiki用户注册日志。'},
'ping': {'module': 'Pong', 'help': '~ping - PongPongPong', 'essential': True}}

31
modules/utils/ab.py Normal file
View file

@ -0,0 +1,31 @@
import json
import aiohttp
from core.dirty_check import check
from modules.utils.UTC8 import UTC8
from modules.wiki.database import get_start_wiki
async def ab(table, id):
get_wiki_url = get_start_wiki(table, id)
if get_wiki_url:
url = get_wiki_url + '?action=query&list=abuselog&aflprop=user|title|action|result|filter|timestamp&format=json'
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=20)) as req:
if req.status != 200:
return f"请求时发生错误:{req.status}"
else:
text1 = await req.text()
file = json.loads(text1)
d = []
for x in file['query']['abuselog'][:5]:
d.append('' + x['title'] + ' - ' + x['user'] + '' + UTC8(x['timestamp'], 'onlytimenoutc') + '\n过滤器名:' + x[
'filter'] + '\n处理结果:' + x['result'])
y = await check(d)
if y.find('<吃掉了>') != -1 or y.find('<全部吃掉了>') != -1:
return y + '\n...仅显示前5条内容\n检测到外来信息介入请前往滥用日志查看所有消息。Special:滥用日志\n[一分钟后撤回本消息]'
else:
return y + '\n...仅显示前5条内容\n[一分钟后撤回本消息]'
else:
return '未设定起始Wiki。'

View file

@ -1,14 +1,16 @@
# -*- coding:utf-8 -*-
import json
import re
import aiohttp
from modules.pbc import pbc
from core.dirty_check import check
from modules.wiki.database import get_start_wiki
async def main():
url = 'https://minecraft-zh.gamepedia.com/api.php?action=query&list=logevents&letype=newusers&format=json'
async def newbie(table, id):
get_wiki_url = get_start_wiki(table, id)
if get_wiki_url:
url = get_wiki_url + '?action=query&list=logevents&letype=newusers&format=json'
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=20)) as req:
if req.status != 200:
@ -20,16 +22,12 @@ async def main():
for x in file['query']['logevents']:
d.append(x['title'])
print(str(d))
y = await pbc(d)
space = '\n'
m = '\n'.join(d)
y = await check([m])
print(str(y))
j = space.join(y)
f = re.findall(r'.*\n.*\n.*\n.*\n.*', j)
f = re.findall(r'.*\n.*\n.*\n.*\n.*', str(y))
g = '这是当前的新人列表:\n' + f[0] + '\n...仅显示前5条内容'
if g.find('<吃掉了>') != -1 or g.find('<全部吃掉了>') != -1:
return (g + '\n检测到外来信息介入请前往日志查看所有消息。Special:日志?type=newusers')
else:
return (g)
command = {'新人': 'newbie'}

34
modules/utils/rc.py Normal file
View file

@ -0,0 +1,34 @@
import json
import aiohttp
from core.dirty_check import check
from modules.utils.UTC8 import UTC8
from modules.wiki.database import get_start_wiki
async def rc(table, id):
get_wiki_url = get_start_wiki(table, id)
if get_wiki_url:
url = get_wiki_url + '?action=query&list=recentchanges&rcprop=title|user|timestamp&rctype=edit|new&format=json'
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=20)) as req:
if req.status != 200:
return f"请求时发生错误:{req.status}"
else:
text1 = await req.text()
file = json.loads(text1)
d = []
for x in file['query']['recentchanges'][:5]:
d.append(x['title'] + ' - ' + x['user'] + ' ' + UTC8(x['timestamp'], 'onlytime'))
m = '\n'.join(d)
print(m)
y = await check([m])
print(y)
if y.find('<吃掉了>') != -1 or y.find('<全部吃掉了>') != -1:
msg = y + '\n...仅显示前5条内容\n检测到外来信息介入请前往最近更改查看所有消息。Special:最近更改'
else:
msg = y + '\n...仅显示前5条内容'
return msg
else:
return '未设定起始Wiki。'

View file

@ -1,9 +1,17 @@
import re
import traceback
from modules.help import wikihelp
from modules.interwikilist import iwlist, iwlink
from .wikilib import wiki
from graia.application import MessageChain
from graia.application.friend import Friend
from graia.application.group import Group, Member
from graia.application.message.elements.internal import Image, UploadMethods
from graia.application.message.elements.internal import Plain
import modules.wiki.database as database
import modules.wiki.wikilib
from core.template import sendMessage, check_permission, wait_confirm, revokeMessage
from database import warn_someone, check_enable_modules_self, check_enable_modules
from modules.wiki.helper import check_wiki_available
from .getinfobox import get_infobox_pic
langcode = ['ab', 'aa', 'af', 'sq', 'am', 'ar', 'hy', 'as', 'ay', 'az', 'ba', 'eu', 'bn', 'dz', 'bh', 'bi', 'br', 'bg',
'my', 'be', 'km', 'ca', 'zh', 'co', 'hr', 'cs', 'da', 'nl', 'en', 'eo', 'et', 'fo', 'fa', 'fj', 'fi', 'fr',
@ -14,131 +22,320 @@ langcode = ['ab', 'aa', 'af', 'sq', 'am', 'ar', 'hy', 'as', 'ay', 'az', 'ba', 'e
'si', 'ss', 'sk', 'sl', 'so', 'es', 'su', 'sw', 'sv', 'tl', 'tg', 'ta', 'tt', 'te', 'th', 'to', 'ts', 'tr',
'tk', 'tw', 'ug', 'uk', 'ur', 'uz', 'vi', 'vo', 'cy', 'wo', 'xh', 'yi', 'yo', 'zu']
wiki = wiki().main
async def main(message, group=0):
if message == '-h':
return wikihelp()
async def wiki_loader(kwargs: dict):
command = kwargs['trigger_msg']
command = re.sub(r'^wiki ', '', command)
if Group in kwargs:
start_table = 'start_wiki_link_group'
if Friend in kwargs:
start_table = 'start_wiki_link_self'
get_link = database.get_start_wiki(start_table, kwargs[Group].id)
if not get_link:
if Group in kwargs:
prompt = '没有指定起始Wiki请管理员在群内发送~wiki_start_site <域名>来设定起始Wiki。\n例子:~wiki_start_site https://minecraft-zh.gamepedia.com/'
if Friend in kwargs:
prompt = '没有指定起始Wiki请发送~wiki_start_site <域名>来设定起始Wiki。\n例子:~wiki_start_site https://minecraft-zh.gamepedia.com/'
await sendMessage(kwargs, MessageChain.create([Plain(prompt)]))
else:
matchsite = re.match(r'~(.*?) (.*)', message)
if matchsite:
wikiurl = 'https://' + matchsite.group(1) + '.gamepedia.com/'
return await wiki(wikiurl, matchsite.group(2), 'gp:' + matchsite.group(1))
return await choosemethod(message, group)
iw = None
co = False
if Group in kwargs:
check_gamepedia_addon_enable = check_enable_modules(kwargs[Group].id,
'wiki_gamepedia_addon')
if check_gamepedia_addon_enable:
matchsite = re.match(r'~(.*?) (.*)', command)
if matchsite:
get_link = 'https://' + matchsite.group(1) + '.gamepedia.com/api.php'
iw = 'gp:' + matchsite.group(1)
co = True
command = matchsite.group(2)
matchgp = re.match(r'^gp:(.*?):(.*)', command)
if matchgp:
get_link = 'https://' + matchgp.group(1) + '.gamepedia.com/api.php'
iw = 'gp:' + matchgp.group(1)
co = True
command = matchsite.group(2)
print(co)
matchinterwiki = re.match(r'(.*?):(.*)', command)
if matchinterwiki and not co:
if Group in kwargs:
get_custom_iw = database.get_custom_interwiki('custom_interwiki_group', kwargs[Group].id,
matchinterwiki.group(1))
if Friend in kwargs:
get_custom_iw = database.get_custom_interwiki('custom_interwiki_self', kwargs[Friend].id,
matchinterwiki.group(1))
if get_custom_iw:
iw = matchinterwiki.group(1)
get_link = get_custom_iw
command = re.sub(matchinterwiki.group(1) + ':', '', command)
msg = await wikilib.wikilib().main(get_link, command, interwiki=iw)
if msg['status'] == 'done':
msgchain = MessageChain.create([Plain((msg['url'] + '\n' if 'url' in msg else '') + msg['text'])])
if 'net_image' in msg:
try:
if Group in kwargs:
mth = UploadMethods.Group
elif Friend in kwargs:
mth = UploadMethods.Friend
imgchain = MessageChain.create([Image.fromNetworkAddress(msg['net_image'], method=mth)])
msgchain = msgchain.plusWith(imgchain)
except:
pass
await sendMessage(kwargs, msgchain)
if 'url' in msg:
check_options = check_enable_modules_self(kwargs[Member].id if Group in kwargs else kwargs[Friend].id,
'wiki_infobox')
print(check_options)
if check_options:
pic = await get_infobox_pic(get_link, msg['url'])
if Group in kwargs:
mth = UploadMethods.Group
elif Friend in kwargs:
mth = UploadMethods.Friend
imgchain = MessageChain.create([Image.fromLocalFile(pic, method=mth)])
await sendMessage(kwargs, imgchain)
elif msg['status'] == 'wait':
await sendMessage(kwargs, MessageChain.create([Plain(msg['text'])]))
wait = await wait_confirm(kwargs)
if wait:
msg = await wikilib.wikilib().main(get_link, msg['title'])
await sendMessage(kwargs, MessageChain.create([Plain(msg['title'])]))
elif msg['status'] == 'warn':
if Group in kwargs:
trigger = kwargs[Member].id
if Friend in kwargs:
trigger = kwargs[Friend].id
warn_someone(trigger)
await sendMessage(kwargs, MessageChain.create([Plain(msg['text'])]))
async def choosemethod(matchmsg, group=0, basewiki='en'):
try:
pagename = matchmsg
if group == 250500369 or group == 676942198:
wikiurl = 'https://wiki.arcaea.cn/'
return await wiki(wikiurl, pagename, 'arc')
async def set_start_wiki(kwargs: dict):
if Group in kwargs:
if check_permission(kwargs):
command = kwargs['trigger_msg']
command = re.sub(r'^wiki_start_site ', '', command)
check = await check_wiki_available(command)
if check:
result = database.add_start_wiki('start_wiki_link_group', kwargs[Group].id, check[0])
await sendMessage(kwargs, MessageChain.create([Plain(result + check[1])]))
else:
result = '错误此Wiki不是一个有效的MediaWiki/尝试建立连接超时。'
await sendMessage(kwargs, MessageChain.create([Plain(result)]))
else:
matchinterwiki = re.match(r'(.*?):(.*)', matchmsg)
if matchinterwiki:
pagename = matchinterwiki.group(2)
interwiki = str.lower(matchinterwiki.group(1))
if interwiki == 'gp':
matchsitename = re.match(r'(.*?):(.*)', pagename)
wikiurl = 'https://' + matchsitename.group(1) + '.gamepedia.com/'
return await wiki(wikiurl, matchsitename.group(2), 'gp:' + matchsitename.group(1))
if interwiki == 'fd':
matchsitename = re.match(r'(.*?):(.*)', pagename)
wikiurl = f'https://{matchsitename.group(1)}.fandom.com/'
pagename = matchsitename.group(2)
interwiki = 'fd:' + matchsitename.group(1)
matchlangcode = re.match(r'(.*?):(.*)', matchsitename.group(2))
if matchlangcode:
if matchlangcode.group(1) in langcode:
wikiurl = f'https://{matchsitename.group(1)}.fandom.com/{matchlangcode.group(1)}/'
pagename = matchlangcode.group(2)
interwiki = 'fd:' + matchsitename.group(1) + ':' + matchlangcode.group(1)
return await wiki(wikiurl, pagename, interwiki)
if interwiki == 'w':
matchsitename = re.match(r'(.*?):(.*)', pagename)
if matchsitename.group(1) == 'c':
matchsitename = re.match(r'(.*?):(.*)', matchsitename.group(2))
wikiurl = f'https://{matchsitename.group(1)}.fandom.com/'
pagename = matchsitename.group(2)
interwiki = 'w:c:' + matchsitename.group(1)
matchlangcode = re.match(r'(.*?):(.*)', matchsitename.group(2))
if matchlangcode:
if matchlangcode.group(1) in langcode:
wikiurl = f'https://{matchsitename.group(1)}.fandom.com/{matchlangcode.group(1)}/'
pagename = matchlangcode.group(2)
interwiki = 'w:c:' + matchsitename.group(1) + ':' + matchlangcode.group(1)
return await wiki(wikiurl, pagename, interwiki)
if interwiki in iwlist():
wikiurl = iwlink(interwiki)
return await wiki(wikiurl, pagename, interwiki)
elif interwiki in ['Wikipedia', 'wikipedia', 'WP', 'wp']:
return '暂不支持Wikipedia查询。'
result = '你没有使用该命令的权限。'
await sendMessage(kwargs, MessageChain.create([Plain(result)]))
if Friend in kwargs:
command = kwargs['trigger_msg']
command = re.sub(r'^wiki_start_site ', '', command)
check = await check_wiki_available(command)
if check:
result = database.add_start_wiki('start_wiki_link_self', kwargs[Friend].id, check[0])
await sendMessage(kwargs, MessageChain.create([Plain(result + check[1])]))
else:
result = '错误此Wiki不是一个有效的MediaWiki/尝试建立连接超时。'
await sendMessage(kwargs, MessageChain.create([Plain(result)]))
async def interwiki(kwargs: dict):
command = kwargs['trigger_msg']
command = re.sub(r'^interwiki ', '', command)
command = command.split(' ')
if Group in kwargs:
check = check_permission(kwargs)
if check:
if command[0] == 'add':
iw = command[1].split('>')
check = await check_wiki_available(iw[1])
if check:
result = database.config_custom_interwiki('add', 'custom_interwiki_group', kwargs[Group].id, iw[0],
check[0])
await sendMessage(kwargs, MessageChain.create([Plain(result + check[1])]))
else:
wikiurl = iwlink(basewiki)
return await wiki(wikiurl, matchmsg, '')
result = '错误此Wiki不是一个有效的MediaWiki/尝试建立连接超时。'
await sendMessage(kwargs, MessageChain.create([Plain(result)]))
elif command[0] == 'del':
result = database.config_custom_interwiki('del', 'custom_interwiki_group', kwargs[Group].id, command[1])
await sendMessage(kwargs, MessageChain.create([Plain(result)]))
else:
wikiurl = iwlink(basewiki)
return await wiki(wikiurl, matchmsg, '')
except Exception as e:
traceback.print_exc()
return f'发生错误:{str(e)}'
async def im(message):
z = []
a = '\n'
for x in message:
pipe = re.match(r'(.*?)\|.*', x)
if pipe:
x = pipe.group(1)
x = re.sub(r'^:', '', x)
url = iwlink('zh')
pagename = x
interwiki = ''
matchinterwiki = re.match(r'(.*?):(.*)', x, re.I)
if matchinterwiki:
z.append(await choosemethod(x, basewiki='zh'))
await sendMessage(kwargs, '命令不合法。')
else:
z.append(await wiki(url, pagename, interwiki))
return a.join(z)
async def imarc(message):
z = []
a = '\n'
for x in message:
pipe = re.match(r'(.*?)\|.*', x, re.I)
x = pipe.group(1)
x = re.sub(r'^:', '', x)
url = 'https://wiki.arcaea.cn/'
interwiki = ''
z.append(await wiki(url, x, interwiki, igmessage=True))
return a.join(z)
async def imt(message):
z = []
a = '\n'
for x in message:
pipe = re.match(r'(.*?)\|.*', x, re.I)
if pipe:
x = pipe.group(1)
x = re.sub(r'^:', '', x)
url = iwlink('zh')
pagename = 'Template:' + x
matchinterwiki = re.match(r'(.*?):(.*)', x)
interwiki = ''
if matchinterwiki:
interwiki = matchinterwiki.group(1)
interwiki = str.lower(interwiki)
if interwiki in iwlist():
url = iwlink(interwiki)
pagename = 'Template:' + matchinterwiki.group(2)
result = '你没有使用该命令的权限。'
await sendMessage(kwargs, MessageChain.create([Plain(result)]))
if Friend in kwargs:
if command[0] == 'add':
iw = command[1].split('>')
check = await check_wiki_available(iw[1])
if check:
result = database.config_custom_interwiki('add', 'custom_interwiki_self', kwargs[Friend].id, iw[0],
check[0])
await sendMessage(kwargs, MessageChain.create([Plain(result + check[1])]))
else:
interwiki = ''
pagename = 'Template:' + x
z.append(await wiki(url, pagename, interwiki, igmessage=False, template=True))
return a.join(z)
result = '错误此Wiki不是一个有效的MediaWiki/尝试建立连接超时。'
await sendMessage(kwargs, MessageChain.create([Plain(result)]))
elif command[0] == 'del':
result = database.config_custom_interwiki('del', 'custom_interwiki_self', kwargs[Friend].id, command[1])
await sendMessage(kwargs, MessageChain.create([Plain(result)]))
else:
await sendMessage(kwargs, '命令不合法。')
command = {'wiki': 'wiki'}
async def regex_wiki(kwargs: dict):
display = kwargs[MessageChain].asDisplay()
async def regex_proc(kwargs: dict, display):
mains = re.findall(r'\[\[(.*?)\]\]', display, re.I)
templates = re.findall(r'\{\{(.*?)\}\}', display, re.I)
find_dict = {}
global_status = 'done'
for main in mains:
if main == '' or main in find_dict:
pass
else:
find_dict.update({main: 'main'})
for template in templates:
if template == '' or template in find_dict:
pass
else:
find_dict.update({template: 'template'})
if find_dict != {}:
waitlist = []
imglist = []
urllist = {}
msglist = MessageChain.create([])
waitmsglist = MessageChain.create([])
if Group in kwargs:
table = 'start_wiki_link_group'
target = kwargs[Group].id
mth = UploadMethods.Group
if Friend in kwargs:
table = 'start_wiki_link_self'
target = kwargs[Friend].id
mth = UploadMethods.Friend
for find in find_dict:
if find_dict[find] == 'template':
template = True
else:
template = False
get_link = database.get_start_wiki(table, target)
if not get_link:
if Group in kwargs:
prompt = '没有指定起始Wiki请管理员在群内发送~wiki_start_site <域名>来设定起始Wiki。\n例子:~wiki_start_site https://minecraft-zh.gamepedia.com/'
if Friend in kwargs:
prompt = '没有指定起始Wiki请发送~wiki_start_site <域名>来设定起始Wiki。\n例子:~wiki_start_site https://minecraft-zh.gamepedia.com/'
prompt = Plain(prompt)
if prompt not in msglist:
msglist.plusWith(MessageChain.create([prompt]))
else:
iw = None
matchinterwiki = re.match(r'(.*?):(.*)', find)
if matchinterwiki:
if Group in kwargs:
iw_table = 'custom_interwiki_group'
if Friend in kwargs:
iw_table = 'custom_interwiki_self'
get_custom_iw = modules.wiki.database.get_custom_interwiki(iw_table,
target,
matchinterwiki.group(1))
if get_custom_iw:
get_link = get_custom_iw
find = re.sub(matchinterwiki.group(1) + ':', '', find)
iw = matchinterwiki.group(1)
# fandom addon
if matchinterwiki.group(1) == 'w':
matchinterwiki = re.match(r'(.*?):(.*)', matchinterwiki.group(2))
if matchinterwiki:
if matchinterwiki.group(1) == 'c':
check_fandom_addon_enable = check_enable_modules(kwargs[Group].id,
'wiki_fandom_addon')
if check_fandom_addon_enable:
matchinterwiki = re.match(r'(.*?):(.*)', matchinterwiki.group(2))
if matchinterwiki:
matchlangcode = re.match(r'(.*?):(.*)', matchinterwiki.group(2))
if matchlangcode:
if matchlangcode.group(1) in langcode:
get_link = f'https://{matchinterwiki.group(1)}.fandom.com/{matchlangcode.group(1)}/api.php'
find = matchlangcode.group(2)
iw = matchinterwiki.group(1) + ':' + matchlangcode.group(1)
else:
get_link = f'https://{matchinterwiki.group(1)}.fandom.com/api.php'
find = matchinterwiki.group(2)
iw = matchinterwiki.group(1)
else:
get_link = f'https://{matchinterwiki.group(1)}.fandom.com/api.php'
find = matchinterwiki.group(2)
iw = matchinterwiki.group(1)
msg = await modules.wiki.wikilib.wikilib().main(get_link, find, interwiki=iw, template=template)
status = msg['status']
if status == 'wait':
global_status = 'wait'
waitlist.append(msg['title'])
waitmsglist = waitmsglist.plusWith(MessageChain.create(
[Plain(('\n' if msglist != MessageChain.create([]) else '') + msg['text'])]))
if status == 'warn':
global_status = 'warn'
msglist = msglist.plusWith(MessageChain.create(
[Plain(('\n' if msglist != MessageChain.create([]) else '') + msg['text'])]))
if status == 'done':
msglist = msglist.plusWith(MessageChain.create([Plain(
('\n' if msglist != MessageChain.create([]) else '') + (
msg['url'] + '\n' if 'url' in msg else '') + msg['text'])]))
if 'net_image' in msg:
imglist.append(msg['net_image'])
if 'url' in msg:
urllist.update({msg['url']: get_link})
if msglist != MessageChain.create([]):
await sendMessage(kwargs, msglist)
if imglist != []:
imgchain = MessageChain.create([])
for img in imglist:
imgchain = imgchain.plusWith(MessageChain.create([Image.fromNetworkAddress(img, method=mth)]))
await sendMessage(kwargs, imgchain)
if urllist != {}:
print(urllist)
check_options = check_enable_modules_self(
kwargs[Member].id if Group in kwargs else kwargs[Friend].id, 'wiki_infobox')
if check_options:
infoboxchain = MessageChain.create([])
for url in urllist:
get_infobox = await get_infobox_pic(urllist[url], url)
if get_infobox:
infoboxchain = infoboxchain.plusWith(
MessageChain.create([Image.fromLocalFile(get_infobox, method=mth)]))
if infoboxchain != MessageChain.create([]):
await sendMessage(kwargs, infoboxchain)
if global_status == 'warn':
if Group in kwargs:
trigger = kwargs[Member].id
if Friend in kwargs:
trigger = kwargs[Friend].id
warn_someone(trigger)
if waitmsglist != MessageChain.create([]):
send = await sendMessage(kwargs, waitmsglist)
wait = await wait_confirm(kwargs)
if wait:
nwaitlist = []
for waits in waitlist:
waits1 = f'[[{waits}]]'
nwaitlist.append(waits1)
await regex_proc(kwargs, '\n'.join(nwaitlist))
else:
await revokeMessage(send)
await regex_proc(kwargs, display)
command = {'wiki': wiki_loader, 'wiki_start_site': set_start_wiki, 'interwiki': interwiki}
regex = {'wiki_regex': regex_wiki}
self_options = ['wiki_infobox']
options = ['wiki_fandom_addon', 'wiki_gamepedia_addon']
help = {'wiki': {'module': '查询Wiki内容。', 'help': '~wiki [interwiki:]<pagename> - 查询Wiki内容。'},
'wiki_start_site': {'module': '设置起始查询Wiki。', 'help': '~wiki_start_site <wikilink> - 设置起始查询Wiki。'},
'interwiki': {'module': '设置自定义Interwiki。', 'help': '~interwiki <add|del> <wikilink> - 设置自定义Interwiki。'},
'wiki_regex': {'module':'启用正则Wikitext查询。', 'help': '[[<pagename>]]|{{<pagename>}} - 当聊天中出现此种Wikitext时进行自动查询。'},
'wiki_infobox': {'module': '当被查询的页面包含Infobox时自动提取并渲染为图片发送。',
'help': 'Infobox渲染已开启当被查询的页面包含Infobox时自动提取并渲染为图片发送。群聊默认开启且不可全局关闭个人可使用~disable self wiki_infobox关闭', 'depend': 'wiki'},
'wiki_fandom_addon': {'module': '启用为Fandom定制的Wiki查询功能。仅群聊',
'help': '提示为Fandom定制的Wiki查询功能已开启现在包含有[[w:c:<wikiname>:[langcode:]<pagename>]]的消息会自动定向查询至Fandom的Wiki。'},
'wiki_gamepedia_addom':{'module': '启用为Gamepedia定制的Wiki查询功能。仅群聊', 'help': '提示为Gamepedia定制的查询功能已开启现在输入~wiki ~<wikiname> <pagename>会自动定向查询至Gamepedia的Wiki。'}}

121
modules/wiki/database.py Normal file
View file

@ -0,0 +1,121 @@
import os
import sqlite3
dbpath = os.path.abspath('./modules/wiki/save.db')
def initialize():
a = open(dbpath, 'w')
a.close()
conn = sqlite3.connect(dbpath)
c = conn.cursor()
c.execute('''CREATE TABLE start_wiki_link_group
(ID INT PRIMARY KEY NOT NULL,
LINK TEXT);''')
c.execute('''CREATE TABLE custom_interwiki_group
(ID INT PRIMARY KEY NOT NULL,
INTERWIKIS TEXT);''')
c.execute('''CREATE TABLE start_wiki_link_self
(ID INT PRIMARY KEY NOT NULL,
LINK TEXT);''')
c.execute('''CREATE TABLE custom_interwiki_self
(ID INT PRIMARY KEY NOT NULL,
INTERWIKIS TEXT);''')
c.close()
def add_start_wiki(table, id, value):
if not os.path.exists(dbpath):
initialize()
conn = sqlite3.connect(dbpath)
c = conn.cursor()
a = c.execute(f"SELECT * FROM {table} WHERE ID={id}").fetchone()
if a:
c.execute(f"UPDATE {table} SET LINK='{value}' WHERE ID='{id}'")
conn.commit()
return '成功设置起始Wiki'
else:
c.execute(f"INSERT INTO {table} (ID, Link) VALUES (?, ?)", (id, value))
conn.commit()
return '成功设置起始Wiki'
def get_start_wiki(table, id):
if not os.path.exists(dbpath):
initialize()
conn = sqlite3.connect(dbpath)
c = conn.cursor()
a = c.execute(f"SELECT * FROM {table} WHERE ID={id}").fetchone()
if a:
return a[1]
else:
return False
def config_custom_interwiki(do, table, id, iw, link=None):
if not os.path.exists(dbpath):
initialize()
conn = sqlite3.connect(dbpath)
c = conn.cursor()
a = c.execute(f"SELECT * FROM {table} WHERE ID={id}").fetchone()
if do == 'add':
if a:
split_iws = a[1].split('|')
iwlist = []
for iws in split_iws:
split_iw = iws.split('>')
iwlist.append(split_iw[0])
if iw in iwlist:
for iws in split_iws:
if iws.find(iw + '>') != -1:
split_iws.remove(iws)
split_iws.append(f'{iw}>{link}')
c.execute(
f"UPDATE {table} SET INTERWIKIS='{'|'.join(split_iws)}' WHERE ID='{id}'")
conn.commit()
return '成功更新自定义Interwiki'
else:
split_iws.append(f'{iw}>{link}')
c.execute(
f"UPDATE {table} SET INTERWIKIS='{'|'.join(split_iws)}' WHERE ID='{id}'")
conn.commit()
return '成功添加自定义Interwiki'
else:
c.execute(f"INSERT INTO {table} (ID, INTERWIKIS) VALUES (?, ?)", (id, f'{iw}>{link}'))
conn.commit()
return '成功添加自定义Interwiki'
elif do == 'del':
if a:
split_iws = a[1].split('|')
iwlist = []
for iws in split_iws:
split_iw = iws.split('>')
iwlist.append(split_iw[0])
if iw in iwlist:
for iws in split_iws:
if iws.find(iw + '>') != -1:
split_iws.remove(iws)
c.execute(
f"UPDATE {table} SET INTERWIKIS='{'|'.join(split_iws)}' WHERE ID='{id}'")
conn.commit()
return '成功删除自定义Interwiki'
else:
return '失败添加过此Interwiki'
else:
return '失败未添加过任何Interwiki。'
def get_custom_interwiki(table, id, iw):
if not os.path.exists(dbpath):
initialize()
conn = sqlite3.connect(dbpath)
c = conn.cursor()
a = c.execute(f"SELECT * FROM {table} WHERE ID={id}").fetchone()
if a:
interwikis = a[1].split('|')
for iws in interwikis:
if iws.find(iw + '>') != -1:
iws = iws.split('>')
return iws[1]
else:
return False

115
modules/wiki/getinfobox.py Normal file
View file

@ -0,0 +1,115 @@
import asyncio
import json
import os
import re
import traceback
import uuid
import aiohttp
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from config import config
from .helper import get_url
config_path = os.path.abspath('./config/config.cfg')
try:
if config_path:
infobox_render = config(config_path, 'infobox_render')
except:
infobox_render = None
async def get_infobox_pic(link, pagelink):
try:
print('hello')
link = re.sub('api.php', '', link)
try:
html = await get_url(pagelink, 'text')
except:
return False
print(111)
soup = BeautifulSoup(html, 'html.parser')
pagename = uuid.uuid4()
url = os.path.abspath(f'./cache/{pagename}.html')
if os.path.exists(url):
os.remove(url)
print(222)
find_infobox = soup.find(class_='notaninfobox')
if find_infobox is None:
find_infobox = soup.find(class_='infobox')
if find_infobox is None:
return False
if infobox_render is None:
open_file = open(url, 'a', encoding='utf-8')
else:
html_list = []
for x in soup.find_all(rel='stylesheet'):
y = str(x.get('href'))
z = re.sub('^/load.php', f'{link}load.php', y)
if infobox_render is None:
open_file.write(f'<link href="{z}" rel="stylesheet"/>\n')
else:
html_list.append(f'<link href="{z}" rel="stylesheet"/>\n')
replace_link = re.sub(r'href=\"/(.*)\"', 'href=\"' + link + '\\1\"', str(find_infobox), re.M)
replace_link = re.sub(r'\(/(media/)', '(' + link + '\\1', replace_link, re.M)
if infobox_render is None:
open_file.write(str(replace_link))
open_file.close()
else:
html_list.append(str(replace_link))
html = {'content': '\n'.join(html_list)}
print(333)
path2 = os.path.abspath('./assets/chromedriver.exe')
picname = os.path.abspath(f'./cache/{pagename}.jpg')
if os.path.exists(picname):
os.remove(picname)
if infobox_render is not None:
async with aiohttp.ClientSession() as session:
async with session.post(infobox_render, headers={
'Content-Type': 'application/json',
}, data=json.dumps(html)) as resp:
with open(picname, 'wb+') as jpg:
jpg.write(await resp.read())
return picname
desired_capabilities = DesiredCapabilities.CHROME
desired_capabilities["pageLoadStrategy"] = "none"
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
driver = webdriver.Chrome(path2, options=options)
driver.set_window_size(500, 400)
js_height = "return document.body.clientHeight"
link = url
print(link)
driver.get(link)
await asyncio.sleep(1)
k = 1
height = driver.execute_script(js_height)
while True:
if k * 500 < height:
js_move = "window.scrollTo(0,{})".format(k * 500)
print(js_move)
driver.execute_script(js_move)
await asyncio.sleep(1)
height = driver.execute_script(js_height)
k += 1
else:
break
scroll_width = driver.execute_script('return document.body.parentNode.scrollWidth')
scroll_height = driver.execute_script('return document.body.parentNode.scrollHeight')
driver.set_window_size(scroll_width, scroll_height)
driver.get_screenshot_as_file(picname)
driver.close()
return picname
except Exception:
traceback.print_exc()
return False

38
modules/wiki/helper.py Normal file
View file

@ -0,0 +1,38 @@
import re
import aiohttp
async def get_url(url, fmt):
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=20)) as req:
if hasattr(req, fmt):
return await getattr(req, fmt)()
else:
raise ValueError(f"NoSuchMethod: {fmt}")
async def check_wiki_available(link):
try:
api = re.match(r'(https?://.*?/api.php$)', link)
json1 = await get_url(api.group(1), 'json')
wikiname = json1['query']['general']['sitename']
return api.group(1), wikiname
except:
pass
if link[-1] not in ['/', '\\']:
link = link + '/'
test1 = link + 'api.php?action=query&meta=siteinfo&format=json'
try:
json1 = await get_url(test1, 'json')
wikiname = json1['query']['general']['sitename']
return link + 'api.php', wikiname
except:
pass
try:
test2 = link + 'w/api.php?action=query&meta=siteinfo&format=json'
json2 = await get_url(test2, 'json')
wikiname = json2['query']['general']['sitename']
return link + 'w/api.php', wikiname
except:
return False

View file

@ -4,10 +4,11 @@ import urllib
import aiohttp
from modules.interwikilist import iwlist, iwlink
import core.dirty_check
from .helper import check_wiki_available
class wiki:
class wikilib:
async def get_data(self, url: str, fmt: str):
async with aiohttp.ClientSession() as session:
try:
@ -18,9 +19,44 @@ class wiki:
raise ValueError(f"NoSuchMethod: {fmt}")
except Exception:
traceback.print_exc()
return False
def danger_wiki_check(self):
if self.wikilink.upper().find('WIKIPEDIA') != -1:
return True
return False
async def danger_text_check(self, text):
if not self.danger_wiki_check():
return False
check = await core.dirty_check.check([text])
print(check)
if check.find('<吃掉了>') != -1 or check.find('<全部吃掉了>') != -1:
return True
return False
async def get_interwiki(self, url):
interwiki_list = url + '?action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local&format=json'
json = await self.get_data(interwiki_list, 'json')
interwikimap = json['query']['interwikimap']
interwiki_dict = {}
for interwiki in interwikimap:
interwiki_dict[interwiki['prefix']] = re.sub('\$1', '', interwiki['url'])
return interwiki_dict
async def get_image(self, pagename):
try:
url = self.wikilink + f'?action=query&titles={pagename}&prop=imageinfo&iiprop=url&format=json'
json = await self.get_data(url, 'json')
parsepageid = self.parsepageid(json)
imagelink = json['query']['pages'][parsepageid]['imageinfo'][0]['url']
return imagelink
except:
traceback.print_exc()
return False
async def getpage(self):
getlinkurl = self.wikilink + 'api.php?action=query&format=json&prop=info&inprop=url&redirects&titles=' + self.pagename
getlinkurl = self.wikilink + '?action=query&format=json&prop=info&inprop=url&redirects&titles=' + self.pagename
getpage = await self.get_data(getlinkurl, "json")
return getpage
@ -32,7 +68,7 @@ class wiki:
async def researchpage(self):
try:
searchurl = self.wikilink + 'api.php?action=query&generator=search&gsrsearch=' + self.pagename + '&gsrsort=just_match&gsrenablerewrites&prop=info&gsrlimit=1&format=json'
searchurl = self.wikilink + '?action=query&generator=search&gsrsearch=' + self.pagename + '&gsrsort=just_match&gsrenablerewrites&prop=info&gsrlimit=1&format=json'
getsecjson = await self.get_data(searchurl, "json")
secpageid = self.parsepageid(getsecjson)
sectitle = getsecjson['query']['pages'][secpageid]['title']
@ -40,19 +76,30 @@ class wiki:
target = ''
else:
target = f'{self.interwiki}:'
return f'[wait]找不到条目,您是否要找的是:[[{target}{sectitle}]]'
prompt = f'找不到{target}{self.pagename},您是否要找的是:[[{target}{sectitle}]]'
if self.templateprompt:
prompt = self.templateprompt + prompt
if await self.danger_text_check(prompt):
return {'status': 'done', 'text': '发生错误:拒绝访问。'}
return {'status': 'wait', 'title': f'{target}{sectitle}', 'text': prompt}
except Exception:
try:
searchurl = self.wikilink + 'api.php?action=query&list=search&srsearch=' + self.pagename + '&srwhat=text&srlimit=1&srenablerewrites=&format=json'
searchurl = self.wikilink + '?action=query&list=search&srsearch=' + self.pagename + '&srwhat=text&srlimit=1&srenablerewrites=&format=json'
getsecjson = await self.get_data(searchurl, "json")
sectitle = getsecjson['query']['search'][0]['title']
if self.interwiki == '':
target = ''
else:
target = f'{self.interwiki}:'
return f'[wait]找不到条目,您是否要找的是:[[{target}{sectitle}]]'
prompt = f'找不到{target}{self.pagename},您是否要找的是:[[{target}{sectitle}]]'
if self.templateprompt:
prompt = self.templateprompt + prompt
if await self.danger_text_check(prompt):
return {'status': 'done', 'text': '发生错误:拒绝访问。'}
return {'status': 'wait', 'title': f'{target}{sectitle}', 'text': prompt}
except Exception:
return '找不到条目。'
traceback.print_exc()
return {'status': 'done', 'text': '找不到条目。'}
async def nullpage(self):
if 'invalid' in self.psepgraw:
@ -60,18 +107,21 @@ class wiki:
self.psepgraw['invalidreason'])
rs = '发生错误:“' + rs1 + '”。'
rs = re.sub('".”', '"', rs)
return rs
return {'status': 'done', 'text': rs}
if 'missing' in self.psepgraw:
self.rspt = await self.researchpage()
self.interference()
return self.rspt
return self.orginwikilink + urllib.parse.quote(self.pagename.encode('UTF-8'))
self.orginwikilink = re.sub('api.php', '', self.orginwikilink)
if not self.sentyouprompt:
msg = self.orginwikilink + urllib.parse.quote(self.pagename.encode('UTF-8'))
else:
msg = '您要的' + self.pagename + '' + self.orginwikilink + urllib.parse.quote(self.pagename.encode('UTF-8'))
return {'status': 'done', 'text': msg}
async def getdesc(self):
try:
descurl = self.wikilink + 'api.php?action=query&prop=extracts&exsentences=1&&explaintext&exsectionformat=wiki' \
'&format=json&titles=' + self.pagename
descurl = self.wikilink + '?action=query&prop=extracts&exsentences=1&&explaintext&exsectionformat=wiki' \
'&format=json&titles=' + self.pagename
loadtext = await self.get_data(descurl, "json")
pageid = self.parsepageid(loadtext)
desc = loadtext['query']['pages'][pageid]['extract']
@ -82,17 +132,22 @@ class wiki:
async def getfirstline(self):
try:
descurl = self.wikilink + f'api.php?action=parse&page={self.gflpagename}&prop=wikitext&section=1&format=json'
descurl = self.wikilink + f'?action=parse&page={self.gflpagename}&prop=wikitext&section=1&format=json'
loaddesc = await self.get_data(descurl, 'json')
descraw = loaddesc['parse']['wikitext']['*']
cutdesc = re.findall(r'(.*(?:!|\?|\.|;|||。|))', descraw, re.S | re.M)
desc = cutdesc[0]
except Exception:
traceback.print_exc()
desc = ''
return desc
async def step1(self):
if self.template:
self.pagename = 'Template:' + self.pagename
self.pageraw = await self.getpage()
if not self.pageraw:
return {'status': 'done', 'text': '发生错误:无法获取到页面。'}
if 'redirects' in self.pageraw['query']:
self.pagename = self.pageraw['query']['redirects'][0]['to']
self.pageid = self.parsepageid(self.pageraw)
@ -103,8 +158,8 @@ class wiki:
if self.template == True:
self.pagename = self.orginpagename = re.sub(r'^Template:', '', self.pagename)
self.template = False
self.interference()
return f'提示:[Template:{self.pagename}]不存在,已自动回滚搜索页面。\n' + await self.step1()
self.templateprompt = f'提示:[Template:{self.pagename}]不存在,已自动回滚搜索页面。\n'
return await self.step1()
return await self.nullpage()
else:
return await self.step2()
@ -116,6 +171,7 @@ class wiki:
if desc == '':
self.gflpagename = geturlpagename.group(2)
desc = await self.getfirstline()
print(desc)
try:
section = re.match(r'.*(\#.*)', self.pagename)
finpgname = geturlpagename.group(2) + urllib.parse.quote(section.group(1).encode('UTF-8'))
@ -125,10 +181,10 @@ class wiki:
finpgname = urllib.parse.unquote(finpgname)
finpgname = re.sub('_', ' ', finpgname)
if finpgname == self.orginpagename:
rmlstlb = re.sub('\n$', '', fullurl + '\n' + desc)
rmlstlb = re.sub('\n$', '', desc)
else:
rmlstlb = re.sub('\n$', '',
f'\n(重定向[{self.orginpagename}] -> [{finpgname}]\n{fullurl}\n{desc}')
f'(重定向[{self.orginpagename}] -> [{finpgname}]{desc}')
rmlstlb = re.sub('\n\n', '\n', rmlstlb)
rmlstlb = re.sub('\n\n', '\n', rmlstlb)
try:
@ -136,47 +192,58 @@ class wiki:
result = rm5lline[0] + '...行数过多已截断。'
except Exception:
result = rmlstlb
if self.interwiki != '':
pagename = self.interwiki + ':' + self.pagename
return f'您要的{self.pagename}{result}'
msgs = {'status': 'done', 'url': fullurl, 'text': result}
matchimg = re.match(r'File:.*?\.(?:png|gif|jpg|jpeg|webp|bmp|ico)', self.pagename, re.I)
if matchimg:
getimg = await self.get_image(self.pagename)
if getimg:
msgs['net_image'] = getimg
if await self.danger_text_check(result):
return {'status': 'done', 'text': '发生错误:拒绝访问。'}
return msgs
def interference(self):
if self.pagename.find('色图来') != -1:#ftynmsl
self.pagename = '你妈'
if self.pagename == '你妈':
self.rspt = '[wait] 提示:找不到[你妈],请问你是否想找一个[[新妈]]'
if self.pagename == '新妈':
self.rspt = '你没有妈。'
async def main(self, wikilink, pagename, interwiki='', igmessage=False, template=False):
async def main(self, wikilink, pagename, interwiki=None, igmessage=False, template=False, tryiw=0):
print(wikilink)
print(pagename)
print(interwiki)
pagename = re.sub('_', ' ', pagename)
pagename = pagename.split('|')[0]
self.orginwikilink = wikilink
self.wikilink = re.sub('index.php/', '', self.orginwikilink)#fxxk
self.wikilink = re.sub('index.php/', '', self.orginwikilink) # fxxk
danger_check = self.danger_wiki_check()
if danger_check:
if await self.danger_text_check(pagename):
return {'status': 'done', 'text': '发生错误:拒绝访问。'}
self.orginpagename = pagename
self.pagename = pagename
self.interwiki = interwiki
if interwiki == None:
self.interwiki = ''
else:
self.interwiki = interwiki
self.igmessage = igmessage
self.template = template
self.templateprompt = None
try:
matchinterwiki = re.match(r'(.*?):(.*)', self.pagename)
if matchinterwiki:
if matchinterwiki.group(1) in iwlist():
return await self.main(iwlink(matchinterwiki.group(1)), matchinterwiki.group(2),
matchinterwiki.group(1),
self.igmessage, self.template)
iwlist = await self.get_interwiki(self.wikilink)
print(iwlist)
if matchinterwiki.group(1) in iwlist:
if tryiw <= 5:
interwiki_link = iwlist[matchinterwiki.group(1)]
check = await check_wiki_available(interwiki_link)
if check:
return await self.main(check[0], matchinterwiki.group(2),
matchinterwiki.group(1),
self.igmessage, self.template, self.sentyouprompt, tryiw + 1)
else:
return {'status': 'done',
'text': f'发生错误指向的interwiki不是一个有效的MediaWiki。{interwiki_link}{matchinterwiki.group(2)}'}
else:
return {'status': 'warn', 'text': '警告尝试重定向已超过5次继续尝试将有可能导致你被机器人加入黑名单。'}
return await self.step1()
except Exception as e:
traceback.print_exc()
if igmessage == False:
return f'发生错误:{str(e)}'
if __name__ == '__main__':
import asyncio
a = asyncio.run(wiki().main('https://minecraft-zh.gamepedia.com/', '海晶石','zh'))
print(a)
return f'发生错误:{str(e)}' + '\n'

View file

@ -1,97 +0,0 @@
import asyncio
import traceback
import aiohttp
from graia.application import MessageChain
from graia.application.message.elements.internal import Plain
from modules.UTC8 import UTC8
from modules.pbc import pbc1
async def get_data(url: str, fmt: str):
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=20)) as req:
if hasattr(req, fmt):
return await getattr(req, fmt)()
else:
raise ValueError(f"NoSuchMethod: {fmt}")
async def newbie(app):
print('subbot newbie launched')
url = 'https://minecraft-zh.gamepedia.com/api.php?action=query&list=logevents&letype=newusers&format=json'
while True:
try:
file = await get_data(url, 'json')
qq = []
for x in file['query']['logevents'][:]:
qq.append(x['title'])
print('!' + x['title'])
while True:
c = 'f'
try:
qqqq = await get_data(url, 'json')
for xz in qqqq['query']['logevents'][:]:
if xz['title'] in qq:
pass
else:
s = await pbc1(UTC8(xz['timestamp'], 'onlytime') + '新增新人:' + xz['title'])
print(s)
if s[0].find("<吃掉了>") != -1 or s[0].find("<全部吃掉了>") != -1:
await app.sendGroupMessage(731397727, MessageChain.create([Plain(s[
0] + '\n检测到外来信息介入请前往日志查看所有消息。Special:日志?type=newusers')]).asSendable())
else:
await app.sendGroupMessage(731397727,
MessageChain.create([Plain(s[0])]).asSendable())
c = 't'
except Exception:
pass
if c == 't':
break
else:
await asyncio.sleep(10)
await asyncio.sleep(5)
except Exception:
traceback.print_exc()
async def ver(app):
from modules.mcvrss import mcvrss
from modules.mcversion import mcversion
url = 'http://launchermeta.mojang.com/mc/game/version_manifest.json'
print('subbot ver launched')
while True:
try:
verlist = mcversion()
file = await get_data(url, 'json')
release = file['latest']['release']
snapshot = file['latest']['snapshot']
if release in verlist:
pass
else:
for qqgroup in mcvrss():
try:
await app.sendGroupMessage(int(qqgroup), MessageChain.create(
[Plain('启动器已更新' + file['latest']['release'] + '正式版。')]).asSendable())
except Exception:
traceback.print_exc()
addversion = open('./assets/mcversion.txt', 'a')
addversion.write('\n' + release)
addversion.close()
if snapshot in verlist:
pass
else:
for qqgroup in mcvrss():
try:
await app.sendGroupMessage(int(qqgroup), MessageChain.create(
[Plain('启动器已更新' + file['latest']['snapshot'] + '快照。')]).asSendable())
except Exception:
traceback.print_exc()
addversion = open('./assets/mcversion.txt', 'a')
addversion.write('\n' + snapshot)
addversion.close()
await asyncio.sleep(10)
except Exception:
traceback.print_exc()
await asyncio.sleep(5)

View file

@ -1,6 +1,3 @@
from wikim import wikim
import asyncio
loop = asyncio.get_event_loop()
result = loop.run_until_complete(wikim('wiki Netherite'))
print(result)
loop.close()
from database import check_enable_modules_all
print(check_enable_modules_all('group_permission', 'wiki'))