diff --git a/README.txt b/README.txt index 2a2896c6a8f2b..3250288c588f5 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 0000000000000..cd1b83e410bc4 --- /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 0000000000000..2ed73dafd577e --- /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 0000000000000..6e8b304e73b89 --- /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 0000000000000..f79b863449a12 --- /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 0000000000000..86013b74a7b05 --- /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 0000000000000..62b72dc2ad207 --- /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 0000000000000..96736fec21c61 --- /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 0000000000000..1f5ae321816f0 --- /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 0000000000000..761c0628d6956 --- /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 0000000000000..ee4e2c07cfe19 --- /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 0000000000000..153af61a41a04 --- /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 0000000000000..500f4384edd0f --- /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 0000000000000..687c4336327a1 --- /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 0000000000000..347ff7ff4766f --- /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 0000000000000..74f257952ed79 --- /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