245 lines
8.8 KiB
Python
245 lines
8.8 KiB
Python
"""
|
||
IRC bot dla tylda.org
|
||
Autor: v0id1st
|
||
Wersja: 0.1
|
||
|
||
Bot do zbierania statystyk na IRC tylda.org oraz dający parę gadżetów
|
||
"""
|
||
|
||
import random
|
||
import socket
|
||
from simpleeval import simple_eval, EvalWithCompoundTypes
|
||
import math
|
||
import time
|
||
import json
|
||
from datetime import date
|
||
from pathlib import Path
|
||
|
||
STATS_FILE = Path("stats/stats.json")
|
||
|
||
try:
|
||
content = STATS_FILE.read_text().strip()
|
||
except FileNotFoundError:
|
||
content = ""
|
||
|
||
FUNCTIONS = {
|
||
"sqrt": math.sqrt,
|
||
"sin": math.sin,
|
||
"cos": math.cos,
|
||
"tan": math.tan,
|
||
"asin": math.asin,
|
||
"acos": math.acos,
|
||
"atan": math.atan,
|
||
"log": math.log,
|
||
"log10": math.log10,
|
||
"log2": math.log2,
|
||
"exp": math.exp,
|
||
"abs": abs,
|
||
"round": round,
|
||
"floor": math.floor,
|
||
"ceil": math.ceil,
|
||
}
|
||
|
||
NAMES = {
|
||
"pi": math.pi,
|
||
"e": math.e,
|
||
"tau": math.tau,
|
||
"inf": math.inf,
|
||
}
|
||
|
||
def calc(expr):
|
||
return simple_eval(expr, functions=FUNCTIONS, names=NAMES)
|
||
|
||
def connect_irc():
|
||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||
s.connect(("127.0.0.1", 6667))
|
||
return s
|
||
|
||
def send_raw(sock, message):
|
||
sock.send(f"{message}\r\n".encode("utf-8"))
|
||
print(f">> {message}")
|
||
|
||
def send_msg(sock, sender, target, message, to_call = True):
|
||
if to_call:
|
||
call = f"{sender}: " if target.startswith("#") else ""
|
||
else:
|
||
call = ""
|
||
reply_to = target if target.startswith("#") else sender
|
||
|
||
send_raw(sock, f"PRIVMSG {reply_to} :{call}{message}")
|
||
|
||
def main():
|
||
print("[+] Lacze z serwerem...")
|
||
irc = connect_irc()
|
||
print("[+] Polaczono!")
|
||
|
||
send_raw(irc, "NICK tylda_bot")
|
||
send_raw(irc, "USER tylda_bot 0 * :Bot tyldowy")
|
||
|
||
buffer = ""
|
||
lastmsg = ""
|
||
|
||
while True:
|
||
data = irc.recv(4096).decode("utf-8", errors="replace")
|
||
if not data:
|
||
print("[!] Rozlaczono.")
|
||
|
||
buffer += data
|
||
lines = buffer.split("\r\n")
|
||
buffer = lines.pop()
|
||
|
||
for line in lines:
|
||
if not line:
|
||
continue
|
||
|
||
print(f"<< {line}")
|
||
|
||
if line.startswith("PING"):
|
||
pong_response = line.replace("PING", "PONG", 1)
|
||
send_raw(irc, pong_response)
|
||
continue
|
||
|
||
if " 001 " in line:
|
||
send_raw(irc, "JOIN #test_bot")
|
||
continue
|
||
|
||
|
||
if "PRIVMSG" in line:
|
||
try:
|
||
content = STATS_FILE.read_text().strip()
|
||
except FileNotFoundError:
|
||
content = ""
|
||
|
||
today = date.today().isoformat()
|
||
|
||
if content:
|
||
stats = json.loads(content)
|
||
if stats["last_date"] != today:
|
||
stats["today_msg"] = 1
|
||
else:
|
||
stats["today_msg"] += 1
|
||
stats["all_msg"] += 1
|
||
stats["last_date"] = today
|
||
else:
|
||
stats = {"last_date": today, "today_msg": 1, "all_msg": 1}
|
||
|
||
STATS_FILE.write_text(json.dumps(stats))
|
||
|
||
parts = line.split(" ", 3)
|
||
if len(parts) >= 4:
|
||
sender = parts[0].split("!")[0][1:]
|
||
target = parts[2]
|
||
message = parts[3][1:].strip()
|
||
if not message.startswith("!"):
|
||
lastmsg = message
|
||
|
||
if message == "!hello":
|
||
greetings = ["Cześć", "Siema", "Siemka", "Siemano", "Elo", "ELO", "NO ELO", "Yo", "Yooooo", "Witaj", "Siema z rana"]
|
||
greeting = random.choice(greetings)
|
||
send_msg(irc, sender, target, f"{greeting} {sender}!")
|
||
|
||
if message == "!gn":
|
||
gns = ["Dobranoc", "Dobranocki", "Kolorowych snów", "Papa", "Paaa", "Śpij dobrze", "Śpij słodko", "Trzymaj się", "Narka"]
|
||
gn = random.choice(gns)
|
||
send_msg(irc, sender, target, f"{gn} {sender}!")
|
||
|
||
if message == "!8ball":
|
||
answers = [
|
||
"To pewne.",
|
||
"Zdecydowanie tak.",
|
||
"Bez wątpienia.",
|
||
"Tak - na pewno.",
|
||
"Możesz na to liczyć.",
|
||
"Jak to widzę, tak.",
|
||
"Najprawdopodobniej.",
|
||
"Perspektywy dobre.",
|
||
"Tak.",
|
||
"Znaki wskazują na tak.",
|
||
"Odpowiedź niewyraźna, spróbuj ponownie.",
|
||
"Zapytaj później.",
|
||
"Lepiej ci teraz nie mówić.",
|
||
"Nie można przewidzieć.",
|
||
"Skoncentruj się i zapytaj ponownie.",
|
||
"Nie licz na to.",
|
||
"Moja odpowiedź brzmi: nie.",
|
||
"Moje źródła mówią nie.",
|
||
"Perspektywy niezbyt dobre.",
|
||
"Bardzo wątpliwe.",
|
||
"Nie."
|
||
]
|
||
answer = random.choice(answers)
|
||
send_msg(irc, sender, target, answer)
|
||
|
||
if message == "!roll":
|
||
answers = [1,2,3,4,5,6]
|
||
answer = random.choice(answers)
|
||
send_msg(irc, sender, target, f"Wylosowałem: {answer}")
|
||
|
||
if message.startswith("!rate "):
|
||
what = " ".join(message.split(" ")[1:])
|
||
score = math.floor(random.random() * 11)
|
||
send_msg(irc, sender, target, f"Moja ocena {what} to: {score}")
|
||
|
||
if message.startswith("!calc "):
|
||
what = " ".join(message.split(" ")[1:])
|
||
try:
|
||
result = calc(what)
|
||
except:
|
||
result = "nope"
|
||
|
||
msg = f"Wynik to: {result}" if result != "nope" else "Nieprawidłowy format!"
|
||
send_msg(irc, sender, target, msg)
|
||
|
||
if message.startswith("!mock"):
|
||
what = " ".join(message.split(" ")[1:])
|
||
if len(what) > 0:
|
||
to_mock = what
|
||
else:
|
||
to_mock = lastmsg
|
||
|
||
mocked = "".join(c.upper() if i % 2 == 0 else c.lower() for i,c in enumerate(to_mock))
|
||
send_msg(irc, sender, target, mocked, False)
|
||
|
||
if message.startswith("!rps "):
|
||
what = " ".join(message.split(" ")[1:])
|
||
if what.startswith("papier"):
|
||
choice = "paper"
|
||
elif what.startswith("kamie"):
|
||
choice = "rock"
|
||
elif what.startswith("no"):
|
||
choice = "scissors"
|
||
|
||
mine = random.choice(["rock", "paper", "scissors"])
|
||
if mine == "rock" and choice == "rock":
|
||
answer = "Kamień! Remis!"
|
||
elif mine == "rock" and choice == "paper":
|
||
answer = "Kamień! Gratulacje <3"
|
||
elif mine == "rock" and choice == "scissors":
|
||
answer = "Kamień! Przykro mi :("
|
||
elif mine == "paper" and choice == "rock":
|
||
answer = "Papier! Przykro mi :(("
|
||
elif mine == "paper" and choice == "paper":
|
||
answer = "Papier! Remis! :D"
|
||
elif mine == "paper" and choice == "scissors":
|
||
answer = "Papier! Gratki <3"
|
||
elif mine == "scissors" and choice == "rock":
|
||
answer = "Nożyce! Nieźle, gratki :)"
|
||
elif mine == "scissors" and choice == "paper":
|
||
answer = "Nożyce! Sorki :c"
|
||
elif mine == "scissors" and choice == "scissors":
|
||
answer = "Nożyce! Remis xD"
|
||
|
||
send_msg(irc, sender, target, f"Wylosowałem.. {answer}")
|
||
|
||
if message == "!help":
|
||
send_msg(irc, sender, target, "Jestem botem, witam. Potrafię następujące rzeczy:")
|
||
time.sleep(0.5)
|
||
send_msg(irc, sender, target, "!hello, !8ball, !roll, !mock [arg], !rps <papier/kamien/nozyce>, !rate <what> oraz !calc <expr>")
|
||
time.sleep(0.5)
|
||
send_msg(irc, sender, target, "Jak chcesz coś mi dorzucić to zapraszam na gita :))))")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|
||
|