Created
March 28, 2021 18:05
-
-
Save matheusfillipe/970482253d2b883a73bd4b40f5e87a7d to your computer and use it in GitHub Desktop.
A virtual and alive crowd for https://github.com/matheusfillipe/triviabot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import socket, time, re, trio | |
from IrcBot.bot import IrcBot, utils | |
import logging | |
import threading | |
import urllib.request | |
from random import randint, choice | |
from cleverbot_free.cbapi import CleverBot | |
url = "http://www.storage.dot.org.es/trivia/questions.txt" | |
res = urllib.request.urlopen(url) | |
if res.getcode() != 200: | |
logging.error("BAD url") | |
exit() | |
questions = [s.decode().replace("\n","") for s in res.readlines()] | |
COLOR="08,01" | |
TRIVIA = "trivia" | |
QUESTION = ["Întrebare:", "Următoarea întrebare:"] | |
CHANCE = 10 | |
TALK = 3 | |
TTL=4 | |
MAX_TALKS = 2 | |
current_talks = 0 | |
STARTERS = [ | |
"How is your mother?", | |
"How is life?", | |
"What are you doing today?", | |
"Do you have friends?", | |
"Isn't it a nice day?", | |
"Oh yes." | |
] | |
PORT = 6667 | |
AI = True | |
HOST = "irc.dot.org.es" | |
ADMINS = ["mattf", "gasconheart"] | |
CHANNEL="#trivia" | |
NAMES=["blanka", "zangief", "ryu", "ken", "guile", "honda", "dhalsim"]# "vega", "bison", "balrog", "chun_li", "pele", "garrincha", "zagalo", "vava", "feral_boy", "corina", "ursula", "mihaela", "andrea", "oana", "ioana", "maria", "aisha", "roberta", "ramona", "dora", "diana", "daiana", "michelle", "luis", "luiza", "carmen", "carmencita", "richard", "murr", "q", "sal", "joe", "paul", "john", "george", "ringo", "patricia", "daniela"] | |
#NAMES=["jose"] | |
cb=None | |
if AI: | |
cb = CleverBot() | |
cb.init() | |
send_ = lambda client, channel, m: client.send_all(f"PRIVMSG {channel} :{m}\r\n".encode()) #sends a private message to the channel or user PM if you pass a nickname | |
raw_send_ = lambda client, m: client.send_all(f"{m}\r\n".encode()) #Use this to implrement more methods: https://tools.ietf.org/html/rfc1459 | |
async def Bot(host, port=6667, name="botty", channel="#lobby"): | |
client = await trio.open_tcp_stream(host, port) | |
#We will keep username a nickname the same and not really care about password | |
await client.send_all(f"NICK {name}\r\n \ | |
USER {name} 0 * :{name}\r\n \ | |
JOIN {channel}\r\n \ | |
PRIVMSG NickServ :set always-on true\r\n".encode()) | |
return client, lambda m: send_(client, channel, m), lambda m: raw_send_(client, m) | |
kill = True | |
async def newBot(n, stop): | |
global cb | |
global kill | |
global current_talks | |
logging.info(n) | |
bot, msg, raw = await Bot(HOST, PORT, n, CHANNEL) | |
playing=False | |
quest=False | |
ttl = TTL | |
conversation=False | |
last="" | |
async for data in bot: | |
if not stop or kill: | |
logging.info("Stopping "+n) | |
await bot.aclose() | |
return | |
data=data.decode().split("\n") | |
for res in data: | |
logging.info(n+" 00000000"+res+"00000000000000000") | |
match=re.match(r'^:(.*)!.*PRIVMSG (\S+) :(.*)$', res) | |
if match and n in res and "PRIVMSG" in res: | |
sender, channel, text=match[1], match[2], match[3] | |
if sender==TRIVIA: | |
continue | |
if sender in NAMES: | |
ttl-=1 | |
if ttl < 0: | |
ttl=TTL | |
conversation=False | |
current_talks-=1 | |
last=text | |
continue | |
logging.info(text) | |
if AI: | |
await msg(sender+": "+cb.getResponse(text)) | |
else: | |
await msg("What is "+text+" ?") | |
elif match: | |
sender, channel, text=match[1], match[2], match[3] | |
if sender in ADMINS and text.lower().strip() == "everyone playing": | |
playing=True | |
continue | |
elif playing and sender==TRIVIA: | |
if quest: | |
if randint(0,100)>CHANCE: | |
continue | |
q=text.replace(COLOR,"").strip()[1:] | |
logging.info("11111111111111111"+q) | |
quest=False | |
for l in questions: | |
x=str(l.split("`")[0].strip()) | |
if q==x: | |
logging.info("SENDING " + l.split("`")[-1]) | |
await trio.sleep(.15) | |
await msg(l.split("`")[-1]) | |
break | |
elif QUESTION[0] in text or QUESTION[1] in text: | |
quest = True | |
elif not conversation and current_talks <= MAX_TALKS: | |
if randint(0,100)>TALK: | |
continue | |
conversation=True | |
current_talks+=1 | |
if not last: | |
await msg(choice(NAMES)+" "+choice(STARTERS)) | |
else: | |
await msg(choice(NAMES)+" "+cb.getResponse(last)) | |
elif "PING" in res: | |
await raw("PONG "+HOST) | |
async def botLoop(stop): | |
async with trio.open_nursery() as nursery: | |
for n in NAMES: | |
nursery.start_soon(newBot, n, stop) | |
await trio.sleep(1) | |
def crowd(stop=True): | |
trio.run(botLoop, stop) | |
t1=None | |
stop_event=None | |
@utils.regex_cmd_with_messsage("^(.*) lucas$") | |
def crowdon(m, message): | |
global t1 | |
global CHANNEL | |
global kill | |
global stop_event | |
if not message.sender_nick in ADMINS: | |
return "No..." | |
m=m[1] | |
if m=="hi": | |
CHANNEL = message.channel | |
stop_event= threading.Event() | |
t1 = threading.Thread(target = crowd, args=(stop_event,)) | |
kill= False | |
t1.start() | |
return "Come in my friends!" | |
if m=='bye': | |
stop_event.set() | |
kill=True | |
return "Bye friends!" | |
bot = IrcBot(HOST, PORT, "lucas", CHANNEL, "") | |
bot.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment