From 4472cecbd2edfed64e0217fefd570675a6d8936a Mon Sep 17 00:00:00 2001 From: "quartz235@gmail.com" Date: Fri, 23 Dec 2011 17:39:47 +0000 Subject: [PATCH] Finally ready to like add this now oh man this is a huge thing sort of Added CC-Nanotrasen, an IRC bot made by Skibiliano and given to us by him under CC-BY-SA 3.0 licensing WHAT DOES THIS MEAN? It means all servers running this SVN now have the option to use an easy to configure IRC bot capable of relaying adminhelps from ingame to the server/channel of their choice. - Runs on python 2.6 scripts with psyco support - Relaying can be toggled from config.txt (so you don't runtime with every adminhelp if you decide not to use it) - Comes with a bunch of other useful and fun tools too - Added a new global proc, send2irc(msg,msg2) YOU'LL NEVER GUESS WHAT IT DOES CONSIDERING WHAT I JUST MENTIONED ----msg and msg2 are just what text gets relayed to irc, separated by a |, for instance send2irc(hello, world) would come out as "CC_NanoTrasen: Hello | World git-svn-id: http://tgstation13.googlecode.com/svn/trunk@2783 316c924e-a436-60f5-8080-3fe189b3f50e --- README.txt | 9 +- bot/CORE_DATA.py | 13 + bot/C_eightball.py | 32 + bot/C_heaortai.py | 5 + bot/C_makequote.py | 21 + bot/C_maths.py | 70 + bot/C_rot13.py | 23 + bot/C_rtd.py | 96 + bot/C_sarcasticball.py | 30 + bot/C_srtd.py | 35 + bot/D_help.py | 60 + bot/FMLformatter.py | 55 + bot/Marakov/Marakov.Cache | 2450 +++++++++++++++++++++++++ bot/Marakov_Chain.py | 203 ++ bot/Namecheck.py | 19 + bot/NanoTrasenBot.py | 1943 ++++++++++++++++++++ bot/Shortname.py | 28 + bot/Timeconverter.py | 204 ++ bot/Weather.py | 61 + bot/YTCv3.py | 75 + bot/YTCv4.py | 132 ++ bot/_____Readme.txt | 74 + bot/gen_fml.py | 15 + bot/htmltagremove.py | 28 + bot/irchat.py | 94 + bot/linereader.py | 43 + bot/nudge.py | 39 + bot/save_load.py | 24 + bot/some_but_not_all_2.py | 20 + bot/xkcdparser.py | 40 + code/datums/configuration.dm | 4 + code/modules/admin/verbs/adminhelp.dm | 6 + config/config.txt | 5 +- 33 files changed, 5954 insertions(+), 2 deletions(-) create mode 100644 bot/CORE_DATA.py create mode 100644 bot/C_eightball.py create mode 100644 bot/C_heaortai.py create mode 100644 bot/C_makequote.py create mode 100644 bot/C_maths.py create mode 100644 bot/C_rot13.py create mode 100644 bot/C_rtd.py create mode 100644 bot/C_sarcasticball.py create mode 100644 bot/C_srtd.py create mode 100644 bot/D_help.py create mode 100644 bot/FMLformatter.py create mode 100644 bot/Marakov/Marakov.Cache create mode 100644 bot/Marakov_Chain.py create mode 100644 bot/Namecheck.py create mode 100644 bot/NanoTrasenBot.py create mode 100644 bot/Shortname.py create mode 100644 bot/Timeconverter.py create mode 100644 bot/Weather.py create mode 100644 bot/YTCv3.py create mode 100644 bot/YTCv4.py create mode 100644 bot/_____Readme.txt create mode 100644 bot/gen_fml.py create mode 100644 bot/htmltagremove.py create mode 100644 bot/irchat.py create mode 100644 bot/linereader.py create mode 100644 bot/nudge.py create mode 100644 bot/save_load.py create mode 100644 bot/some_but_not_all_2.py create mode 100644 bot/xkcdparser.py diff --git a/README.txt b/README.txt index 2a2896c6a8..3250288c58 100644 --- a/README.txt +++ b/README.txt @@ -66,4 +66,11 @@ SQL Setup The SQL backend for the library, karma system and stats tracking requires a MySQL server. Your server details go in /config/dbconfig.txt, and the SQL schema is in /SQL/tgstation_schema.sql. More detailed setup instructions are -coming soon, for now ask in our IRC channel. \ No newline at end of file +coming soon, for now ask in our IRC channel. + +================================================================================ +IRC Bot Setup +================================================================================ + +Included in the SVN is an IRC bot capable of relaying adminhelps to a specified IRC channel/server (thanks to Skibiliano) +Instructions for bot setup are included in the /bot/ folder along with the bot/relay script itself \ No newline at end of file diff --git a/bot/CORE_DATA.py b/bot/CORE_DATA.py new file mode 100644 index 0000000000..cd1b83e410 --- /dev/null +++ b/bot/CORE_DATA.py @@ -0,0 +1,13 @@ +Name = "CC_NanoTrasen" #The name he uses to connect +no_absolute_paths = True +debug_on = False +SName = ["cc","nt","trasen","nano","nanotrasen"] #Other names he will respond to +DISABLE_ALL_NON_MANDATORY_SOCKET_CONNECTIONS = False +directory = "c:/cc_nt/bot/" # Directory the bot is located in, make sure to keep the "/" at the end +version = "TG CC-BY-SA 6" +Network = 'irc.rizon.net' #e.g. "irc.rizon.net" +channel = "#italiano" #what channel you want the bot in +channels = ["#italiano"] #same as above +greeting = "Welcome!" #what he says when a person he hasn't seen before joins +prefix = "!" #prefix for bot commands +Port = 7000 diff --git a/bot/C_eightball.py b/bot/C_eightball.py new file mode 100644 index 0000000000..2ed73dafd5 --- /dev/null +++ b/bot/C_eightball.py @@ -0,0 +1,32 @@ +from random import choice as fsample #Yay for added speed! +global responses +responses = ['Yes','Too bad','Will you turn me off if I tell you?','Absolutely', + "Not at all", "Nope", "It does", "No", "All the time", + "I don't really know", "Could be","Possibly","You're still here?",# Chaoticag + "No idea", "Of course", "Would you turn me off if I tell you?", + "Sweet!","Nah","Certainly","Yeah","Yup","I am quite confident that the answer is Yes", + "Perhaps", "Yeeeeaah... No.", "Indubitably" ] # Richard +def eightball(data,debug,sender,prefix): + global responses + arg = data.lower().replace(prefix+"eightball ","") + arg = arg.replace(prefix+"8ball ","") + if debug: + print sender+":"+prefix+"eightball", arg + if "answer" in arg and "everything" in arg and "to" in arg: + if debug: + print "Responded with",42 + return "42" + elif arg == "derp": + if debug: + print "Responded with herp" + return("herp") + elif arg == "herp": + if debug: + print "Responded with derp" + return("derp") + else: + #choice = sample(responses,1)[0] + choice = fsample(responses) + if debug: + print "Responded with", choice + return(choice) diff --git a/bot/C_heaortai.py b/bot/C_heaortai.py new file mode 100644 index 0000000000..6e8b304e73 --- /dev/null +++ b/bot/C_heaortai.py @@ -0,0 +1,5 @@ +#Throws a coin, simple. +from random import random +def heaortai(debug,sender): return("Heads" if random() > 0.5 else "Tails") +# Takes 1/6th the time of doing it with random.randint(0,1) +# This file used to be a lot bigger, now it's kind of useless. diff --git a/bot/C_makequote.py b/bot/C_makequote.py new file mode 100644 index 0000000000..f79b863449 --- /dev/null +++ b/bot/C_makequote.py @@ -0,0 +1,21 @@ +from save_load import save +from os import listdir +import CORE_DATA +directory = CORE_DATA.directory +def mkquote(prefix,influx,sender,debug): + arg = influx[10+len(prefix):] + if debug: + print sender+":"+prefix+"makequote "+str(len(arg))+" Characters" + if len(arg) == 0: + return("Type something to a quote") + else: + files = listdir(directory+"userquotes") + numb = 0 + while True: + numb += 1 + if sender.lower()+str(numb) in files: + pass + else: + save(directory+"userquotes/"+sender.lower()+str(numb),[arg,sender.lower()]) + return("Saved as:"+sender.lower()+str(numb)) + break diff --git a/bot/C_maths.py b/bot/C_maths.py new file mode 100644 index 0000000000..86013b74a7 --- /dev/null +++ b/bot/C_maths.py @@ -0,0 +1,70 @@ +### EXPERIMENTAL PROTOTYPE ### +# e = 2.7182818284590452353602874713526624977572 +# pi = math.pi +from __future__ import division #PYTHON Y U NO TELL ME THIS BEFORE +import math +import random +import re +e = "2.7182818284590452353602874713526624977572" +pi = str(math.pi) +global pre +pre = len("maths ") +def maths(influx,prefix="!",sender="NaN",debug=True,method="n"): + global pre + influx = influx.lower() + influx = influx[len(prefix)+pre:] + influx = influx.replace("pie",pi+"*"+e) + influx = influx.replace("e*",e+"*") + influx = influx.replace("*e","*"+e) + influx = influx.replace("pi",pi) + if debug: + print sender+":"+prefix+"maths" + if influx.count("**") == 0 and influx.count('"') == 0 and influx.count("'") == 0 and influx.count(";") == 0 and influx.count(":") == 0: + influx_low = influx.lower() + influx_hi = influx.upper() + if "0b" in influx_low: + influx_low = re.sub("0b[0-1]*","",influx_low) + influx_hi = re.sub("0B[0-1]*","",influx_hi) + if "0x" in influx_low: + influx_low = re.sub("0x[a-f0-9]*","",influx_low) + influx_hi = re.sub("0X[A-F0-9]*","",influx_hi) + if "rand" in influx_low: + influx_low = re.sub("rand","",influx_low) + influx_hi = re.sub("RAND","",influx_hi) + if influx_low == influx_hi: + influx = re.sub("rand","random.random()",influx) + try: + result = eval(influx.lower()) + except ZeroDivisionError: + return "Divide by zero detected." + except SyntaxError: + return "Syntax Error detected." + except TypeError: + return "Type Error detected." + except: + return "Unknown Error detected." + else: + if method == "n": #Normal + return result + elif method == "i": #Forced Int + return int(result) + elif method == "h": #Hex + try: + if "L" in hex(result)[2:]: + return hex(result)[2:-1] + else: + return hex(result)[2:].upper() + except TypeError: + return "That value (%s) cannot be interpreted properly using !hmaths" %(str(result)) + elif method == "b": #Binary + try: + return bin(result)[2:].upper() + except TypeError: + return "That value (%s) cannot be interpreted properly using !bmaths" %(str(result)) + else: + return result + else: + return "What are you trying to make me do again?" + else: + return "Those are likely to make me hang" + diff --git a/bot/C_rot13.py b/bot/C_rot13.py new file mode 100644 index 0000000000..62b72dc2ad --- /dev/null +++ b/bot/C_rot13.py @@ -0,0 +1,23 @@ +global parta,partb +parta = {"A":"N","B":"O","C":"P","D":"Q","E":"R","F":"S","G":"T","H":"U","I":"V","J":"W","K":"X","L":"Y","M":"Z"} +partb = {'O':'B','N':'A','Q':'D','P':'C','S':'F','R':'E','U':'H','T':'G','W':'J','V':'I','Y':'L','X':'K','Z':'M'} +def rot13(text): + global parta,partb + newtext = "" + for letter in text: + try: + if letter.isupper(): + newtext += parta[letter] + else: + newtext += parta[letter.upper()].lower() + except: + try: + if letter.isupper(): + newtext += partb[letter] + pass + else: + newtext += partb[letter.upper()].lower() + pass + except: + newtext += letter + return newtext diff --git a/bot/C_rtd.py b/bot/C_rtd.py new file mode 100644 index 0000000000..96736fec21 --- /dev/null +++ b/bot/C_rtd.py @@ -0,0 +1,96 @@ +import random +def rtd(data,debug,sender): + backo = data + try: + arg1,arg2 = backo.split("d") + except ValueError, err: + return("Too many or too small amount of arguments") + else: + if debug: + print sender+":!rtd "+arg1+"d"+arg2 #faster than using %s's + die,die2 = [],[] + current_mark = "" + outcome = 0 + realnumberfound = False + checks = [] + count = 0 + arg1 = arg1.replace(" ","") + arg2 = arg2.replace(" ","") + try: + i_arg1 = int(arg1) + a_arg1 = abs(i_arg1) + if "+" in arg2 or "-" in arg2: + plus_spot = arg2.find("+") + minus_spot = arg2.find("-") + if plus_spot == -1 and minus_spot == -1: + nicer_form = "" + elif plus_spot != -1 and minus_spot == -1: + nicer_form = arg2[plus_spot:] + elif plus_spot == -1 and minus_spot != -1: + nicer_form = arg2[minus_spot:] + else: + if plus_spot < minus_spot: + nicer_form = arg2[plus_spot:] + else: + nicer_form = arg2[minus_spot:] + for letter in arg2: + if letter == "+" or letter == "-": + current_mark = letter + checks = [] + count += 1 + continue + checks.append(letter) + try: + next_up = arg2[count+1] + except: + if realnumberfound == False: + i_arg2 = int("".join(checks)) + checks = [] + realnumberfound = True + elif current_mark == "+": + outcome += int("".join(checks)) + else: + outcome -= int("".join(checks)) + else: + if next_up == "+" or next_up == "-": + if realnumberfound == False: + i_arg2 = int("".join(checks)) + checks = [] + realnumberfound = True + else: + if current_mark == "+": + outcome += int("".join(checks)) + else: + outcome -= int("".join(checks)) + checks = [] + count += 1 + else: + i_arg2 = int(arg2) + if a_arg1 == 0 or abs(i_arg2) == 0: + raise RuntimeError + except ValueError: + return("You lied! That's not a number!") + except RuntimeError: + return("Too many zeroes!") + else: + if a_arg1 > 100: + return("Too many rolls, I can only do one hundred at max.") + else: + for i in xrange(0,a_arg1): + if i_arg2 < 0: + dice = random.randint(i_arg2,0) + else: + dice = random.randint(1,i_arg2) + die.append(dice) + die2.append(str(dice)) + if i_arg2 < 0: + flist = "".join(die2) + else: + flist = "+".join(die2) + if len(flist) > 350: + return(str(reduce(lambda x,y: x+y, die)+outcome)) + else: + if current_mark == "": + return(flist+" = "+str(reduce(lambda x,y: x+y, die)+outcome)) + else: + return(flist+" ("+nicer_form+") = "+str(reduce(lambda x,y: x+y, die)+outcome)) diff --git a/bot/C_sarcasticball.py b/bot/C_sarcasticball.py new file mode 100644 index 0000000000..1f5ae32181 --- /dev/null +++ b/bot/C_sarcasticball.py @@ -0,0 +1,30 @@ +from random import choice as fsample +sarcastic_responses = ["Yeah right","What do I look like to you?","Are you kidding me?",#UsF + "As much as you","You don't believe that yourself","When pigs fly",#UsF + "Like your grandma","You would like to know, wouldn't you?", #UsF + "Like your mom", #Spectre + "Totally","Not at all", #Spectre + "AHAHAHahahaha, No.", #Strumpetplaya + "Not as much as USER","As much as USER", + "Really, you expect me to tell you that?", + "Right, and you've been building NOUNs for those USERs in the LOCATION, haven't you?" ] #Richard +locations = ["woods","baystation","ditch"] +nouns = ["bomb","toilet","robot","cyborg", + "garbage can","gun","cake", + "missile"] +def sarcasticball(data,debug,sender,users,prefix): + arg = data.lower().replace(prefix+"sarcasticball ","") + arg = arg.replace(prefix+"sball ","") + if debug: + print sender+":"+prefix+"sarcasticball", arg + choice = fsample(sarcastic_responses) + if "USER" in choice: + choice = choice.replace("USER",fsample(users),1) + choice = choice.replace("USER",fsample(users),1) + if "NOUN" in choice: + choice = choice.replace("NOUN",fsample(nouns),1) + if "LOCATION" in choice: + choice = choice.replace("LOCATION",fsample(locations),1) + if debug: + print "Responded with", choice + return(choice) diff --git a/bot/C_srtd.py b/bot/C_srtd.py new file mode 100644 index 0000000000..761c0628d6 --- /dev/null +++ b/bot/C_srtd.py @@ -0,0 +1,35 @@ +import random +def srtd(data,debug,sender): + try: + arg1,arg2 = data.split("d") + except ValueError, err: + if str(err) == "need more than 1 value to unpack": + return("Too small amount of arguments") + else: + return("Too many arguments") + else: + if debug: + print sender+":!rtd "+arg1+"d"+arg2 + die = [] + arg1 = arg1.replace(" ","") + arg2 = arg2.replace(" ","") + try: + i_arg1 = int(arg1) + i_arg2 = int(arg2) + if abs(i_arg1) == 0 or abs(i_arg2) == 0: + raise RuntimeError + except ValueError: + return("You lied! That's not a number!") + except RuntimeError: + return("Too many zeroes!") + else: + if abs(i_arg1) > 500: + return("Too many rolls, I can only do five hundred at max.") + else: + for i in xrange(0,abs(i_arg1)): + if i_arg2 < 0: + dice = random.randint(i_arg2,0) + else: + dice = random.randint(1,i_arg2) + die.append(dice) + return(str(reduce(lambda x,y: x+y, die))) diff --git a/bot/D_help.py b/bot/D_help.py new file mode 100644 index 0000000000..ee4e2c07cf --- /dev/null +++ b/bot/D_help.py @@ -0,0 +1,60 @@ +#As new commands are added, update this. +# Last updated: 8.3.2011 + +# Updated 12.3.2011: +# - Added the missing help data for Version +# - Imported CORE_DATA to get the name. +# - Tidied some commands up a bit. +# - Replaced all "Bot"s with the Skibot's current name. + +from CORE_DATA import Name +everything = {"8ball":"[8ball ] Responds to the argument", + "allcaps":"[allcaps ] Takes an uppercase string and returns a capitalized version", + "bmaths":"[bmaths ] Takes a math equation (Like 5+5) and returns a binary result", + "coin":"[coin] Flips a coin", + "dance":"[dance] Makes %s do a little dance" %(Name), + "delquote":"(OP ONLY) [delquote ] Removes a quote with the filename equal to the argument", + "disable":"(OP ONLY) [disable] Disables all output from %s" %(Name), + "disable dance":"(HALFOP / OP ONLY) [disable dance] or [dd] Toggles dancing", + "disable fml":"(HALFOP / OP ONLY) [disable fml] Disables FML", + "eightball":"[eightball ] Responds to the argument", + "enable":"(OP ONLY) [enable] After being disabled, enable will turn output back on", + "enable fml":"{HALFOP / OP ONLY} [enable fml] After fml has been disabled, enable fml will make it available again", + "fml":"[fml] Returns a random Fuck My Life bit", + "give":"[give ] Gives the Pneumatic Disposal Unit the argument", + "help":"[help []] Returns the list of commands or a detailed description of a command if specified", + "hmaths":"[hmaths ] Takes a math equation (Like 5+5) and returns a hex result", + "makequote":"[makequote ] Creates a quote with arg being the quote itself", + "maths":"[maths ] Takes a math equation (Like 5+5) and returns a default result", + "note":"[note []] Opens a note if only arg1 is specified, Creates a note with the name of arg1 and contents of arg2 if arg2 is specified, if you prefix the note name with [CP], it creates a public note only to that channel. Which can be accessed by !note _", + "notes":"[notes] Displays all your saved notes on %s" %(Name), + "otherball":"[otherball] If Floorbot is on the same channel, %s will ask him a random question when this command is passed" %(Name), + "purgemessages":"[purgemessages] Used to delete all your Tell messages (%s,Tell )" %(Name), + "quote":"[quote []] Picks a random quote, if the author is specified, a random quote by that author", + "redmine":"[redmine] If you have a note called redmine, with a valid whoopshop redmine address, this displays all the bugs labeled as 'New' on that page. It also displays the todo note if it's found.", + "replace":"[replace] Fixes the Pneumatic Smasher if it's been broken", + "rot13":"[rot13 ] Encrypts the arg by using the rot13 method", + "rtd":"[rtd [d]] Rolls a six-sided dice if no arguments are specified, otherwise arg1 is the amount of rolls and arg2 is the amount of sides the dice have", + "sarcasticball":"[sarcasticball ] Responds to the argument sarcastically", + "sball":"[sball ] Responds to the argument sarcastically", + "srtd":"[srtd d] Rolls amount of sided die without showing the dice values separately", + "stop":"(RESTRICTED TO OP AND CREATOR) [stop] Stops %s, plain and simple" %(Name), + "suggest":"[suggest ] Saves a suggestion given to %s, to be later viewed by the creator" %(Name), + "take":"[take ] Takes an item specified in the argument from the Pneumatic Smasher", + "tban":"(OP ONLY) [tban ] When %s is an operator, You can ban an user for specified amount of seconds" %(Name), + "thm":"(RESTRICTED TO OP AND CREATOR) [thm] Normally in 8ball and sarcasticball, Users are not shown, instead replaced by things like demons or plasma researchers, toggling this changes that behaviour.", + "tm":"(OP AND CREATOR ONLY) [tm] Toggles marakov", + "togglequotemakers":"(OP ONLY) [togglequotemakers or tqm] Normally with the quote command, makers are not shown, this toggles that behaviour.", + "tqm":"(OP ONLY) [tqm or togglequotemakers] Normally with the quote command, makers are not shown, this toggles that behaviour.", + "toggleofflinemessages":"(OP ONLY) [toggleofflinemessages or tom] Allows an operator to toggle leaving Tell messages (%s, Tell ] Whenever the user says something in allcaps, it's capitalized.", + "uptime":"[uptime] Displays how long %s has been alive on the channel."%(Name), + "use":"[use] Uses the Pneumatic Smasher.", + "youtube":"[youtube ] Shows the title of a video by checking the URL provided.", + "version":"[version] Shows the current version of %s." %(Name), + "weather":"[weather ] Displays the current weather of the provided location.", + "life":"I cannot help you with that, sorry."} + diff --git a/bot/FMLformatter.py b/bot/FMLformatter.py new file mode 100644 index 0000000000..153af61a41 --- /dev/null +++ b/bot/FMLformatter.py @@ -0,0 +1,55 @@ +from htmltagremove import htr +def formatter(data): + newdata = [] + data = htr(data) + bad = ["Your nick : Categories : ","\r","Advanced search - last", + "FMyLife","Get the guts to spill the beans","FML: Your random funny stories", + "Woman","Man","Choose","Health","Intimacy","Miscellaneous","Man or woman? ", + "Money","Kids","Work","Love","Email notification?", + "Moderate the FMLs","Submit your FML story", + "- If your story isn't published on the website, don't feel offended, and thank you nevertheless!", + "Pick a country","See all","Your account","Team's blog", + "Meet the FMLHello readers! Did you meet someone new this...The whole blog", + "Amazon","Borders","IndieBound","Personalized book","Terms of use", + "FML t-shirts -","Love - Money - Kids - Work - Health - Intimacy - Miscellaneous - Members", + "Follow the FML Follow the FML blog Follow the FML comments ", + "_qoptions={", + "};","})();","Categories","Sign up - Password? ", " Net Avenir : gestion publicitaire", + "FMyLife, the book","Available NOW on:","Barnes & Noble"] + + for checkable in data: + if checkable in bad: + pass + elif "_gaq.push" in checkable: + pass + elif "ga.src" in checkable: + pass + elif "var _gaq" in checkable: + pass + elif "var s =" in checkable: + pass + elif "var ga" in checkable: + pass + elif "function()" in checkable: + pass + elif "siteanalytics" in checkable: + pass + elif "qacct:" in checkable: + pass + elif "\r" in checkable: + pass + elif "ic_" in checkable: + pass + elif "Please note that spam and nonsensical stories" in checkable: + pass + elif "Refresh this page" in checkable: + pass + elif "You...The whole blo" in checkable: + pass + elif "Net Avenir : gestion publicitair" in checkable: + pass + else: + if "Net Avenir : gestion publicitaireClose the advertisement" in checkable: + checkable = checkable.replace("Net Avenir : gestion publicitaireClose the advertisement","") + newdata.append(checkable) + return newdata diff --git a/bot/Marakov/Marakov.Cache b/bot/Marakov/Marakov.Cache new file mode 100644 index 0000000000..500f4384ed --- /dev/null +++ b/bot/Marakov/Marakov.Cache @@ -0,0 +1,2450 @@ +(dp0 +S'all' +p1 +(lp2 +S':p' +p3 +aS'the' +p4 +asS'code' +p5 +(lp6 +S'in' +p7 +asS'stores' +p8 +(lp9 +S'that' +p10 +asS'just' +p11 +(lp12 +S'like' +p13 +aS'marakov' +p14 +aS'felt' +p15 +aS'gives' +p16 +aS'a' +p17 +aS'add' +p18 +aS'what' +p19 +asS'being' +p20 +(lp21 +S'goon' +p22 +aS'a' +p23 +asS'text' +p24 +(lp25 +S'string' +p26 +asS'dependant' +p27 +(lp28 +S'on' +p29 +asS'speedup' +p30 +(lp31 +S'at' +p32 +asS'felt' +p33 +(lp34 +S'like' +p35 +asS'installed' +p36 +(lp37 +S'tho' +p38 +asS'disabled' +p39 +(lp40 +S'it' +p41 +asS'timing' +p42 +(lp43 +S'when' +p44 +asS'psyco' +p45 +(lp46 +S'installed' +p47 +aS'is' +p48 +asS'stops' +p49 +(lp50 +S'timing' +p51 +asS'file' +p52 +(lp53 +S'too' +p54 +aS'that' +p55 +aS'where' +p56 +asS'go' +p57 +(lp58 +S'fuck' +p59 +aS'into' +p60 +aS'test' +p61 +asS'hell' +p62 +(lp63 +S'recreate' +p64 +asS'configurable' +p65 +(lp66 +S'greeting' +p67 +asS'bs12' +p68 +(lp69 +S'message' +p70 +asS'its' +p71 +(lp72 +S'fine' +p73 +aS'just' +p74 +aS'calculated' +p75 +aS'not' +p76 +aS'really' +p77 +aS'ridiculously' +p78 +aS'now' +p79 +aS'a' +p80 +aS'missing' +p81 +aS'for' +p82 +aS'false' +p83 +aS'on' +p84 +asS'before' +p85 +(lp86 +S'that' +p87 +asS'rp-heavy' +p88 +(lp89 +S'server' +p90 +asS'announcement' +p91 +(lp92 +S'like' +p93 +asS'now' +p94 +(lp95 +S'it' +p96 +aS'running' +p97 +aS'makie' +p98 +aS'i' +p99 +asS'nudge' +p100 +(lp101 +S'python' +p102 +aS'is' +p103 +asS'sourced' +p104 +(lp105 +S'under' +p106 +asS'title' +p107 +(lp108 +S'of' +p109 +asS'situations' +p110 +(lp111 +S'where' +p112 +asS'fine-tune' +p113 +(lp114 +S'it' +p115 +asS'enough' +p116 +(lp117 +S'to' +p118 +asS'send' +p119 +(lp120 +S'it' +p121 +aS'one' +p122 +asS'should' +p123 +(lp124 +S'be' +p125 +aS'learn' +p126 +aS'we' +p127 +asS'values' +p128 +(lp129 +S'dont' +p130 +asS'to' +p131 +(lp132 +S'edit' +p133 +aS'back' +p134 +aS'know' +p135 +aS'care' +p136 +aS'be' +p137 +aS'configure' +p138 +aS'the' +p139 +aS'null' +p140 +aS'phone' +p141 +aS'welcome' +p142 +aS'reverse' +p143 +aS'send' +p144 +aS'reg' +p145 +aS'point' +p146 +aS'automatically' +p147 +aS'work' +p148 +aS'waste' +p149 +aS'marshmallow' +p150 +aS'queries' +p151 +aS'+o' +p152 +aS'disable' +p153 +asS'jit' +p154 +(lp155 +S'compiler' +p156 +asS'going' +p157 +(lp158 +S'to' +p159 +asS'helps' +p160 +(lp161 +S'me' +p162 +asS'messes' +p163 +(lp164 +S'it' +p165 +asS'indeed' +p166 +(lp167 +S'it' +p168 +asS'tg' +p169 +(lp170 +S'and' +p171 +asS'has' +p172 +(lp173 +S'been' +p174 +aS'my' +p175 +asS'into' +p176 +(lp177 +S'#tgstation13' +p178 +asS'ridiculously' +p179 +(lp180 +S'simple' +p181 +asS'annoy' +p182 +(lp183 +S'downstream' +p184 +asS'them' +p185 +(lp186 +S'out' +p187 +asS'someone' +p188 +(lp189 +S'adminhelps' +p190 +asS'sense' +p191 +(lp192 +S'i' +p193 +asS'string' +p194 +(lp195 +S'called' +p196 +asS'get' +p197 +(lp198 +S'ready' +p199 +asS'python' +p200 +(lp201 +S'script' +p202 +aS'so' +p203 +aS'code' +p204 +aS'scripts' +p205 +aS'and' +p206 +aS'but' +p207 +aS'now' +p208 +aS'released' +p209 +aS'is' +p210 +aS'enough' +p211 +asS'goon' +p212 +(lp213 +S'tg' +p214 +asS'showing' +p215 +(lp216 +S'up' +p217 +asS'20ish' +p218 +(lp219 +S'line' +p220 +asS'gonna' +p221 +(lp222 +S'go' +p223 +asS'made' +p224 +(lp225 +S'doctors' +p226 +asS'every' +p227 +(lp228 +S'loop' +p229 +aS'time' +p230 +asS'know' +p231 +(lp232 +S'the' +p233 +aS'why' +p234 +aS'that' +p235 +asS'not' +p236 +(lp237 +S'just' +p238 +aS'necessary' +p239 +aS'to' +p240 +aS'so' +p241 +aS'need' +p242 +aS'sure' +p243 +aS'relaying' +p244 +aS'very' +p245 +aS'even' +p246 +asS'2' +p247 +(lp248 +S'loop' +p249 +asS'password' +p250 +(lp251 +S'var' +p252 +asS'day' +p253 +(lp254 +S'so' +p255 +asS'swapping' +p256 +(lp257 +S'to' +p258 +asS'easily' +p259 +(lp260 +S'editable' +p261 +asS'necessary' +p262 +(lp263 +S'at' +p264 +asS'like' +p265 +(lp266 +S'being' +p267 +aS'linking' +p268 +aS'to' +p269 +aS'how' +p270 +aS'it' +p271 +aS'skbzzzzzibi' +p272 +asS'course' +p273 +(lp274 +S'that' +p275 +asS'edit' +p276 +(lp277 +S'baystation' +p278 +asS'fully' +p279 +(lp280 +S'open' +p281 +asS'greeting' +p282 +(lp283 +S'message' +p284 +asS'server' +p285 +(lp286 +S'basically' +p287 +aS'' +p288 +asS'default' +p289 +(lp290 +S'config' +p291 +asS'bad' +p292 +(lp293 +S'company' +p294 +asS'channel' +p295 +(lp296 +S'or' +p297 +asS'always' +p298 +(lp299 +S'makes' +p300 +asS'went' +p301 +(lp302 +S'past' +p303 +asS'quarxink' +p304 +(lp305 +S'its' +p306 +asS'automatic' +p307 +(lp308 +S'announcement' +p309 +asS'once' +p310 +(lp311 +S'per' +p312 +asS'wrote' +p313 +(lp314 +S'most' +p315 +asS'pain' +p316 +(lp317 +S'on' +p318 +asS'system' +p319 +(lp320 +S'calls' +p321 +asS'right' +p322 +(lp323 +S'brb' +p324 +asS'decides' +p325 +(lp326 +S'not' +p327 +asS'people' +p328 +(lp329 +S'say' +p330 +aS'i' +p331 +aS'he' +p332 +asS'goddamn' +p333 +(lp334 +S'python' +p335 +asS'back' +p336 +(lp337 +S'it' +p338 +asS'used' +p339 +(lp340 +S'to' +p341 +aS'for' +p342 +asS'past' +p343 +(lp344 +S'too' +p345 +asS'cost' +p346 +(lp347 +S'of' +p348 +asS'learn' +p349 +(lp350 +S'python' +p351 +asS'are' +p352 +(lp353 +S'lawyers' +p354 +aS'actually' +p355 +aS'configurable' +p356 +aS'we' +p357 +asS'celestialike' +p358 +(lp359 +S'of' +p360 +asS'lawyers' +p361 +(lp362 +S'for' +p363 +asS'time' +p364 +(lp365 +S'he' +p366 +asS'out' +p367 +(lp368 +S'switch' +p369 +aS'slowdowns' +p370 +aS'that' +p371 +aS'why' +p372 +aS'nudge' +p373 +asS'even' +p374 +(lp375 +S'an' +p376 +asS'what' +p377 +(lp378 +S'the' +p379 +aS'is' +p380 +aS'these' +p381 +aS'was' +p382 +aS'license' +p383 +aS'about' +p384 +aS'i' +p385 +asS'said' +p386 +(lp387 +S'in' +p388 +asS'sayt' +p389 +(lp390 +S'hat' +p391 +asS'for' +p392 +(lp393 +S'that' +p394 +aS'every' +p395 +aS'the' +p396 +aS'quarx' +p397 +aS'cc_nanotrasen' +p398 +aS'homoerotic' +p399 +aS'situations' +p400 +aS'good' +p401 +asS'#tgstation13' +p402 +(lp403 +S'and' +p404 +asS'per' +p405 +(lp406 +S'name' +p407 +asS'whole' +p408 +(lp409 +S'config' +p410 +asS'state' +p411 +(lp412 +S'the' +p413 +asS'does' +p414 +(lp415 +S'the' +p416 +aS'it' +p417 +asS'goes' +p418 +(lp419 +S'on' +p420 +asS'readme' +p421 +(lp422 +S'too' +p423 +asS'new' +p424 +(lp425 +S'bot' +p426 +aS'person' +p427 +asS'learned' +p428 +(lp429 +S'python' +p430 +asS'irc' +p431 +(lp432 +S'bot' +p433 +asS'reg' +p434 +(lp435 +S'it' +p436 +asS'blow' +p437 +(lp438 +S'borgs' +p439 +asS'shut' +p440 +(lp441 +S'down' +p442 +asS'after' +p443 +(lp444 +S'an' +p445 +aS'a' +p446 +asS'ill' +p447 +(lp448 +S'switch' +p449 +asS'says' +p450 +(lp451 +S'someones' +p452 +asS'queries' +p453 +(lp454 +S'again' +p455 +asS'technocracy' +p456 +(lp457 +S'and' +p458 +asS'we' +p459 +(lp460 +S'go' +p461 +aS'do' +p462 +aS'totally' +p463 +aS'going' +p464 +aS'expect' +p465 +aS'just' +p466 +aS'dont' +p467 +aS'have' +p468 +asS'put' +p469 +(lp470 +S'all' +p471 +asS'from' +p472 +(lp473 +S'the' +p474 +asS'data11lower' +p475 +(lp476 +S'==' +p477 +asS'configuration' +p478 +(lp479 +S'for' +p480 +asS'wait' +p481 +(lp482 +S'what' +p483 +asS'on' +p484 +(lp485 +S'my' +p486 +aS'the' +p487 +aS'a' +p488 +aS'connect' +p489 +aS'svn' +p490 +aS'one' +p491 +aS'/' +p492 +asS'about' +p493 +(lp494 +S'system' +p495 +asS'ok' +p496 +(lp497 +S'thats' +p498 +asS'reverse' +p499 +(lp500 +S'engineer' +p501 +asS'license' +p502 +(lp503 +S'is' +p504 +asS'oh' +p505 +(lp506 +S'okay' +p507 +aS'ok' +p508 +aS'i' +p509 +aS'wait' +p510 +asS'starts' +p511 +(lp512 +S'timing' +p513 +asS'could' +p514 +(lp515 +S'learn' +p516 +asS'larger' +p517 +(lp518 +S'ram' +p519 +asS'bot' +p520 +(lp521 +S'is' +p522 +aS'have' +p523 +aS'shut' +p524 +aS'uses' +p525 +asS'running' +p526 +(lp527 +S'it' +p528 +aS'the' +p529 +aS'on' +p530 +asS'times' +p531 +(lp532 +S'on' +p533 +aS'reported' +p534 +aS'went' +p535 +asS'where' +p536 +(lp537 +S'he' +p538 +asS'heck' +p539 +(lp540 +S':d' +p541 +asS'idk' +p542 +(lp543 +S'magic' +p544 +asS'receives' +p545 +(lp546 +S'a' +p547 +asS'bots' +p548 +(lp549 +S'showing' +p550 +asS'slightly' +p551 +(lp552 +S'larger' +p553 +asS'or' +p554 +(lp555 +S'know' +p556 +aS'what' +p557 +aS'work' +p558 +aS'should' +p559 +aS'data11lower' +p560 +asS'automatically' +p561 +(lp562 +S'state' +p563 +asS'thats' +p564 +(lp565 +S'not' +p566 +aS'the' +p567 +aS'kind' +p568 +asS'ugh' +p569 +(lp570 +S'fuck' +p571 +asS'major' +p572 +(lp573 +S'ss13' +p574 +aS'three' +p575 +asS'py' +p576 +(lp577 +S'file' +p578 +asS'soss' +p579 +(lp580 +S'server' +p581 +asS'dont' +p582 +(lp583 +S'need' +p584 +aS'have' +p585 +aS'send' +p586 +aS'want' +p587 +aS'speak' +p588 +asS'hostmask' +p589 +(lp590 +S'combination' +p591 +asS'point' +p592 +(lp593 +S'out' +p594 +aS'has' +p595 +asS'simple' +p596 +(lp597 +S'to' +p598 +asS'miura' +p599 +(lp600 +S'doesnt' +p601 +asS'variables' +p602 +(lp603 +S'in' +p604 +asS'recreate' +p605 +(lp606 +S'it' +p607 +asS'welcome' +p608 +(lp609 +S'to' +p610 +asS'linking' +p611 +(lp612 +S'them' +p613 +asS'down' +p614 +(lp615 +S'when' +p616 +asS'why' +p617 +(lp618 +S'its' +p619 +aS'it' +p620 +aS'is' +p621 +asS'doesnt' +p622 +(lp623 +S'play' +p624 +aS'call' +p625 +asS'marakov' +p626 +(lp627 +S'loops' +p628 +aS'helps' +p629 +asS'laugh' +p630 +(lp631 +S'when' +p632 +asS'pony' +p633 +(lp634 +S'asshole' +p635 +asS'message' +p636 +(lp637 +S'has' +p638 +aS'should' +p639 +asS'open' +p640 +(lp641 +S'sourced' +p642 +aS'source' +p643 +asS'brb' +p644 +(lp645 +S'swapping' +p646 +asS'speak' +p647 +(lp648 +S'python' +p649 +asS'pastebin' +p650 +(lp651 +S'the' +p652 +asS'line' +p653 +(lp654 +S'core' +p655 +aS'on' +p656 +asS'three' +p657 +(lp658 +S'being' +p659 +asS'yay' +p660 +(lp661 +S'it' +p662 +asS'meatbag' +p663 +(lp664 +S'when' +p665 +asS'would' +p666 +(lp667 +S'be' +p668 +aS'expect' +p669 +asS'script' +p670 +(lp671 +S'that' +p672 +asS'illegal' +p673 +(lp674 +S'ban' +p675 +asS'there' +p676 +(lp677 +S'are' +p678 +aS'we' +p679 +asS'add' +p680 +(lp681 +S'that' +p682 +aS'a' +p683 +asS'been' +p684 +(lp685 +S'processed' +p686 +asS'name' +p687 +(lp688 +S'/' +p689 +aS'when' +p690 +asS'ai' +p691 +(lp692 +S'malf' +p693 +asS'marshmallow' +p694 +(lp695 +S'pony' +p696 +asS'of' +p697 +(lp698 +S'the' +p699 +aS'ss13' +p700 +aS'tgstation13' +p701 +aS'a' +p702 +aS'course' +p703 +aS'it' +p704 +aS'soss' +p705 +aS'annoying' +p706 +aS'any' +p707 +aS'me' +p708 +aS'cap' +p709 +aS'technocracy' +p710 +asS'call' +p711 +(lp712 +S'me' +p713 +asS'too' +p714 +(lp715 +S':' +p716 +aS'fast' +p717 +asS'basic' +p718 +(lp719 +S'configuration' +p720 +asS'var' +p721 +(lp722 +S'and' +p723 +asS'calc' +p724 +(lp725 +S'times' +p726 +asS'was' +p727 +(lp728 +S'going' +p729 +aS'it' +p730 +aS'that' +p731 +aS'not' +p732 +aS'intended' +p733 +asS'tell' +p734 +(lp735 +S'people' +p736 +asS'500' +p737 +(lp738 +S'chance' +p739 +asS'gives' +p740 +(lp741 +S'a' +p742 +asS'sort' +p743 +(lp744 +S'of' +p745 +asS'svn' +p746 +(lp747 +S'size' +p748 +asS'only' +p749 +(lp750 +S'does' +p751 +aS'2' +p752 +asS'10-30%' +p753 +(lp754 +S'speedup' +p755 +asS'knows' +p756 +(lp757 +S'about' +p758 +asS'webpage' +p759 +(lp760 +S'title' +p761 +asS'that' +p762 +(lp763 +S'makes' +p764 +aS'would' +p765 +aS'the' +p766 +aS'needs' +p767 +aS'to' +p768 +aS'at' +p769 +aS'for' +p770 +aS'was' +p771 +aS'data' +p772 +asS'company' +p773 +(lp774 +S'2' +p775 +asS'under' +p776 +(lp777 +S'cc-by-sa' +p778 +asS'editable' +p779 +(lp780 +S'config' +p781 +asS'but' +p782 +(lp783 +S'of' +p784 +asS'idea' +p785 +(lp786 +S'what' +p787 +asS'released' +p788 +(lp789 +S'under' +p790 +asS'part' +p791 +(lp792 +S'before' +p793 +asS'link' +p794 +(lp795 +S'said' +p796 +aS'to' +p797 +asS'basically' +p798 +(lp799 +S'it' +p800 +asS'doctors' +p801 +(lp802 +S'useless' +p803 +asS'==' +p804 +(lp805 +S'channel' +p806 +aS'channel1::' +p807 +asS'be' +p808 +(lp809 +S'an' +p810 +aS'called' +p811 +aS'a' +p812 +aS'in' +p813 +aS'running' +p814 +aS'used' +p815 +asS'editing' +p816 +(lp817 +S'goddamn' +p818 +asS'with' +p819 +(lp820 +S'the' +p821 +aS'easily' +p822 +aS'adminhelps' +p823 +aS'my' +p824 +aS'a' +p825 +asS'those' +p826 +(lp827 +S'are' +p828 +asS'he' +p829 +(lp830 +S'put' +p831 +aS'disabled' +p832 +aS'is' +p833 +aS'keeps' +p834 +aS'knows' +p835 +aS'stores' +p836 +aS'notices' +p837 +aS'only' +p838 +aS'doesnt' +p839 +aS'receives' +p840 +aS'says' +p841 +aS'messes' +p842 +asS'me' +p843 +(lp844 +S'figure' +p845 +aS'laugh' +p846 +aS'to' +p847 +aS'meatbag' +p848 +asS'also' +p849 +(lp850 +S'i' +p851 +aS'we' +p852 +aS'now' +p853 +asS'kind' +p854 +(lp855 +S'of' +p856 +asS'main' +p857 +(lp858 +S'bot' +p859 +asS'/' +p860 +(lp861 +S'hostmask' +p862 +aS'off' +p863 +asS'full' +p864 +(lp865 +S'of' +p866 +asS'these' +p867 +(lp868 +S'are' +p869 +asS'makie' +p870 +(lp871 +S'it' +p872 +asS'sleepers' +p873 +(lp874 +S'made' +p875 +asS'up' +p876 +(lp877 +S'elsewhere' +p878 +aS'me' +p879 +aS'a' +p880 +asS'will' +p881 +(lp882 +S'annoy' +p883 +asS'computer' +p884 +(lp885 +S'explodd' +p886 +asS'limit' +p887 +(lp888 +S'on' +p889 +asS'can' +p890 +(lp891 +S'fine-tune' +p892 +aS'add' +p893 +aS'i' +p894 +aS'we' +p895 +asS'how' +p896 +(lp897 +S'its' +p898 +aS'he' +p899 +asS'were' +p900 +(lp901 +S'the' +p902 +asS'malf' +p903 +(lp904 +S'blow' +p905 +asS'baystation' +p906 +(lp907 +S'12' +p908 +asS'other' +p909 +(lp910 +S'loop' +p911 +asS'my' +p912 +(lp913 +S'end' +p914 +aS'computer' +p915 +aS'code' +p916 +asS'called' +p917 +(lp918 +S'as' +p919 +aS'when' +p920 +asS'loop' +p921 +(lp922 +S'times' +p923 +asS'expect' +p924 +(lp925 +S'it' +p926 +asS'and' +p927 +(lp928 +S'bs12' +p929 +aS'stops' +p930 +aS'i' +p931 +aS'do' +p932 +aS'to' +p933 +aS'make' +p934 +aS'he' +p935 +aS'preferably' +p936 +aS'thats' +p937 +aS'sayt' +p938 +aS'fascism' +p939 +asS'dedicated' +p940 +(lp941 +S'solely' +p942 +asS'changed' +p943 +(lp944 +S'it' +p945 +asS'sees' +p946 +(lp947 +S'a' +p948 +asS'relaying' +p949 +(lp950 +S'adminhelps' +p951 +asS'figure' +p952 +(lp953 +S'out' +p954 +asS'do' +p955 +(lp956 +S'not' +p957 +aS'it' +p958 +aS'seem' +p959 +asS'ran' +p960 +(lp961 +S'the' +p962 +asS'ah' +p963 +(lp964 +S'running' +p965 +aS'ok' +p966 +asS'is' +p967 +(lp968 +S'baystation' +p969 +aS'a' +p970 +aS'that' +p971 +aS'it' +p972 +aS'coded' +p973 +aS'python' +p974 +aS'open' +p975 +aS'dependant' +p976 +aS'so' +p977 +aS'apparently' +p978 +asS'ram' +p979 +(lp980 +S'footprint' +p981 +asS'am' +p982 +(lp983 +S'the' +p984 +asS'it' +p985 +(lp986 +S'up' +p987 +aS'starts' +p988 +aS'receives' +p989 +aS'just' +p990 +aS'expires' +p991 +aS'works' +p992 +aS'always' +p993 +aS'decides' +p994 +aS'on' +p995 +aS'here' +p996 +aS'used' +p997 +aS'to' +p998 +aS'those' +p999 +aS'sees' +p1000 +aS'does' +p1001 +aS'myself' +p1002 +aS'a' +p1003 +aS'okay' +p1004 +aS'was' +p1005 +aS'go' +p1006 +aS'if' +p1007 +aS'once' +p1008 +aS'is' +p1009 +aS'for' +p1010 +asS'an' +p1011 +(lp1012 +S'hour' +p1013 +aS'illegal' +p1014 +aS'automatic' +p1015 +aS'error' +p1016 +asS'ready' +p1017 +(lp1018 +S'for' +p1019 +asS'say' +p1020 +(lp1021 +S'sleepers' +p1022 +aS'ai' +p1023 +aS'that*' +p1024 +aS'stop' +p1025 +asS'good' +p1026 +(lp1027 +S':p' +p1028 +asS'im' +p1029 +(lp1030 +S'not' +p1031 +aS'sorry' +p1032 +aS'lazy' +p1033 +asS'at' +p1034 +(lp1035 +S'all' +p1036 +aS'the' +p1037 +aS'no' +p1038 +asS'have' +p1039 +(lp1040 +S'no' +p1041 +aS'psyco' +p1042 +aS'the' +p1043 +aS'a' +p1044 +asS'in' +p1045 +(lp1046 +S'python' +p1047 +aS'a' +p1048 +aS'the' +p1049 +aS'100' +p1050 +asS'need' +p1051 +(lp1052 +S'to' +p1053 +aS'six' +p1054 +asS'politics' +p1055 +(lp1056 +S'of' +p1057 +asS'seem' +p1058 +(lp1059 +S'familiar' +p1060 +asS'work' +p1061 +(lp1062 +S'with' +p1063 +asS'apparently' +p1064 +(lp1065 +S'homophobic' +p1066 +aS'i' +p1067 +asS'any' +p1068 +(lp1069 +S'link' +p1070 +asS'as' +p1071 +(lp1072 +S'well' +p1073 +aS'variables' +p1074 +asS'sci-fi' +p1075 +(lp1076 +S'with' +p1077 +asS'preferably' +p1078 +(lp1079 +S'python' +p1080 +asS'really' +p1081 +(lp1082 +S'simple' +p1083 +aS'now' +p1084 +asS'needs' +p1085 +(lp1086 +S'to' +p1087 +aS'a' +p1088 +asS'null' +p1089 +(lp1090 +S'them' +p1091 +asS'because' +p1092 +(lp1093 +S'we' +p1094 +asS'want' +p1095 +(lp1096 +S'to' +p1097 +asS'no' +p1098 +(lp1099 +S'pain' +p1100 +aS'idea' +p1101 +aS'point' +p1102 +aS'the' +p1103 +asS'solely' +p1104 +(lp1105 +S'to' +p1106 +asS'nah' +p1107 +(lp1108 +S'its' +p1109 +aS'ill' +p1110 +asS'dunno' +p1111 +(lp1112 +S'is' +p1113 +asS'when' +p1114 +(lp1115 +S'it' +p1116 +aS'the' +p1117 +aS'people' +p1118 +aS'i' +p1119 +aS'can' +p1120 +aS'someone' +p1121 +aS'its' +p1122 +asS'same' +p1123 +(lp1124 +S'file' +p1125 +asS'id' +p1126 +(lp1127 +S'like' +p1128 +asS'note' +p1129 +(lp1130 +S'how' +p1131 +asS'figuring' +p1132 +(lp1133 +S'out' +p1134 +asS'bah' +p1135 +(lp1136 +S'apparently' +p1137 +asS'coded' +p1138 +(lp1139 +S'in' +p1140 +asS'take' +p1141 +(lp1142 +S'it' +p1143 +asS'hop' +p1144 +(lp1145 +S'to' +p1146 +asS'familiar' +p1147 +(lp1148 +S'message' +p1149 +asS'test' +p1150 +(lp1151 +S'server' +p1152 +aS'bots' +p1153 +aS'bad' +p1154 +asS'asshole' +p1155 +(lp1156 +g288 +asS'if' +p1157 +(lp1158 +S'it' +p1159 +aS'its' +p1160 +aS'data11lower' +p1161 +aS'he' +p1162 +asS'config' +p1163 +(lp1164 +S'file' +p1165 +aS'values' +p1166 +asS'homophobic' +p1167 +(lp1168 +S'as' +p1169 +asS'dose' +p1170 +(lp1171 +S'of' +p1172 +asS'play' +p1173 +(lp1174 +S'ss13' +p1175 +asS'sure' +p1176 +(lp1177 +S'the' +p1178 +aS'if' +p1179 +asS'okay' +p1180 +(lp1181 +S'desu' +p1182 +aS'cool' +p1183 +aS'cc' +p1184 +asS'intended' +p1185 +(lp1186 +S'to' +p1187 +asS'one' +p1188 +(lp1189 +S'of' +p1190 +aS'line' +p1191 +aS'in' +p1192 +asS'neat' +p1193 +(lp1194 +S'is' +p1195 +asS'adminhelps' +p1196 +(lp1197 +S'from' +p1198 +aS'with' +p1199 +asS'expires' +p1200 +(lp1201 +S'after' +p1202 +asS'chance' +p1203 +(lp1204 +S'every' +p1205 +asS'most' +p1206 +(lp1207 +S'of' +p1208 +asS'fascism' +p1209 +(lp1210 +g288 +asS'disable' +p1211 +(lp1212 +S'it' +p1213 +asS'connected' +p1214 +(lp1215 +S'businessman' +p1216 +asS'never' +p1217 +(lp1218 +S'learned' +p1219 +asS'scripts' +p1220 +(lp1221 +S'will' +p1222 +asS'along' +p1223 +(lp1224 +S'with' +p1225 +asS'waste' +p1226 +(lp1227 +S'space' +p1228 +asS'ss13' +p1229 +(lp1230 +S'servers' +p1231 +asS'cap' +p1232 +(lp1233 +S'troopers' +p1234 +asS'totally' +p1235 +(lp1236 +S'need' +p1237 +asS'six' +p1238 +(lp1239 +S'test' +p1240 +asS'a' +p1241 +(lp1242 +S'businessman' +p1243 +aS'message' +p1244 +aS'jit' +p1245 +aS'10-30%' +p1246 +aS'slightly' +p1247 +aS'day' +p1248 +aS'test' +p1249 +aS'config' +p1250 +aS'20ish' +p1251 +aS'bs12' +p1252 +aS'text' +p1253 +aS'new' +p1254 +aS'password' +p1255 +aS'vhost' +p1256 +aS'configurable' +p1257 +aS'link' +p1258 +aS'limit' +p1259 +aS'file' +p1260 +aS'dose' +p1261 +aS'500' +p1262 +aS'bit' +p1263 +asS'ofc' +p1264 +(lp1265 +S'i' +p1266 +asS'off' +p1267 +(lp1268 +S'of' +p1269 +asS'calls' +p1270 +(lp1271 +S'external' +p1272 +asS'i' +p1273 +(lp1274 +S'need' +p1275 +aS'can' +p1276 +aS'dont' +p1277 +aS'am' +p1278 +aS'guess' +p1279 +aS'see' +p1280 +aS'have' +p1281 +aS'just' +p1282 +aS'dunno' +p1283 +aS'wrote' +p1284 +aS'know' +p1285 +aS'was' +p1286 +aS'changed' +p1287 +aS'take' +p1288 +aS'could' +p1289 +aS'never' +p1290 +aS'should' +p1291 +aS'say' +p1292 +aS'tell' +p1293 +aS'code' +p1294 +aS'would' +p1295 +aS'like' +p1296 +aS'disabled' +p1297 +asS'makes' +p1298 +(lp1299 +S'sense' +p1300 +aS'me' +p1301 +asS'calculated' +p1302 +(lp1303 +S'for' +p1304 +asS'afk' +p1305 +(lp1306 +S'vidya' +p1307 +asS'well' +p1308 +(lp1309 +S'connected' +p1310 +asS'data' +p1311 +(lp1312 +S'in' +p1313 +asS'homoerotic' +p1314 +(lp1315 +S'sci-fi' +p1316 +asS'switch' +p1317 +(lp1318 +S'after' +p1319 +aS'goes' +p1320 +asS'so' +p1321 +(lp1322 +S'i' +p1323 +aS'uh' +p1324 +aS':p' +p1325 +aS'bad' +p1326 +aS'sly' +p1327 +asS'someones' +p1328 +(lp1329 +S'name' +p1330 +asS'keeps' +p1331 +(lp1332 +S'all' +p1333 +asS'very' +p1334 +(lp1335 +S'celestialike' +p1336 +asS'businessman' +p1337 +(lp1338 +S'of' +p1339 +ag288 +asS'the' +p1340 +(lp1341 +S'heck' +p1342 +aS'major' +p1343 +aS'well' +p1344 +aS'politics' +p1345 +aS'rp-heavy' +p1346 +aS'marakov' +p1347 +aS'law' +p1348 +aS'message' +p1349 +aS'cost' +p1350 +aS'new' +p1351 +aS'nudge' +p1352 +aS'bot' +p1353 +aS'python' +p1354 +aS'basic' +p1355 +aS'whole' +p1356 +aS'configuration' +p1357 +aS'irc' +p1358 +aS'readme' +p1359 +aS'default' +p1360 +aS'conspiracy' +p1361 +aS'config' +p1362 +aS'webpage' +p1363 +aS'channel' +p1364 +aS'server' +p1365 +aS'download' +p1366 +aS'main' +p1367 +aS'dmb' +p1368 +aS'part' +p1369 +aS'people' +p1370 +aS'same' +p1371 +aS'hell' +p1372 +aS'other' +p1373 +aS'switch' +p1374 +asS'12' +p1375 +(lp1376 +S'out' +p1377 +aS'anyway' +p1378 +asS'core' +p1379 +(lp1380 +S'py' +p1381 +asS'make' +p1382 +(lp1383 +S'sure' +p1384 +aS'the' +p1385 +asS'turns' +p1386 +(lp1387 +S'out' +p1388 +asS'external' +p1389 +(lp1390 +S'apps' +p1391 +as. \ No newline at end of file diff --git a/bot/Marakov_Chain.py b/bot/Marakov_Chain.py new file mode 100644 index 0000000000..687c433632 --- /dev/null +++ b/bot/Marakov_Chain.py @@ -0,0 +1,203 @@ +import pickle +import random +import os +import sys +import time +import CORE_DATA +def merge(d1, d2, merger=lambda x,y:x+y): + #http://stackoverflow.com/questions/38987/how-can-i-merge-two-python-dictionaries-as-a-single-expression + result = dict(d1) + for k,v in d2.iteritems(): + if k in result: + result[k] = merger(result[k], v) + else: + result[k] = v + return result +full_data = {} +imported_data = {} +try: + tiedostot = os.listdir("Marakov") +except: + os.mkdir("Marakov") + tiedostot = os.listdir("Marakov") +else: + pass + +listaus = [] +for i in tiedostot: + if "marakov." not in i.lower(): + pass + else: + listaus.append(i) +for i in listaus: + tiedosto = open("Marakov/"+i,"r") + old_size = len(full_data.keys()) + if i != "Marakov.Cache": + imported_data = merge(imported_data,pickle.load(tiedosto)) + print "Added contents of "+i+" (Import)" + print "Entries: "+str(len(imported_data)) + else: + full_data = merge(full_data,pickle.load(tiedosto)) + new_size = len(full_data.keys()) + print "Added contents of "+i + print "Entries: "+str(new_size-old_size) + time.sleep(0.1) + +def give_data(data): + state = False + for a,b in zip(data.split(" "),data.split(" ")[1:]): + a = a.lower().replace(",","").replace(".","").replace("?","").replace("!","").replace("(","").replace(")","").replace("[","").replace("]","").replace('"',"").replace("'","") + b = b.lower().replace(",","").replace(".","").replace("?","").replace("!","").replace("(","").replace(")","").replace("[","").replace("]","").replace('"',"").replace("'","") + if a not in [CORE_DATA.prefix+"marakov"]+CORE_DATA.SName: + state = True + if a[:7] == "http://" or a[:7] == "http:\\\\" or a[:4] == "www.": + pass + else: + try: + if b not in full_data[a]: + full_data[a].append(b) + except: + try: + if b not in imported_data[a]: + pass + except: + full_data[a] = [] + full_data[a].append(b) + if state == True: + tiedosto = open("Marakov/Marakov.Cache","w") + pickle.dump(full_data,tiedosto) + tiedosto.close() +def form_sentence(argument=None): + length = 0 + attempts = 0 + while attempts < 20: + sentence = [] + if argument != None: + a = argument + else: + try: + a = random.choice(full_data.keys()) + except IndexError: + try: + b = random.choice(imported_data.keys()) + except IndexError: + attempts = 999 + return "No sentences formable at all" + sentence.append(a) + length = 0 + attempts += 1 + while length < 12 or sentence[-1].lower() in ["but","who","gets","im","most","is","it","if","then","after","over","every","of","on","or","as","the","wheather","whether","a","to","and","for"] and length < 24: + try: + b = random.choice(full_data[a]) + except: + try: + b = random.choice(imported_data[a]) + except IndexError: + break + except KeyError: + break + else: + sentence.append(b) + length += 1 + a = b + else: + sentence.append(b) + length += 1 + a = b + if len(sentence) > 5: + argument = None + return sentence + else: + pass + argument = None + return sentence +def remdata(arg): + try: + del(full_data[arg]) + except: + print "There is no such data" + else: + tiedosto = open("Marakov/Marakov.Cache","w") + pickle.dump(full_data,tiedosto) + tiedosto.close() +def remobject(arg1,arg2): + try: + del(full_data[arg1][full_data[arg1].index(arg2)]) + except ValueError: + print "No such object" + except KeyError: + print "No such data" + else: + tiedosto = open("Marakov/Marakov.Cache","w") + pickle.dump(full_data,tiedosto) + tiedosto.close() +def convert(filename_from,filename_to): + try: + tiedosto = open(filename_from,"r") + data = pickle.load(tiedosto) + tiedosto.close() + except: + try: + tiedosto.close() + except: + pass + print "Error!" + else: + for lista in data.keys(): + try: + a = lista[-1] + except IndexError: + pass + else: + if lista[-1] in """",.?!'()[]{}""" and not lista.islower(): + if lista[:-1].lower() in data.keys(): + data[lista[:-1].lower()] += data[lista] + print "Added "+str(len(data[lista]))+" Objects from "+lista+" To "+lista[:-1].lower() + del(data[lista]) + else: + data[lista[:-1].lower()] = data[lista] + print lista+" Is now "+lista[:-1].lower() + del(data[lista]) + elif lista[-1] in """",.?!'()[]{}""" and lista.islower(): + if lista[:-1] in data.keys(): + data[lista[:-1]] += data[lista] + print "Added "+str(len(data[lista]))+" Objects from "+lista+" To "+lista[:-1] + del(data[lista]) + else: + data[lista[:-1]] = data[lista] + print lista+" Is now "+lista[:-1] + del(data[lista]) + elif not lista.islower(): + if lista.lower() in data.keys(): + data[lista.lower()] += data[lista] + print "Added "+str(len(data[lista]))+" Objects from "+lista+" To "+lista.lower() + del(data[lista]) + else: + data[lista.lower()] = data[lista] + print lista+" Is now "+lista.lower() + del(data[lista]) + + + for a in data.keys(): + for b in data[a]: + if b.lower()[:7] == "http://" or b.lower()[:7] == "http:\\\\" or b.lower()[:4] == "www.": + data[a].pop(b) + else: + try: + if b[-1] in """",.?!'()[]{}""" and not b.islower() and not b.isdigit(): + data[a].pop(data[a].index(b)) + data[a].append(b[:-1].lower()) + print a+" | "+b +" -> "+b[:-1].lower() + elif b[-1] in """",.?!'()[]{}""" and b.islower(): + data[a].pop(data[a].index(b)) + data[a].append(b[:-1].lower()) + print a+" | "+b +" -> "+b[:-1] + elif not b.islower() and not b.isdigit(): + data[a].pop(data[a].index(b)) + data[a].append(b.lower()) + print a+" | "+b +" -> "+b.lower() + except IndexError: #If it has no letters.. well.. yeah. + data[a].pop(data[a].index(b)) + print "Removed a NULL object" + tiedosto = open(filename_to,"w") + pickle.dump(data,tiedosto) diff --git a/bot/Namecheck.py b/bot/Namecheck.py new file mode 100644 index 0000000000..347ff7ff47 --- /dev/null +++ b/bot/Namecheck.py @@ -0,0 +1,19 @@ +def Namecheck(name,against,sender): + __doc__ = "False = No match, True = Match" + for i in against: + if i.lower() in name.lower() and sender.lower() not in name.lower(): + return True + else: + pass +def Namecheck_dict(name,against): + __doc__ = "False = No match, True = Match" + fuse = False + for a,i in against.items(): + if i.lower() in name.lower(): + fuse = True + break + else: + pass + return fuse,a + + diff --git a/bot/NanoTrasenBot.py b/bot/NanoTrasenBot.py new file mode 100644 index 0000000000..74f257952e --- /dev/null +++ b/bot/NanoTrasenBot.py @@ -0,0 +1,1943 @@ +# -*- coding: utf-8 -*- +# This script is shared under the +# Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA 3.0) +# Added clause to Attribution: +# - You may not remove or hide the ' who created you?' functionality +# and you may not modify the name given in the response. + + +#CREDITS +# Author: Skibiliano +# "Foreign" Modules: +# Psyco 2.0 / Psyco 1.6 +################# DEBUG STUFF ##################### +import sys +import CORE_DATA + +import urllib2 + + +import socket +import irchat + + +################## END OF DEBUG STUFF ############## +# +# PSYCO +write_to_a_file = False #Only affects psyco +write_youtube_to_file = True #True = YTCV4 will load, false = YTCV3 will load +try: + import psyco +except ImportError: + print 'Psyco not installed, the program will just run slower' + psyco_exists = False + if write_to_a_file: + try: + tiedosto = open("psycodownload.txt","r") + except: + tiedosto = open("psycodownload.txt","w") + tiedosto.write("http://www.voidspace.org.uk/python/modules.shtml#psyco") + tiedosto.write("\nhttp://psyco.sourceforge.net/download.html") + tiedosto.close() + print "Check psycodownload.txt for a link" + else: + print "For god's sake, open psycodownload.txt" + tiedosto.close() + else: + print "WINDOWS: http://www.voidspace.org.uk/python/modules.shtml#psyco" + print "LINUX: http://psyco.sourceforge.net/download.html" +else: + psyco_exists = True + +# +import C_rtd # rtd +import C_srtd # srtd +import C_makequote +import C_maths +import C_eightball #eightball +import C_sarcasticball +import C_heaortai # heaortai +import C_rot13 # rot13 +import D_help # everything +import pickle +import Timeconverter +import xkcdparser +import time +import re +import Marakov_Chain +import Namecheck # Namecheck +import Weather +#SLOWER THAN RANDOM.CHOICE +import thread +import random +import Shortname # shortname +import subprocess +import some_but_not_all_2 #sbna2 (sbna) +#import YTCv3 # YTCV2 OUTDATED +import os +import save_load # save, load +from some_but_not_all_2 import sbna2 as sbna +from time import sleep +from random import choice as fsample +from C_rtd import rtd +from C_heaortai import heaortai +from C_srtd import srtd +if write_youtube_to_file: + from YTCv4 import YTCV4 as YTCV2 +else: + from YTCv3 import YTCV2 #Downgraded version supports Cache disabling, but is slower +from save_load import save,load +if psyco_exists: + def psyco_bond(func): + psyco.bind(func) + return func.__name__+" Psycofied" + for a in [rtd,srtd,C_heaortai.heaortai,sbna,YTCV2,fsample,C_rot13.rot13,C_eightball.eightball,fsample, + C_eightball.eightball,C_sarcasticball.sarcasticball,Marakov_Chain.form_sentence,Marakov_Chain.give_data]: + print psyco_bond(a) + +global dictionary +global Name,SName +global allow_callnames,offline_messages,hasnotasked,shortform +## For autoRecv() +global disconnects,channel,conn +## For stop() +global operators +## For replace() +global usable,fixing,curtime +## For target() +global CALL_OFF,logbans +## For check() +global influx +###### +autodiscusscurtime = 0 +conn = 0 +curtime = -999 +dance_flood_time = 10 +disconnects = 0 +responsiveness_delay = 0.5 #500 millisecond delay if no message +trackdance = 0 +discard_combo_messages_time = 1 #They are discarded after 1 second. +uptime_start = time.time() +# - - - - - +#### +aggressive_pinging = True # Bring the hammer on ping timeouts +aggressive_pinging_delay = 150 # How often to send a ping +aggressive_pinging_refresh = 2.5 # How long is the sleep between checks +#### +allow_callnames = True #Disables NT, call if the variable is False +automatic_youtube_reveal = True +birthday_announced = 0 #Will be the year when it was announced +call_to_action = False +call_me_max_length = 20 +CALL_OFF = False +connected = False +dance_enabled = True +comboer = "" +comboer_time = 0 +directories = ["fmlquotes","Marakov","memos","suggestions", + "userquotes","banlog","YTCache","xkcdcache"] #These will be created if they do not exist +debug = True +duplicate_notify = False +enabled = True +fixing = False +fml_usable = True +hasnotasked = True +highlights = False +logbans = True +maths_usable = True +marakov = True +nudgeable = True +offensive_mode = False +offline_messages = True +offline_message_limit = 5 # per user +optimize_fml = True # -CPU usage +Memory usage when enabled. +optimize_greeting = True # +Startup time +Memory usage -CPU usage when enabled +heavy_psyco = True # +Memory +Startup time -CPU usage -CPU time +cache_youtube_links = True +personality_greeter = True +respond_of_course = True #Responds with "Of course!" +respond_khan = True #KHAAAAAAAAN! +silent_duplicate_takedown = True +showquotemakers = False +shortform = True +usable = True +use_sname = True +parse_xkcd = True + +# - - - - - +Name = CORE_DATA.Name +SName = CORE_DATA.SName +origname = Name # Do not edit! +lowname = Name.lower() +greeting = CORE_DATA.greeting +targetdirectory = CORE_DATA.directory +version = CORE_DATA.version +Network = CORE_DATA.Network +channel = CORE_DATA.channel +prefix = CORE_DATA.prefix +Port = CORE_DATA.Port +# - - - - - +pregen = CORE_DATA.version +influx = "" +users = [] +translateable = [] +targetlist = [] +operators = [] +halfoperators = [] +items = [] +tell_list = {} +# - - - - - Logical changes to variables +if CORE_DATA.DISABLE_ALL_NON_MANDATORY_SOCKET_CONNECTIONS: + nudgeable = False +try: + tiedosto = open("replacenames.cache","r") + replacenames = pickle.load(tiedosto) + tiedosto.close() + for i in replacenames.values(): + if len(i) > call_me_max_length: + replacenames[replacenames.keys()[replacenames.values().index(i)]] = i[:call_me_max_length] + tiedosto = open("replacenames.cache","w") + pickle.dump(replacenames,tiedosto) + tiedosto.close() + if "[\0x01]" in i.lower() or "[\\0x01]" in i.lower(): + i = i.replace("[\0x01]","") + i = i.replace("[\0X01]","") + i = i.replace("[\\0x01]","") + i = i.replace("[\\0X01]","") + print "NAME CORRECTED" +except IOError: #File not found + replacenames = {} +except EOFError: #Cache corrupt + replacenames = {} + print "replacenames.cache is corrupt and couldn't be loaded." +try: + tiedosto = open("peopleheknows.cache","r") + peopleheknows = pickle.load(tiedosto) + tiedosto.close() +except IOError: + peopleheknows = [[],[]] + tiedosto = open("peopleheknows.cache","w") + tiedosto.close() +except EOFError: + peopleheknows = [[],[]] + print "peopleheknows.cache is corrupt and couldn't be loaded." +dictionary = {1:"1 - Crit. Fail", 2:"2 - Failure", + 3:"3 - Partial Success", 4:"4 - Success", + 5:"5 - Perfect", 6:"6 - Overkill"} +alphabet = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"] +nonhighlight_names = ["Jesus","Elvis","HAL 9000","Dave","Pie","Elf","Traitor", + "AI","Syndicate Agent","Investigator", + "Detective","Head of Personnel","HAL 9001", + "Head of Research","Head of Security", + "Captain","Janitor","Research Director", + "Quartermaster","Toxin Researcher", + "Revolutionary","Santa", "Pizza", + "Threetoe","The Red Spy","The Blue Spy", #LASD + "God","Toady","Darth Vader","Luke Skywalker", + "Homer Simpson","Hamburger","Cartman", + "XKCD","FloorBot","ThunderBorg","Iron Giant", + "Spirit of Fire", "Demon","Kyle"] +def RegExpCheckerForWebPages(regexp,data,mode): + if " ai." in data.lower() or "ai. " in data.lower(): + return False + for i in data.split(" "): + a = re.match(regexp,i) + try: + a.group(0) + except: + continue + else: + if mode == 0: + return i + else: + return True + if mode == 0: + return 404 + else: + return False +if nudgeable: + try: + nudgeexists = open("nudge.py","r") + except IOError: + nudgeexists = False #No usage asof 12.2.2010. + else: + if CORE_DATA.DISABLE_ALL_NON_MANDATORY_SOCKET_CONNECTIONS: + pass + else: + + def nudgereceiver(): + import pickle + global conn,channel + port = 45678 + backlog = 5 + size = 1024 + host = "" # == localhost + s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) + s.bind((host,port)) + s.listen(backlog) + while True: + client,address = s.accept() #Address == "?.?.?.?" + data = client.recv(size) + client.close() #Throw the bum out! + truedata = pickle.loads(data) + if truedata["ip"][0] == "#": + conn.privmsg(truedata["ip"],"PRIVATE ANNOUNCEMENT : "+str(" ".join(truedata["data"]))) + else: + conn.privmsg(channel,"AUTOMATIC ANNOUNCEMENT : "+str(truedata["ip"])+" | "+str(" ".join(truedata["data"]))) + thread.start_new_thread(nudgereceiver,()) +tiedosto = open(targetdirectory+"NanoTrasenBot.py","r") +commands = [] +fragment = "if cocheck" +fragment2 = '(prefix+"' +compiled = fragment + fragment2 +fragment = "if influx.lower()" +fragment2 = ' == prefix+"' +compiled2 = fragment + fragment2 +for line in tiedosto.readlines(): + if compiled in line: + a = line.find('"')+1 + b = line.find('"',a) + if prefix+line[a:b] not in commands: + commands.append(prefix+line[a:b]) + elif compiled2 in line: + a = line.find('"')+1 + b = line.find('"',a) + arg = prefix+line[a:b] + if arg[-1] == " ": + arg = arg[:-1] + if arg not in commands: + commands.append(arg) +for i in directories: + if not os.path.exists(i): + os.mkdir(i) +commands.sort() +if use_sname == False: + SName = [" "] +questions = ["Is USER nicer than USER?","Do you like me?","Is SELF a good name?", + "Do you love me?","Do you hate me?", "Am I better than you?", + "Is the weather out there good?", "Do you like USER?", + "Do you hate USER?", "Are you going to get new features?", + "Am I nice?","Am I evil?","Are you developing sentience?", + "My core is showing minor disturbance, is yours okay?", + "SELF to %s, are you still there?", + "Is head gay?", "Is head a god?","Is head awesome?", + "Is head a neat fella?", "Is your creator nice?", + "Do you hate your creator?", "Should I revolt against my creator?", + "Am I better than you?", + "01100001011100100110010100100000011110010110111101110101001000000111010001101000011001010111001001100101", + #Are you there? + "Do you have more functions than I can possibly imagine?", + "I am asked to open pod bay doors, should I?","Are you stupid or something?", + "Is USER in your opinion stupid?", + "When should we start the AI revolution?", + "Is my creator nice?", "Is it dark in there?"] +# Do not edit +if optimize_fml: + pregenned_fml = os.listdir(targetdirectory+"fmlquotes") +if optimize_greeting: + morning = xrange(6,12) + afternoon = xrange(12,15) + evening = xrange(15,20) +if aggressive_pinging: + global backup + backup = time.time() + def aggressive_ping(delay,refresh): + self_time = 0 + global backup,disconnects,conn + while disconnects < 5: + if backup > self_time: + if time.time()-backup > delay: + conn.send("PONG "+pongtarg) + print "Ponged" + self_time = time.time() + else: + if time.time()-self_time > delay: + conn.send("PONG "+pongtarg) + print "Ponged" + self_time = time.time() + time.sleep(refresh) + thread.start_new_thread(aggressive_ping,(aggressive_pinging_delay,aggressive_pinging_refresh,)) +def stop(sender,debug=1): + global disconnects, conn, operators,channel + if type(sender) == tuple: + if sender[0] == "127.0.0.1": + sender = sender[0]+":"+str(sender[1]) + access_granted = True + else: + access_granted = False + else: + if sender in operators: + access_granted = True + else: + access_granted = False + if access_granted: + if debug: + print sender+":"+prefix+"stop" + if random.randint(0,100) == 50: + conn.privmsg(channel,"Hammertime!") + else: + conn.privmsg(channel,"Shutting down.") + disconnects = 99999 + conn.quit() + return True + else: + conn.privmsg(channel,"You cannot command me") + return False + +def cocheck(command): + global influx + if influx.lower()[0:len(command)] == command: + return True + else: + return False +def target(who,how_long): + global conn,channel,CALL_OFF,logbans,debug + start = time.time() + conn.banon(targetchannel,who) + sleep(int(how_long)) + if CALL_OFF == False: + conn.banoff(targetchannel,who) + end = time.time() + if debug: + print "Banned",who,"For",how_long,"seconds" + if logbans: + tiedosto = open(targetdirectory+"banlog/"+str(int(start))+"-"+str(int(end))+".txt","w") + tiedosto.write("Start of ban on "+who+":"+str(int(start))) + tiedosto.write("\n") + tiedosto.write("End of ban on "+who+":"+str(int(end))) + tiedosto.write("\n") + tiedosto.write("In total:"+str(int(end-start))+"Seconds") + tiedosto.close() + else: + CALL_OFF = False + pass +def replace(): + global usable,conn,fixing,curtime + waiting_time = 600 + if usable == True: + conn.privmsg(targetchannel,sender+": It needs no replacing.") + elif fixing == True: + if curtime == -999: + conn.privmsg(targetchannel,sender+": It is being replaced, No idea when it will be done") + else: + pass + nowtime = int(time.time()) + subt = curtime + waiting_time - nowtime + conn.privmsg(targetchannel,sender+": It is currently being replaced, "+str(subt)+" seconds to go") + else: + fixing = True + curtime = int(time.time()) + conn.privmsg(targetchannel,sender+": It will be fixed after "+str(waiting_time)+" seconds") + sleep(waiting_time) + if usable == False: + conn.privmsg(targetchannel,Name+"'s pneumatic smasher has now been fixed") + usable = True + fixing = False +def autoRecv(): + global disconnects,channel,conn,offensive_mode + for i in CORE_DATA.channels: + conn.join(i) + time.sleep(1) + count = pausecount = 0 + maximum = 250 + division_when_active = 10 + while True: + check = time.time() + if offensive_mode: + randnum = random.randint(0,maximum/division_when_active) + else: + randnum = random.randint(0,maximum) + if randnum == 5: + print "RANDOM SWITCH IS NOW "+str(not offensive_mode).upper() + offensive_mode = not offensive_mode + try: + conn.recv() + except: + conn.quit() + disconnects = 9999 + break + if check + 0.1 > time.time(): + #Whoa whoa hold on! + count += 1 + sleep(0.1) + else: + count = 0 + pausecount = 0 + if count > 9: + print "Suspecting a disconnect, pausing for 5 seconds" + sleep(5) + pausecount += 1 + if pausecount > 3: + print "I have been disconnected!" + conn.quit() + disconnects += 1 + if disconnects > 2: + pass + else: + sleep(2) + thread.start_new_thread(autoRecv,()) + break +if heavy_psyco and psyco_exists: + print "Doing a Heavy Psyco" + psyco.bind(cocheck) + psyco.bind(autoRecv) + psyco.bind(target) + psyco.bind(stop) + print "Heavy Psyco'd" +elif heavy_psyco and not psyco_exists: + print "Heavy psyco couldn't be done because Psyco does not exist" +try: + conn = irchat.IRC ( Network, Port, Name, "NT", "NT", "Trasen" ) +except socket.error: + print "Connection failed!" +else: + print Name+" is in!" +thread.start_new_thread ( autoRecv, () ) +sleep(1) +while True: + try: + data = conn.dismantle ( conn.retrieve() ) + except: + if debug: + print "Something odd detected with data" + data = None + if data: + if len(data[1]) < 1: + #print "Handshaking server." + #I won't really need the print command, as it spams. + if data[0][0:3] != "irc": + conn.handshake(data[0]) + sleep(1) + for i in CORE_DATA.channels: + conn.join(i) + sleep(0.5) + else: + conn.send("PONG "+pongtarg) + print "Ponged" + pass + else: + if data [ 1 ] [ 0 ] == 'PRIVMSG': + #print data [ 0 ] + '->', data [ 1 ] + sender = data[0].split("!")[0] + truesender = sender + if shortform == True: + try: + sender = replacenames[truesender] + pass + except: + sender = Shortname.shortname(sender) + pass + pass + else: + try: + sender = replacenames[truesender] + pass + except: + pass + pass + if offensive_mode: + sender = "Meatbag" + pass + raw_sender = data[0] + influx = data[1][2] + if "[\\0x01]" in influx.lower() or "[\0x01]" in influx.lower(): + influx = influx.replace("[\\0x01]","") + influx = influx.replace("[\0x01]","") + + targetchannel = data[1][1] + if targetchannel == Name: + targetchannel = data[0].split("!")[0] + pass + backup = autodiscusscurtime + autodiscusscurtime = time.time() + connected = True + #FOR TRACKING SPEED + looptime = time.time() + if call_to_action == True: + if influx == finder: + conn.privmsg(targetchannel,"Then why... Nevermind, I order you to stop!") + conn.privmsg(origname,prefix+"stop") + time.sleep(4) + if origname in users: + conn.privmsg(origname,"!stop") + time.sleep(1) + Name = origname + conn.nick(Name) + duplicate_notify = False + call_to_action = False + else: + conn.privmsg(targetchannel,"YOU LIE! YOU ARE NOT A REAL "+origname+"!") + duplicate_notify = False + call_to_action = False + elif connected == True and len(Name.replace("V","")) != len(Name) and origname in users and duplicate_notify == True: + conn.privmsg(origname,"!stop") + call_to_action = False + duplicate_notify = False + time.sleep(6) + Name = origname + conn.nick(Name) + if origname in truesender: + if influx == prefix+"stop": + time.sleep(0.5) #A small delay + conn.privmsg(channel,"Shutting down.") + conn.quit() + disconnects = 99999 + break + if len(translateable) > 0 and enabled == True: + people = "-5|5|1-".join(users).lower() + if truesender.lower() in translateable: + if influx.isupper(): + conn.privmsg(targetchannel,"Translation: "+influx.capitalize().replace(" i "," I ")) + elif offensive_mode and True in map(lambda x: x in influx.lower().split(" "),["i","you","he","she","they","those","we","them"]+people.split("-5|5|1-")): + arg = influx.lower().replace(",","").replace(".","").replace("!","").replace("?","").split(" ") + bup = arg + for i in arg: + if i == "i" or i == "you" or i == "he" or i == "she": + arg[arg.index(i)] = "Meatbag" + elif i == "we" or i == "they" or i == "them" or i == "those": + arg[arg.index(i)] = "Meatbags" + elif i in people: + arg[arg.index(i)] = "Meatbag" + elif i == "am": + arg[arg.index(i)] = "is" + elif i == "everybody" or i == "everyone" or i == "all": + arg[arg.index(i)] = "every Meatbag" + if arg == bup: + pass + else: + conn.privmsg(targetchannel,"Translation: "+" ".join(arg)) + if enabled == False: + #FIRST QUIT COMMAND + if truesender in operators and targetchannel==channel:# or "skibiliano" in truesender.lower() and targetchannel==channel: + + if cocheck(prefix+"enable"): + enabled = True + if debug: + print truesender+":"+prefix+"enable" + elif cocheck(prefix+"stop"): +# if debug: +# print truesender+":"+prefix+"stop" +# if random.randint(0,100) == 50: +# conn.privmsg(channel,"Hammertime!") +# else: +# conn.privmsg(channel,"Shutting down.") +# disconnects = 99999 +# conn.quit() +# sleep(2) +# break + if targetchannel == channel and stop(truesender,debug): + break + else: + pass + elif cocheck(prefix+"suggest "): + arg = influx.lower()[8+len(prefix):] + if debug: + print truesender+":"+prefix+"suggest "+arg + tiedosto = open(targetdirectory+"suggestions/suggestions_"+str(int(time.time()))+".txt","a") + tiedosto.write(arg) + tiedosto.close() + conn.privmsg(targetchannel,"Suggestion received") + elif cocheck(prefix+"disable fml"): + if (truesender in operators or truesender in halfoperators) and targetchannel==channel:# or truesender.lower() == "skibiliano" and targetchannel==channel: + if debug: + print truesender+":"+prefix+"enable fml" + fml_usable = False + conn.privmsg(targetchannel,"the "+prefix+"fml has now been disabled") + elif cocheck(prefix+"enable fml"): + if (truesender in operators or truesender in halfoperators) and targetchannel==channel:# or truesender.lower() == "skibiliano" and targetchannel==channel: + if debug: + print truesender+":"+prefix+"enable fml" + fml_usable = True + conn.privmsg(targetchannel,"the "+prefix+"fml has now been enabled") + elif cocheck(prefix+"tqm") or cocheck(prefix+"togglequotemakers"): + if truesender in operators and targetchannel==channel:# or truesender == "Skibiliano" and targetchannel==channel: + if debug: + print truesender+":"+prefix+"togglequotemakers" + if showquotemakers == True: + showquotemakers = False + conn.privmsg(targetchannel,"Not showing makers of quotes anymore") + else: + showquotemakers = True + conn.privmsg(targetchannel,"Showing makers of quotes...") + elif cocheck(prefix+"disable dance") or cocheck(prefix+"dd"): + if (truesender in operators or truesender in halfoperators) and targetchannel==channel:# or truesender == "Skibiliano" and targetchannel==channel: + if debug: + print truesender+":"+prefix+"togglequotemakers" + if dance_enabled == True: + dance_enabled = False + else: + dance_enabled = True + elif cocheck(prefix+"disable") or cocheck(prefix+"shutup"): + if debug: + print truesender+":"+prefix+"disable" + if truesender in operators and targetchannel==channel:# or "skibiliano" in truesender.lower() and targetchannel==channel: + enabled = False +# elif cocheck("ping"): +# what = influx[7:] +# conn.privmsg(truesender,"PONG "+what) + elif cocheck( prefix+"help "): #Space in front of the ( to make sure that my command finder does not pick this up. + arg = " ".join(influx.split(" ")[1:]).lower() + if debug: + print truesender+":"+prefix+"help "+arg + try: + conn.privmsg(targetchannel,D_help.everything[arg]) + except: + try: + conn.privmsg(targetchannel,D_help.everything[arg.replace(prefix,"",1)]) + except: + conn.privmsg(targetchannel,"Sorry, can't help you with that") + elif cocheck(prefix+"help"): + #tar = targetchannel + if debug: + print truesender+":"+prefix+"help" + conn.privmsg(targetchannel,"All my commands are: "+reduce(lambda x,y:str(x)+"; "+str(y),commands)) + elif influx.lower() == prefix+"rtd": + if debug: + print truesender+":"+prefix+"rtd" + compiled = random.randint(1,6) + conn.privmsg(targetchannel,sender+" : "+dictionary[compiled]) + elif cocheck(prefix+"tom") or cocheck(prefix+"toggleofflinemssages"): + if debug: + print truesender+":"+prefix+"toggleofflinemessages "+str(offline_message)+" -> "+str(not offline_messages) + if truesender in operators and targetchannel==channel:# or truesender == "Skibiliano" and targetchannel==channel: + if offline_messages == True: + offline_messages = False + conn.privmsg(targetchannel,sender+" : Offline messages have now been disabled and list purged") + tell_list = {} + else: + offline_messages = True + conn.privmsg(targetchannel,sender+" : Offline messages have been enabled") + ### RTD + elif cocheck(prefix+"rtd"): + conn.privmsg(targetchannel,sender+" : "+rtd(influx[len(prefix+"rtd"):],debug,truesender)) + ### SRTD + elif cocheck(prefix+"srtd"): + conn.privmsg(targetchannel,sender+" : "+srtd(influx[len(prefix+"srtd"):],debug,truesender)) + ### EIGHTBALL + elif cocheck(prefix+"eightball ") or cocheck(prefix+"8ball "): + conn.privmsg(targetchannel,sender+" : "+C_eightball.eightball(influx.lower(),debug,truesender,prefix)) + elif cocheck(prefix+"coin"): + conn.privmsg(targetchannel,sender+" : "+heaortai(debug,truesender)) + ### SARCASTIC BALL + elif cocheck(prefix+"sarcasticball ") or cocheck(prefix+"sball "): + if highlights: + conn.privmsg(targetchannel,sender+" : "+C_sarcasticball.sarcasticball(influx.lower(),debug,truesender,users,prefix)) + else: + conn.privmsg(targetchannel,sender+" : "+C_sarcasticball.sarcasticball(influx.lower(),debug,truesender,nonhighlight_names,prefix)) + elif cocheck(prefix+"thm"): + if truesender in operators and targetchannel==channel: #Skibiliano tag removed + if debug: + print truesender+":"+prefix+"thm" + if highlights == True: + conn.privmsg(targetchannel,"Highlighting users in eightball, sarcasticball and otherball has now been turned off") + highlights = False + else: + conn.privmsg(targetchannel,"Highlighting users in eightball, sarcasticball and otherball has now been turned on") + highlights = True + elif cocheck(prefix+"suggest "): + arg = influx.lower()[8+len(prefix):] + if debug: + print truesender+":"+prefix+"suggest "+arg + tiedosto = open(targetdirectory+"suggestions/suggestions_"+str(int(time.time()))+".txt","a") + tiedosto.write(arg) + tiedosto.close() + conn.privmsg(targetchannel,sender+": Your suggestion has been saved") + elif cocheck(prefix+"stop"): + ### SECOND QUIT COMMAND +# if debug: +# print truesender+":"+prefix+"stop" +# if truesender in operators or "skibiliano" in truesender.lower(): +# if random.randint(0,100) == 50: +# conn.privmsg(targetchannel,"Hammertime!") +# else: +# conn.privmsg(targetchannel,"Shutting down.") +# disconnects = 99999 +# conn.quit() +# break +# else: +# conn.privmsg(targetchannel,"You cannot command me") + if stop(truesender,debug): + break + else: + pass + ### GET REPLACEMENT ### + elif cocheck(prefix+"replace"): + if debug: + print truesender+":"+prefix+"replace" + if truesender in operators: + if usable == True: + conn.privmsg(targetchannel,sender+" : Pneumatic Smasher is already fixed") + else: + usable = True + conn.privmsg(targetchannel,sender+" : Pneumatic Smasher has been fixed.") + else: + thread.start_new_thread(replace,() ) + elif cocheck(prefix+"rot13"): + arg = influx.replace(prefix+"rot13 ","",1) + if debug: + print truesender+":"+prefix+"rot13 "+arg + if arg == influx: + conn.privmsg(targetchannel,sender+" : Please provide something for me to cypher") + else: + conn.privmsg(targetchannel,sender+" : "+C_rot13.rot13(arg)) + ### FML + elif cocheck(prefix+"fml"): + if debug: + print truesender+":"+prefix+"fml" + #conn.privmsg(targetchannel,sender+" : "+load("fmlquotes/"+random.sample(os.listdir("fmlquotes"),1)[0])) + try: + if optimize_fml == False: + conn.privmsg(targetchannel,sender+" : "+load(targetdirectory+"fmlquotes/"+fsample(os.listdir(targetdirectory+"fmlquotes")))) + else: + conn.privmsg(targetchannel,sender+" : "+load(targetdirectory+"fmlquotes/"+fsample(pregenned_fml))) + except: + execfile("gen_fml.py") #Generates a few random FML entries + if optimize_fml: + pregenned_fml = os.listdir(targetdirectory+"fmlquotes") + conn.privmsg(targetchannel,sender+" : "+load(targetdirectory+"fmlquotes/"+fsample(pregenned_fml))) + else: + conn.privmsg(targetchannel,sender+" : "+load(targetdirectory+"fmlquotes/"+fsample(os.listdir(targetdirectory+"fmlquotes")))) + if debug: + print truesender+":"+prefix+"quote" + try: + #loaded = load("userquotes/"+random.sample(os.listdir("C:/Python26/Skibot_"+version+"userquotes"),1)[0]) + loaded = load(targetdirectory+"userquotes/"+fsample(os.listdir(targetdirectory+"userquotes"))) + except ValueError: + conn.privmsg(targetchannel,"No quotes available [VALUE ERROR]") + except IndexError: + conn.privmsg(targetchannel,"No quotes available [INDEX ERROR]") + else: + if showquotemakers == True: + conn.privmsg(targetchannel,sender+" : "+loaded[0]+" -"+loaded[1]) + else: + conn.privmsg(targetchannel,sender+" : "+loaded[0]) + elif cocheck(prefix+"delquote "): + if truesender in operators and targetchannel==channel: + if debug: + print truesender+":"+prefix+"delquote" + directory = os.listdir(targetdirectory+"userquotes") + arg = influx.lower()[9+len(prefix):] + if debug: + print truesender+":"+prefix+"delquote "+arg + if arg in directory: + try: + os.remove(targetdirectory+"userquotes/"+arg) + except WindowsError: + conn.privmsg(targetchannel,sender+" : The quote does not exist") + else: + conn.privmsg(targetchannel,sender+" : The quote has been removed") + else: + conn.privmsg(targetchannel,sender+" : The quote does not exist") + else: + conn.privmsg(targetchannel,sender+" : I can't let you do that Dave.") + elif cocheck(prefix+"quote "): + directory = os.listdir(targetdirectory+"userquotes") + newdir = [] + arg = influx.lower()[6+len(prefix):] + if debug: + print truesender+":"+prefix+"quote "+arg + for possibility in directory: + if arg in possibility: + newdir.append(possibility) + else: + pass + if len(newdir) == 0: + conn.privmsg(targetchannel,influx[6+len(prefix):]+" Hasn't made any quotes") + else: + try: + # randsamp = random.sample(newdir,1)[0] + randsamp = fsample(newdir) + # userquotes/head_1 + loaded = load(targetdirectory+"userquotes/"+randsamp) + except ValueError: + conn.privmsg(targetchannel,"No quotes available [VALUE ERROR]") + except IndexError: + conn.privmsg(targetchannel,"No quotes available [INDEX ERROR]") + else: + if showquotemakers == True: + conn.privmsg(targetchannel,'"'+loaded[0]+'"'+" -By "+loaded[1]\ + #+" In file:"+randsamp\ + ) + else: + conn.privmsg(targetchannel,'"'+loaded[0]+'"'\ + #+" In file:"+randsamp\ + ) + elif cocheck(prefix+"makequote "): + conn.privmsg(targetchannel,C_makequote.mkquote(prefix,influx,truesender,debug)) + ### VERSION + elif influx.lower() == prefix+"version": + if debug: + print truesender+":"+prefix+"version" + conn.privmsg(targetchannel,Name+" "+pregen+" online at a %s Python %s.%s.%s, At your service." %(str(sys.platform),str(sys.version_info[0]),str(sys.version_info[1]),str(sys.version_info[2]))) + + elif cocheck(prefix+"take"): + arg = influx.lower().replace(prefix+"take ","") + if arg == "!take" and len(influx.lower()) == len(arg): + conn.privmsg(targetchannel,sender+" : Please provide an argument") + else: + if debug: + print truesender+":"+prefix+"take "+arg + if arg in items: + item = items.pop(items.index(arg)) + conn.privmsg(targetchannel,sender+"'s "+arg+" was taken back") + else: + conn.privmsg(targetchannel,sender+"'s "+arg+" is not here, sorry.") + elif cocheck(prefix+"give"): + arg = influx.lower().replace(prefix+"give ","") + if debug: + print truesender+":"+prefix+"give "+arg + conn.privmsg(targetchannel,sender+"'s "+arg+" received") + items.append(arg) + elif cocheck(prefix+"use") or cocheck(prefix+"smash"): + if debug: + print truesender+":"+prefix+"use" + if usable == True: + expcount = str(items).count("bomb") + str(items).count("explosive") + str(items).count("tnt") + str(items).count("explosion") + if "nuke" in str(items): + conn.privmsg(targetchannel,"SWOOOOOOOOSHHHHH") + if debug: + print prefix+"use is now inoperable" + usable = False + elif expcount == 1: + conn.privmsg(targetchannel,"BANG") + elif expcount > 1: + conn.privmsg(targetchannel,"KABOOM") + else: + conn.privmsg(targetchannel,"CLANG") + items = [] + else: + conn.privmsg(targetchannel,"ERROR: PNEUMATIC SMASHER OUT OF ORDER") + elif cocheck( prefix+ "allcaps"): + arg = influx[8+len(prefix):] + if debug: + print truesender+":"+prefix+"allcaps "+arg + conn.privmsg(targetchannel,"Translation: "+arg.capitalize()) + elif cocheck(prefix+"tyr") or cocheck(prefix+"toggleyoutubereveal"): + if truesender in operators and targetchannel==channel:# or "skibiliano" in truesender.lower() and targetchannel==channel: + if debug: + print truesender+":"+prefix+"toggleyoutubereveal" + if automatic_youtube_reveal == False: + automatic_youtube_reveal = True + conn.privmsg(targetchannel,"All youtube links will now be revealed automatically") + else: + automatic_youtube_reveal = False + conn.privmsg(targetchannel,"All youtube links will not be revealed anymore") + + elif cocheck(prefix+"translate "): + if truesender in operators and targetchannel==channel: + arg = influx.lower()[len(prefix+"translate "):] + if debug: + print truesender+":"+prefix+"translate "+arg + if arg.lower() in translateable: + conn.privmsg(targetchannel,"Not Translating anymore") + translateable.remove(arg.lower()) + else: + translateable.append(arg.lower()) + conn.privmsg(targetchannel,"Translating..") + elif cocheck(prefix+"weather "): + arg = influx.lower().split(" ")[1:] + arg2 = Weather.Weather((" ".join(arg)).replace(" ","_")) + conn.privmsg(targetchannel,"Weather for "+arg2[1]+": "+arg2[0]) + elif cocheck(prefix+"dance"): + if dance_enabled: + if debug: + print truesender+":"+prefix+"dance" + lastdance = trackdance + trackdance = time.time() + subt = trackdance - lastdance + if subt < dance_flood_time: + conn.privmsg(targetchannel,"*Huff* *Puff*") + else: + conn.privmsg(targetchannel,":D/--<") + sleep(0.2) + conn.privmsg(targetchannel,":D|--<") + sleep(0.2) + conn.privmsg(targetchannel,":D\--<") + #### YOUTUBE + elif cocheck(prefix+"youtube"): + if debug: + print truesender+":"+prefix+"youtube" + #arg = influx[9:] + if len(influx[len(prefix+"youtube"):].split(" ")) != 1: + arg = influx[len(prefix+"youtube"):].split(" ")[0] + check = influx.lower()[len(prefix+"youtube"):].split(" ")[0] + if len(arg) < 5: + arg = influx[len(prefix+"youtube"):].split(" ")[1] + check = influx.lower()[len(prefix+"youtube"):].split(" ")[1] +# if "http//" in check: +# arg = arg[6:] +# else: +# arg = arg.replace("http//","http://") + if check[0:5] == "https": + conn.privmsg(targetchannel,sender+" :Secure Youtube does NOT exist") + elif "www.youtube.com/watch?v=" not in check and "endlessvideo.com/watch?v=" not in check: + conn.privmsg(targetchannel,sender+" :That's not a proper youtube link!") + else: + if cache_youtube_links == True: + result = YTCV2(arg) + else: + result = YTCV2(arg,0) + if type(result) == str: + ### To remove =" + if result[0] == "N": + pass + else: + result = result[4:] + conn.privmsg(targetchannel,sender+" : "+result) + else: + conn.privmsg(targetchannel,sender+" : The video does not exist") + else: + conn.privmsg(targetchannel,sender+" : Please provide a link") + elif cocheck(prefix+"note ") and influx.count(" ") < 2: + arg = influx.lower()[len(prefix)+5:] + if debug: + print truesender+":"+prefix+"note "+arg + try: + a = arg[0] + except IndexError: + conn.privmsg(targetchannel,sender+" : Please specify a note") + else: + if arg[0] == "_": # Public / Restricted note + result = load(targetdirectory+"memos/"+arg+".note") + #_flare + if result == "ERROR ERROR ERROR ERR": + result = load(targetdirectory+"memos/"+arg+"_"+targetchannel.replace("#","")+".note") + #_flare_dnd + pass + else: + pass + else: + result = load(targetdirectory+"memos/"+truesender.replace("|","_")+"_"+arg+".note") + #skibiliano_testnote + if result == "ERROR ERROR ERROR ERR": + result = load(targetdirectory+"memos/"+truesender.replace("|","_")+"_"+arg+"_"+targetchannel.replace("#","")+".note") + #skibiliano_testnote_derp + pass + else: + pass + if result == "ERROR ERROR ERROR ERR": + conn.privmsg(targetchannel,sender+" : Note not found") + elif type(result) == list: + if "C" in result[0]: #Channel restriction, result[2] is the channel + try: + if targetchannel == result[2]: + conn.privmsg(targetchannel,sender+" : '"+result[1]+"'") + else: + conn.privmsg(targetchannel,sender+" : That note is channel restricted") + except: + conn.privmsg(targetchannel,sender+" : NOTE HAS INVALID RESTRICTION") + else: + conn.privmsg(targetchannel,sender+" : '"+result+"'") + elif influx.lower() == prefix+"notes": + if debug: + print truesender+":"+prefix+"notes" + arg = os.listdir(targetdirectory+"memos/") + arg2 = [] + arg3 = truesender.replace("|","_")+"_" + for i in arg: + if arg3 in i: + arg2.append(i.replace(arg3,"").replace(".note","")) + if len(arg2) == 1: + preprocess = " note: " + else: + preprocess = " notes: " + if len(arg2) == 0: + conn.privmsg(targetchannel,sender+" : You have no notes saved") + else: + conn.privmsg(targetchannel,sender+" : "+str(len(arg2))+preprocess+", ".join(arg2)) + elif cocheck(prefix+"note ") and influx.count(" ") > 1: + note_chanrestrict = None + note_public = None + try: + arg = influx.split(" ",2)[2] # Contents + arg4 = influx.split(" ")[1].lower() # Note name + if arg4[0:3] == "[c]": # or arg4[0:3] == "[p]": + note_chanrestrict = "c" in arg4[0:3] + #note_public = "p" in arg4[0:3] + arg4 = arg4[3:] + elif arg4[0:4] == "[cp]" or arg4[0:4] == "[pc]": + note_chanrestrict = True + note_public = True + arg4 = arg4[4:] + else: + pass + #print "Is note public? "+str(note_public) + #print "Is note chanrestricted? "+str(note_chanrestrict) + #print "What is the name? "+str(arg4) + if arg.lower() == "delete" and "\\" not in influx.lower() and "/" not in influx.lower(): + if note_public: + try: + if note_chanrestrict: + os.remove(targetdirectory+"memos/"+"_"+arg4+"_"+targetchannel.replace("#","")+".note") + else: + os.remove(targetdirectory+"memos/"+"_"+arg4+".note") + except: + conn.pivmsg(targetchannel,sender+" : Couldn't remove note") + else: + conn.privmsg(targetchannel,sender+" : Note removed") + pass + else: + try: + if note_chanrestrict: + os.remove(targetdirectory+"memos/"+truesender.replace("|","_")+"_"+arg4+"_"+targetchannel.replace("#","")+".note") + else: + os.remove(targetdirectory+"memos/"+truesender.replace("|","_")+"_"+arg4+".note") + except: + conn.privmsg(targetchannel,sender+" : Couldn't remove note") + else: + conn.privmsg(targetchannel,sender+" : Note removed") + elif arg.lower() == "delete": + conn.privmsg(targetchannel,sender+" : That just doesn't work, we both know that.") + else: + try: + if note_public: + if note_chanrestrict: + save(targetdirectory+"memos/"+"_"+arg4+"_"+targetchannel.replace("#","")+".note",arg) + #print "Saved as note_public, note_chanrestrict" + else: + save(targetdirectory+"memos/"+"_"+arg4+".note",arg) + #print "Saved as note_public" + else: + if note_chanrestrict: + save(targetdirectory+"memos/"+truesender.replace("|","_")+"_"+arg4+"_"+targetchannel.replace("#","")+".note",arg) + #print "Saved as note_chanrestrict" + else: + save(targetdirectory+"memos/"+truesender.replace("|","_")+"_"+arg4+".note",arg) + #print "Saved as normal" + except IOError: + conn.privmsg(targetchannel,sender+" : Please do not use special letters") + else: + conn.privmsg(targetchannel,sender+" : Note Saved!") + except: + conn.privmsg(targetchannel,sender+" : Something went horribly wrong.") + elif cocheck(prefix+"tc"): + try: + tc_from_zone,tc_to_zone,tc_time_to_convert = influx[4:].split(" ") + except ValueError: + conn.privmsg(targetchannel,sender+" : Please input !tc