2026-05-12 00:45:10 +08:00
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
from yuxi.utils.logging_config import logger
|
|
|
|
|
|
|
|
|
|
from .protocol import format_ctcp, is_ctcp_message, parse_ctcp
|
|
|
|
|
from .send import send_raw_line
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def handle_ctcp(
|
|
|
|
|
send_fn,
|
|
|
|
|
source_nick: str,
|
|
|
|
|
text: str,
|
2026-05-13 16:10:40 +08:00
|
|
|
) -> bool:
|
2026-05-12 00:45:10 +08:00
|
|
|
if not is_ctcp_message(text):
|
2026-05-13 16:10:40 +08:00
|
|
|
return False
|
2026-05-12 00:45:10 +08:00
|
|
|
|
|
|
|
|
command, args = parse_ctcp(text)
|
|
|
|
|
logger.debug(f"IRC CTCP from {source_nick}: {command} {args}")
|
|
|
|
|
|
|
|
|
|
if command == "PING":
|
|
|
|
|
reply = format_ctcp("PING", args)
|
|
|
|
|
send_raw_line(send_fn, f"NOTICE {source_nick} :{reply}")
|
|
|
|
|
elif command == "VERSION":
|
|
|
|
|
reply = format_ctcp("VERSION", "ForcePilot IRC Bot v1.0")
|
|
|
|
|
send_raw_line(send_fn, f"NOTICE {source_nick} :{reply}")
|
|
|
|
|
elif command == "TIME":
|
|
|
|
|
import time as _time
|
|
|
|
|
|
|
|
|
|
reply = format_ctcp("TIME", f"{_time.time():.0f}")
|
|
|
|
|
send_raw_line(send_fn, f"NOTICE {source_nick} :{reply}")
|
|
|
|
|
elif command == "CLIENTINFO":
|
2026-05-13 16:10:40 +08:00
|
|
|
reply = format_ctcp("CLIENTINFO", "PING VERSION TIME ACTION")
|
2026-05-12 00:45:10 +08:00
|
|
|
send_raw_line(send_fn, f"NOTICE {source_nick} :{reply}")
|
2026-05-13 16:10:40 +08:00
|
|
|
elif command == "ACTION":
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def extract_ctcp_action(text: str) -> str | None:
|
|
|
|
|
if not is_ctcp_message(text):
|
|
|
|
|
return None
|
|
|
|
|
command, args = parse_ctcp(text)
|
|
|
|
|
if command == "ACTION":
|
|
|
|
|
return args
|
|
|
|
|
return None
|
2026-05-12 00:45:10 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def supports_ctcp() -> bool:
|
|
|
|
|
return True
|