hyper-bot 0.75__tar.gz → 0.78__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hyper-bot-0.75 → hyper-bot-0.78}/Hyper/Adapters/OneBot.py +45 -51
- {hyper-bot-0.75 → hyper-bot-0.78}/Hyper/Adapters/OneBotLib/Manager.py +43 -9
- hyper-bot-0.78/Hyper/Adapters/OneBotLib/Res.py +111 -0
- hyper-bot-0.78/Hyper/Adapters/Satori.py +105 -0
- {hyper-bot-0.75 → hyper-bot-0.78}/Hyper/Configurator.py +38 -3
- {hyper-bot-0.75 → hyper-bot-0.78}/Hyper/Events.py +36 -3
- hyper-bot-0.78/Hyper/Listener.py +18 -0
- {hyper-bot-0.75 → hyper-bot-0.78}/Hyper/Logger.py +1 -2
- {hyper-bot-0.75 → hyper-bot-0.78}/Hyper/Manager.py +2 -0
- hyper-bot-0.78/Hyper/Network.py +155 -0
- {hyper-bot-0.75 → hyper-bot-0.78}/Hyper/Segments.py +33 -93
- {hyper-bot-0.75/Hyper → hyper-bot-0.78/Hyper/Utils}/Errors.py +6 -0
- {hyper-bot-0.75/Hyper → hyper-bot-0.78/Hyper/Utils}/Logic.py +23 -27
- hyper-bot-0.78/Hyper/Utils/TypeExt.py +191 -0
- hyper-bot-0.78/Hyper/__init__.py +1 -0
- {hyper-bot-0.75 → hyper-bot-0.78}/PKG-INFO +1 -1
- {hyper-bot-0.75 → hyper-bot-0.78}/hyper_bot.egg-info/PKG-INFO +1 -1
- {hyper-bot-0.75 → hyper-bot-0.78}/hyper_bot.egg-info/SOURCES.txt +6 -4
- {hyper-bot-0.75 → hyper-bot-0.78}/setup.py +4 -2
- hyper-bot-0.75/Hyper/DataBase.py +0 -81
- hyper-bot-0.75/Hyper/Listener.py +0 -7
- hyper-bot-0.75/Hyper/ModuleClass.py +0 -67
- hyper-bot-0.75/Hyper/Network.py +0 -77
- {hyper-bot-0.75 → hyper-bot-0.78}/LICENSE +0 -0
- {hyper-bot-0.75 → hyper-bot-0.78}/hyper_bot.egg-info/dependency_links.txt +0 -0
- {hyper-bot-0.75 → hyper-bot-0.78}/hyper_bot.egg-info/top_level.txt +0 -0
- {hyper-bot-0.75 → hyper-bot-0.78}/setup.cfg +0 -0
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import json
|
|
2
|
-
import queue
|
|
3
2
|
import threading
|
|
4
3
|
import time
|
|
5
4
|
import asyncio
|
|
6
5
|
import os
|
|
7
6
|
from typing import Union
|
|
8
7
|
|
|
9
|
-
from Hyper import
|
|
8
|
+
from Hyper import Network, Events
|
|
9
|
+
from Hyper.Utils import Errors, Logic
|
|
10
|
+
from Hyper.Manager import reports
|
|
10
11
|
from Hyper.Events import *
|
|
11
12
|
|
|
12
|
-
reports = queue.Queue()
|
|
13
13
|
config = Configurator.cm.get_cfg()
|
|
14
14
|
logger = Logger.Logger()
|
|
15
15
|
logger.set_level(config.log_level)
|
|
@@ -24,20 +24,13 @@ class Actions:
|
|
|
24
24
|
self.connection = cnt_i
|
|
25
25
|
|
|
26
26
|
def __getattr__(self, item) -> callable:
|
|
27
|
-
def wrapper(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
else:
|
|
35
|
-
packet = Manager.Packet(
|
|
36
|
-
str(item),
|
|
37
|
-
**kwargs
|
|
38
|
-
)
|
|
39
|
-
packet.send_to(self.connection)
|
|
40
|
-
return get_ret(packet.echo)
|
|
27
|
+
async def wrapper(**kwargs) -> str:
|
|
28
|
+
packet = Manager.Packet(
|
|
29
|
+
str(item),
|
|
30
|
+
**kwargs
|
|
31
|
+
)
|
|
32
|
+
packet.send_to(self.connection)
|
|
33
|
+
return packet.echo
|
|
41
34
|
|
|
42
35
|
return wrapper
|
|
43
36
|
|
|
@@ -60,7 +53,7 @@ class Actions:
|
|
|
60
53
|
else:
|
|
61
54
|
raise Errors.ArgsInvalidError("'send' API requires 'group_id' or 'user_id' but none of them are provided.")
|
|
62
55
|
packet.send_to(self.connection)
|
|
63
|
-
return
|
|
56
|
+
return Manager.Ret.fetch(packet.echo)
|
|
64
57
|
|
|
65
58
|
@Logger.AutoLogAsync.register(Logger.AutoLog.templates().recall, logger)
|
|
66
59
|
async def del_message(self, message_id: int) -> None:
|
|
@@ -90,13 +83,13 @@ class Actions:
|
|
|
90
83
|
async def get_login_info(self) -> Manager.Ret:
|
|
91
84
|
packet = Manager.Packet("get_login_info")
|
|
92
85
|
packet.send_to(self.connection)
|
|
93
|
-
return
|
|
86
|
+
return Manager.Ret.fetch(packet.echo)
|
|
94
87
|
|
|
95
88
|
@Logic.Cacher().cache_async
|
|
96
89
|
async def get_version_info(self) -> Manager.Ret:
|
|
97
90
|
packet = Manager.Packet("get_version_info")
|
|
98
91
|
packet.send_to(self.connection)
|
|
99
|
-
return
|
|
92
|
+
return Manager.Ret.fetch(packet.echo)
|
|
100
93
|
|
|
101
94
|
async def send_forward_msg(self, message: Manager.Message) -> Manager.Ret:
|
|
102
95
|
packet = Manager.Packet(
|
|
@@ -104,7 +97,7 @@ class Actions:
|
|
|
104
97
|
messages=await message.get()
|
|
105
98
|
)
|
|
106
99
|
packet.send_to(self.connection)
|
|
107
|
-
return
|
|
100
|
+
return Manager.Ret.fetch(packet.echo)
|
|
108
101
|
|
|
109
102
|
async def send_group_forward_msg(self, group_id: int, message: Manager.Message) -> Manager.Ret:
|
|
110
103
|
packet = Manager.Packet(
|
|
@@ -113,7 +106,7 @@ class Actions:
|
|
|
113
106
|
messages=await message.get()
|
|
114
107
|
)
|
|
115
108
|
packet.send_to(self.connection)
|
|
116
|
-
return
|
|
109
|
+
return Manager.Ret.fetch(packet.echo)
|
|
117
110
|
|
|
118
111
|
@Logger.AutoLogAsync.register(Logger.AutoLog.templates().set_req, logger)
|
|
119
112
|
async def set_group_add_request(self, flag: str, sub_type: str, approve: bool, reason: str = "Refused") -> None:
|
|
@@ -133,7 +126,7 @@ class Actions:
|
|
|
133
126
|
no_cache=True,
|
|
134
127
|
)
|
|
135
128
|
packet.send_to(self.connection)
|
|
136
|
-
return
|
|
129
|
+
return Manager.Ret.fetch(packet.echo)
|
|
137
130
|
|
|
138
131
|
@Logic.Cacher().cache_async
|
|
139
132
|
async def get_group_member_info(self, group_id: int, user_id: int) -> Manager.Ret:
|
|
@@ -144,7 +137,7 @@ class Actions:
|
|
|
144
137
|
no_cache=True
|
|
145
138
|
)
|
|
146
139
|
packet.send_to(self.connection)
|
|
147
|
-
return
|
|
140
|
+
return Manager.Ret.fetch(packet.echo)
|
|
148
141
|
|
|
149
142
|
@Logic.Cacher().cache_async
|
|
150
143
|
async def get_group_info(self, group_id: int) -> Manager.Ret:
|
|
@@ -154,12 +147,12 @@ class Actions:
|
|
|
154
147
|
no_cache=True
|
|
155
148
|
)
|
|
156
149
|
packet.send_to(self.connection)
|
|
157
|
-
return
|
|
150
|
+
return Manager.Ret.fetch(packet.echo)
|
|
158
151
|
|
|
159
152
|
async def get_status(self) -> Manager.Ret:
|
|
160
153
|
packet = Manager.Packet("get_status")
|
|
161
154
|
packet.send_to(self.connection)
|
|
162
|
-
return
|
|
155
|
+
return Manager.Ret.fetch(packet.echo)
|
|
163
156
|
|
|
164
157
|
@Logger.AutoLogAsync.register(Logger.AutoLog.templates().set_ess, logger)
|
|
165
158
|
async def set_essence_msg(self, message_id: int) -> None:
|
|
@@ -182,33 +175,33 @@ class Actions:
|
|
|
182
175
|
message_id=msg_id
|
|
183
176
|
)
|
|
184
177
|
packet.send_to(self.connection)
|
|
185
|
-
return
|
|
178
|
+
return Manager.Ret.fetch(packet.echo)
|
|
186
179
|
|
|
187
180
|
|
|
188
181
|
async def tester(message_data: Event, actions: Actions) -> None:
|
|
189
182
|
...
|
|
190
183
|
|
|
191
184
|
|
|
192
|
-
|
|
185
|
+
def __handler(data: dict, actions: Actions) -> None:
|
|
193
186
|
if data.get("echo") is not None:
|
|
194
|
-
reports.put(
|
|
187
|
+
reports.put(data)
|
|
195
188
|
elif data.get("post_type") == "meta_event" or data.get("user_id") == data.get("self_id"):
|
|
196
189
|
pass
|
|
197
190
|
else:
|
|
198
|
-
task = asyncio.create_task(handler(Events.em.new(data), actions))
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
191
|
+
# task = asyncio.create_task(handler(Events.em.new(data), actions))
|
|
192
|
+
asyncio.run(handler(Events.em.new(data), actions))
|
|
193
|
+
# timed = 0
|
|
194
|
+
#
|
|
195
|
+
# while not task.done():
|
|
196
|
+
# time.sleep(0.1)
|
|
197
|
+
# timed += 0.1
|
|
198
|
+
# if timed >= 30:
|
|
199
|
+
# task.cancel()
|
|
200
|
+
# logger.log(f"处理{task.get_name()}超时", level=Logger.levels.ERROR)
|
|
201
|
+
# break
|
|
208
202
|
|
|
209
203
|
|
|
210
204
|
handler: callable = tester
|
|
211
|
-
connection: callable = tester
|
|
212
205
|
|
|
213
206
|
|
|
214
207
|
def reg(func: callable):
|
|
@@ -216,16 +209,7 @@ def reg(func: callable):
|
|
|
216
209
|
handler = func
|
|
217
210
|
|
|
218
211
|
|
|
219
|
-
|
|
220
|
-
old = None
|
|
221
|
-
while True:
|
|
222
|
-
content: Manager.Ret = reports.get()
|
|
223
|
-
if old is not None:
|
|
224
|
-
reports.put(old)
|
|
225
|
-
if content.echo == echo:
|
|
226
|
-
return content
|
|
227
|
-
else:
|
|
228
|
-
old = content
|
|
212
|
+
connection: Union[Network.WebsocketConnection, Network.HTTPConnection]
|
|
229
213
|
|
|
230
214
|
|
|
231
215
|
def run():
|
|
@@ -266,7 +250,9 @@ def run():
|
|
|
266
250
|
break
|
|
267
251
|
except json.decoder.JSONDecodeError:
|
|
268
252
|
logger.log("收到错误的JSON内容", level=Logger.levels.ERROR)
|
|
269
|
-
|
|
253
|
+
continue
|
|
254
|
+
# threading.Thread(target=lambda: asyncio.run(__handler(data, actions))).start()
|
|
255
|
+
threading.Thread(target=lambda: __handler(data, actions)).start()
|
|
270
256
|
except KeyboardInterrupt:
|
|
271
257
|
logger.log("正在退出(Ctrl+C)", level=Logger.levels.WARNING)
|
|
272
258
|
try:
|
|
@@ -274,3 +260,11 @@ def run():
|
|
|
274
260
|
except:
|
|
275
261
|
pass
|
|
276
262
|
os._exit(0)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def stop() -> None:
|
|
266
|
+
try:
|
|
267
|
+
connection.close()
|
|
268
|
+
except:
|
|
269
|
+
pass
|
|
270
|
+
logger.log("停止运行监听器", level=Logger.levels.WARNING)
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
from Hyper
|
|
3
|
-
from Hyper.
|
|
1
|
+
import Hyper.Utils.TypeExt
|
|
2
|
+
from Hyper import Configurator, Logger, Network, Segments
|
|
3
|
+
from Hyper.Utils import Logic
|
|
4
4
|
|
|
5
5
|
from typing import Union
|
|
6
|
-
import
|
|
6
|
+
import queue
|
|
7
7
|
import random
|
|
8
|
+
import json
|
|
8
9
|
|
|
10
|
+
reports = queue.Queue()
|
|
9
11
|
config = Configurator.cm.get_cfg()
|
|
10
12
|
logger = Logger.Logger()
|
|
11
13
|
logger.set_level(config.log_level)
|
|
@@ -33,7 +35,30 @@ class Packet:
|
|
|
33
35
|
connection.send(self.endpoint, payload, self.echo)
|
|
34
36
|
|
|
35
37
|
|
|
38
|
+
class MessageBuilder:
|
|
39
|
+
def __init__(self):
|
|
40
|
+
self.sgs = []
|
|
41
|
+
|
|
42
|
+
def __getattr__(self, item):
|
|
43
|
+
if item == "build":
|
|
44
|
+
def build() -> Message:
|
|
45
|
+
return Message(*self.sgs)
|
|
46
|
+
|
|
47
|
+
return build
|
|
48
|
+
|
|
49
|
+
elif item in Segments.message_types.keys():
|
|
50
|
+
def wrapper(*args, **kwargs):
|
|
51
|
+
self.sgs.append(Segments.message_types[item]["type"](*args, **kwargs))
|
|
52
|
+
return self
|
|
53
|
+
|
|
54
|
+
return wrapper
|
|
55
|
+
else:
|
|
56
|
+
return None
|
|
57
|
+
|
|
58
|
+
|
|
36
59
|
class Message:
|
|
60
|
+
builder = MessageBuilder()
|
|
61
|
+
|
|
37
62
|
def __init__(self, *args):
|
|
38
63
|
if len(args) == 1 and isinstance(args[0], list):
|
|
39
64
|
contents = args[0]
|
|
@@ -47,10 +72,7 @@ class Message:
|
|
|
47
72
|
self.contents.append(content)
|
|
48
73
|
|
|
49
74
|
async def get(self) -> list:
|
|
50
|
-
|
|
51
|
-
for i in self.contents:
|
|
52
|
-
ret.append(i.to_json())
|
|
53
|
-
return ret
|
|
75
|
+
return self.get_sync()
|
|
54
76
|
|
|
55
77
|
def get_sync(self) -> list:
|
|
56
78
|
ret = []
|
|
@@ -93,5 +115,17 @@ class Ret:
|
|
|
93
115
|
def __init__(self, json_data: dict):
|
|
94
116
|
self.status = json_data["status"]
|
|
95
117
|
self.ret_code = json_data["retcode"]
|
|
96
|
-
self.data = json_data.get("data")
|
|
118
|
+
self.data = Hyper.Utils.TypeExt.ObjectedJson(json_data.get("data"))
|
|
97
119
|
self.echo = json_data.get("echo")
|
|
120
|
+
|
|
121
|
+
@classmethod
|
|
122
|
+
def fetch(cls, echo: str) -> "Ret":
|
|
123
|
+
old = None
|
|
124
|
+
while True:
|
|
125
|
+
content = reports.get()
|
|
126
|
+
if old is not None:
|
|
127
|
+
reports.put(old)
|
|
128
|
+
if content["echo"] == echo:
|
|
129
|
+
return cls(content)
|
|
130
|
+
else:
|
|
131
|
+
old = content
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
message_types = {}
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def segment_builder(sg_type: str, summary_tmp: str = None):
|
|
5
|
+
# print(inspect.get_annotations(cls))
|
|
6
|
+
def inner_builder(cls):
|
|
7
|
+
var = dict(vars(cls))
|
|
8
|
+
anns: dict = var.get("__annotations__", False) or dict()
|
|
9
|
+
|
|
10
|
+
def init(self, *args, **kwargs):
|
|
11
|
+
arg = {}
|
|
12
|
+
if len(args) > 0:
|
|
13
|
+
for i in args:
|
|
14
|
+
arg[list(anns.keys())[list(args).index(i)]] = i
|
|
15
|
+
|
|
16
|
+
if len(kwargs) > 0:
|
|
17
|
+
for i in kwargs:
|
|
18
|
+
try:
|
|
19
|
+
arg[i] = anns[i](kwargs[i])
|
|
20
|
+
except TypeError:
|
|
21
|
+
arg[i] = kwargs[i]
|
|
22
|
+
new_arg = arg.copy()
|
|
23
|
+
|
|
24
|
+
if len(anns) > len(arg):
|
|
25
|
+
for i in anns.keys():
|
|
26
|
+
if i not in arg.keys():
|
|
27
|
+
if i not in var.keys():
|
|
28
|
+
new_arg[i] = None
|
|
29
|
+
continue
|
|
30
|
+
if not isinstance(var[i], anns[i]):
|
|
31
|
+
new_arg[i] = anns[i](var[i])
|
|
32
|
+
else:
|
|
33
|
+
new_arg[i] = var[i]
|
|
34
|
+
|
|
35
|
+
for i in new_arg:
|
|
36
|
+
setattr(self, i, new_arg[i])
|
|
37
|
+
|
|
38
|
+
cls.__init__ = init
|
|
39
|
+
|
|
40
|
+
def to_json(self) -> dict:
|
|
41
|
+
base = {"type": sg_type, "data": {}}
|
|
42
|
+
for i in anns:
|
|
43
|
+
if getattr(self, i) is None:
|
|
44
|
+
continue
|
|
45
|
+
if not isinstance(getattr(self, i), anns[i]):
|
|
46
|
+
base["data"][i] = anns[i](getattr(self, i))
|
|
47
|
+
else:
|
|
48
|
+
base["data"][i] = getattr(self, i)
|
|
49
|
+
# try:
|
|
50
|
+
# base["data"][i] = anns[i](getattr(self, i))
|
|
51
|
+
# except TypeError:
|
|
52
|
+
# base["data"][i] = getattr(self, i)
|
|
53
|
+
return base
|
|
54
|
+
|
|
55
|
+
cls.to_json = to_json
|
|
56
|
+
|
|
57
|
+
def to_str(self) -> str:
|
|
58
|
+
text = summary_tmp
|
|
59
|
+
if text is None:
|
|
60
|
+
text = "[]"
|
|
61
|
+
if "<" not in text and ">" not in text:
|
|
62
|
+
return text
|
|
63
|
+
|
|
64
|
+
for i in anns:
|
|
65
|
+
if f"<{i}>" in summary_tmp:
|
|
66
|
+
try:
|
|
67
|
+
v = self.__getattribute__(i)
|
|
68
|
+
except AttributeError:
|
|
69
|
+
v = None
|
|
70
|
+
text = text.replace(f"<{i}>", str(v))
|
|
71
|
+
|
|
72
|
+
return text
|
|
73
|
+
|
|
74
|
+
cls.__str__ = to_str if cls().__str__() == "__not_set__" else cls.__str__
|
|
75
|
+
|
|
76
|
+
def eq(self, other) -> bool:
|
|
77
|
+
if type(self) is type(other) and self.to_json() == other.to_json():
|
|
78
|
+
return True
|
|
79
|
+
else:
|
|
80
|
+
return False
|
|
81
|
+
|
|
82
|
+
cls.__eq__ = eq
|
|
83
|
+
|
|
84
|
+
def ne(self, other) -> bool:
|
|
85
|
+
if type(self) is type(other) and self.to_json() == other.to_json():
|
|
86
|
+
return False
|
|
87
|
+
else:
|
|
88
|
+
return True
|
|
89
|
+
|
|
90
|
+
cls.__ne__ = ne
|
|
91
|
+
|
|
92
|
+
message_types[sg_type] = {
|
|
93
|
+
"type": cls,
|
|
94
|
+
"args": list(anns.keys())
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return cls
|
|
98
|
+
|
|
99
|
+
return inner_builder
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class Base:
|
|
103
|
+
def __init__(self, *args, **kwargs): ...
|
|
104
|
+
|
|
105
|
+
def to_json(self) -> dict: ...
|
|
106
|
+
|
|
107
|
+
def __str__(self) -> str: return "__not_set__"
|
|
108
|
+
|
|
109
|
+
def __eq__(self, other) -> bool: ...
|
|
110
|
+
|
|
111
|
+
def __ne__(self, other) -> bool: ...
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
from Hyper.Adapters.OneBot import *
|
|
2
|
+
from Hyper.Utils.Errors import *
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Actions(Actions):
|
|
6
|
+
def __init__(self, cnt: Union[Network.WebsocketConnection, Network.HTTPConnection, Network.SatoriConnection]):
|
|
7
|
+
self.connection = cnt
|
|
8
|
+
|
|
9
|
+
class CustomAction:
|
|
10
|
+
def __init__(self,
|
|
11
|
+
cnt_i: Union[Network.WebsocketConnection, Network.HTTPConnection, Network.SatoriConnection]):
|
|
12
|
+
self.connection = cnt_i
|
|
13
|
+
|
|
14
|
+
def __getattr__(self, item) -> callable:
|
|
15
|
+
def wrapper(**kwargs) -> str:
|
|
16
|
+
packet = Manager.Packet(
|
|
17
|
+
str(item),
|
|
18
|
+
**kwargs
|
|
19
|
+
)
|
|
20
|
+
packet.send_to(self.connection)
|
|
21
|
+
return packet.echo
|
|
22
|
+
|
|
23
|
+
return wrapper
|
|
24
|
+
|
|
25
|
+
self.custom = CustomAction(self.connection)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
async def __handler(data: dict, actions: Actions) -> None:
|
|
29
|
+
if data["op"] == 2:
|
|
30
|
+
pass
|
|
31
|
+
else:
|
|
32
|
+
# task = asyncio.create_task(handler(Events.em.new(data), actions))
|
|
33
|
+
# timed = 0
|
|
34
|
+
#
|
|
35
|
+
# while not task.done():
|
|
36
|
+
# await asyncio.sleep(0.1)
|
|
37
|
+
# timed += 0.1
|
|
38
|
+
# if timed >= 30:
|
|
39
|
+
# task.cancel()
|
|
40
|
+
# logger.log(f"处理{task.get_name()}超时", level=Logger.levels.ERROR)
|
|
41
|
+
# break
|
|
42
|
+
print(data)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def reg(func: callable):
|
|
46
|
+
global handler
|
|
47
|
+
handler = func
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
connection: Union[Network.WebsocketConnection, Network.SatoriConnection]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def run():
|
|
54
|
+
global connection
|
|
55
|
+
try:
|
|
56
|
+
if handler is tester:
|
|
57
|
+
raise Errors.ListenerNotRegisteredError("No handler registered")
|
|
58
|
+
# connection = websocket.WebSocket()
|
|
59
|
+
if isinstance(config.connection, Configurator.WSConnectionC):
|
|
60
|
+
connection = Network.SatoriConnection(
|
|
61
|
+
config.connection.host, config.connection.port, config.connection.token
|
|
62
|
+
)
|
|
63
|
+
else:
|
|
64
|
+
raise ConfigError
|
|
65
|
+
retried = 0
|
|
66
|
+
while True:
|
|
67
|
+
try:
|
|
68
|
+
connection.connect()
|
|
69
|
+
except ConnectionRefusedError or TimeoutError:
|
|
70
|
+
if retried >= config.connection.retries:
|
|
71
|
+
logger.log(f"重试次数达到最大值({config.connection.retries}),退出", level=Logger.levels.CRITICAL)
|
|
72
|
+
break
|
|
73
|
+
|
|
74
|
+
logger.log(f"连接建立失败,3秒后重试({retried}/{config.connection.retries})",
|
|
75
|
+
level=Logger.levels.WARNING)
|
|
76
|
+
retried += 1
|
|
77
|
+
time.sleep(3)
|
|
78
|
+
continue
|
|
79
|
+
logger.log("成功建立连接", level=Logger.levels.INFO)
|
|
80
|
+
retried = 0
|
|
81
|
+
actions = Actions(connection)
|
|
82
|
+
while True:
|
|
83
|
+
try:
|
|
84
|
+
data = connection.recv()
|
|
85
|
+
except ConnectionResetError:
|
|
86
|
+
logger.log("连接断开", level=Logger.levels.ERROR)
|
|
87
|
+
break
|
|
88
|
+
except json.decoder.JSONDecodeError:
|
|
89
|
+
logger.log("收到错误的JSON内容", level=Logger.levels.ERROR)
|
|
90
|
+
threading.Thread(target=lambda: asyncio.run(__handler(data, actions))).start()
|
|
91
|
+
except KeyboardInterrupt:
|
|
92
|
+
logger.log("正在退出(Ctrl+C)", level=Logger.levels.WARNING)
|
|
93
|
+
try:
|
|
94
|
+
connection.close()
|
|
95
|
+
except:
|
|
96
|
+
pass
|
|
97
|
+
os._exit(0)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def stop() -> None:
|
|
101
|
+
try:
|
|
102
|
+
connection.close()
|
|
103
|
+
except:
|
|
104
|
+
pass
|
|
105
|
+
logger.log("停止运行监听器", level=Logger.levels.WARNING)
|
|
@@ -1,13 +1,23 @@
|
|
|
1
|
+
import json
|
|
1
2
|
import typing
|
|
2
3
|
|
|
3
|
-
from Hyper import Logic
|
|
4
|
+
from Hyper.Utils import Logic
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class WSConnectionC:
|
|
7
|
-
def __init__(self, host: str, port: int, retries: int = 0):
|
|
8
|
+
def __init__(self, host: str, port: int, retries: int = 0, satori_token: str = None):
|
|
8
9
|
self.host: str = host
|
|
9
10
|
self.port: int = port
|
|
10
11
|
self.retries: int = retries
|
|
12
|
+
self.token: str = satori_token
|
|
13
|
+
|
|
14
|
+
def to_json(self) -> dict:
|
|
15
|
+
return dict(
|
|
16
|
+
host=self.host,
|
|
17
|
+
port=self.port,
|
|
18
|
+
retries=self.retries,
|
|
19
|
+
satori_token=self.token
|
|
20
|
+
)
|
|
11
21
|
|
|
12
22
|
|
|
13
23
|
class HTTPConnectionC:
|
|
@@ -18,6 +28,15 @@ class HTTPConnectionC:
|
|
|
18
28
|
self.listener_port: int = listener_port
|
|
19
29
|
self.retries: int = retries
|
|
20
30
|
|
|
31
|
+
def to_json(self) -> dict:
|
|
32
|
+
return dict(
|
|
33
|
+
host=self.host,
|
|
34
|
+
port=self.port,
|
|
35
|
+
listener_host=self.listener_host,
|
|
36
|
+
listener_port=self.listener_port,
|
|
37
|
+
retries=self.retries
|
|
38
|
+
)
|
|
39
|
+
|
|
21
40
|
|
|
22
41
|
class Config:
|
|
23
42
|
def __init__(
|
|
@@ -55,7 +74,8 @@ class Config:
|
|
|
55
74
|
self.connection = WSConnectionC(
|
|
56
75
|
config_json["Connection"]["host"],
|
|
57
76
|
config_json["Connection"]["port"],
|
|
58
|
-
config_json["Connection"]["retries"]
|
|
77
|
+
config_json["Connection"]["retries"],
|
|
78
|
+
config_json["Connection"].get("satori_token")
|
|
59
79
|
)
|
|
60
80
|
elif config_json["Connection"]["mode"] == "HTTP":
|
|
61
81
|
self.connection = HTTPConnectionC(
|
|
@@ -71,6 +91,21 @@ class Config:
|
|
|
71
91
|
self.inited = True
|
|
72
92
|
return self
|
|
73
93
|
|
|
94
|
+
def dump(self, file: str = None) -> None:
|
|
95
|
+
if file or self.file:
|
|
96
|
+
file = file or self.file
|
|
97
|
+
cfg = dict(
|
|
98
|
+
owner=self.owner,
|
|
99
|
+
black_list=self.black_list,
|
|
100
|
+
silents=self.silents,
|
|
101
|
+
Connection=self.connection.to_json(),
|
|
102
|
+
log_level=self.log_level,
|
|
103
|
+
protocol=self.protocol,
|
|
104
|
+
Others=self.others
|
|
105
|
+
)
|
|
106
|
+
with open(file, "w", encoding="utf-8") as f:
|
|
107
|
+
f.write(json.dumps(cfg, indent=2))
|
|
108
|
+
|
|
74
109
|
|
|
75
110
|
class ConfigManager:
|
|
76
111
|
def __init__(self, config: Config):
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from Hyper import Configurator, Logger, Manager
|
|
2
|
-
from Hyper.
|
|
2
|
+
from Hyper.Utils.TypeExt import Integer
|
|
3
|
+
from Hyper.Segments import message_types, At
|
|
3
4
|
from Hyper.Logger import levels
|
|
4
5
|
|
|
5
6
|
config = Configurator.cm.get_cfg()
|
|
@@ -14,10 +15,12 @@ class EventManager:
|
|
|
14
15
|
"notice": {},
|
|
15
16
|
"request": {}
|
|
16
17
|
}
|
|
18
|
+
self.events = []
|
|
17
19
|
|
|
18
20
|
def reg(self, type_of: str, str_eql: str) -> callable:
|
|
19
21
|
def wrapper(cls):
|
|
20
22
|
self.event_lis[type_of][str_eql] = cls
|
|
23
|
+
self.events.append(cls)
|
|
21
24
|
return cls
|
|
22
25
|
|
|
23
26
|
return wrapper
|
|
@@ -28,6 +31,7 @@ class EventManager:
|
|
|
28
31
|
except KeyError:
|
|
29
32
|
typ = data[f"{data['post_type']}_type"]
|
|
30
33
|
logger.log(f"不存在的事件类型:{data['post_type']}.{typ}", levels.WARNING)
|
|
34
|
+
logger.log(str(data), levels.DEBUG)
|
|
31
35
|
return Event(data)
|
|
32
36
|
|
|
33
37
|
|
|
@@ -75,6 +79,7 @@ def gen_message(data: dict) -> Manager.Message:
|
|
|
75
79
|
message.add(message_types[i["type"]]["type"](*args))
|
|
76
80
|
else:
|
|
77
81
|
logger.log(f"无法序列化的消息段 {i['type']}", levels.WARNING)
|
|
82
|
+
logger.log(str(i), levels.DEBUG)
|
|
78
83
|
|
|
79
84
|
return message
|
|
80
85
|
|
|
@@ -88,8 +93,7 @@ class Event:
|
|
|
88
93
|
self.user_id = data.get("user_id")
|
|
89
94
|
self.group_id = data.get("group_id")
|
|
90
95
|
|
|
91
|
-
self.is_owner =
|
|
92
|
-
self.servicing = False
|
|
96
|
+
self.is_owner = Integer.convert_from(self.user_id) in config.owner
|
|
93
97
|
self.blocked = True if self.user_id in config.black_list or self.group_id in config.black_list else False
|
|
94
98
|
self.is_silent = self.user_id in config.silents or self.group_id in config.silents or 0 in config.silents
|
|
95
99
|
|
|
@@ -103,6 +107,7 @@ class MessageEvent(Event):
|
|
|
103
107
|
self.sub_type = data.get("sub_type")
|
|
104
108
|
self.message_id = str(data.get("message_id"))
|
|
105
109
|
self.message = gen_message(data=data)
|
|
110
|
+
self.msg_str = str(self.message)
|
|
106
111
|
|
|
107
112
|
|
|
108
113
|
@em.reg("message", "private")
|
|
@@ -123,6 +128,7 @@ class GroupMessageEvent(MessageEvent):
|
|
|
123
128
|
super().__init__(data)
|
|
124
129
|
self.sender = GroupSender(data.get("sender"))
|
|
125
130
|
self.anonymous = GroupAnonymous(data.get("anonymous"))
|
|
131
|
+
self.is_mentioned = True if At(str(self.self_id)) in self.message else False
|
|
126
132
|
|
|
127
133
|
self.print_log()
|
|
128
134
|
|
|
@@ -245,6 +251,33 @@ class NotifyEvent(NoticeEvent):
|
|
|
245
251
|
self.honor_type = data.get("honor_type")
|
|
246
252
|
|
|
247
253
|
|
|
254
|
+
@em.reg("notice", "essence")
|
|
255
|
+
class GroupEssenceEvent(NoticeEvent):
|
|
256
|
+
def __init__(self, data: dict):
|
|
257
|
+
super().__init__(data)
|
|
258
|
+
self.sub_type = data.get("sub_type")
|
|
259
|
+
self.sender_id = data.get("sender_id")
|
|
260
|
+
self.operator_id = data.get("operator_id")
|
|
261
|
+
self.message_id = data.get("message_id")
|
|
262
|
+
|
|
263
|
+
self.print_log()
|
|
264
|
+
|
|
265
|
+
def print_log(self) -> None:
|
|
266
|
+
action = "设置" if self.sub_type == "add" else "移除"
|
|
267
|
+
logger.log(f"{self.operator_id} 在群 {self.group_id} 中将 {self.sender_id} 的消息 {self.message_id} {action}精华")
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
@em.reg("notice", "reaction")
|
|
271
|
+
class MessageReactionEvent(NoticeEvent):
|
|
272
|
+
def __init__(self, data: dict):
|
|
273
|
+
super().__init__(data)
|
|
274
|
+
self.message_id = data.get("message_id")
|
|
275
|
+
self.operator_id = data.get("operator_id")
|
|
276
|
+
self.sub_type = data.get("sub_type")
|
|
277
|
+
self.code = data.get("code")
|
|
278
|
+
self.count = data.get("count")
|
|
279
|
+
|
|
280
|
+
|
|
248
281
|
class RequestEvent(Event):
|
|
249
282
|
def __init__(self, data: dict):
|
|
250
283
|
super().__init__(data)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from Hyper import Configurator
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
config = Configurator.cm.get_cfg()
|
|
7
|
+
|
|
8
|
+
if config.protocol == "OneBot":
|
|
9
|
+
from Hyper.Adapters.OneBot import *
|
|
10
|
+
elif config.protocol == "Satori":
|
|
11
|
+
from Hyper.Adapters.Satori import *
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def restart() -> None:
|
|
15
|
+
stop()
|
|
16
|
+
os.execv(sys.executable, ['python'] + sys.argv)
|
|
17
|
+
os._exit(1)
|
|
18
|
+
|