新增Twitch IRC协议相关的全套实现,包括: 1. 基础工具类:令牌处理、消息格式化、速率限制、消息去重 2. 核心适配器组件:IRC解析器、消息归一化、外发消息处理 3. API客户端:Helix API封装、认证提供者 4. 配置与部署:配置校验、设置向导 5. 辅助功能:配对管理、健康检查、目标解析等
63 lines
2.0 KiB
Python
63 lines
2.0 KiB
Python
from __future__ import annotations
|
||
|
||
import asyncio
|
||
import time
|
||
|
||
|
||
class RateLimiter:
|
||
"""Twitch 速率限制令牌桶
|
||
|
||
默认 20msg/30s (known user),Mod/VIP 切换至 100msg/30s。
|
||
mod 模式 60 秒后自动切回 known 模式。
|
||
"""
|
||
|
||
MOD_TIMEOUT = 60.0
|
||
|
||
def __init__(self, limit: int = 20, window: float = 30.0, mod_limit: int = 100):
|
||
self._default_limit = limit
|
||
self._mod_limit = mod_limit
|
||
self._current_limit = limit
|
||
self._window = window
|
||
self._tokens = float(limit)
|
||
self._last_refill = time.monotonic()
|
||
self._mod_until: float | None = None
|
||
self._lock = asyncio.Lock()
|
||
|
||
async def switch_to_mod(self) -> None:
|
||
async with self._lock:
|
||
if self._current_limit == self._mod_limit:
|
||
return
|
||
self._current_limit = self._mod_limit
|
||
self._tokens = float(self._mod_limit)
|
||
self._last_refill = time.monotonic()
|
||
self._mod_until = time.monotonic() + self.MOD_TIMEOUT
|
||
|
||
async def switch_to_known(self) -> None:
|
||
async with self._lock:
|
||
self._current_limit = self._default_limit
|
||
self._tokens = float(self._default_limit)
|
||
self._last_refill = time.monotonic()
|
||
self._mod_until = None
|
||
|
||
async def acquire(self) -> bool:
|
||
async with self._lock:
|
||
now = time.monotonic()
|
||
|
||
if self._mod_until is not None and now >= self._mod_until:
|
||
self._current_limit = self._default_limit
|
||
self._mod_until = None
|
||
|
||
elapsed = now - self._last_refill
|
||
refill = elapsed * (self._current_limit / self._window)
|
||
self._tokens = min(float(self._current_limit), self._tokens + refill)
|
||
self._last_refill = now
|
||
|
||
if self._tokens >= 1.0:
|
||
self._tokens -= 1.0
|
||
return True
|
||
return False
|
||
|
||
@property
|
||
def available_tokens(self) -> float:
|
||
return self._tokens
|