该提交实现了完整的B站渠道插件,包含以下核心功能: 1. 支持B站直播弹幕监听与处理,包含弹幕、SC、礼物等多种直播间事件 2. 支持B站私信的轮询接收与发送 3. 内置WBI签名算法,适配B站API鉴权要求 4. 提供账号配对、黑白名单等弹幕私信权限控制 5. 集成速率限制与防风险机制,降低账号封禁风险 6. 完善的配置管理与状态监控能力
70 lines
2.1 KiB
Python
70 lines
2.1 KiB
Python
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import random
|
|
import time
|
|
|
|
|
|
class RateLimitExceeded(Exception):
|
|
pass
|
|
|
|
|
|
class AntiRisk:
|
|
RATE_LIMITS = {
|
|
"dm_send": (30, 60),
|
|
"dm_poll": (20, 60),
|
|
"danmaku_send": (5, 60),
|
|
"comment_reply": (10, 60),
|
|
"follow_user": (5, 60),
|
|
}
|
|
|
|
DELAY_RANGES = {
|
|
"dm_send": (1.5, 4.0),
|
|
"dm_poll": (3.0, 8.0),
|
|
"danmaku_send": (2.0, 5.0),
|
|
"comment_reply": (2.0, 5.0),
|
|
"follow_user": (3.0, 6.0),
|
|
}
|
|
|
|
def __init__(self, level: str = "moderate", multiplier: float = 1.5):
|
|
self._level = level
|
|
self._multiplier = multiplier
|
|
self._action_timestamps: dict[str, list[float]] = {}
|
|
|
|
async def throttle(self, action: str) -> None:
|
|
base_delay = self.DELAY_RANGES.get(action, (1.0, 2.0))
|
|
min_d, max_d = base_delay
|
|
|
|
level_mult = {"low": 0.5, "moderate": 1.0, "strict": 2.0}[self._level]
|
|
delay = random.uniform(min_d, max_d) * self._multiplier * level_mult
|
|
|
|
jitter = random.uniform(0.7, 1.3)
|
|
delay *= jitter
|
|
|
|
self._check_rate_limit(action)
|
|
|
|
await asyncio.sleep(delay)
|
|
self._record_action(action)
|
|
|
|
def random_delay(self, min_sec: float, max_sec: float) -> float:
|
|
base = random.uniform(min_sec, max_sec)
|
|
level_mult = {"low": 0.6, "moderate": 1.0, "strict": 2.0}[self._level]
|
|
return base * self._multiplier * level_mult
|
|
|
|
def _check_rate_limit(self, action: str) -> None:
|
|
limit = self.RATE_LIMITS.get(action, (100, 60))
|
|
max_count, window = limit
|
|
|
|
timestamps = self._action_timestamps.get(action, [])
|
|
now = time.time()
|
|
|
|
recent = [t for t in timestamps if now - t < window]
|
|
if len(recent) >= max_count:
|
|
raise RateLimitExceeded(f"操作 '{action}' 超过速率限制: {len(recent)}/{max_count} in {window}s")
|
|
self._action_timestamps[action] = recent
|
|
|
|
def _record_action(self, action: str) -> None:
|
|
if action not in self._action_timestamps:
|
|
self._action_timestamps[action] = []
|
|
self._action_timestamps[action].append(time.time())
|