commit 0080ce2710dbc85a611842624ef2185e07267f6e Author: wr34k Date: Thu Jun 28 10:00:12 2018 +0200 First commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3f04cb2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# pyCache +__pycache__/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/__pycache__/fight.cpython-36.pyc b/__pycache__/fight.cpython-36.pyc new file mode 100644 index 0000000..ebfc573 Binary files /dev/null and b/__pycache__/fight.cpython-36.pyc differ diff --git a/__pycache__/fighter.cpython-36.pyc b/__pycache__/fighter.cpython-36.pyc new file mode 100644 index 0000000..d3d859d Binary files /dev/null and b/__pycache__/fighter.cpython-36.pyc differ diff --git a/__pycache__/ircCommands.cpython-36.pyc b/__pycache__/ircCommands.cpython-36.pyc new file mode 100644 index 0000000..ce75085 Binary files /dev/null and b/__pycache__/ircCommands.cpython-36.pyc differ diff --git a/__pycache__/ircReload.cpython-36.pyc b/__pycache__/ircReload.cpython-36.pyc new file mode 100644 index 0000000..dd6504c Binary files /dev/null and b/__pycache__/ircReload.cpython-36.pyc differ diff --git a/__pycache__/log.cpython-36.pyc b/__pycache__/log.cpython-36.pyc new file mode 100644 index 0000000..709ad8f Binary files /dev/null and b/__pycache__/log.cpython-36.pyc differ diff --git a/__pycache__/mircformat.cpython-36.pyc b/__pycache__/mircformat.cpython-36.pyc new file mode 100644 index 0000000..cff1b9c Binary files /dev/null and b/__pycache__/mircformat.cpython-36.pyc differ diff --git a/admins b/admins new file mode 100644 index 0000000..8e386b3 --- /dev/null +++ b/admins @@ -0,0 +1 @@ +*!*@*.sp0ns0r3d.sploit.sh diff --git a/config.json b/config.json new file mode 100644 index 0000000..35fd112 --- /dev/null +++ b/config.json @@ -0,0 +1,215 @@ +{ + "info": { + "lowhp": [ + "%defender% starts bleeding", + "%defender% is having trouble focusing", + "%defender% is stagging", + "%defender% seems wasted" + ], + "ground2stand": [ + "%attacker% gets back on its feet", + "%attacker% is standing up" + ], + "stand2ground": [ + "%defender% just fell to the ground", + "%defender% falls over" + ] + }, + + "moves": { + "stand": { + "kick": { + "high": { + "stand": { + "dmgidx": 40, + "mindmg": 20, + "fallchance": 5, + "blockidx": 40, + "text": [ + "%attacker% head kicks %defender%" + ] + }, + "ground": { + "dmgidx": 60, + "mindmg": 25, + "blockidx": 28, + "text": [ + "%attacker% stomps %defender% in the head!" + ] + } + }, + "middle": { + "stand": { + "dmgidx": 30, + "mindmg": 10, + "fallchance": 8, + "blockidx": 28, + "text": [ + "%attacker% middle kicks %defender%" + ] + }, + "ground": { + "dmgidx": 45, + "mindmg": 20, + "blockidx": 34, + "text": [ + "%attacker% stomps %defender% in the body!" + ] + } + }, + "low": { + "stand": { + "dmgidx": 23, + "mindmg": 5, + "fallchance": 15, + "blockidx": 35, + "text": [ + "%attacker% low kicks %defender%" + ] + }, + "ground": { + "dmgidx": 30, + "mindmg": 15, + "blockidx": 40, + "text": [ + "%attacker% kicks %defender%'s legs while %defender% is on the ground" + ] + } + } + }, + "punch": { + "high": { + "stand": { + "dmgidx": 30, + "mindmg": 10, + "fallchance": 2, + "blockidx": 30, + "text": [ + "%attacker% head punches %defender%" + ] + } + }, + "middle": { + "stand": { + "dmgidx": 20, + "mindmg": 5, + "fallchance": 4, + "blockidx": 15, + "text": [ + "%attacker% punches %defender% to the body" + ] + } + } + }, + "block": { + "high": { + "chance": 85, + "text": [ + "Good block from %defender% he managed to avoid the hit!" + ] + }, + "middle": { + "chance": 85, + "text": [ + "Good block from %defender% he managed to avoid the hit!" + ] + }, + "low": { + "chance": 80, + "text": [ + "Good block from %defender% he managed to avoid the hit!" + ] + } + } + }, + "ground": { + "standup": { + "stand": { + "chance": 30 + }, + "ground": { + "chance": 70 + } + }, + "kick": { + "high": { + "stand": { + "dmgidx": 30, + "mindmg": 10, + "fallchance": 8, + "blockidx": 40, + "text": [ + "%attacker% head kicks %defender% from the ground!" + ] + }, + "ground": { + "dmgidx": 40, + "mindmg": 23, + "blockidx": 55, + "text": [ + "%attacker% hit %defender% with huge kneel kicks to the head!" + ] + } + }, + "middle": { + "stand": { + "dmgidx": 20, + "mindmg": 5, + "fallchance": 5, + "blockidx": 40, + "text": [ + "%attacker% middle kicks %defender% from the ground!" + ] + }, + "ground": { + "dmgidx": 25, + "mindmg": 17, + "blockidx": 50, + "text": [ + "%attacker% hit %defender% with kneel kicks to the body" + ] + } + }, + "low": { + "stand": { + "dmgidx": 15, + "mindmg": 3, + "fallchance": 18, + "blockidx": 45, + "text": [ + "%attacker% low kicks %defender% from the ground!" + ] + }, + "ground": { + "dmgidx": 15, + "mindmg": 2, + "blockidx": 30, + "text": [ + "%attacker% hit %defender% with kneel kicks to the legs" + ] + } + } + }, + "block": { + "high": { + "chance": 90, + "text": [ + "Good block from %defender% he managed to avoid the hit!" + ] + }, + "middle": { + "chance": 90, + "text": [ + "Good block from %defender% he managed to avoid the hit!" + ] + }, + "low": { + "chance": 85, + "text": [ + "Good block from %defender% he managed to avoid the hit!" + ] + } + } + } + } +} diff --git a/fight.py b/fight.py new file mode 100644 index 0000000..400cbea --- /dev/null +++ b/fight.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python3 + +from fighter import Fighter +import random, json + +CONFIG_FILE = "./config.json" + +class Fight(object): + def __init__(self, IRC): + self.IRC = IRC + self.state = 'inactive' + self.fighters = [] + + self.get_config() + + def get_config(self): + with open(CONFIG_FILE, "r") as f: + self.config = json.loads(f.read()) + + def addFighter(self, nick): + self.state = 'waiting_fighter' + if nick in self.fighters: + self.IRC.privmsg(self.IRC.channel, "Hey {} you're already registered!".format(nick)) + return + else: + self.fighters += [nick] + + if len(self.fighters) == 2: + self.IRC.privmsg(self.IRC.channel, "Alright {}, {}, let's fight!".format(self.fighters[0], self.fighters[1])) + self.state = 'fighters_ready' + else: + self.IRC.privmsg(self.IRC.channel, "Waiting for 2nd fighter...") + + + def startFight(self): + self.state = 'starting_fight' + + self.fighters[0] = Fighter(self.fighters[0], self.IRC.mirc.RED) + self.fighters[1] = Fighter(self.fighters[1], self.IRC.mirc.BLUE) + + + # who start? + roll1 = roll2 = 0 + while roll1 == roll2: + roll1 = random.random() + roll2 = random.random() + + + if roll1 > roll2: + self.fighters[0].advantage = True + else: + self.fighters[1].advantage = True + + self.print_fighters_action() + + + def print_fighters_action(self): + self.state = 'waiting_fighters_action' + + for f in self.fighters: + self.IRC.privmsg(f.nick, "What is your next move?") + self.IRC.privmsg(f.nick, "Actions available: '{}'".format("', '".join(self.get_next_avail_action(f.nick)))) + + + def get_next_avail_action(self, nick): # TODO: fix this mess. + f = self.fighters[0] if self.fighters[0].nick == nick else self.fighters[1] + e = self.fighters[0] if self.fighters[1].nick == nick else self.fighters[1] + cmds = [] + for i in self.config['moves'][f.stance]: + if i == 'standup': + cmds += [i] + elif i == 'punch' and e.stance == 'ground': + pass + else: + for j in self.config['moves'][f.stance][i]: + cmds += ["{} {}".format(i, j)] + + return cmds + + def set_next_action(self, nick, action): + for f in self.fighters: + if f.nick == nick: + if f.nextAction is not None: + self.IRC.privmsg(nick, "You already chose your next move!") + return + + if " ".join(action) in self.get_next_avail_action(nick): + f.nextAction = action + self.IRC.privmsg(nick, "Next move set!") + else: + self.IRC.privmsg(nick, "Move not recognized") + + done = True + for f in self.fighters: + if f.nextAction is None: + done = False + + if done: + self.performNextTurn() + + + def getStatus(self, nick): + for f in self.fighters: + if f.nick == nick: + self.IRC.privmsg(nick, "Status for {} -> Current health: {} | Current stance: {} | Next action: {}".format(f.nick, f.hp, f.stance, f.nextAction)) + else: + self.IRC.privmsg(nick, "Status for {} -> Current health: {} | Current stance: {}".format(f.nick, f.hp, f.stance)) + + + + def fightOver(self): + winner = self.fighters[0] if self.fighters[1].hp <= 0 else self.fighters[1] + looser = self.fighters[0] if self.fighters[0].hp <= 0 else self.fighters[1] + + winner.wins += 1 + looser.looses += 1 + + self.shout("\x02\x0315Fight is over.") + self.shout("\x02\x03{}{}\x0f won the fight against \x02\x03{}{}\x0f with \x02\x0303{}\x0f hp left.".format(winner.colour, winner.nick, looser.colour, looser.nick, int(winner.hp))) + + self.state = 'inactive' + self.fighters = [] + + def performNextTurn(self): + self.state = 'processing_turn' + + self.attack() + + if self.state == 'fight_over': + self.fightOver() + return + + for f in self.fighters: + f.nextAction = None + + self.print_fighters_action() + + + + def get_next_move_data(self, f, e): + dmg = self.config['moves'][f.stance][f.nextAction[0]][f.nextAction[1]][e.stance]['dmgidx'] + mindmg = self.config['moves'][f.stance][f.nextAction[0]][f.nextAction[1]][e.stance]['mindmg'] + blockidx = self.config['moves'][f.stance][f.nextAction[0]][f.nextAction[1]][e.stance]['blockidx'] + fallchance = self.config['moves'][f.stance][f.nextAction[0]][f.nextAction[1]][e.stance]['fallchance'] \ + if 'fallchance' in self.config['moves'][f.stance][f.nextAction[0]][f.nextAction[1]][e.stance] \ + else 0 + standchance = self.config['moves'][f.stance][f.nextAction[0]][f.nextAction[1]][e.stance]['standchance'] \ + if 'standchance' in self.config['moves'][f.stance][f.nextAction[0]][f.nextAction[1]][e.stance] \ + else 0 + + texts = self.config['moves'][f.stance][f.nextAction[0]][f.nextAction[1]][e.stance]['text'] + + return dmg, mindmg, blockidx, fallchance, standchance, texts + + def attack(self): + + roll1 = roll2 = 0 + while roll1 == roll2: + roll1 = random.random() + roll2 = random.random() + + + if self.fighters[0].advantage: + roll1 += 0.15 + else: + roll2 += 0.15 + + if roll1 > roll2: + attacker = self.fighters[0] + defender = self.fighters[1] + else: + attacker = self.fighters[1] + defender = self.fighters[0] + + if attacker.nextAction[0] == 'block' and defender.nextAction[0] != 'block': + tmp = attacker + attacker = defender + defender = tmp + elif attacker.nextAction[0] == 'block' and defender.nextAction[0] == 'block': + self.shout("Both fighters are trying to block at the same time, resulting in a completely retarded action...") + return + + attacker.advantage = True + defender.advantage = False + + if attacker.nextAction[0] == 'standup': + standchance = self.config['moves'][attacker.stance]['standup'][defender.stance]['chance'] + else: + dmg, mindmg, blockidx, fallchance, standchance, texts = self.get_next_move_data(attacker, defender) + + txt = self.prettyTxt(attacker, defender, texts) + self.shout("{}".format(txt)) + + blockchance = 0 + if defender.nextAction[0] == 'block': + if defender.nextAction[1] == attacker.nextAction[1]: + blockchance = self.config["moves"][defender.stance][defender.nextAction[0]][defender.nextAction[1]]["chance"] + blocktxts = self.config["moves"][defender.stance][defender.nextAction[0]][defender.nextAction[1]]["text"] + + + if (random.random() * 100) < blockchance * (blockidx / 100): + blocktxt = self.prettyTxt(attacker, defender, blocktxts) + self.shout("{}".format(blocktxt)) + else: + if defender.nextAction[0] == 'block': + self.shout("{} Tryed to block {} but failed miserably!".format(defender.nick, defender.nextAction[1])) + + + realdmg = (random.random() * dmg) + mindmg + + text = self.prettyTxt(attacker, defender, texts) + defender.hp -= realdmg + + if (random.random() * 100) < fallchance: # defender falls down? + defender.stance = 'ground' + falltxt = self.prettyTxt(attacker, defender, self.config['info']['stand2ground']) + self.shout("{}".format(falltxt)) + + + if defender.hp <= 0: + self.IRC.privmsg(self.IRC.channel, "\x02\x0305{} passed out.\x0f".format(defender.nick)) + self.state = "fight_over" + return + + if defender.hp < 25 and defender.first_time_lowhp: + defender.first_time_lowhp=False + lowhptxt = self.prettyTxt(attacker, defender, self.config['info']['lowhp']) + self.shout("{}".format(lowhptxt)) + + + if attacker.nextAction[0] == 'standup': # attacker gets up? + if (random.random() * 100) < standchance: # DO you get up? + attacker.stance = 'stand' + standtxt = self.prettyTxt(attacker, defender, self.config['info']['ground2stand']) + self.shout("{}".format(standtxt)) + + + + def prettyTxt(self, attacker, defender, txtlist): + txt = txtlist[random.randint(0, len(txtlist)-1)] + txt = txt.replace("%attacker%", "\x02\x03{}{}\x0f".format(attacker.colour, attacker.nick)) + txt = txt.replace("%defender%", "\x02\x03{}{}\x0f".format(defender.colour, defender.nick)) + return txt + + def shout(self, msg): + for f in self.fighters: + self.IRC.privmsg(f.nick, msg) + self.IRC.privmsg(self.IRC.channel, msg) diff --git a/fighter.py b/fighter.py new file mode 100644 index 0000000..003c168 --- /dev/null +++ b/fighter.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 + + + + +class Fighter(object): + def __init__(self, nick, colour): + + self.nick = nick + self.colour = colour + + self.hp = 100 + self.stance = 'stand' + + self.nextAction = None + + self.advantage = False + self.groundpos = None + + self.first_time_lowhp = True + + self.wins = 0 + self.looses = 0 diff --git a/irc.py b/irc.py new file mode 100644 index 0000000..82c5e2b --- /dev/null +++ b/irc.py @@ -0,0 +1,202 @@ +#!/usr/bin/python3 + +import sys, socket, ssl, time, os, re + +from log import Colors, Log +from mircformat import MIRCFormat +from ircReload import recompile + +from ircCommands import IrcCommands + + +server = 'irc.servercentral.net' +port = 9999 +channel = ('#wololo', None) # (chan, key) +use_ssl = True + +nickname = 'devbruce' +username = 'rrarrar' +realname = '** WE BOTTIN **' + +optkey= "!" +timeout=0.4 + +DEBUG = True +sys.dont_write_bytecode = True + + + + +class Irc(object): + + def __init__(self): + self.sock = None + self.lag=False + + self.last_cmd={} + self.flood_flag={} + self.flood_count={} + + self.mirc = MIRCFormat() + + self.optkey = optkey + + self.log = Log(DEBUG) + + self.server = server + self.port = port + self.ssl = use_ssl + + self.nick = nickname + self.user = username + self.real = realname + + self.channel, self.chankey = channel + + self.nameslists = {} + self.nameslistFlag = {} + + self.cmds = IrcCommands(self) + + self.timeouts = {} + + def connect(self): + try: + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + if use_ssl: + self.sock = ssl.wrap_socket(self.sock) + self.sock.connect((server, port)) + except Exception as e: + self.log.error("Connexion failed", e) + return + + + def run(self): + self.connect() + self.register() + self.listen() + + def register(self): + self.log.info("Identifying...") + self.raw("USER {} 0 * :{}".format(self.user, self.real)) + self.raw("NICK {}".format(self.nick)) + + def updateNick(self): + self.log.info("Updating NICK to {}".format(self.nick)) + self.raw("NICK {}".format(self.nick)) + + def listen(self): + while True: + if self.lag: + self.lag=False + data += self.sock.recv(1024).decode('utf-8', 'ignore') + else: + data = self.sock.recv(1024).decode('utf-8', 'ignore') + + for line in [x.split() for x in data.split("\r\n") if len(x.split()) > 1]: + self.log.info("<< {}".format(' '.join(line))) + + if line[0][1:] == 'ING': + self.raw("PONG {}".format(line[1])) + + elif line[1] == '001': # connected + self.join() + + elif line[1] == 'JOIN': # Someone joined a channel + self.log.info("{} JOIN to {}".format(line[0], line[2])) + pass + + elif line[1] == 'PART': # Someone emopart a channel + self.log.info("{} PART from {}".format(line[0], line[2])) + pass + + elif line[1] == '433': # Nick already in use + self.nick += "_" + self.updateNick() + + elif line[1] == 'KICK': #Got kicked lmao + if line[0][1:].split("@")[0].split("!") == self.nick: + self.log.warn("Got kicked from {} !".format(line[2])) + chan = line[2] + if chan == self.channel: + self.join() + + elif line[1] == 'INVITE': + self.log.info("{} invited the bot to {}".format(line[0][1:].split("!")[0], line[3][1:])) + self.join(line[3][1:]) + + + elif line[1] == 'PRIVMSG': + nick,user = line[0][1:].split("@")[0].split("!") + user = user[1:] if user[0] == '~' else user + host = line[0].split("@")[1] + self.handle_msg(line[2], self.isAdmin(line[0][1:]), nick, user, host, ' '.join(line[3:])[1:]) + + def join(self): + self.log.info("Now joining {} ...".format(self.channel)) + self.raw("JOIN {} {}".format(self.channel, self.chankey)) if self.chankey else self.raw("JOIN {}".format(self.channel)) + + + def raw(self, msg, timeout=None): + msg = msg.replace("\r", "") + msg = msg.replace("\n", "") + self.log.info(">> " + msg) + self.sock.send(bytes(msg + "\r\n", 'utf-8')) + if timeout: + time.sleep(timeout) + + def isAdmin(self, ident): + ret = False + for line in [line.strip() for line in open('admins', 'r').readlines() if line]: + if re.compile(line.replace('*', '.*')).search(ident): + ret = True + return ret + + + def handle_msg(self, chan, admin, nick, user, host, msg): + args = msg.split() + if admin: + if args[0] == '{}reload'.format(self.optkey): + ret = recompile(args[1]) # Let you add new code to the bot without restarting it + if ret == True: + self.privmsg(chan, "{} recompiled successfully!".format(args[1])) + return + else: + self.privmsg(chan, "Man we had a issue while recompiling {}".format(args[1])) + self.log.error(ret) + return + + self.cmds.handle_msg(chan, admin, nick, user, host, msg) + + + def privmsg(self, chan, msg): + if chan not in self.timeouts: + self.timeouts[chan] = {'last_cmd': time.time(), 'burst': 0, 'timeout': 0} + self.raw("PRIVMSG {} :{}".format(chan, msg), self.timeouts[chan]['timeout']) + self.editTimeouts() + + + + def editTimeouts(self): + if (time.time() - self.timeouts[chan]['last_cmd']) < 3: + self.timeouts[chan]['burst'] += 1 + else: + self.timeouts[chan]['burst'] = 0 + + if self.timeouts[chan]['burst'] > 3: + self.timeouts[chan]['timeout'] += 0.075 + else: + self.timeouts[chan]['timeout'] = 0 + + if self.timeouts[chan]['timeout'] > 0.4: + self.timeouts[chan]['timeout'] = 0.4 + + self.timeouts[chan]['last_cmd'] = time.time() + + + def action(self, chan, msg): + self.privmsg(chan, "\x01ACTION {}\x01".format(msg)) + + +if __name__=='__main__': + Irc().run() diff --git a/ircCommands.py b/ircCommands.py new file mode 100644 index 0000000..ccaf77b --- /dev/null +++ b/ircCommands.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 + +import time +from fight import Fight + +class IrcCommands(object): + def __init__(self, IRC): + self.IRC = IRC + self.fight = Fight(self.IRC) + + def handle_msg(self, chan, admin, nick, user, host, msg): + args = msg.split() + if args[0][0] == self.IRC.optkey: + self.handle_cmd(chan, admin, nick, user, host, args[0][1:], args[1:]) + + + def check_flood(self, chan, nick): + if chan not in self.IRC.flood_flag: + self.IRC.flood_flag[chan] = False + if chan not in self.IRC.last_cmd: + self.IRC.last_cmd[chan] = 0 + + if self.IRC.flood_flag[chan] and (time.time() - self.IRC.last_cmd[chan]) < 5: + return True + if (time.time() - self.IRC.last_cmd[chan]) < 2 and self.IRC.flood_count[chan] > 2: + self.IRC.privmsg(chan, "\00305,01{}\00315 Slow down m8".format(nick)) + self.IRC.flood_flag[chan]=True + self.IRC.last_cmd[chan] = time.time() + return True + if (time.time() - self.IRC.last_cmd[chan]) < 1: + self.IRC.flood_count[chan]+=1 + self.IRC.privmsg(chan, "\00305,01{}\00315 Slow down m8".format(nick)) + self.IRC.last_cmd[chan] = time.time() + return True + + return False + + + + def handle_cmd(self, chan, admin, nick, user, host, cmd, args): + if chan == self.IRC.nick: + chan = nick + + if self.check_flood(chan, nick): + return + + if admin: + if cmd == 'raw': + if args[0].lower() == 'nick': + self.IRC.nick = args[1] + self.IRC.updateNick() + elif args[0].lower() == 'join': + self.IRC.join(" ".join(args[1:])) + else: + self.IRC.raw(" ".join(args)) + + + + if self.fight.state in ('inactive', 'waiting_fighter'): + if cmd == 'fight': + self.fight.addFighter(nick) + if self.fight.state == 'fighters_ready': + self.fight.startFight() + + else: + if cmd == 'status': + self.fight.getStatus(nick) + + + if self.fight.state == 'waiting_fighters_action': + if cmd == 'action': + if chan != self.IRC.channel: + self.fight.set_next_action(nick, args) + else: + self.IRC.privmsg(self.IRC.channel, "Not here retard your opponent can see your next move!") + + + self.IRC.flood_flag[chan] = False + self.IRC.flood_count[chan] = 0 + self.IRC.last_cmd[chan] = time.time() diff --git a/ircReload.py b/ircReload.py new file mode 100644 index 0000000..b10a898 --- /dev/null +++ b/ircReload.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 + +from importlib import reload +import sys + +def recompile(modulename): + try: + modImport = __import__(modulename) + except: + return "Error @ __import__({})".format(modulename) + + pycfile = modImport.__file__ + + modPath = pycfile.replace(".pyc", ".py") + + try: + f = open(modPath, "rU") + code = f.read() + except Exception as e: + return "Error @ open({}, 'rU') : {}".format(modPath, e) + + f.close() + + try: + compile(code, modulename, "exec") + except Exception as e: + return "Error @ compile({}..., {}, 'exec') : {}".format(code[:10], modulename, e) + + try: + exec(code) + except Exception as e: + return "Error @ execfile({}) : {}".format(modPath, e) + + + + reload(sys.modules[modulename]) + return True + + +print(recompile("ircCommands")) diff --git a/log.py b/log.py new file mode 100644 index 0000000..5c9f506 --- /dev/null +++ b/log.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 + + +class Colors(object): + class Format(object): + RESET = "\033[0m" + BOLD = "\033[1m" + DIM = "\033[2m" + UNDERLINED = "\033[4m" + BLINK = "\033[5m" + REVERSE = "\033[7m" + HIDDEN = "\033[8m" + + class Foreground(object): + DEFAULT = "\033[39m" + BLACK = "\033[30m" + RED = "\033[31m" + GREEN = "\033[32m" + YELLOW = "\033[33m" + BLUE = "\033[34m" + MAGENTA = "\033[35m" + CYAN = "\033[36m" + LIGHTGREY = "\033[37m" + DARKGREY = "\033[90m" + LIGHTRED = "\033[91m" + LIGHTGREEN = "\033[92m" + LIGHTYELLOW = "\033[93m" + LIGHTBLUE = "\033[94m" + LIGHTMAGENTA = "\033[95m" + LIGHTCYAN = "\033[96m" + WHITE = "\033[97m" + class Background(object): + DEFAULT = "\033[49m" + BLACK = "\033[40m" + RED = "\033[41m" + GREEN = "\033[42m" + YELLOW = "\033[43m" + BLUE = "\033[44m" + MAGENTA = "\033[45m" + CYAN = "\033[46m" + LIGHTGREY = "\033[47m" + DARKGREY = "\033[100m" + LIGHTRED = "\033[101m" + LIGHTGREEN = "\033[102m" + LIGHTYELLOW = "\033[103m" + LIGHTBLUE = "\033[104m" + LIGHTMAGENTA = "\033[105m" + LIGHTCYAN = "\033[106m" + WHITE = "\033[107m" + + def __init__(self): + self.format = self.Format() + self.fg = self.Foreground() + self.bg = self.Background() + +class Log(object): + def __init__(self, debug, func=print): + self.colors = Colors() + self.debug = debug + self.func = func + + def construct(self, *args): + return "".join(a for a in args) + + def info(self, msg): + if not self.debug: + self.func( self.construct( "[", self.colors.fg.LIGHTGREEN, "*", self.colors.fg.DEFAULT, "] ", msg ) ) + + def warn(self, msg): + if not self.debug: + self.func( self.construct( "[", self.colors.fg.LIGHTYELLOW, "!", self.colors.fg.DEFAULT, "] ", msg ) ) + + def error(self, msg, exception=None): + if not self.debug: + self.func( self.construct( "[", self.colors.fg.LIGHTRED, "x", self.colors.fg.DEFAULT, "] ", msg ) ) + if exception: + self.func( self.construct( "[", self.colors.fg.LIGHTRED, "x", self.colors.fg.DEFAULT, "] ", str(exception) ) ) diff --git a/mircformat.py b/mircformat.py new file mode 100644 index 0000000..0d81d70 --- /dev/null +++ b/mircformat.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + +class MIRCFormat(object): + BOLD = "\x02" + ITALIC = "\x1D" + UNDERLINED = "\x1F" + REVERSE = "\x16" + RESET = "\x0F" + WHITE = "\x0300" + BLACK = "\x0301" + BLUE = "\x0302" + GREEN = "\x0303" + RED = "\x0304" + BROWN = "\x0305" + PURPLE = "\x0306" + ORANGE = "\x0307" + YELLOW = "\x0308" + LIGHTGREEN = "\x0309" + CYAN = "\x0310" + LIGHTCYAN = "\x0311" + LIGHTBLUE = "\x0312" + PINK = "\x0313" + GREY = "\x0314" + LIGHTGREY = "\x0315"