mirror of
https://github.com/nichkara/InfinitumBotty.git
synced 2026-06-10 22:26:23 +02:00
Initalize repo
This commit is contained in:
40
FaustBot/Modules/ActivityObserver.py
Normal file
40
FaustBot/Modules/ActivityObserver.py
Normal file
@@ -0,0 +1,40 @@
|
||||
# from ..FaustBot import ModuleType
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Model.UserProvider import UserProvider
|
||||
from FaustBot.Modules.JoinObserverPrototype import JoinObserverPrototype
|
||||
from FaustBot.Modules.ModuleType import ModuleType
|
||||
from ..Modules.NickChangeObserverPrototype import NickChangeObserverPrototype
|
||||
from ..Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
|
||||
|
||||
class ActivityObserver(PrivMsgObserverPrototype, JoinObserverPrototype, NickChangeObserverPrototype):
|
||||
"""
|
||||
A Class only reacting to pings
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return None
|
||||
|
||||
def update_on_join(self, data, connection: Connection):
|
||||
users = UserProvider()
|
||||
if data['channel'] == connection.details.get_channel():
|
||||
users.set_active(data['nick'])
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
users = UserProvider()
|
||||
if data['channel'] == connection.details.get_channel():
|
||||
users.set_active(data['nick'])
|
||||
users.add_characters(data['nick'], len(data['message']))
|
||||
|
||||
def update_on_nick_change(self, data, connection: Connection):
|
||||
users = UserProvider()
|
||||
users.set_active(data['new_nick'])
|
||||
|
||||
@staticmethod
|
||||
def get_module_types():
|
||||
return [ModuleType.ON_MSG, ModuleType.ON_JOIN, ModuleType.ON_NICK_CHANGE]
|
||||
41
FaustBot/Modules/AllSeenObserver.py
Normal file
41
FaustBot/Modules/AllSeenObserver.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import datetime
|
||||
import time
|
||||
from collections import defaultdict
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Model.UserProvider import UserProvider
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
from ..Model.i18n import i18n
|
||||
from FaustBot.Modules.UserList import UserList
|
||||
|
||||
class AllSeenObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".seen"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".seen <nick> - um abzufragen wann <nick> zuletzt hier war"
|
||||
|
||||
def __init__(self, user_list: UserList):
|
||||
super().__init__()
|
||||
self.user_list = user_list
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
if data['message'].find('.allseen') == -1:
|
||||
return
|
||||
if not self._is_idented_mod(data, connection):
|
||||
return
|
||||
User_afk = defaultdict(int)
|
||||
for who in self.user_list.userList.keys():
|
||||
user_provider = UserProvider()
|
||||
activity = user_provider.get_activity(who)
|
||||
delta = time.time() - activity
|
||||
User_afk[who] = delta
|
||||
print(who)
|
||||
print(delta)
|
||||
for w in sorted(User_afk, key=User_afk.get):
|
||||
output = (w+":\t"+str(datetime.timedelta(seconds=User_afk[w])))
|
||||
connection.send_back(output, data)
|
||||
|
||||
def _is_idented_mod(self, data: dict, connection: Connection):
|
||||
return data['nick'] in self._config.mods and connection.is_idented(data['nick'])
|
||||
130
FaustBot/Modules/AntiSpamObserver.py
Normal file
130
FaustBot/Modules/AntiSpamObserver.py
Normal file
@@ -0,0 +1,130 @@
|
||||
from FaustBot.Communication.Communication import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
from FaustBot.Modules.JoinObserverPrototype import JoinObserverPrototype
|
||||
from FaustBot.Model.Config import Config
|
||||
from enum import Enum
|
||||
from datetime import datetime
|
||||
|
||||
"""
|
||||
This Module contains multiple classes to handle spam.
|
||||
Goal of this module is to provide an easy to use AntiSpam-Module, which can be activated if needed.
|
||||
It should support multiple modes regarding the aggressivity of the anti-spam-handling.
|
||||
"""
|
||||
|
||||
|
||||
class AntiSpamLevel(Enum):
|
||||
"""
|
||||
Which action to be done if spam is detected.
|
||||
"""
|
||||
OFF = 0 # No action is taken if spam is detected.
|
||||
WARN = 1 # Warns the user by messaging him/her without any further steps.
|
||||
WARN_KICK = 2 # Warns the user first, then kicks him/her.
|
||||
KICK = 3 # Kicks the user without any further warning.
|
||||
WARN_KICK_BAN = 4 # Like WARN_KICK but also bans the user directly.
|
||||
KICK_BAN = 5 # Like KICK, but also bans the user directly.
|
||||
|
||||
|
||||
class AntiSpamAggressivity(Enum):
|
||||
"""
|
||||
Settings to detect spam.
|
||||
a: Amount of seconds between two similiar messages to detect them as spam
|
||||
b: Amount of (non similiar) messages to be received with time-distance c, to detect them as spam
|
||||
c: Time between messages of b:
|
||||
d: Trustfactor
|
||||
"""
|
||||
LOW = (3, 7, 0.5, 15) # (a, b, c, d)
|
||||
MEDIUM = (5, 5, 0.7, 10)
|
||||
HIGH = (7, 3, 1.0, 5)
|
||||
ULTRA = (10, 3, 1.0, 2)
|
||||
|
||||
|
||||
class AntiSpamEntry(object):
|
||||
"""
|
||||
Entry collecting information about possible spammers.
|
||||
"""
|
||||
|
||||
def __init__():
|
||||
super().__init__()
|
||||
self.user = ""
|
||||
self.warn_count = 0
|
||||
self.msg = ""
|
||||
self.timestamp = datetime.now()
|
||||
|
||||
@property
|
||||
def user(self):
|
||||
return self.user
|
||||
|
||||
@user.setter
|
||||
def user(self, user)
|
||||
self.user = user
|
||||
|
||||
@property
|
||||
def warn_count(self):
|
||||
return self.warn_count
|
||||
|
||||
@warn_count.setter
|
||||
def warn_count(self, warn_count)
|
||||
self.warn_count = warn_count
|
||||
|
||||
def inc_warn_count(self)
|
||||
self.warn_count += 1
|
||||
|
||||
@property
|
||||
def msg(self):
|
||||
return self.msg
|
||||
|
||||
@msg.setter
|
||||
def msg(self, msg):
|
||||
self.msg = msg
|
||||
|
||||
@property
|
||||
def timestamp(self):
|
||||
return self.timestamp
|
||||
|
||||
@timestamp.setter
|
||||
def timestamp(self, timestamp):
|
||||
self.timestamp = timestamp
|
||||
|
||||
|
||||
class AntiSpamObserver(PrivMsgObserverPrototype, JoinObserverPrototype):
|
||||
|
||||
@staticmethod
|
||||
def cmd():
|
||||
raise NotImplementedError("TBD!")
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
raise NotImplementedError("TBD!")
|
||||
|
||||
@staticmethod
|
||||
def get_module_types():
|
||||
return [ModuleType.ON_JOIN,
|
||||
ModuleType.ON_PRIVMSG]
|
||||
|
||||
def __init__(self, config : Config):
|
||||
super().__init__()
|
||||
self._msg_map = dict()
|
||||
self._anti_spam_level = AntiSpamLevel.OFF
|
||||
self._anti_spam_aggressivity = AntiSpamAggressivity.LOW
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
if _bot_name in data['channel']: # TBD! _bot_name should be fetched from the config!
|
||||
self._handle_command(data, connection)
|
||||
|
||||
if self._anti_spam_level == AntiSpamLevel.OFF:
|
||||
return
|
||||
|
||||
def update_on_join(self, data: dict, connection: Connection):
|
||||
raise NotImplementedError("TBD!")
|
||||
|
||||
def _is_spam(self, user: str, msg: str)
|
||||
pass
|
||||
|
||||
def _handle_command(self, data: dict, connection: Connection)
|
||||
pass
|
||||
|
||||
def _is_idented_mod(self, data: dict, connection: Connection):
|
||||
"""
|
||||
Check wether the issuer of a module control command is a moderator or not
|
||||
"""
|
||||
return data['nick'] in self._config.mods and connection.is_idented(data['nick']
|
||||
50
FaustBot/Modules/BlockObserver.py
Normal file
50
FaustBot/Modules/BlockObserver.py
Normal file
@@ -0,0 +1,50 @@
|
||||
import datetime
|
||||
import time
|
||||
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Model.UserProvider import UserProvider
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
from ..Model.i18n import i18n
|
||||
from FaustBot.Model.BlockedUsers import BlockProvider
|
||||
|
||||
class BlockObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [""]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ""
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
if not self._is_idented_mod(data, connection):
|
||||
return
|
||||
if data['message'].find('.block ') != -1:
|
||||
self.block(data, connection)
|
||||
if data['message'].find ('.unblock')!=-1:
|
||||
self.unblock(data, connection)
|
||||
if data['message'].find('.isblocked') != -1:
|
||||
self.isBlocked(data, connection)
|
||||
|
||||
def block(self,data,connection):
|
||||
blocklist = BlockProvider()
|
||||
blocklist.block(self.isolateTarget(data))
|
||||
connection.send_back("blocked: "+ self.isolateTarget(data), data)
|
||||
|
||||
def unblock(self,data,connection):
|
||||
blocklist = BlockProvider()
|
||||
blocklist.delete_block(self.isolateTarget(data))
|
||||
connection.send_back("unblocked: "+ self.isolateTarget(data), data)
|
||||
|
||||
def isBlocked(self,data,connection):
|
||||
blocklist= BlockProvider()
|
||||
answ = blocklist.is_blocked(self.isolateTarget(data))
|
||||
if answ:
|
||||
connection.send_back(self.isolateTarget(data) + " ist geblocked", data)
|
||||
return
|
||||
connection.send_back(self.isolateTarget(data)+" ist nicht geblocked", data)
|
||||
def isolateTarget(self,data):
|
||||
return data['message'].split(' ')[1]
|
||||
|
||||
def _is_idented_mod(self, data: dict, connection: Connection):
|
||||
return data['nick'] in self._config.mods and connection.is_idented(data['nick'])
|
||||
43
FaustBot/Modules/ComicObserver.py
Normal file
43
FaustBot/Modules/ComicObserver.py
Normal file
@@ -0,0 +1,43 @@
|
||||
import random
|
||||
import urllib
|
||||
import requests
|
||||
import html
|
||||
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
from FaustBot.Modules.TitleObserver import TitleObserver
|
||||
from FaustBot.Modules.ComicScraper import ComicScraper
|
||||
|
||||
from comics import *
|
||||
|
||||
|
||||
class ComicObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return ['.comic']
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return '.comic liefer einen Link zu einem zufälligen Comic.'
|
||||
|
||||
def update_on_priv_msg(self, data: dict, connection: Connection):
|
||||
if data['message'].find('.comic') == -1:
|
||||
return
|
||||
|
||||
#Join list of comics that have a web based random functionality and those that need a scraper
|
||||
all_comics=comics+scraper_comics
|
||||
|
||||
#Choose from the joined list
|
||||
comic = random.choice(all_comics)
|
||||
|
||||
#Check which type of comic it is: If it's one that doesn't need a scraper, get the url and return it.
|
||||
#If it needs a scraper, use ComicScraper to scrape the comic.
|
||||
#If you want to add custom comic scrapers: Look at ComicScraper.py and insert your functionality.
|
||||
if not comic in scraper_comics:
|
||||
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)'}
|
||||
req = urllib.request.Request(comic, None, headers)
|
||||
resource = urllib.request.urlopen(req)
|
||||
title = TitleObserver.getTitle(TitleObserver(), resource)
|
||||
connection.send_back(resource.geturl() + " " + title, data)
|
||||
else:
|
||||
connection.send_back(ComicScraper.getRandomComic(comic),data);
|
||||
41
FaustBot/Modules/ComicScraper.py
Normal file
41
FaustBot/Modules/ComicScraper.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import random
|
||||
import urllib
|
||||
import requests
|
||||
import html
|
||||
|
||||
#Comic scraper scrapes comics from urls that have no website based random functionality. Comic URLs have to be in comics.py
|
||||
class ComicScraper():
|
||||
|
||||
#Scrapers for specific websites follow here:
|
||||
|
||||
#scraper for Betamonkeys
|
||||
def scrapeBetamonkeys(url):
|
||||
#get latest comic id from the website, then generate a random number within the range of 1 and the latest comic.
|
||||
#Finally generate a new comic url from that. I know this is dirty - But it works for a comic i guess ;)
|
||||
r = requests.get(url)
|
||||
comic_id_latest=r.content.decode("utf-8").split("http://betamonkeys.co.uk/wp-content/stripshow_comics/betamonkeys")[1].split(".png")[0]
|
||||
random_comic_number=str(random.randint(1,int(comic_id_latest)))
|
||||
random_comic_url="http://betamonkeys.co.uk/wp-content/stripshow_comics/betamonkeys"+random_comic_number+".png"
|
||||
return random_comic_url+ " Betamonkeys "+ random_comic_number + " | Betamonkeys"
|
||||
|
||||
#scraper for Nichtlustig
|
||||
def scrapeNichtlustig(url):
|
||||
#TODO: Write a scraper for Nichtlustig!
|
||||
return "Bisher kein Scraper für Nichtlustig."
|
||||
|
||||
#your custom scraper here
|
||||
#def scrapeYourCustomComic(url):
|
||||
#return "Your custom scraped URL"
|
||||
|
||||
|
||||
|
||||
#Main scraping function. Takes url, decides scraping method to use. If no scraping method is found: return "No parser found"
|
||||
def getRandomComic(url):
|
||||
if "betamonkeys.co.uk" in url:
|
||||
return ComicScraper.scrapeBetamonkeys(url)
|
||||
|
||||
if "nichtlustig.de" in url:
|
||||
return ComicScraper.scrapeNichtlustig(url)
|
||||
|
||||
else:
|
||||
return "No parser found for comic URL: "+url
|
||||
94
FaustBot/Modules/CustomUserModules/GlossaryModule.py
Normal file
94
FaustBot/Modules/CustomUserModules/GlossaryModule.py
Normal file
@@ -0,0 +1,94 @@
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Model.Config import Config
|
||||
from FaustBot.Model.GlossaryProvider import GlossaryProvider
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
from FaustBot.Modules.WikiObserver import WikiObserver
|
||||
|
||||
class GlossaryModule(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [GlossaryModule._ADD_EXPLANATION,
|
||||
GlossaryModule._REMOVE_EXPLANATION,
|
||||
GlossaryModule._QUERY_EXPLANATION]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return None
|
||||
|
||||
_QUERY_EXPLANATION = '.?'
|
||||
_REMOVE_EXPLANATION = '.?-'
|
||||
_ADD_EXPLANATION = '.?+'
|
||||
|
||||
def __init__(self, config: Config):
|
||||
super().__init__()
|
||||
self._config = config
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
msg = data['message']
|
||||
if not -1 == msg.find(GlossaryModule._REMOVE_EXPLANATION):
|
||||
self._remove_query(data, connection)
|
||||
elif not -1 == msg.find(GlossaryModule._ADD_EXPLANATION):
|
||||
self._add_query(data, connection)
|
||||
elif not -1 == msg.find(GlossaryModule._QUERY_EXPLANATION):
|
||||
self._answer_query(data, connection)
|
||||
|
||||
def _answer_query(self, data, connection: Connection):
|
||||
"""
|
||||
:param data:
|
||||
:param connection:
|
||||
:return:
|
||||
"""
|
||||
glossary_provider = GlossaryProvider()
|
||||
split = data['message'].split(GlossaryModule._QUERY_EXPLANATION)
|
||||
if not len(split) == 2:
|
||||
return
|
||||
answer = glossary_provider.get_explanation(split[1].strip())
|
||||
if answer is None or answer[1] is None or answer[1].strip() == '':
|
||||
if split[1].strip() == '':
|
||||
return
|
||||
# connection.send_back("Tut mir leid, " + data['nick'] + ". Für " + split[1].strip() +
|
||||
# " habe ich noch keinen Eintrag. Aber Wikipedia sagt dazu:", data)
|
||||
wikiObserver = WikiObserver()
|
||||
wikiObserver.config = self.config
|
||||
data2 = data.copy()
|
||||
data2['message'] = '.w '+split[1]+" \r\n"
|
||||
wikiObserver.update_on_priv_msg(data2, connection)
|
||||
else:
|
||||
connection.send_back(data['nick'] + ": " + split[1] + " - " + answer[1], data)
|
||||
|
||||
def _remove_query(self, data, connection: Connection):
|
||||
"""
|
||||
|
||||
:param data:
|
||||
:param connection:
|
||||
:return:
|
||||
"""
|
||||
if not self._is_idented_mod(data, connection):
|
||||
connection.send_back("Dir fehlen die Berechtigungen zum Löschen von Einträgen, " + data['nick'] + ".", data)
|
||||
return
|
||||
glossary_provider = GlossaryProvider()
|
||||
split = data['message'].split(GlossaryModule._REMOVE_EXPLANATION)
|
||||
if not len(split) == 2:
|
||||
return
|
||||
glossary_provider.delete_explanation(split[1])
|
||||
connection.send_back("Der Eintrag zu " + split[1] + " wurde gelöscht, " + data['nick'] + ".", data)
|
||||
|
||||
def _add_query(self, data, connection: Connection):
|
||||
"""
|
||||
|
||||
:param data:
|
||||
:param connection:
|
||||
:return:
|
||||
"""
|
||||
if not self._is_idented_mod(data, connection):
|
||||
connection.send_back("Dir fehlen leider die Rechte zum Hinzufügen von Einträgen, " + data['nick'] + ".",
|
||||
data)
|
||||
return
|
||||
msg = data['message'].split(GlossaryModule._ADD_EXPLANATION)[1].strip()
|
||||
split = msg.split(' ', 1)
|
||||
glossary_provider = GlossaryProvider()
|
||||
glossary_provider.save_or_replace(split[0], split[1])
|
||||
connection.send_back(data['nick'] + ": der Eintrag zu " + split[0] + " wurde gespeichert.", data)
|
||||
|
||||
def _is_idented_mod(self, data: dict, connection: Connection):
|
||||
return data['nick'] in self._config.mods and connection.is_idented(data['nick'])
|
||||
42
FaustBot/Modules/CustomUserModules/ICDObserver.py
Normal file
42
FaustBot/Modules/CustomUserModules/ICDObserver.py
Normal file
@@ -0,0 +1,42 @@
|
||||
import csv
|
||||
import re
|
||||
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
|
||||
|
||||
class ICDObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return None
|
||||
|
||||
def get_icd(self, code):
|
||||
if code == "C64" or code == "P20":
|
||||
return ""
|
||||
icd10_codes = open('care_icd10_de.csv', 'r',encoding='utf8')
|
||||
icd10 = csv.reader(icd10_codes, delimiter=';', quotechar='"')
|
||||
for row in icd10:
|
||||
if row[0] == code:
|
||||
return code +' - ' + row[1]
|
||||
return 0
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
if data['channel'] != connection.details.get_channel():
|
||||
return
|
||||
regex = r'\b(\w\d{2}\.?\d?\d?)\b'
|
||||
codes = re.findall(regex, data['message'])
|
||||
for code in codes:
|
||||
code = code.capitalize()
|
||||
text = self.get_icd(code)
|
||||
if text == 0:
|
||||
if code.find('.') != -1:
|
||||
code += '-'
|
||||
else:
|
||||
code += '.-'
|
||||
text = self.get_icd(code)
|
||||
if text != 0:
|
||||
connection.send_back(text, data)
|
||||
21
FaustBot/Modules/CustomUserModules/ModmailObserver.py
Normal file
21
FaustBot/Modules/CustomUserModules/ModmailObserver.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
|
||||
|
||||
class ModmailObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".modmail"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".modmail <msg> - Sendet allen Moderatoren <msg> per PN"
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
if data['message'].find('.modmail') == -1:
|
||||
return
|
||||
mods = connection.details.get_mods()
|
||||
print(mods)
|
||||
message = data['message'].split('.modmail ')[1]
|
||||
for mod in mods:
|
||||
connection.send_to_user(mod, data['nick'] + ' meldet: ' + message)
|
||||
0
FaustBot/Modules/CustomUserModules/__init__.py
Normal file
0
FaustBot/Modules/CustomUserModules/__init__.py
Normal file
88
FaustBot/Modules/DuckObserver.py
Normal file
88
FaustBot/Modules/DuckObserver.py
Normal file
@@ -0,0 +1,88 @@
|
||||
from FaustBot.Modules.ModuleType import ModuleType
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
from FaustBot.Modules.PingObserverPrototype import PingObserverPrototype
|
||||
from random import randint
|
||||
from collections import defaultdict
|
||||
|
||||
class DuckObserver(PrivMsgObserverPrototype, PingObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return ['.freunde', '.schiessen', '.starthunt','.stophunt','.ducks']
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return 'duck game'
|
||||
|
||||
@staticmethod
|
||||
def get_module_types():
|
||||
return [ModuleType.ON_MSG, ModuleType.ON_PING]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.active = 0
|
||||
self.duck_alive = 0
|
||||
self.ducks_hunt = defaultdict(int)
|
||||
self.ducks_befriend = defaultdict(int)
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
if data['message'].find('.starthunt') != -1:
|
||||
if not self._is_idented_mod(data, connection):
|
||||
connection.send_back("Dir fehlen leider die Rechte zum Starten der Jagd, " + data['nick'] + ".",data)
|
||||
return
|
||||
self.active = 1
|
||||
connection.send_channel("Jagd eröffnet")
|
||||
return
|
||||
if data['message'].find('.stophunt') != -1:
|
||||
if not self._is_idented_mod(data, connection):
|
||||
connection.send_back("Dir fehlen leider die Rechte zum Stoppen der Jagd, " + data['nick'] + ".",
|
||||
data)
|
||||
return
|
||||
self.active = 0
|
||||
self.duck_alive = 0
|
||||
connection.send_channel("Jagd beended")
|
||||
return
|
||||
if data['message'].find('.ducks') != -1:
|
||||
connection.send_channel(data['nick'] + " hat schon " + str(self.ducks_befriend[data['nick']]) + " befreundete Enten und " + str(self.ducks_hunt[data['nick']]) + " getötete Enten.")
|
||||
if data['message'].find('.freunde') != -1:
|
||||
self.befriend(data, connection)
|
||||
if data['message'].find('.schiessen') != -1:
|
||||
self.shoot(data, connection)
|
||||
|
||||
def befriend(self, data, connection):
|
||||
if self.duck_alive == 1:
|
||||
if randint(1, 100) > 97:
|
||||
connection.send_channel(data['nick'] + " probiert eine Ente zu befreunden aber sie will nicht.")
|
||||
else:
|
||||
self.duck_alive = 0
|
||||
self.ducks_befriend[data['nick']] += 1
|
||||
connection.send_channel(data['nick'] + " hat schon " + str(self.ducks_befriend[data['nick']]) + " befreundete Enten und " + str(self.ducks_hunt[data['nick']]) + " getötete Enten.")
|
||||
return
|
||||
if (self.duck_alive == 0 and self.active == 1):
|
||||
connection.send_channel(data['nick']+ " probiert eine nicht existente Ente zu befreunden")
|
||||
if self.active == 0:
|
||||
connection.send_channel("Es läuft derzeit keine Entenjagd.")
|
||||
def shoot(self, data, connection):
|
||||
if self.duck_alive == 1:
|
||||
if randint(1,100) >97:
|
||||
connection.send_channel(data['nick'] + " trifft daneben")
|
||||
else:
|
||||
self.duck_alive = 0
|
||||
self.ducks_hunt[data['nick']] += 1
|
||||
connection.send_channel(data['nick'] + " hat schon " + str(self.ducks_befriend[data['nick']]) + " befreundete Enten und " + str(self.ducks_hunt[data['nick']]) + " getötete Enten.")
|
||||
return
|
||||
if (self.duck_alive == 0 and self.active == 1):
|
||||
connection.send_channel(data['nick']+ " schiesst ins Nichts")
|
||||
if self.active == 0:
|
||||
connection.send_channel("Es läuft derzeit keine Entenjagd.")
|
||||
|
||||
def update_on_ping(self, data, connection: Connection):
|
||||
if self.active == 0:
|
||||
return
|
||||
if 1 == randint(1,11):
|
||||
if self.duck_alive == 0:
|
||||
connection.send_channel("*. *. *. * <<w°)> *. *. * Quack!")
|
||||
self.duck_alive = 1
|
||||
|
||||
def _is_idented_mod(self, data: dict, connection: Connection):
|
||||
return data['nick'] in self._config.mods and connection.is_idented(data['nick'])
|
||||
17
FaustBot/Modules/FreeHugsObserver.py
Normal file
17
FaustBot/Modules/FreeHugsObserver.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from FaustBot.Communication import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
|
||||
|
||||
class FreeHugsObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".hug"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".hug - verteilt Umarmungen"
|
||||
|
||||
def update_on_priv_msg(self, data: dict, connection: Connection):
|
||||
if data['message'].find('.hug') == -1:
|
||||
return
|
||||
connection.send_back('\001ACTION knuddelt ' + data['nick'] + '.\001', data)
|
||||
23
FaustBot/Modules/GiveCookieObserver.py
Normal file
23
FaustBot/Modules/GiveCookieObserver.py
Normal file
@@ -0,0 +1,23 @@
|
||||
import random
|
||||
|
||||
from FaustBot.Communication import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
|
||||
kekse = ['einen Schokoladenkeks', 'einen Vanillekeks', 'einen Doppelkeks', 'keinen Keks',
|
||||
'einen Keks', 'einen Erdbeerkeks', 'einen Schokoladen-Cheesecake-Keks',
|
||||
'einen Glückskeks', 'einen Scherzkeks', 'einen Unglückskeks']
|
||||
|
||||
|
||||
class GiveCookieObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".cookie"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".cookie - verteilt kekse; oder auch nicht"
|
||||
|
||||
def update_on_priv_msg(self, data: dict, connection: Connection):
|
||||
if data['message'].find('.cookie') == -1:
|
||||
return
|
||||
connection.send_back('\001ACTION schenkt ' + data['nick'] + ' ' + random.choice(kekse) + '.\001', data)
|
||||
20
FaustBot/Modules/GiveDrinkObserver.py
Normal file
20
FaustBot/Modules/GiveDrinkObserver.py
Normal file
@@ -0,0 +1,20 @@
|
||||
import random
|
||||
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
from getraenke import getraenke
|
||||
|
||||
|
||||
class GiveDrinkObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".drink"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".drink - schenkt Getränke aus"
|
||||
|
||||
def update_on_priv_msg(self, data: dict, connection: Connection):
|
||||
if data['message'].find('.drink') == -1:
|
||||
return
|
||||
connection.send_back('\001ACTION schenkt ' + data['nick'] + ' ' + random.choice(getraenke) + ' ein.\001', data)
|
||||
98
FaustBot/Modules/GiveDrinkToObserver.py
Normal file
98
FaustBot/Modules/GiveDrinkToObserver.py
Normal file
@@ -0,0 +1,98 @@
|
||||
import random
|
||||
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
from getraenkeOnlyGoodOnes import getraenkegoodones
|
||||
from getraenke import getraenke
|
||||
from essen import essen
|
||||
from icecreamlist import icecream
|
||||
from extras import giveextras
|
||||
from snacks import snacks
|
||||
kekse = ['einen Schokoladenkeks', 'einen Vanillekeks', 'einen Doppelkeks',
|
||||
'einen Keks', 'einen Erdbeerkeks', 'einen Schokoladen-Cheesecake-Keks',
|
||||
'einen Glückskeks', 'einen Scherzkeks', 'einen Unglückskeks']
|
||||
|
||||
class GiveDrinkToObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".givedrink"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".givedrink NUTZER - schenkt jemand anders ein Getränke aus"
|
||||
|
||||
def update_on_priv_msg(self, data: dict, connection: Connection):
|
||||
if data['message'].find('.give') == -1:
|
||||
return
|
||||
receiver = data['message'].split()[1]
|
||||
if receiver == data['nick']:
|
||||
type = data['message'].split()[2]
|
||||
if type is not None:
|
||||
if type.lower() == "kaffee":
|
||||
connection.send_back('Fehler 418 Ich bin eine Teekanne', data)
|
||||
return
|
||||
connection.send_back('Bitte nutze .drink um dir selbst ein Getränk zu besorgen', data)
|
||||
return
|
||||
if len(data['message'].split()) < 3:
|
||||
connection.send_back(
|
||||
'\001ACTION serviert ' + receiver + ' ' + random.choice(getraenkegoodones) + '. Schöne Grüße von ' + data[
|
||||
'nick'] + '\001', data)
|
||||
return
|
||||
type = data['message'].split()[2]
|
||||
if type is not None:
|
||||
matchingDrinks = []
|
||||
for drink in getraenkegoodones:
|
||||
if type.lower() in drink.lower():
|
||||
matchingDrinks.append(drink)
|
||||
if matchingDrinks:
|
||||
connection.send_back(
|
||||
'\001ACTION serviert ' + receiver + ' ' + random.choice(matchingDrinks) + '. Schöne Grüße von ' + data[
|
||||
'nick'] + '\001', data)
|
||||
return
|
||||
if type.lower() == "drink":
|
||||
connection.send_back(
|
||||
'\001ACTION serviert ' + receiver + ' ' + random.choice(getraenke) + '. Schöne Grüße von ' +
|
||||
data[
|
||||
'nick'] + '\001', data)
|
||||
return
|
||||
|
||||
if type.lower() == "food":
|
||||
connection.send_back(
|
||||
'\001ACTION serviert ' + receiver + ' ' + random.choice(essen) + '. Schöne Grüße von ' +
|
||||
data[
|
||||
'nick'] + '\001', data)
|
||||
return
|
||||
|
||||
if type.lower() == "cookie":
|
||||
connection.send_back(
|
||||
'\001ACTION serviert ' + receiver + ' ' + random.choice(kekse) + '. Schöne Grüße von ' +
|
||||
data[
|
||||
'nick'] + '\001', data)
|
||||
return
|
||||
if type.lower() == "snack":
|
||||
connection.send_back(
|
||||
'\001ACTION serviert ' + receiver + ' ' + random.choice(snacks) + '. Schöne Grüße von ' +
|
||||
data[
|
||||
'nick'] + '\001', data)
|
||||
return
|
||||
if type.lower() == "massage":
|
||||
connection.send_back(
|
||||
'\001ACTION knetet ' + receiver + ' feste den Rücken durch. ' +
|
||||
data[
|
||||
'nick'] + ' meinte ich solle dir was gutes tun. \001', data)
|
||||
return
|
||||
for drink in getraenke+essen+icecream+giveextras+snacks:
|
||||
if type.lower() in drink.lower():
|
||||
matchingDrinks.append(drink)
|
||||
if matchingDrinks:
|
||||
connection.send_back(
|
||||
'\001ACTION serviert ' + receiver + ' ' + random.choice(matchingDrinks) + '. Schöne Grüße von ' +
|
||||
data[
|
||||
'nick'] + '\001', data)
|
||||
return
|
||||
else:
|
||||
connection.send_back(
|
||||
'Tut mir leid ' + data['nick'] + ', '+ type+' haben wir nicht auf der Karte!', data)
|
||||
return
|
||||
connection.send_back('\001ACTION serviert ' + receiver + ' ' + random.choice(getraenkegoodones) + '. Schöne Grüße von '+data['nick']+'\001', data)
|
||||
|
||||
20
FaustBot/Modules/GiveFoodObserver.py
Normal file
20
FaustBot/Modules/GiveFoodObserver.py
Normal file
@@ -0,0 +1,20 @@
|
||||
import random
|
||||
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
from essen import essen
|
||||
|
||||
|
||||
class GiveFoodObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".food"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".food - gibt etwas zu essen aus"
|
||||
|
||||
def update_on_priv_msg(self, data: dict, connection: Connection):
|
||||
if data['message'].find('.food') == -1:
|
||||
return
|
||||
connection.send_back('\001ACTION tischt ' + data['nick'] + ' ' + random.choice(essen) + ' auf.\001', data)
|
||||
20
FaustBot/Modules/GiveIceObserver.py
Normal file
20
FaustBot/Modules/GiveIceObserver.py
Normal file
@@ -0,0 +1,20 @@
|
||||
import random
|
||||
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
from icecreamlist import icecream
|
||||
|
||||
|
||||
class GiveIceObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".ice"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".ice - schenkt Eis"
|
||||
|
||||
def update_on_priv_msg(self, data: dict, connection: Connection):
|
||||
if data['message'].find('.ice') == -1:
|
||||
return
|
||||
connection.send_back('\001ACTION serviert ' + data['nick'] + ' ' + random.choice(icecream) + '.\001', data)
|
||||
36
FaustBot/Modules/GoogleObserver.py
Normal file
36
FaustBot/Modules/GoogleObserver.py
Normal file
@@ -0,0 +1,36 @@
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Model.i18n import i18n
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
|
||||
|
||||
class GoogleObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return None
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
if data['message'].find('.g') == -1:
|
||||
return
|
||||
i18n_server = i18n()
|
||||
lang = i18n_server.get_text('google_lang')
|
||||
t = i18n_server.get_text('google_tld')
|
||||
q = data['message'].split(' ')
|
||||
query = ''
|
||||
for word in q:
|
||||
if word.strip() != '.g':
|
||||
query += word + ' '
|
||||
# g = google.search(query, tld=t, lang=lang, num=1, start=0, stop=0, pause=2.0)
|
||||
# s = next(g)
|
||||
# print(s)
|
||||
|
||||
# Connection.singleton().send_channel(g)
|
||||
# if g has nonzero results:
|
||||
# Connection.singleton().send_channel(data['nick'] + ', ' + i18n_server.get_text('google_fail'))
|
||||
# return
|
||||
# Connection.singleton().send_channel(data['nick'] + ' ' + gefundenes erstes result)
|
||||
# Connection.singleton().send_channel(title von dem link)
|
||||
pass
|
||||
31
FaustBot/Modules/Greeter.py
Normal file
31
FaustBot/Modules/Greeter.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.JoinObserverPrototype import JoinObserverPrototype
|
||||
import time
|
||||
from collections import defaultdict
|
||||
|
||||
class Greeter(JoinObserverPrototype):
|
||||
"""
|
||||
A Class only reacting to pings
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return None
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.names = defaultdict(int)
|
||||
|
||||
def update_on_join(self, data, connection: Connection):
|
||||
if data['channel'] == connection.details.get_channel():
|
||||
if int(time.time()) - self.names[data['nick']] > 28800:
|
||||
if data['nick'].find("Neuling") != -1:
|
||||
connection.send_back("Herzlich Willkommen bei uns "+data['nick'],data)
|
||||
self.names[data['nick']] = int(time.time())
|
||||
return
|
||||
connection.send_back("Hallo " + data['nick'], data)
|
||||
self.names[data['nick']] = int(time.time())
|
||||
294
FaustBot/Modules/HangmanObserver.py
Normal file
294
FaustBot/Modules/HangmanObserver.py
Normal file
@@ -0,0 +1,294 @@
|
||||
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
from FaustBot.Model.ScoreProvider import ScoreProvider
|
||||
from FaustBot.Model.HanDatabaseProvider import HanDatabaseProvider
|
||||
from collections import defaultdict
|
||||
from threading import Lock
|
||||
import csv
|
||||
import random
|
||||
import time
|
||||
import datetime
|
||||
|
||||
class HangmanObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return ['.guess', '.word', '.stop', '.hint', '.score', '.spielregeln']
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return 'hangman game'
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
HangmanObserver.lock = Lock()
|
||||
self.word = ''
|
||||
self.guesses = ['-', '/', ' ', '_','.']
|
||||
self.tries_left = 0
|
||||
self.wrong_guessed = []
|
||||
self.worder = ''
|
||||
self.wrongly_guessedWords = []
|
||||
self.time = time.time()
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
if data['message'].find('.guess ') != -1:
|
||||
self.guess(data, connection)
|
||||
return
|
||||
if data['message'].find('.word ') != -1:
|
||||
self.take_word(data, connection)
|
||||
if data['message'].find('.han') != -1 and not data['message'].find('.handelete')!= -1 and not data['message'].find('hanadd'
|
||||
) != -1:
|
||||
self.start_solo_game(data, connection)
|
||||
if data['message'].find('hanadd') != -1:
|
||||
self.han_user_add(data, connection)
|
||||
if data['message'].find('.stop') != -1 and not data['message'].find('.stophunt') != -1 \
|
||||
and not data['message'].find('.stopMath') != -1:
|
||||
connection.send_channel("Spiel gestoppt. Das Wort war: " + self.word + " in: "+self.timeRelapsedString())
|
||||
self.word = ''
|
||||
self.guesses = []
|
||||
self.tries_left = 0
|
||||
self.wrong_guessed = []
|
||||
self.worder = ''
|
||||
self.wrongly_guessedWords = []
|
||||
self.worder = ''
|
||||
if data['message'].find('.hint') != -1:
|
||||
self.hint(data, connection)
|
||||
if data['message'].find('.score') != -1:
|
||||
self.print_score(data, connection)
|
||||
if data['message'].find('.spielregeln') != -1:
|
||||
self.rules(data, connection)
|
||||
if data['message'].find('.look') != -1:
|
||||
self.look(data, connection)
|
||||
if data['message'].find('.resetscore') != -1:
|
||||
self.reset(data,connection)
|
||||
if data['message'].find('.handelete') != -1:
|
||||
self.delete_HanWord(data, connection)
|
||||
|
||||
def delete_HanWord(self,data,connection):
|
||||
if not self._is_idented_mod(data, connection):
|
||||
connection.send_back(
|
||||
"Du hast keine Berechtigung Wörter zu löschen " + data['nick'], data)
|
||||
return
|
||||
if data['message'].split(' ')[1] is not None:
|
||||
self.deleteHanWord(data['message'].split(' ')[1].upper())
|
||||
connection.send_back("Das Wort "+data['message'].split(' ')[1].upper()+" wurde gelöscht, " + data['nick'], data)
|
||||
|
||||
def reset(self,data,connection):
|
||||
score_provider = ScoreProvider()
|
||||
score_provider.delete_score(data['nick'])
|
||||
connection.send_back("Dein Score wurde gelöscht "+data['nick'], data)
|
||||
|
||||
def look(self,data, connection):
|
||||
if self.worder != '':
|
||||
connection.send_channel("Das Wort kommt von: "+self.worder )
|
||||
connection.send_channel(self.prepare_word(data))
|
||||
self.hint(data,connection)
|
||||
|
||||
def print_score(self, data, connection):
|
||||
punkte = self.getScore(data['nick'])
|
||||
connection.send_back(data['nick']+" hat einen Hangman-Score von: " + str(punkte), data)
|
||||
|
||||
def hint(self, data, connection):
|
||||
wrongGuessesString = ""
|
||||
if len(self.wrong_guessed) == 0 and len(self.wrongly_guessedWords) == 0:
|
||||
wrongGuessesString = "Noch keine falschen Buchstaben."
|
||||
if len(self.wrong_guessed) > 0:
|
||||
wrongGuessesString += "Falsch geratene Buchstaben bis jetzt: "
|
||||
for w in self.wrong_guessed:
|
||||
if w == self.wrong_guessed[0]:
|
||||
wrongGuessesString += w
|
||||
else:
|
||||
wrongGuessesString += ", " + w
|
||||
|
||||
# Append wrongly guessed words
|
||||
for w in self.wrongly_guessedWords:
|
||||
if w == self.wrongly_guessedWords[0]:
|
||||
if len(self.wrong_guessed) > 0:
|
||||
wrongGuessesString += " | "
|
||||
wrongGuessesString += "Falsche Wörter: " + w
|
||||
else:
|
||||
wrongGuessesString += ", " + w
|
||||
if self.worder == "":
|
||||
wrongGuessesString = ""
|
||||
else:
|
||||
connection.send_back(wrongGuessesString, data)
|
||||
|
||||
def start_solo_game(self, data, connection):
|
||||
if self.word == '':
|
||||
self.time = time.time()
|
||||
self.word = self.getRandomHanWord()
|
||||
self.guesses = ['-', '/', ' ', '_','.']
|
||||
self.wrong_guessed = []
|
||||
self.tries_left = 11
|
||||
self.wrongly_guessedWords = []
|
||||
connection.send_channel("Automatisch gewähltes Wort")
|
||||
self.worder = "Botty"
|
||||
connection.send_channel(self.prepare_word(data))
|
||||
else:
|
||||
connection.send_back("Sorry es läuft bereits ein Wort", data)
|
||||
|
||||
def guess(self, data, connection):
|
||||
if data['channel'] != connection.details.get_channel():
|
||||
connection.send_back("Sorry kein raten im Query", data)
|
||||
return
|
||||
guess = data['message'].split(' ')[1].upper()
|
||||
if self.tries_left < 1:
|
||||
connection.send_channel("Flüstere mir ein neues Wort mit .word WORT")
|
||||
return
|
||||
word_unique_chars = len(set(self.word))
|
||||
if guess == self.word:
|
||||
score = word_unique_chars * self.count_missing_unique()
|
||||
self.addToScore(data['nick'], int(score))
|
||||
self.word = ''
|
||||
self.worder = ''
|
||||
connection.send_channel("Das ist korrekt: " + guess + " gelöst hat: "+data["nick"]+ " in: "+self.timeRelapsedString())
|
||||
self.giveExtraPointsInTime(data["nick"])
|
||||
return
|
||||
if guess in self.word:
|
||||
if guess not in self.guesses:
|
||||
score = word_unique_chars / 2
|
||||
self.addToScore(data['nick'], int(score))
|
||||
self.guesses.append(guess)
|
||||
else:
|
||||
self.tries_left -= 1
|
||||
punishment_factor = 1
|
||||
if guess in self.guesses:
|
||||
punishment_factor = 2
|
||||
self.addToScore(data['nick'], -1)
|
||||
#(int((word_unique_chars / 20) * punishment_factor * 10))
|
||||
|
||||
# append thread safe wrongly guessed characters and words
|
||||
HangmanObserver.lock.acquire()
|
||||
try:
|
||||
if guess not in self.wrong_guessed:
|
||||
if len(guess) == 1:
|
||||
self.wrong_guessed.append(guess)
|
||||
else:
|
||||
self.wrongly_guessedWords.append(guess)
|
||||
finally:
|
||||
HangmanObserver.lock.release()
|
||||
|
||||
connection.send_channel(self.prepare_word(data))
|
||||
|
||||
def take_word(self, data, connection):
|
||||
if self.word == '':
|
||||
self.time =time.time()
|
||||
if data['message'].split(' ')[1] is not None:
|
||||
self.addHanWord(data['message'].split(' ')[1].upper())
|
||||
log = open('HangmanLog', 'a')
|
||||
log.write(data['nick'] + ' ; ' + data['message'].split(' ')[1].upper() + '\n')
|
||||
log.close()
|
||||
self.word = data['message'].split(' ')[1].upper()
|
||||
self.guesses = ['-', '/', ' ', '_','.']
|
||||
self.wrong_guessed = []
|
||||
self.tries_left = 11
|
||||
self.wrongly_guessedWords = []
|
||||
connection.send_back("Danke für das Wort, es ist nun im Spiel!", data)
|
||||
connection.send_channel("Das Wort ist von: "+data['nick'])
|
||||
self.worder = data['nick']
|
||||
connection.send_channel(self.prepare_word(data))
|
||||
else:
|
||||
connection.send_back("Sorry es läuft bereits ein Wort", data)
|
||||
def han_user_add(self, data, connection):
|
||||
if data['message'].split(' ')[1] is not None:
|
||||
self.addHanWord(data['message'].split(' ')[1].upper())
|
||||
connection.send_channel("Das Wort "+data['message'].split(' ')[1].upper() +" wurde von "+ data['nick']+ " hinzugefügt")
|
||||
def prepare_word(self, data):
|
||||
outWord = ""
|
||||
failedChars = 0
|
||||
for char in self.word:
|
||||
if char in self.guesses:
|
||||
outWord += char + " "
|
||||
else:
|
||||
outWord += "_ "
|
||||
failedChars += 1
|
||||
if failedChars == 0:
|
||||
if len(self.word) > 0:
|
||||
outWord = "Das ist korrekt: " + self.word + " gelöst hat: "+data["nick"]+ " in : "+self.timeRelapsedString()
|
||||
self.giveExtraPointsInTime(data["nick"])
|
||||
self.addToScore(data['nick'], 5)
|
||||
self.word = ''
|
||||
self.worder = ''
|
||||
return outWord
|
||||
else:
|
||||
outWord = "Bitte gib ein neues Wort mit .word im Query an."
|
||||
return outWord
|
||||
if self.tries_left == 0:
|
||||
self.addToScore(self.worder,11)
|
||||
outWord = "Das richtige Wort wäre gewesen: " + self.word + " in: "+self.timeRelapsedString()
|
||||
self.word = ''
|
||||
self.worder = ''
|
||||
return outWord
|
||||
outWord += "Verbleibende Rateversuche: "+str(self.tries_left)
|
||||
return outWord
|
||||
|
||||
def count_missing(self):
|
||||
missing_chars = 0
|
||||
for char in self.word:
|
||||
if char not in self.guesses:
|
||||
missing_chars += 1
|
||||
return missing_chars
|
||||
|
||||
def count_missing_unique(self):
|
||||
return len(set(self.word) - set(self.guesses))
|
||||
|
||||
def rules(self, data, connection):
|
||||
if data['channel'] == connection.details.get_channel():
|
||||
connection.send_back("Spielregeln bitte im Query abfragen",data)
|
||||
return
|
||||
connection.send_back("""Wort starten mit ".word Wort" im Query mit dem Bot""", data)
|
||||
connection.send_back("""Raten mit ".guess Buchstabe" im Channel""", data)
|
||||
connection.send_back("""Geraten werden können einzelne Buchstaben oder das ganze Wort.""", data)
|
||||
connection.send_back("""Alle dürfen durcheinander raten. Es gibt keine Reihenfolge.""", data)
|
||||
connection.send_back("""".hint" gibt alle bereits falsch geratenen Buchstaben aus.""", data)
|
||||
connection.send_back("""Bei 2 verbleibenden Versuchen darf nach einem Tipp vom Steller des Wortes gefragt
|
||||
werden.""", data)
|
||||
connection.send_back("""Wer ein Wort errät, darf das nächste stellen.""", data)
|
||||
connection.send_back("""Wird ein Wort nicht gelöst, darf derjenige, der es gestellt hat, nochmal.""", data)
|
||||
connection.send_back("""Zulässig sind alle Wörter, die deutsch oder im deutschen Sprachraum geläufig sind.""", data)
|
||||
|
||||
def getScore(self, nick:str):
|
||||
score_provider = ScoreProvider()
|
||||
score = score_provider.get_score(nick)
|
||||
if score is not None:
|
||||
return score[1]
|
||||
else:
|
||||
return 0
|
||||
|
||||
def writeScore(self, nick:str, score:int):
|
||||
score_provider = ScoreProvider()
|
||||
score_provider.save_or_replace(nick, score)
|
||||
|
||||
def addToScore(self, nick:str, add_score: int):
|
||||
score = self.getScore(nick)
|
||||
self.writeScore(nick, score + add_score)
|
||||
|
||||
def addHanWord(self, hanWord:str):
|
||||
hanDB = HanDatabaseProvider()
|
||||
hanDB.addWord(hanWord.strip().upper())
|
||||
|
||||
def getRandomHanWord(self):
|
||||
hanDB = HanDatabaseProvider()
|
||||
word = hanDB.get_random_word()
|
||||
if word is not None:
|
||||
return word[0].upper()
|
||||
else:
|
||||
return "dummywort".upper()
|
||||
|
||||
def deleteHanWord(self, hanWord:str):
|
||||
hanDB = HanDatabaseProvider()
|
||||
hanDB.delete_hanWord(hanWord.strip().upper())
|
||||
|
||||
def _is_idented_mod(self, data: dict, connection: Connection):
|
||||
return data['nick'] in self._config.mods and connection.is_idented(data['nick'])
|
||||
|
||||
def timeRelapsedString(self):
|
||||
delta = time.time()-self.time
|
||||
return str(datetime.timedelta(seconds= delta))
|
||||
|
||||
def giveExtraPointsInTime(self, nick):
|
||||
delta = time.time()-self.time
|
||||
if delta <30:
|
||||
self.addToScore(nick, 5)
|
||||
if delta <60:
|
||||
self.addToScore(nick, 5)
|
||||
32
FaustBot/Modules/HelpObserver.py
Normal file
32
FaustBot/Modules/HelpObserver.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from FaustBot.Communication import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
|
||||
|
||||
class HelpObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".help"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".help - zeigt Hilftexte aller Module an"
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
msg = data["message"]
|
||||
if not msg.startswith(".help"):
|
||||
return
|
||||
|
||||
if data["channel"] == connection.details.get_channel():
|
||||
all_cmd = []
|
||||
for observer in connection.priv_msg_observable.get_observer():
|
||||
cmds = observer.cmd()
|
||||
if cmds is not None:
|
||||
all_cmd.extend(cmds)
|
||||
msg = ", ".join(all_cmd)
|
||||
msg = "Bekannte Befehle: " + msg + ". Für Details per Query .help ."
|
||||
connection.send_back(msg, data)
|
||||
else:
|
||||
all_help = [m.help() for m in connection.priv_msg_observable.get_observer()]
|
||||
for help_msg in all_help:
|
||||
if help_msg is not None:
|
||||
connection.send_back(help_msg, data)
|
||||
27
FaustBot/Modules/IdentNickServObserver.py
Normal file
27
FaustBot/Modules/IdentNickServObserver.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import re
|
||||
|
||||
from FaustBot.Communication import Connection
|
||||
from FaustBot.Modules.NoticeObserverPrototype import NoticeObserverPrototype
|
||||
|
||||
|
||||
class IdentNickServObserver(NoticeObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return None
|
||||
|
||||
def update_on_notice(self, data, connection: Connection):
|
||||
# b':NickServ!NickServ@services. NOTICE FaustBotDev :corvidae ACC 3 \r\n'
|
||||
if not data['nick'].lower() == 'nickserv':
|
||||
return
|
||||
with connection.condition_lock:
|
||||
if re.match(r'.*? ACC [0-3].*', data['message']):
|
||||
msg_parts = data['message'].split(' ')
|
||||
if msg_parts[2] == '3':
|
||||
connection.idented_look_up[msg_parts[0]] = True
|
||||
else:
|
||||
connection.idented_look_up[msg_parts[0]] = False
|
||||
connection.condition_lock.notify_all()
|
||||
54
FaustBot/Modules/IntroductionObserver.py
Normal file
54
FaustBot/Modules/IntroductionObserver.py
Normal file
@@ -0,0 +1,54 @@
|
||||
from FaustBot.Communication import Connection
|
||||
from FaustBot.Model.Introduction import IntroductionProvider
|
||||
from FaustBot.Modules import UserList
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
|
||||
|
||||
class IntroductionObserver(PrivMsgObserverPrototype):
|
||||
def __init__(self, user_list: UserList):
|
||||
super().__init__()
|
||||
self.userList = user_list
|
||||
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".me"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".me - kann von registrierten Nutzern verwendet werden um eine Vorstellung zu speichern"
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
msg = data["message"]
|
||||
nick = data["nick"]
|
||||
if not msg.startswith(".me") and not msg.startswith(".me-"):
|
||||
return
|
||||
if not self.authenticated(nick, connection):
|
||||
connection.send_back("Für die Nutzung von .me ist es zwingend erforderlich, einen registrierten Nick zu "
|
||||
"haben sowie eingeloggt zu sein. Wie dies geht, erfährst du unter "
|
||||
"https://freenode.net/kb/answer/registration", data)
|
||||
return
|
||||
intro_provider = IntroductionProvider()
|
||||
msg = msg.split('.me')[1].strip()
|
||||
if len(msg) == 0:
|
||||
intro = intro_provider.get_intro(nick)
|
||||
text = ""
|
||||
if intro is not None:
|
||||
text = nick + " ist " + intro[1]
|
||||
else:
|
||||
text = nick + " für dich gibt es noch keinen Eintrag, vielleicht magst du ja mittels .me <intro> noch " \
|
||||
"einen hinzufügen? "
|
||||
connection.send_back(text, data)
|
||||
elif len(msg) == 1 and '-' in msg:
|
||||
intro_provider.delete_intro(nick)
|
||||
connection.send_back(nick + " dein Intro wurde gelöscht!", data)
|
||||
else:
|
||||
intro = msg.strip()
|
||||
intro_provider.save_or_replace(nick, intro)
|
||||
connection.send_back(
|
||||
nick + ": Dein Intro wurde gespeichert! Mittels .me- kannst du deinen Eintrag wieder löschen.", data)
|
||||
text = nick + " ist " + intro_provider.get_intro(nick)[1]
|
||||
connection.send_back(text, data)
|
||||
|
||||
def authenticated(self, nick: str, connection: Connection):
|
||||
return nick in self.userList.userList and \
|
||||
connection.is_idented(nick)
|
||||
27
FaustBot/Modules/JoinObserverPrototype.py
Normal file
27
FaustBot/Modules/JoinObserverPrototype.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.ModulePrototype import ModulePrototype
|
||||
from FaustBot.Modules.ModuleType import ModuleType
|
||||
|
||||
|
||||
class JoinObserverPrototype(ModulePrototype):
|
||||
"""
|
||||
The Prototype of a Class who can react to every action
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def cmd():
|
||||
raise NotImplementedError()
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
raise NotImplementedError("Need sto be implemented by subclasses!")
|
||||
|
||||
@staticmethod
|
||||
def get_module_types():
|
||||
return [ModuleType.ON_JOIN]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def update_on_join(self, data, connection: Connection):
|
||||
raise NotImplementedError("Some module doesn't do anything")
|
||||
209
FaustBot/Modules/JokeObserver.py
Normal file
209
FaustBot/Modules/JokeObserver.py
Normal file
@@ -0,0 +1,209 @@
|
||||
import random
|
||||
import time
|
||||
from FaustBot.Communication import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
|
||||
jokes = [['Was ist orange und geht über die Berge?'
|
||||
,'Eine Wanderine.']
|
||||
,['Was ist orange und schaut durchs Schlüsselloch?'
|
||||
,'Eine Spannderine.']
|
||||
,['Was ist violett und sitzt in der Kirche ganz vorne?'
|
||||
,'Eine Frommbeere.']
|
||||
,['Was ist grün und liegt im Sarg?'
|
||||
,'Ein Sterbschen.']
|
||||
,['Was ist bunt und läuft über den Tisch davon?'
|
||||
,'Ein Fluchtsalat.']
|
||||
,['Was ist braun und schwimmt im Wasser?'
|
||||
,'Ein U-Brot.']
|
||||
,['Was ist schwarz/weiß und hüpft von Eisscholle zu Eisscholle?'
|
||||
,'Ein Springuin.']
|
||||
,['Was ist rot und sitzt auf dem WC?'
|
||||
,'Eine Klomate!']
|
||||
,['Was ist braun und fährt einen verschneiten Hang hinunter?'
|
||||
,'Ein Snowbrot.']
|
||||
,['Was ist braun und späht durchs Schlafzimmerfenster?'
|
||||
,'Ein Spannzapfen.']
|
||||
,['Was ist weiß und springt im Wald umher?'
|
||||
,'Ein Jumpignon.']
|
||||
,['Was ist braun, süß und rennt durch den Wald?'
|
||||
,'Eine Joggolade.']
|
||||
,['Was ist braun und sitzt hinter Gittern?'
|
||||
,'Eine Knastanie.']
|
||||
,['Was ist rot, rund und hat ein Maschinengewehr?'
|
||||
,'Ein Rambodischen.']
|
||||
,['Was ist braun, knusprig und läuft mit dem Korb durch den Wald?'
|
||||
,'Brotkäppchen.']
|
||||
,['Was ist braun, klebrig und läuft in der Wüste umher?'
|
||||
,'Ein Karamel.']
|
||||
,['Was ist rot, sitzt in einer Konservendose und spielt Musik?'
|
||||
,'Ein Radioli.']
|
||||
,['Was ist grün und radelt durch die Gegend?'
|
||||
,'Eine Velone.']
|
||||
,['Was ist orange, tiefergelegt und hat einen Spoiler?'
|
||||
,'Ein Mantarinchen']
|
||||
,['Was ist gelb, krumm und schwimmt auf dem Wasser?'
|
||||
,'Eine Schwanane']
|
||||
,['Was ist orange und steckt traurig in der Erde?'
|
||||
,'Ein Trübchen.']
|
||||
,['Was ist orange, sauer und kann keine Minute ruhig sitzen?'
|
||||
,'Eine Zappelsine.']
|
||||
,['Was ist haarig und wird in der Pfanne frittiert?'
|
||||
,'Bartkartoffeln.']
|
||||
,['Was ist gesund und kräftig und spielt den Beleidigten?'
|
||||
,'Ein Schmollkornbrot.']
|
||||
,['Was steht im Schlafzimmer des Metzgers neben dem Bett?'
|
||||
,'Ein Schlachttischlämpchen.']
|
||||
,['Was ist grün, sauer und versteckt sich vor der Polizei?'
|
||||
,'Ein Essig-Schurke.']
|
||||
,['Was ist orange, rund und versteckt sich vor der Polizei?'
|
||||
,'Ein Vandalinchen.']
|
||||
,['Was ist grün und schaut durchs Schlüsselloch?'
|
||||
,'Ein Spionat']
|
||||
,['Was ist groß, grau und telefoniert aus Afrika?'
|
||||
,'Ein Telefant.']
|
||||
,['Was ist gelb und flattert im Wind?'
|
||||
,'Eine Fahnane.']
|
||||
,['Was ist grün und klopft an die Tür?'
|
||||
,'Ein Klopfsalat.']
|
||||
,['Was ist braun, sehr zäh und fliegt umher?'
|
||||
,'Eine Ledermaus.']
|
||||
,['Was macht "Muh" und hilft beim Anziehen?'
|
||||
,'Ein Kuhlöffel.']
|
||||
,['Was ist viereckig, hat Noppen und einen Sprachfehler?'
|
||||
,'Ein Legosteniker.']
|
||||
,['Was ist gelb und immer bekifft?'
|
||||
,'Ein Bong-Frites.']
|
||||
,['Was ist grün, glücklich und hüpft von Grashalm zu Grashalm?'
|
||||
,'Eine Freuschrecke.']
|
||||
,['Was ist ist braun, hat einen Beutel und hängt am Baum?'
|
||||
,'Ein Hänguruh.']
|
||||
,['Was ist orange-rot und riskiert alles?'
|
||||
,'Eine Mutorange']
|
||||
,['Was ist gelb, ölig und und sitzt in der Kirche in der ersten Reihe?'
|
||||
,'Eine Frommfrites']
|
||||
,['Was ist grün und irrt durch Istanbul?'
|
||||
,'Ein Gürke']
|
||||
,['Was ist hellbraun und hangelt sich von Tortenstück zu Tortenstück?'
|
||||
,'Ein Tarzipan.']
|
||||
,['Was ist braun und klebt an der Wand?'
|
||||
,'Ein Klebkuchen']
|
||||
,['Was ist rot und läuft die Straße auf und ab?'
|
||||
,'Eine Hagenutte.']
|
||||
,['Was ist weiss und läuft die Straße auf und ab?'
|
||||
,'Schneeflittchen.']
|
||||
,['Was ist grün und läuft die Straße auf und ab?'
|
||||
,'Eine Frosch-tituierte.']
|
||||
,['Was ist braun und trägt Strapse?'
|
||||
,'Ein Haselnüttchen.']
|
||||
,['Was ist gelb und steht frankiert und abgestempelt am Strassenrand?'
|
||||
,'Eine Postituierte.']
|
||||
,['Was leuchtet und geht fremd?'
|
||||
,'Ein Schlampion.']
|
||||
,['Was ist gelb und rutscht den Hang hinunter?'
|
||||
,'Ein Cremeschlitten.']
|
||||
,['Was ist weiss und tanzt ums Feuer?'
|
||||
,'Rumpelpilzchen.']
|
||||
,['Was ist weiss und liegt schnarchend auf der Wiese?'
|
||||
,'Ein Schlaf.']
|
||||
,['Was ist gelb, saftig und sitzt bei jedem Fussballspiel vor dem Fernseher?'
|
||||
,'Eine Fananas.']
|
||||
,['Was ist rosa und schwimmt im Wasser?'
|
||||
,'Eine Meerjungsau.']
|
||||
,['Was ist durchsichtig, stinkt und es ist ihm alles egal?'
|
||||
,'Ein Schnurz.']
|
||||
,['Was ist unordentlich und gibt Licht?'
|
||||
,'Eine Schlampe.']
|
||||
,['Was ist blöd, süß und bunt?'
|
||||
,'Ein Dummibärchen.']
|
||||
,['Was trägt einen Frack und hilft im Haushalt?'
|
||||
,'Ein Diener Schnitzel.']
|
||||
,['Was ist silbrig, sticht und hat Spass daran?'
|
||||
,'Eine Sadistel.']
|
||||
,['Was ist gelb und kann schießen?'
|
||||
,'Eine Banone']
|
||||
,['Was kommt nach Elch?'
|
||||
,'Zwölch']
|
||||
,['Was liegt am Strand und spricht undeutlich?'
|
||||
,'Eine Nuschel']
|
||||
,['Was hüpft über die Wiese und raucht?'
|
||||
,'Ein Kaminchen']
|
||||
,['Was ist knusprig und liegt unterm Baum?'
|
||||
,'Schattenplätzle']
|
||||
,['Kleines Schwein das nach Hilfe schreit?'
|
||||
,'Ein Notrufsäule']
|
||||
,['Was liegt am Strand und hat Schnupfen?'
|
||||
,'Eine Niesmuschel']
|
||||
,['Was ist ein Cowboy ohne Pferd?'
|
||||
,'Ein Sattelschlepper']
|
||||
,['Was ist grün und trägt Kopftuch?'
|
||||
,'Eine Gürkin']
|
||||
,['Was ist rot und sitzt unterm Tisch?'
|
||||
,'Ne Paprikantin']
|
||||
,['Was ist schwarz-weiß und kommt nicht vom Fleck?'
|
||||
,'Ein Klebra']
|
||||
,['Was ist rosa, quiekt und wird zum Hausbau verwendet?'
|
||||
,'Ein Ziegelschwein']
|
||||
,['Wer ist bei jeder Wanderung betrunken?'
|
||||
,'Der Schlucksack']
|
||||
,['Was ist rot und wiehert?'
|
||||
,'Die Pferdbeere']
|
||||
,['Was ist weiß, blau, grün und steht auf der Wiese?'
|
||||
,'Eine Schlumpfdotterblume']
|
||||
,['Was kaut und hat immer Verspätung?'
|
||||
,'Die Essbahn']
|
||||
,['Was fährt unter der Erde und macht Muh?'
|
||||
,'Die Kuhbahn']
|
||||
,['Was wühlt den Himmel auf?'
|
||||
,'Ein Pflugzeug']
|
||||
,['Welche Frucht wächst im Gerichtssaal?'
|
||||
,'Advokado']
|
||||
,['Wie nennt man einen “scharfen” Mann mit Kilt?'
|
||||
,'Chilischotte']
|
||||
,['Was lebt im Meer und kann gut rechnen?'
|
||||
,'Der Octoplus']
|
||||
,['Was ist tiefergelegt und schwimmt unter wasser?'
|
||||
,'Der Tunefisch']
|
||||
,['Was ist unter der Erde und stinkt?'
|
||||
,'Eine Furzel']
|
||||
,['Von was wird man nachts beobachtet?'
|
||||
,'Vom Spannbettlaken']
|
||||
,['Wo wohnen die meisten Katzen?'
|
||||
,'Im Miezhaus']
|
||||
,['Warum ging der Luftballon kaputt?'
|
||||
,'Aus Platzgründen']
|
||||
,['Wie nennt man einen ausgehungerten Frosch?'
|
||||
,'Magerquak']
|
||||
,['Was macht ein Dieb im Zirkus?'
|
||||
,'Clown']
|
||||
,['Was macht ein Clown im Büro?'
|
||||
,'Faxen']
|
||||
,['Wie nennt man eine Zauberin in der Wüste?'
|
||||
,'Sand Witch']
|
||||
,['Wo betrinkt sich eine Mücke?'
|
||||
,'In Sekt']
|
||||
,['Warum können Seeräuber keine Kreise berechnen?'
|
||||
,'Weil sie pi raten']
|
||||
,['Was sitzt in der Savanne und wäscht sich?'
|
||||
,'Die Hygiäne']
|
||||
,['Was sitzt im Dschungel und spielt unfair?'
|
||||
,'Mogli']
|
||||
,['Wie nennt man den Paarungsruf von Leutstofflampen?'
|
||||
,'Neonröhren']]
|
||||
|
||||
|
||||
class JokeObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".joke"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".joke erzählt einen Flachwitz"
|
||||
|
||||
def update_on_priv_msg(self, data: dict, connection: Connection):
|
||||
if data['message'].find('.joke') == -1:
|
||||
return
|
||||
joke = random.choice(jokes)
|
||||
connection.send_back(joke[0], data)
|
||||
time.sleep(30)
|
||||
connection.send_back(joke[1], data)
|
||||
27
FaustBot/Modules/KickObserverPrototype.py
Normal file
27
FaustBot/Modules/KickObserverPrototype.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.ModulePrototype import ModulePrototype
|
||||
from FaustBot.Modules.ModuleType import ModuleType
|
||||
|
||||
|
||||
class KickObserverPrototype(ModulePrototype):
|
||||
"""
|
||||
The Prototype of a Class who can react to every action
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def cmd():
|
||||
raise NotImplementedError()
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
raise NotImplementedError("Need sto be implemented by subclasses!")
|
||||
|
||||
@staticmethod
|
||||
def get_module_types():
|
||||
return [ModuleType.ON_KICK]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def update_on_kick(self, data, connection: Connection):
|
||||
raise NotImplementedError("Some module doesn't do anything")
|
||||
53
FaustBot/Modules/Kicker.py
Normal file
53
FaustBot/Modules/Kicker.py
Normal file
@@ -0,0 +1,53 @@
|
||||
import random
|
||||
import time
|
||||
from collections import defaultdict
|
||||
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Model.UserProvider import UserProvider
|
||||
from FaustBot.Modules.UserList import UserList
|
||||
from getraenke import getraenke
|
||||
from essen import essen
|
||||
from icecreamlist import icecream
|
||||
|
||||
from ..Modules.PingObserverPrototype import PingObserverPrototype
|
||||
|
||||
|
||||
class Kicker(PingObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return None
|
||||
|
||||
def __init__(self, user_list: UserList, idle_time: int):
|
||||
super().__init__()
|
||||
self.idle_time = idle_time
|
||||
self.user_list = user_list
|
||||
self.warned_users = defaultdict(int)
|
||||
|
||||
def update_on_ping(self, data, connection: Connection):
|
||||
for user in self.user_list.userList.keys():
|
||||
offline_time = Kicker.get_offline_time(user)
|
||||
if offline_time < self.idle_time:
|
||||
self.warned_users[user] = 0
|
||||
host = self.user_list.userList.get(user).host
|
||||
if offline_time > self.idle_time \
|
||||
and not user == connection.details.get_nick() \
|
||||
and 'freenode/staff' not in host and 'freenode/utility-bot' not in host:
|
||||
if self.warned_users[user] % 30 == 0:
|
||||
connection.send_channel(
|
||||
'\001ACTION serviert ' + user + ' ' + random.choice(getraenke+essen+icecream) + '.\001')
|
||||
self.warned_users[user] += 1
|
||||
if self.warned_users[user] % 29 == 0:
|
||||
connection.raw_send("KICK " + connection.details.get_channel() + " " + user +
|
||||
" :Zu lang geidlet, komm gerne wieder!")
|
||||
|
||||
@staticmethod
|
||||
def get_offline_time(nick):
|
||||
who = nick
|
||||
user_provider = UserProvider()
|
||||
activity = user_provider.get_activity(who)
|
||||
delta = time.time() - activity
|
||||
return delta
|
||||
27
FaustBot/Modules/LeaveObserverPrototype.py
Normal file
27
FaustBot/Modules/LeaveObserverPrototype.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.ModulePrototype import ModulePrototype
|
||||
from FaustBot.Modules.ModuleType import ModuleType
|
||||
|
||||
|
||||
class LeaveObserverPrototype(ModulePrototype):
|
||||
"""
|
||||
The Prototype of a Class who can react to every action
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def cmd():
|
||||
raise NotImplementedError()
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
raise NotImplementedError("Need sto be implemented by subclasses!")
|
||||
|
||||
@staticmethod
|
||||
def get_module_types():
|
||||
return [ModuleType.ON_LEAVE]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def update_on_leave(self, data, connection: Connection):
|
||||
raise NotImplementedError("Some module doesn't do anything")
|
||||
18
FaustBot/Modules/LoveAndPeaceObserver.py
Normal file
18
FaustBot/Modules/LoveAndPeaceObserver.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from FaustBot.Communication import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
|
||||
|
||||
class LoveAndPeaceObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".peace"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".peace - sorgt für Frieden"
|
||||
|
||||
def update_on_priv_msg(self, data: dict, connection: Connection):
|
||||
if data['message'].find('.peace') == -1:
|
||||
return
|
||||
connection.send_back('\001ACTION hüpft durch den Raum, schmeißt Blumen um sich und singt: \"Love and '
|
||||
'Peace, wir haben uns alle lieb..!\".\001', data)
|
||||
27
FaustBot/Modules/MagicNumberObserverPrototype.py
Normal file
27
FaustBot/Modules/MagicNumberObserverPrototype.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.ModulePrototype import ModulePrototype
|
||||
from FaustBot.Modules.ModuleType import ModuleType
|
||||
|
||||
|
||||
class MagicNumberObserverPrototype(ModulePrototype):
|
||||
"""
|
||||
The Prototype of a Class who can react to server actions
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def cmd():
|
||||
raise NotImplementedError()
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
raise NotImplementedError("Need sto be implemented by subclasses!")
|
||||
|
||||
@staticmethod
|
||||
def get_module_types():
|
||||
return [ModuleType.ON_MAGIC_NUMBER]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def update_on_magic_number(self, data, connection: Connection):
|
||||
raise NotImplementedError("Some module doesn't do anything")
|
||||
76
FaustBot/Modules/MathRunObserver.py
Normal file
76
FaustBot/Modules/MathRunObserver.py
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
from random import randrange
|
||||
from time import sleep
|
||||
class MathRunObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return ['.s', '.startMath', '.stopMath']
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return 'startMath startet eine Reihe von Aufgaben. StopMath beendet sie.'
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.players = {}
|
||||
self.solutionForGame = 0
|
||||
self.type = 0
|
||||
self.running = False
|
||||
self.oldSolution = 0
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
if data['message'].find('.s ') != -1 :
|
||||
self.solution(data, connection)
|
||||
if data['message'].find('.startMath') != -1:
|
||||
self.start_math(data, connection)
|
||||
|
||||
def solution(self, data, connection):
|
||||
nick = data["nick"]
|
||||
solutionByPlayer = data['message'].split()[1]
|
||||
if solutionByPlayer is None:
|
||||
connection.send_back("Sorry du hast keine Lösung angegeben " + nick, data)
|
||||
return
|
||||
if solutionByPlayer == str(self.solutionForGame):
|
||||
connection.send_channel("Korrekte Lösung " + nick)
|
||||
if nick not in self.players:
|
||||
self.players[nick] = 0
|
||||
self.players[nick] += 1
|
||||
self.oldSolution = self.solutionForGame
|
||||
self.start_math(data, connection)
|
||||
return
|
||||
if solutionByPlayer == str(self.oldSolution):
|
||||
connection.send_channel("Korrekte Lösung für das Problem davor " + nick)
|
||||
if nick not in self.players:
|
||||
self.players[nick] = 0
|
||||
self.players[nick] += 1
|
||||
return
|
||||
connection.send_channel("Sorry die Lösung ist falsch "+nick )
|
||||
|
||||
def start_math(self, data, connection):
|
||||
summand1 = randrange(1,100)
|
||||
summand2 = randrange(1,11)
|
||||
operation = randrange(1,3)
|
||||
if operation == 1:
|
||||
self.solutionForGame = summand1 - summand2
|
||||
connection.send_channel(str(summand1) +" - "+str(summand2) +" = ?")
|
||||
if operation == 2:
|
||||
self.solutionForGame = summand1 + summand2
|
||||
connection.send_channel(str(summand1) +" + "+str(summand2) +" = ?")
|
||||
if not self.running:
|
||||
self.running = True
|
||||
self.stop_Timer(data, connection)
|
||||
|
||||
def stop_math(self, data, connection):
|
||||
for player in self.players.keys():
|
||||
connection.send_channel(player + " hat\t" + str(self.players[player]) + "\t Punkte")
|
||||
connection.send_channel("Spiel beendet")
|
||||
self.players = {}
|
||||
self.solutionForGame = 0
|
||||
self.type = 0
|
||||
self.running = False
|
||||
|
||||
def stop_Timer(self, data, connection):
|
||||
sleep(120)
|
||||
self.stop_math(data, connection)
|
||||
23
FaustBot/Modules/ModulePrototype.py
Normal file
23
FaustBot/Modules/ModulePrototype.py
Normal file
@@ -0,0 +1,23 @@
|
||||
class ModulePrototype(object):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
raise NotImplementedError()
|
||||
|
||||
@staticmethod
|
||||
def get_module_types():
|
||||
raise NotImplementedError("This method needs to be implemented by a subclass!")
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
raise NotImplementedError("Needs to be implemented by subclasses")
|
||||
|
||||
def __init__(self):
|
||||
self._config = None
|
||||
|
||||
@property
|
||||
def config(self):
|
||||
return self._config
|
||||
|
||||
@config.setter
|
||||
def config(self, value):
|
||||
self._config = value
|
||||
12
FaustBot/Modules/ModuleType.py
Normal file
12
FaustBot/Modules/ModuleType.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class ModuleType(Enum):
|
||||
ON_JOIN = 'ON_JOIN'
|
||||
ON_KICK = 'ON_KICK'
|
||||
ON_LEAVE = 'ON_LEAVE'
|
||||
ON_PING = 'ON_PING'
|
||||
ON_NICK_CHANGE = 'ON_NICK_CHANGE'
|
||||
ON_MSG = 'ON_MSG'
|
||||
ON_NOTICE = 'ON_NOTICE'
|
||||
ON_MAGIC_NUMBER = 'ON_MAGIC_NUMBER'
|
||||
27
FaustBot/Modules/NickChangeObserverPrototype.py
Normal file
27
FaustBot/Modules/NickChangeObserverPrototype.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.ModulePrototype import ModulePrototype
|
||||
from FaustBot.Modules.ModuleType import ModuleType
|
||||
|
||||
|
||||
class NickChangeObserverPrototype(ModulePrototype):
|
||||
"""
|
||||
The Prototype of a Class who can react to every action
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def cmd():
|
||||
raise NotImplementedError()
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
raise NotImplementedError("Need sto be implemented by subclasses!")
|
||||
|
||||
@staticmethod
|
||||
def get_module_types():
|
||||
return [ModuleType.ON_NICK_CHANGE]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def update_on_nick_change(self, data, connection: Connection):
|
||||
raise NotImplementedError("Some module doesn't do anything")
|
||||
23
FaustBot/Modules/NoticeObserverPrototype.py
Normal file
23
FaustBot/Modules/NoticeObserverPrototype.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from FaustBot.Communication import Connection
|
||||
from FaustBot.Modules.ModulePrototype import ModulePrototype
|
||||
from FaustBot.Modules.ModuleType import ModuleType
|
||||
|
||||
|
||||
class NoticeObserverPrototype(ModulePrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
raise NotImplementedError()
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
raise NotImplementedError("Need sto be implemented by subclasses!")
|
||||
|
||||
@staticmethod
|
||||
def get_module_types():
|
||||
return [ModuleType.ON_NOTICE]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def update_on_notice(self, data, connection: Connection):
|
||||
raise NotImplementedError('Needs to be implemented by csubclasses!')
|
||||
17
FaustBot/Modules/PartyObserver.py
Normal file
17
FaustBot/Modules/PartyObserver.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from FaustBot.Communication import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
|
||||
|
||||
class PartyObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".party"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".party - sorgt für Konfetti"
|
||||
|
||||
def update_on_priv_msg(self, data: dict, connection: Connection):
|
||||
if data['message'].find('.party') == -1:
|
||||
return
|
||||
connection.send_back('\001ACTION schmeißt mit Konfetti aus buntem Esspapier um sich.\001', data)
|
||||
21
FaustBot/Modules/PingAnswerObserver.py
Normal file
21
FaustBot/Modules/PingAnswerObserver.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.PingObserverPrototype import PingObserverPrototype
|
||||
|
||||
|
||||
class ModulePing(PingObserverPrototype):
|
||||
"""
|
||||
A Class only reacting to pings
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return None
|
||||
|
||||
def update_on_ping(self, data, connection: Connection):
|
||||
# print('Module Ping')
|
||||
msg = 'PONG ' + data['server']
|
||||
connection.raw_send(msg)
|
||||
27
FaustBot/Modules/PingObserverPrototype.py
Normal file
27
FaustBot/Modules/PingObserverPrototype.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.ModulePrototype import ModulePrototype
|
||||
from FaustBot.Modules.ModuleType import ModuleType
|
||||
|
||||
|
||||
class PingObserverPrototype(ModulePrototype):
|
||||
"""
|
||||
The Prototype of a Class who can react to every action
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def cmd():
|
||||
raise NotImplementedError()
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
raise NotImplementedError("Need sto be implemented by subclasses!")
|
||||
|
||||
@staticmethod
|
||||
def get_module_types():
|
||||
return [ModuleType.ON_PING]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def update_on_ping(self, data, connection: Connection):
|
||||
raise NotImplementedError("Some module doesn't do anything")
|
||||
17
FaustBot/Modules/PrideObserver.py
Normal file
17
FaustBot/Modules/PrideObserver.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from FaustBot.Communication import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
|
||||
|
||||
class PrideObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".pride"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".party - sorgt für sehr viele Pride Flags"
|
||||
|
||||
def update_on_priv_msg(self, data: dict, connection: Connection):
|
||||
if data['message'].find('.pride') == -1:
|
||||
return
|
||||
connection.send_back('\001ACTION schmückt den Channel mit ganz vielen großen Pride Flaggen.\001', data)
|
||||
27
FaustBot/Modules/PrivMsgObserverPrototype.py
Normal file
27
FaustBot/Modules/PrivMsgObserverPrototype.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.ModulePrototype import ModulePrototype
|
||||
from FaustBot.Modules.ModuleType import ModuleType
|
||||
|
||||
|
||||
class PrivMsgObserverPrototype(ModulePrototype):
|
||||
"""
|
||||
The Prototype of a Class who can react to every action
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def cmd():
|
||||
raise NotImplementedError()
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
raise NotImplementedError("Need sto be implemented by subclasses!")
|
||||
|
||||
@staticmethod
|
||||
def get_module_types():
|
||||
return [ModuleType.ON_MSG]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
raise NotImplementedError("Some module doesn't do anything")
|
||||
34
FaustBot/Modules/SeenObserver.py
Normal file
34
FaustBot/Modules/SeenObserver.py
Normal file
@@ -0,0 +1,34 @@
|
||||
import datetime
|
||||
import time
|
||||
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Model.UserProvider import UserProvider
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
from ..Model.i18n import i18n
|
||||
|
||||
|
||||
class SeenObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".seen"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".seen <nick> - um abzufragen wann <nick> zuletzt hier war"
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
if data['message'].find('.seen ') == -1:
|
||||
return
|
||||
if not self._is_idented_mod(data, connection):
|
||||
return
|
||||
who = data['message'].split(' ')[1]
|
||||
user_provider = UserProvider()
|
||||
activity = user_provider.get_activity(who)
|
||||
output = data['nick']+": Ich habe "+who+" zuletzt am "+str(datetime.datetime.fromtimestamp(activity).strftime("%d.%m.%Y um %H:%M:%S"))+ ' Uhr gesehen'
|
||||
if not self._is_idented_mod(data, connection):
|
||||
connection.send_channel(output)
|
||||
return
|
||||
connection.send_back(output, data)
|
||||
|
||||
def _is_idented_mod(self, data: dict, connection: Connection):
|
||||
return data['nick'] in self._config.mods and connection.is_idented(data['nick'])
|
||||
20
FaustBot/Modules/SnacksObserver.py
Normal file
20
FaustBot/Modules/SnacksObserver.py
Normal file
@@ -0,0 +1,20 @@
|
||||
import random
|
||||
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
from snacks import snacks
|
||||
|
||||
|
||||
class SnacksObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".snack"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".snack - teilt Snacks aus"
|
||||
|
||||
def update_on_priv_msg(self, data: dict, connection: Connection):
|
||||
if data['message'].find('.snack') == -1:
|
||||
return
|
||||
connection.send_back('\001ACTION serviert ' + data['nick'] + ' ' + random.choice(snacks) + '.\001', data)
|
||||
20
FaustBot/Modules/TellObserver.py
Normal file
20
FaustBot/Modules/TellObserver.py
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
|
||||
|
||||
class TellObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return None
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
if data['message'].find('.tell') != -1 and self._is_idented_mod(data, connection):
|
||||
connection.send_channel(data['message'][6:])
|
||||
def _is_idented_mod(self, data: dict, connection: Connection):
|
||||
return data['nick'] in self._config.mods and connection.is_idented(data['nick'])
|
||||
53
FaustBot/Modules/TitleObserver.py
Normal file
53
FaustBot/Modules/TitleObserver.py
Normal file
@@ -0,0 +1,53 @@
|
||||
import html
|
||||
import re
|
||||
import urllib
|
||||
from urllib import request
|
||||
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
|
||||
|
||||
class TitleObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return None
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
regex = "(?P<url>https?://[^\s]+)"
|
||||
url = re.search(regex, data['message'])
|
||||
if url is not None:
|
||||
url = url.group()
|
||||
print(url)
|
||||
try:
|
||||
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)'}
|
||||
url = url
|
||||
req = urllib.request.Request(url, None, headers)
|
||||
resource = urllib.request.urlopen(req)
|
||||
title = self.getTitle(resource)
|
||||
print(title)
|
||||
title = title[:350]
|
||||
connection.send_back(title, data)
|
||||
except Exception as exc:
|
||||
print(exc)
|
||||
pass
|
||||
|
||||
def getTitle(self, resource):
|
||||
encoding = resource.headers.get_content_charset()
|
||||
# der erste Fall kann raus, wenn ein anderer Channel benutzt wird
|
||||
if resource.geturl().find('rehakids.de') != -1:
|
||||
encoding = 'windows-1252'
|
||||
if not encoding:
|
||||
encoding = 'utf-8'
|
||||
content = resource.read().decode(encoding, errors='replace')
|
||||
title_re = re.compile("<title>(.+?)</title>")
|
||||
title = title_re.search(content).group(1)
|
||||
title = html.unescape(title)
|
||||
title = title.replace('\n', ' ').replace('\r', '')
|
||||
title = title.replace("<", "<")
|
||||
title = title.replace(">", ">")
|
||||
title = title.replace("&", "&")
|
||||
return title
|
||||
56
FaustBot/Modules/UserList.py
Normal file
56
FaustBot/Modules/UserList.py
Normal file
@@ -0,0 +1,56 @@
|
||||
from FaustBot.Model.RemoteUser import RemoteUser
|
||||
from FaustBot.Modules.JoinObserverPrototype import JoinObserverPrototype
|
||||
from FaustBot.Modules.ModuleType import ModuleType
|
||||
from ..Modules.KickObserverPrototype import KickObserverPrototype
|
||||
from ..Modules.LeaveObserverPrototype import LeaveObserverPrototype
|
||||
from ..Modules.NickChangeObserverPrototype import NickChangeObserverPrototype
|
||||
|
||||
|
||||
class UserList(JoinObserverPrototype, KickObserverPrototype, LeaveObserverPrototype, NickChangeObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return None
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.userList = {}
|
||||
|
||||
@staticmethod
|
||||
def get_module_types():
|
||||
return [ModuleType.ON_JOIN, ModuleType.ON_KICK, ModuleType.ON_LEAVE, ModuleType.ON_NICK_CHANGE]
|
||||
|
||||
def update_on_kick(self, data, connection):
|
||||
if data['nick'] in self.userList:
|
||||
del self.userList[data['nick']]
|
||||
# print(self.userList)
|
||||
|
||||
def update_on_leave(self, data, connection):
|
||||
if data['nick'] in self.userList:
|
||||
del self.userList[data['nick']]
|
||||
# print(self.userList)
|
||||
|
||||
def update_on_join(self, data, connection):
|
||||
self.userList[data['nick']] = RemoteUser(data['nick'], data['user'], data['host'])
|
||||
# print(self.userList)
|
||||
|
||||
def update_on_nick_change(self, data, connection):
|
||||
if data['old_nick'] in self.userList:
|
||||
remuser = self.userList[data['old_nick']]
|
||||
del self.userList[data['old_nick']]
|
||||
else:
|
||||
# shouldn't happen but let's be safe.
|
||||
remuser = RemoteUser('UN.KNOWN', 'UN.KNOWN', 'UN.KNOWN')
|
||||
|
||||
remuser.nick = data['new_nick']
|
||||
self.userList[data['new_nick']] = remuser
|
||||
# print(self.userList)
|
||||
|
||||
def clear_list(self):
|
||||
self.userList = {}
|
||||
|
||||
def add_user(self, remuser):
|
||||
self.userList[remuser.nick] = remuser
|
||||
51
FaustBot/Modules/WhoObserver.py
Normal file
51
FaustBot/Modules/WhoObserver.py
Normal file
@@ -0,0 +1,51 @@
|
||||
from FaustBot.Communication import Connection
|
||||
from FaustBot.Model.RemoteUser import RemoteUser
|
||||
from FaustBot.Modules.MagicNumberObserverPrototype import MagicNumberObserverPrototype
|
||||
from FaustBot.Modules.ModuleType import ModuleType
|
||||
from FaustBot.Modules.PingObserverPrototype import PingObserverPrototype
|
||||
from FaustBot.Modules.UserList import UserList
|
||||
import time
|
||||
|
||||
|
||||
class WhoObserver(MagicNumberObserverPrototype, PingObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return None
|
||||
|
||||
def __init__(self, user_list: UserList):
|
||||
super().__init__()
|
||||
self.user_list = user_list
|
||||
self.pings_seen = 1
|
||||
self.pending_whos = []
|
||||
|
||||
@staticmethod
|
||||
def get_module_types():
|
||||
return [ModuleType.ON_MAGIC_NUMBER, ModuleType.ON_PING]
|
||||
|
||||
def update_on_magic_number(self, data, connection):
|
||||
if data['number'] == '352': # RPL_WHOREPLY
|
||||
self.input_who(data, connection)
|
||||
elif data['number'] == '315': # RPL_ENDOFWHO
|
||||
#make sure other thread runs to its end.
|
||||
time.sleep(10)
|
||||
self.end_who()
|
||||
|
||||
def input_who(self, data, connection: Connection):
|
||||
# target #channel user host server nick status :0 gecos
|
||||
target, channel, user, host, server, nick, *ign = data['arguments'].split(' ')
|
||||
self.pending_whos.append(RemoteUser(nick, user, host))
|
||||
|
||||
def end_who(self):
|
||||
self.user_list.clear_list()
|
||||
for remuser in self.pending_whos:
|
||||
self.user_list.add_user(remuser)
|
||||
self.pending_whos = []
|
||||
|
||||
def update_on_ping(self, data, connection: Connection):
|
||||
if self.pings_seen % 90 == 0: # 90 * 2 min = 3 Stunden
|
||||
connection.raw_send('WHO ' + connection.details.get_channel())
|
||||
self.pings_seen += 1
|
||||
45
FaustBot/Modules/WikiObserver.py
Normal file
45
FaustBot/Modules/WikiObserver.py
Normal file
@@ -0,0 +1,45 @@
|
||||
from wikipedia import wikipedia
|
||||
|
||||
from FaustBot.Model.i18n import i18n
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
|
||||
|
||||
class WikiObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return [".w"]
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return ".w <term> - fragt Wikipediaartikel zu <term> ab"
|
||||
|
||||
def update_on_priv_msg(self, data, connection):
|
||||
|
||||
if data['message'].find('.w ') == -1:
|
||||
return
|
||||
i18n_server = i18n()
|
||||
w = wikipedia.set_lang(i18n_server.get_text('wiki_lang', lang=self.config.lang))
|
||||
q = data['message'].split(' ')
|
||||
query = ''
|
||||
for word in q:
|
||||
if word.strip() != '.w':
|
||||
query += word + ' '
|
||||
w = wikipedia.search(query)
|
||||
if w.__len__() == 0: # TODO BUG BELOW, ERROR MESSAGE NOT SHOWN!
|
||||
connection.send_back(data['nick'] + ', ' +
|
||||
i18n_server.get_text('wiki_fail',
|
||||
lang=self.config.lang),
|
||||
data)
|
||||
return
|
||||
try:
|
||||
page = wikipedia.WikipediaPage(w.pop(0))
|
||||
except wikipedia.DisambiguationError as error:
|
||||
print('disambiguation page')
|
||||
page = wikipedia.WikipediaPage(error.args[1][0])
|
||||
connection.send_back(data['nick'] + ' ' + page.url, data)
|
||||
index = 51 + page.summary[50:350].rfind('. ')
|
||||
if index == 50 or index > 230:
|
||||
index = page.summary[0:350].rfind(' ')
|
||||
connection.send_back(page.summary[0:index], data)
|
||||
else:
|
||||
connection.send_back(page.summary[0:index], data)
|
||||
97
FaustBot/Modules/WordRunObserver.py
Normal file
97
FaustBot/Modules/WordRunObserver.py
Normal file
@@ -0,0 +1,97 @@
|
||||
|
||||
from FaustBot.Communication.Connection import Connection
|
||||
from FaustBot.Modules.PrivMsgObserverPrototype import PrivMsgObserverPrototype
|
||||
from collections import defaultdict
|
||||
from time import sleep
|
||||
|
||||
|
||||
class WordRunObserver(PrivMsgObserverPrototype):
|
||||
@staticmethod
|
||||
def cmd():
|
||||
return ['.a', '.add', '.begin', '.end']
|
||||
|
||||
@staticmethod
|
||||
def help():
|
||||
return 'hangman game'
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.player = {}
|
||||
self.gamestatus = 0
|
||||
"""
|
||||
0 = Kein Spiel
|
||||
1 = Spiel mit Silbe am Anfang
|
||||
2 = Spiel mit Silbe am Ende
|
||||
"""
|
||||
self.syllable = ""
|
||||
|
||||
def update_on_priv_msg(self, data, connection: Connection):
|
||||
if data['message'].find('.a ') != -1 or data['message'].find('.add ') != -1:
|
||||
self.add(data, connection)
|
||||
if data['message'].find('.begin ') != -1:
|
||||
self.begin_word(data, connection)
|
||||
if data['message'].find('.end ') != -1:
|
||||
self.end_word(data, connection)
|
||||
|
||||
def add(self, data, connection):
|
||||
if self.gamestatus == 0:
|
||||
connection.send_channel("Es läuft derzeit kein Wordrun, bitte einen neuen mit .begin <Silbe> oder .end <silbe> erstellen!")
|
||||
return
|
||||
if self.gamestatus == 1 or self.gamestatus == 2:
|
||||
self.check_word(data["nick"], data['message'], connection)
|
||||
|
||||
def begin_word(self, data, connection):
|
||||
if self.gamestatus != 0:
|
||||
connection.send_channel("Es läuft bereits ein Spiel")
|
||||
return
|
||||
self.gamestatus = 1
|
||||
self.handle_game(data,connection)
|
||||
|
||||
def end_word(self, data, connection):
|
||||
if self.gamestatus != 0:
|
||||
connection.send_channel("Es läuft bereits ein Spiel")
|
||||
return
|
||||
self.gamestatus = 2
|
||||
self.handle_game(data,connection)
|
||||
|
||||
def check_word(self,player , message, connection):
|
||||
for word in message.split():
|
||||
if word == '.a':
|
||||
continue
|
||||
if self.gamestatus == 1:
|
||||
if word.upper().startswith(self.syllable.upper()):
|
||||
self.add_to_dict(player, word, connection)
|
||||
if self.gamestatus == 2:
|
||||
if word.upper().endswith(self.syllable.upper()):
|
||||
self.add_to_dict(player, word, connection)
|
||||
|
||||
def add_to_dict(self, nick, word, connection):
|
||||
for p in self.player.keys():
|
||||
for w in self.player[p]:
|
||||
if w.upper() == word.upper():
|
||||
connection.send_channel("Das Wort "+word+" wurde bereits von "+p+ " genannt")
|
||||
return
|
||||
if nick not in self.player:
|
||||
self.player[nick] = []
|
||||
self.player[nick].append(word)
|
||||
|
||||
def handle_game(self, data, connection):
|
||||
self.syllable = data["message"].split()[1]
|
||||
if self.gamestatus == 1:
|
||||
connection.send_channel("Das Wort muss mit " + self.syllable + "- beginnen")
|
||||
if self.gamestatus == 2:
|
||||
connection.send_channel("Das Wort muss mit -" + self.syllable + " enden")
|
||||
sleep(150)
|
||||
connection.send_channel("Noch 30 Sekunden")
|
||||
sleep(30)
|
||||
player_score = defaultdict(int)
|
||||
s = "Folgende Ergebnisse: "
|
||||
for p in self.player.keys():
|
||||
for w in self.player[p]:
|
||||
print(p+" "+w)
|
||||
player_score[p] += 1
|
||||
for p in self.player.keys():
|
||||
s = s + p + " : "+str(player_score[p])+ "; "
|
||||
connection.send_channel(s)
|
||||
self.gamestatus = 0
|
||||
self.player = {}
|
||||
1
FaustBot/Modules/__init__.py
Normal file
1
FaustBot/Modules/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
__author__ = 'Pups'
|
||||
Reference in New Issue
Block a user