diff --git a/FightBot.py b/FightBot.py index 942d85a..d9e7e7b 100644 --- a/FightBot.py +++ b/FightBot.py @@ -1,986 +1,1014 @@ -#!/usr/bin/env python -# FightBot IRC bot - based on acidvegas skeleton in python -import argparse -import asyncio -import logging -import logging.handlers -import ssl -import sqlite3 -import random -import time - -# Formatting Control Characters / Color Codes -bold = '\x02' -italic = '\x1D' -underline = '\x1F' -reverse = '\x16' -reset = '\x0f' -white = '00' -black = '01' -blue = '02' -green = '03' -red = '04' -brown = '05' -purple = '06' -orange = '07' -yellow = '08' -light_green = '09' -cyan = '10' -light_cyan = '11' -light_blue = '12' -pink = '13' -grey = '14' -light_grey = '15' -conn = sqlite3.connect('data.db') -c = conn.cursor() - - -def createtable(): - c.execute('''CREATE TABLE if not exists users ( - name text unique, - level integer, - experience integer, - health integer, - attack integer, - defense integer, - money integer, - healthmax integer - -)''') - c.execute('''CREATE TABLE if not exists weapons ( - name text unique, - weaponheld integer, - clip integer, - ammunition integer, - expire integer - -)''') - c.execute('''CREATE TABLE if not exists items ( - name text unique, - bandages integer - )''') - c.execute('''CREATE TABLE if not exists stats ( - name text unique, - kills integer, - deaths integer - )''') - - -class Users: - def __init__(self, name, level, experience, health, attack, defense, money, healthmax): - self.name = name - self.level = level - self.experience = experience - self.health = health - self.attack = attack - self.defense = defense - self.money = money - self.healthmax = healthmax - -class Weapons: - def __init__(self, name, weaponheld, clip, ammunition): - self.name = name - self.weaponheld = weaponheld - self.clip = clip - self.ammunition = ammunition - self.expire = 0 -class Items: - def __init__(self, name, bandages): - self.name = name - self.bandages = bandages -async def addkillstat(name): - c.execute(f'SELECT rowid FROM stats WHERE name=(:name)', {'name': name}) - checkrow=c.fetchone() - if checkrow == None: - kills = 1 - deaths = 0 - c.execute(f'INSERT OR REPLACE INTO stats VALUES (:name, :kills, :deaths)', {'name': name, 'kills': kills, 'deaths': deaths}) - conn.commit() - await bot.sendmsg(config.irc.channel, f'[Player {color(name, light_green)} has a total of {color(kills, red)} kills!]') - - else: - c.execute(f'SELECT * FROM stats WHERE name=(:name)', {'name': name}) - getkills=c.fetchall() - for retrieve in getkills: - kills = retrieve[1] + 1 - - c.execute(f'UPDATE stats SET KILLS = (:kills) WHERE name=(:name)', {'kills': kills, 'name': name}) - conn.commit() - await bot.sendmsg(config.irc.channel, f'[Player {color(name, light_green)} has a total of {color(kills, red)} kills!]') - -async def adddeathstat(name): - c.execute(f'SELECT rowid FROM stats WHERE name=(:name)', {'name': name}) - checkrow=c.fetchone() - if checkrow == None: - kills = 0 - deaths = 1 - c.execute(f'INSERT OR REPLACE INTO stats VALUES (:name, :kills, :deaths)', {'name': name, 'kills': kills, 'deaths': deaths}) - conn.commit() - await bot.sendmsg(config.irc.channel, f'[Opponent Player {color(name, red)} has died {color(deaths, red)} times!]') - - else: - c.execute(f'SELECT * FROM stats WHERE name=(:name)', {'name': name}) - getkills=c.fetchall() - for retrieve in getkills: - kills = retrieve[1] - deaths = retrieve[2] + 1 - - c.execute(f'UPDATE stats SET DEATHS = (:deaths) WHERE name=(:name)', {'deaths': deaths, 'name': name}) - conn.commit() - await bot.sendmsg(config.irc.channel, f'[Player {color(name, red)} has died {color(deaths, red)} times!]') - - -async def buybandages(name, amount): - if amount == 0 or amount == None: - await bot.sendmsg(config.irc.channel, f'[Must specify how many bandages you want... !buy bandages ]') - c.execute(f'SELECT rowid FROM items WHERE name=(:name)', {'name': name}) - checkrow=c.fetchone() - if checkrow == None: - bandages = 0 - c.execute(f'INSERT OR REPLACE INTO items VALUES (:name, :bandages)', {'name': name, 'bandages': bandages}) - conn.commit() - shopamount = amount * 50 - c.execute(f'SELECT * FROM items WHERE name=(:name)', {'name': name}) - look = c.fetchall() - - for band in look: - bandages = band[1] - - c.execute(f'SELECT * FROM users WHERE name=(:name)', {'name': name}) - usermoney = c.fetchall() - for grabmoney in usermoney: - money = grabmoney[6] - if money >= shopamount: - await bot.sendmsg(config.irc.channel, f'[You have enough money [${money:,}] to purchase [{amount}] bandages! Cost is ${shopamount:,}]') - else: - await bot.sendmsg(config.irc.channel, f'[You do {color("NOT", red)} have enough funds!]') - return - bandages = band[1] - bandagestotal = bandages + amount - c.execute(f'UPDATE ITEMS set BANDAGES = (:bandages) WHERE NAME = (:name)', {'bandages': bandagestotal, 'name': name}) - conn.commit() - money = money - shopamount - c.execute(f'UPDATE users set MONEY = (:money) WHERE NAME = (:name)', {'money': money, 'name': name}) - conn.commit() -async def heal(name): - - - c.execute(f'SELECT * from USERS WHERE name= (:name)', {'name': name}) - newtest=c.fetchall() - for userinfo in newtest: - health = userinfo[3] - if health <= 0: - await bot.sendmsg(config.irc.channel, f'[You are dead... !revive to bring yourself back]') - return - c.execute(f'SELECT rowid FROM items WHERE name = (:name)', {'name': name}) - havebandages=c.fetchone() - if havebandages == None: - await bot.sendmsg(config.irc.channel, f'[You do not have any bandages... !buy bandages ]') - return - - maxhealth = userinfo[7] - if health == maxhealth: - await bot.sendmsg(config.irc.channel, f'[You already at FULL HEALTH]') - return - newhealth = health + 25 - if newhealth >= maxhealth: - health = maxhealth - c.execute(f'UPDATE USERS set HEALTH = (:health) where NAME = (:name)', {'health': health, 'name': name}) - conn.commit() - await bot.sendmsg(config.irc.channel, f'[Player healed {color("+25", light_green)} to MAX health {color(health, light_green)}]') - else: - c.execute(f'UPDATE USERS set HEALTH = (:health) where NAME = (:name)', {'health': newhealth, 'name': name}) - conn.commit() - await bot.sendmsg(config.irc.channel, f'[Player healed {color("+25", light_green)} to health {color(newhealth, light_green)}]') - - - c.execute(f'SELECT * FROM items WHERE name=(:name)', {'name': name}) - bandaids=c.fetchall() - for checkitems in bandaids: - bandages = checkitems[1] - bandages = bandages - 1 - c.execute(f'UPDATE ITEMS set BANDAGES = (:bandages) WHERE name = (:name)', {'bandages': bandages, 'name': name}) - conn.commit() -async def checkexist(player): - - c.execute(f"SELECT rowid FROM users WHERE name=(:name)", {'name': player}) - - data=c.fetchone() - if data is None: - await bot.sendmsg(config.irc.channel, 'Invalid Player: %s'%player) - return False - else: - return True -async def reload(nick): - c.execute(f"SELECT rowid FROM users WHERE name=(:name)", {'name': nick}) - data=c.fetchone() - - if data == None: - logging.debug('User is trying to reload without having an account') - await bot.sendmsg(config.irc.channel, f'[User {nick} does not have an account]') - return - - c.execute(f"SELECT * FROM weapons WHERE name=(:name)", {'name': nick}) - data=c.fetchall() - name = nick - for check in data: - hasweapon = check[1] - if hasweapon == False: - logging.debug('User does not have weapon') - await bot.sendmsg(config.irc.channel, f'[You do not currently have a weapon.. !buy weapon]') - return - - maxclip = 30 - clip = check[2] - ammunition = check[3] - if ammunition <= 0: - await bot.sendmsg(config.irc.channel, f'!buy ammo') - return - clipadd = 30 - clip - if ammunition >= clipadd: - ammunition = ammunition - clipadd - clip = clip + clipadd - else: - clip = clip + ammunition - ammunition = 0 - - logging.debug(f'[Current clip ammunition is at {clip} rounds and backup ammunition is at {ammunition} magazine rouunds!]') - - await bot.sendmsg(config.irc.channel, f'[Current clip has {clip} rounds out of {maxclip} mag ammo size and {ammunition} in the arsenal!]') - c.execute(f"UPDATE WEAPONS set CLIP = (:clip) WHERE NAME = (:name)", {'clip': clip, 'name': nick}) - conn.commit() - c.execute(f"UPDATE WEAPONS set AMMUNITION = (:ammunition) WHERE NAME = (:name)", {'ammunition': ammunition, 'name': name}) - conn.commit() -async def shoot(player, nick): - check = await checkexist(player) - if check is False: - return - else: - if player == nick: - logging.debug('Player cannot attack oneself') - await bot.sendmsg(config.irc.channel, '[Error: {1}]'.format(0,color('Cannot Attack Yourself', red))) - return - - c.execute(f'SELECT rowid FROM weapons WHERE name=(:name)', {'name': nick}) - checkrow=c.fetchone() - if checkrow == None: - await bot.sendmsg(config.irc.channel, f'[Error: {color("No Weapons", red)}] - !buy weapon') - return - c.execute(f"SELECT * FROM users WHERE name=(:name)", {'name': nick}) - healthcheck = c.fetchall() - for checkalive in healthcheck: - alive = checkalive[3] - if alive <= 0: - await bot.sendmsg(config.irc.channel, f'[Error: {color("You Are Dead... !revive", red)}]') - return - c.execute(f"SELECT * FROM users WHERE name=(:name)", {'name': player}) - playerhealthcheck = c.fetchall() - for checkalive in playerhealthcheck: - health = checkalive[3] - if health <= 0: - logging.debug('Player targeted is DEAD') - await bot.sendmsg(config.irc.channel, f'[Player targeted is {color("DEAD", light_blue)}]') - return - - c.execute(f"SELECT * FROM weapons WHERE name=(:name)", {'name': nick}) - weapons = c.fetchall() - for reg in weapons: - - name = nick - weaponheld = reg[1] - expire = reg[4] - c.execute(f"SELECT rowid FROM weapons WHERE name=(:name)", {'name': name}) - - if weaponheld == 0: - await bot.sendmsg(config.irc.channel, 'You do not own a weapon!') - return - clip = reg[2] - - ammunition = reg[3] - - if clip == 0: - logging.debug('Weapon out of ammo! !buy ammo and !reload') - c.execute("INSERT OR REPLACE INTO weapons VALUES (:name, :weaponheld, :clip, :ammunition, :expire)", {'name': nick, 'weaponheld': weaponheld, 'clip': clip, 'ammunition': ammunition, 'expire': expire}) - - conn.commit() - await bot.sendmsg(config.irc.channel, f'{color("OUT OF AMMO - !reload", red)}') - else: - c.execute("SELECT * FROM weapons WHERE name=(:name)", {'name': name}) - checkexpire=c.fetchall() - for expiring in checkexpire: - expires = expiring[4] - if expires == 300: - logging.debug('User weapon has expired Weapon and Ammo Purged. !buy weapon') - await bot.sendmsg(config.irc.channel, f'[Player weapon has expired... purging weapon! for a new one]') - c.execute('''UPDATE WEAPONS set WEAPONHELD = False, - CLIP = 0, - AMMUNITION = 0, - EXPIRE = 0 - WHERE name = (:name)''', {'name': name}) - conn.commit() - return - - clip = clip - 3 - c.execute("INSERT OR REPLACE INTO weapons VALUES (:name, :weaponheld, :clip, :ammunition, :expire)", {'name': nick, 'weaponheld': weaponheld, 'clip': clip, 'ammunition': ammunition, 'expire': expire}) - - conn.commit() - - shooter = c.execute("SELECT * FROM users WHERE name=(:name)", {'name': player}) - for reg in shooter: - playerhealth = reg[3] - damage = random.randint(80, 120) - damage = min(damage, int(playerhealth)) - - playerhealth = int(playerhealth) - int(damage) - expire = expire + 1 - c.execute("UPDATE WEAPONS set EXPIRE = (:expire) where NAME = (:name)", {'expire': expire, 'name': name}) - conn.commit() - if playerhealth <= 0: - await bot.sendmsg(config.irc.channel, '[Player {1} killed {2} and did {3} damage]'.format(0, color(nick, light_green), color(player, red), color(int(damage), light_green))) - await addmoney(nick) - await addkillstat(nick) - await adddeathstat(player) - playerhealth = 0 - c.execute('UPDATE USERS set HEALTH = (:health) where NAME = (:name)', {'health': playerhealth, 'name': player}) - conn.commit() - return - c.execute('UPDATE USERS set HEALTH = (:health) where NAME = (:name)', {'health': playerhealth, 'name': player}) - conn.commit() - #await bot.sendmsg(config.irc.channel, f'[{player} health is now {playerhealth} and took {damage} damage!]') - await bot.sendmsg(config.irc.channel, '[Character: {1}] shot at [{2}] with an M16 and did [{3}] damage!'.format(0, color(nick, light_green), color(player, red), color(int(damage), green))) - - - await bot.sendmsg(config.irc.channel, f'[Remaining clip magazine rounds: {clip}]') -async def shop(): - logging.debug('Printing shop items!') - await bot.sendmsg(config.irc.channel, f'[Shop Accessories]') - await bot.sendmsg(config.irc.channel, f'[!buy weapon - purchase a 3-round burst gun (note: weapon has a quality of 300 trigger limit)]') - await bot.sendmsg(config.irc.channel, f'[!buy ammo - buy ammunition (+60 rounds) for your weapon]') - await bot.sendmsg(config.irc.channel, f'[!buy bandages ]') - # await bot.sendmsg(config.irc.channel, f'[!buy bandages - buys bandages for health] {color("* not done yet", red)}') - -async def buyammo(nick): - c.execute(f"SELECT * FROM weapons WHERE name=:name", {'name': nick}) - weapons = c.fetchall() - c.execute(f"SELECT * FROM users WHERE name=:name", {'name': nick}) - user = c.fetchall() - for reg in user: - name = nick - money = reg[6] - newmoney = money - 50 - c.execute("UPDATE USERS set MONEY = (:money) where NAME = (:name)", {'money': newmoney, 'name': name}) - conn.commit() - await bot.sendmsg(config.irc.channel, f'[Player {name} purchased 60 rounds of ammunition!]') - for weps in weapons: - - ammunition = weps[3] - weaponheld = weps[1] - clip = weps[2] - ammunition += 60 - expire = weps[4] - c.execute("INSERT OR REPLACE INTO weapons VALUES (:name, :weaponheld, :clip, :ammunition, :expire)", {'name': nick, 'weaponheld': weaponheld, 'clip': clip, 'ammunition': ammunition, 'expire': expire}) - conn.commit() - await bot.sendmsg(config.irc.channel, f'[Player {nick} weapon ammunition is now {ammunition}]') - -async def removeweapon(nick): - remweapon = Weapons(nick, 0, 0, 0) - - c.execute("UPDATE WEAPONS set WEAPONHELD = (:weaponheld) where NAME = (:name)", {'weaponheld': 0, 'name': nick}) - conn.commit() - logging.debug('Removed weapon') - -async def buyweapon(nick): - c.execute(f"SELECT * FROM weapons WHERE name=:name", {'name': nick}) - weapons = c.fetchall() - c.execute(f"SELECT * FROM users WHERE name=:name", {'name': nick}) - user = c.fetchall() - for regs in user: - name = nick - money = regs[6] - for weapon in weapons: - weaponheld = weapon[1] - if weaponheld == 1: - await bot.sendmsg(config.irc.channel, "[Weapon is already held, !buy ammo for more ammunition]") - logging.debug('Weapon is already held, returning') - return - clip = 30 - ammunition = 60 - money = money - 500 - - c.execute("UPDATE USERS set MONEY = (:money) where NAME = (:name)", {'money': money, 'name': nick}) - conn.commit() - logging.debug(f'Attempting to buy Weapon for {nick}') - weaponheld = True - - await bot.sendmsg(config.irc.channel, f"[Player: {nick} has purchased a gun for $500! Loaded clip of {clip} rounds!]") - logging.debug('Buying weapon') - expire = 0 - c.execute("INSERT OR REPLACE INTO weapons VALUES (:name, :weaponheld, :clip, :ammunition, :expire)", {'name': nick, 'weaponheld': weaponheld, 'clip': clip, 'ammunition': ammunition, 'expire': expire}) - conn.commit() - -async def removeuser(nick): - logging.debug(f'Removing user {nick}') - name = nick - c.execute('''DELETE FROM users WHERE name=?''',(name,)) - conn.commit() - logging.debug(f'Removed user {nick}') - -async def createuser(nick): - - logging.debug(f'Attemping to create user {nick}') - reguser = Users(nick, 1, 500, 500, 100, 100, 5000, 500) - - logging.debug(f'User {nick} added to database') - - c.execute("INSERT OR REPLACE INTO users VALUES (:name, :level, :experience, :health, :attack, :defense, :money, :healthmax)", {'name': nick, 'level': reguser.level, 'experience': reguser.experience, 'health': reguser.health, 'attack': reguser.attack, 'defense': reguser.defense, 'money': reguser.money, 'healthmax': reguser.healthmax}) - conn.commit() - c.execute(f'SELECT rowid FROM stats WHERE name=(:name)', {'name': nick}) - checkrow=c.fetchone() - if checkrow == None: - kills = 0 - deaths = 0 - c.execute(f'INSERT OR REPLACE INTO stats VALUES (:name, :kills, :deaths)', {'name': nick, 'kills': kills, 'deaths': deaths}) - conn.commit() - #await bot.sendmsg(config.irc.channel, f'[Player {color(name, light_green)} has a total of {color(kills, red)} kills!]') -async def setlevel(nick, level): - if level == '1': - experience = '500' - health = '500' - attack = '100' - defense = '100' - healthmax = '500' - c.execute(f'''UPDATE USERS set LEVEL = (:level), - EXPERIENCE = (:experience), - HEALTH = (:health), - ATTACK = (:attack), - DEFENSE = (:defense), - HEALTHMAX = (:healthmax) - where NAME = (:name)''', {'level': level, 'experience': experience, 'health': health, 'attack': attack, 'defense': defense, 'name': nick, 'healthmax': healthmax}) - conn.commit() - await bot.sendmsg(config.irc.channel, f"[Player: {nick} is now level {color(level, red)}]") - - elif level == '2': - experience = '1000' - health = '1000' - attack = '150' - defense = '150' - healthmax = '1000' - c.execute(f'''UPDATE USERS set LEVEL = (:level), - EXPERIENCE = (:experience), - HEALTH = (:health), - ATTACK = (:attack), - DEFENSE = (:defense), - HEALTHMAX = (:healthmax) - where NAME = (:name)''', {'level': level, 'experience': experience, 'health': health, 'attack': attack, 'defense': defense, 'name': nick, 'healthmax': healthmax}) - conn.commit() - await bot.sendmsg(config.irc.channel, f"[Player: {nick} is now level {color(level, red)}]") - - - elif level == '3': - experience = '2000' - health = '1500' - attack = '175' - defense = '175' - healthmax = '1500' - c.execute(f'''UPDATE USERS set LEVEL = (:level), - EXPERIENCE = (:experience), - HEALTH = (:health), - ATTACK = (:attack), - DEFENSE = (:defense), - HEALTHMAX = (:healthmax) - where NAME = (:name)''', {'level': level, 'experience': experience, 'health': health, 'attack': attack, 'defense': defense, 'name': nick, 'healthmax': healthmax}) - conn.commit() - await bot.sendmsg(config.irc.channel, f"[Player: {nick} is now level {color(level, red)}]") - - elif level == '4': - experience = '3000' - health = '2000' - attack = '200' - defense = '200' - healthmax = '2000' - c.execute(f'''UPDATE USERS set LEVEL = (:level), - EXPERIENCE = (:experience), - HEALTH = (:health), - ATTACK = (:attack), - DEFENSE = (:defense), - HEALTHMAX = (:healthmax) - where NAME = (:name)''', {'level': level, 'experience': experience, 'health': health, 'attack': attack, 'defense': defense, 'name': nick, 'healthmax': healthmax}) - conn.commit() - await bot.sendmsg(config.irc.channel, f"[Player: {nick} is now level {color(level, red)}]") - - elif level == '5': - experience = '5000' - health = '3000' - attack = '225' - defense = '225' - healthmax = '3000' - c.execute(f'''UPDATE USERS set LEVEL = (:level), - EXPERIENCE = (:experience), - HEALTH = (:health), - ATTACK = (:attack), - DEFENSE = (:defense), - HEALTHMAX = (:healthmax) - where NAME = (:name)''', {'level': level, 'experience': experience, 'health': health, 'attack': attack, 'defense': defense, 'name': nick, 'healthmax': healthmax}) - conn.commit() - await bot.sendmsg(config.irc.channel, f"[Player: {nick} is now level {color(level, red)}]") - elif int(level) > 5: - await bot.sendmsg(config.irc.channel, "[Error: Invalid Level]") - return - -async def closesql(): - conn.close() -class combat: - class attacker: - name = '' - attack = '' - class defender: - name = '' - defense = '' - health = '' - -async def punch(player, nick): - check = await checkexist(player) - if check is False: - return - else: - for name in (nick): - c.execute(f"SELECT * FROM users WHERE name=:name", {'name': nick}) - attacker = c.fetchall() - c.execute(f"SELECT * FROM users WHERE name=:name", {'name': player}) - defender = c.fetchall() - if nick == player: - await bot.sendmsg(config.irc.channel, '[Error: {1}]'.format(0,color('Cannot Attack Yourself', red))) - return - for att in attacker: - combat.attacker.name = att[0] - combat.attacker.attack = att[4] - combat.attacker.health = att[3] - if combat.attacker.health == 0: - await bot.sendmsg(config.irc.channel, '[Error: You Are {1}!]'.format(0, color('Dead', red))) - return - for defend in defender: - combat.defender.name = defend[0] - combat.defender.defense = defend[5] - combat.defender.health = defend[3] - playerhealth = combat.defender.health - - if combat.defender.health <= 0: - await bot.sendmsg(config.irc.channel, f'[Player targeted is {color("DEAD", light_blue)}]') - return - playerdef = combat.defender.defense - playerattack = combat.attacker.attack - critical_multiplier = 1.1 if random.random() < 0.10 else 1.0 - effective_defense = int(playerdef) * random.uniform(0.9, 1.1) - effective_attack = int(playerattack) * random.uniform(1.0, 1.1) - damage = effective_attack * (50 / (50 + effective_defense)) * critical_multiplier - damage = min(damage, int(playerhealth)) - - combat.defender.health = int(playerhealth) - int(damage) - c.execute(f'''UPDATE USERS set HEALTH = (:health) where NAME = (:name)''', {'health': combat.defender.health, 'name': combat.defender.name}) - - conn.commit() - if combat.defender.health <= 0: - await bot.sendmsg(config.irc.channel, '[Player {1} killed {2} and did {3} damage]'.format(0, color(nick, light_green), color(player, red), color(int(damage), light_green))) - await addmoney(nick) - await addkillstat(nick) - await adddeathstat(player) - combat.defender.health = 0 - return - await bot.sendmsg(config.irc.channel, '[Character: {1}] Punched [{2}] and did [{3}] damage!'.format(0, color(nick, light_green), color(player, red), color(int(damage), green))) - - - c.execute(f'''UPDATE USERS set HEALTH = (:health) where NAME = (:name)''', {'health': combat.defender.health, 'name': combat.defender.name}) - - conn.commit() - -async def profile(nick): - - - check = await checkexist(nick) - if check is False: - return - try: - c.execute(f"SELECT * FROM users WHERE name=(:name)", {'name': nick}) - reg = c.fetchall() - for regs in reg: - name = regs[0] - level = regs[1] - experience = regs[2] - health = regs[3] - attack = regs[4] - defense = regs[5] - money = regs[6] - healthmax = regs[7] - c.execute(f'SELECT * FROM stats WHERE name=(:name)', {'name': name}) - grabstats=c.fetchall() - for stats in grabstats: - kills = stats[1] - deaths = stats[2] - await bot.sendmsg(config.irc.channel, f'[Player: {color(name, light_green)}] [Level: {color(level, red)}] [Experience: {color(experience, blue)}] [Health: {color(health, light_green)}/{color(healthmax, green)}] [Att/Def: {color(attack, light_green)}/{color(defense, red)}] [Money: {color(money, light_blue)}] [Kills: {color(kills, light_blue)}] [Deaths: {color(deaths, red)}]') - - except Exception as ex: - print('Error {0}'.format(0, ex)) - #bot.sendmsg(config.irc.channel, '[Error: No Such User]') - -async def revive(nick): - check = await checkexist(nick) - if check is False: - return - - c.execute("SELECT * FROM users WHERE name=(:name)", {'name': nick}) - - checkhealth=c.fetchall() - - for amount in checkhealth: - health = amount[3] - max = amount[7] - if health <= 0: - c.execute("UPDATE USERS set HEALTH = (:health) WHERE NAME = (:name)", {'health': max, 'name': nick}) - logging.debug('test') - conn.commit() - await bot.sendmsg(config.irc.channel, f'[Player {color(nick,light_green)} has been revived!]') - else: - await bot.sendmsg(config.irc.channel, f'[You are not DEAD! No reviving the living!]') -class config: - class irc: - server = 'irc.supernets.org' - port = 6667 - username = 'vortex' - realname = 'FightBot by vorteckz' - nickname = 'FightBot' - channel = '#dev' - channelkey = 'test' - admins = {'vortex', 'vorteckz','acidvegas','peanuter'} - class throttle: - cmd = 0.5 - msg = 0.5 - reconnect = 10 - rejoin = 3 - last = 0 - slow = False - lastnick = None - -def color(msg: str, foreground: str, background: str='') -> str: - ''' - Color a string with the specified foreground and background colors. - - :param msg: The string to color. - :param foreground: The foreground color to use. - :param background: The background color to use. - ''' - return f'\x03{foreground},{background}{msg}{reset}' if background else f'\x03{foreground}{msg}{reset}' - -def ssl_ctx() -> ssl.SSLContext: - '''Create a SSL context for the connection.''' - ctx = ssl.create_default_context() - #ctx.verify_mode = ssl.CERT_NONE # Comment out this line to verify hosts - #ctx.load_cert_chain('/path/to/cert', password='loldongs') - return ctx -async def getmoney(nick): - c.execute(f"SELECT * FROM users WHERE name=(:name)", {'name': nick}) - moneygrab = c.fetchall() - for money in moneygrab: - moneyamount = money[6] - writemoney = f'{moneyamount:,}' - await bot.sendmsg(config.irc.channel, f'[Bank Balance: ${color(writemoney, light_blue)}]') - -async def ammo(nick): - c.execute(f'SELECT rowid FROM users WHERE name=(:name)', {'name': nick}) - exist = c.fetchone() - - if exist is None: - await bot.sendmsg(config.irc.channel, f'[User {nick} does not have an account!]') - return - c.execute(f"SELECT * FROM weapons WHERE name=(:name)", {'name': nick}) - checkammo = c.fetchall() - - for ammo in checkammo: - hasweapon = ammo[1] - if hasweapon == False: - await bot.sendmsg(config.irc.channel, f'[You do not currently have a weapon.. !buy weapon]') - return - ammoclipcount = ammo[2] - ammomagcount = ammo[3] - await bot.sendmsg(config.irc.channel, f"[Ammo Count] [Current Clip Holding: {ammoclipcount}] [Arsenal Magazine Rounds: {ammomagcount}]") -async def addmoney(nick): - c.execute(f"SELECT * FROM users WHERE name=:name", {'name': nick}) - - moneygrab = c.fetchall() - - for money in moneygrab: - moneyamount = money[6] - profit = 500 - moneyamount += profit - moneyamountformat = f'{moneyamount:,}' - await bot.sendmsg(config.irc.channel, f'[You gained ${color(profit, blue)}!] [Bank Balance: ${color(moneyamountformat, light_blue)}]') - c.execute(f'''UPDATE USERS set MONEY = (:money) where NAME = (:name)''', {'money': moneyamount, 'name': nick}) - conn.commit() - - - -class Bot(): - def __init__(self): - self.nickname = config.irc.nickname - self.username = config.irc.username - self.realname = config.irc.realname - self.channel = config.irc.channel - self.channelkey = config.irc.channelkey - self.reader = None - self.writer = None - - createtable() - - async def action(self, chan: str, msg: str): - ''' - Send an ACTION to the IRC server. - - :param chan: The channel to send the ACTION to. - :param msg: The message to send to the channel. - ''' - await self.sendmsg(chan, f'\x01ACTION {msg}\x01') - - async def raw(self, data: str): - ''' - Send raw data to the IRC server. - - :param data: The raw data to send to the IRC server. (512 bytes max including crlf) - ''' - self.writer.write(data[:510].encode('utf-8') + b'\r\n') - - async def sendmsg(self, target: str, msg: str): - ''' - Send a PRIVMSG to the IRC server. - - :param target: The target to send the PRIVMSG to. (channel or user) - :param msg: The message to send to the target. - ''' - try: - await self.raw(f'PRIVMSG {target} :{msg}') - - time.sleep(config.throttle.msg) - except: - await bot.sendmsg(config.irc.channel, "Slow Down Nerd!") - - async def connect(self): - '''Connect to the IRC server.''' - while True: - try: - options = { - 'host' : args.server, - 'port' : args.port if args.port else 6697 if args.ssl else 6667, - 'limit' : 1024, # Buffer size in bytes (don't change this unless you know what you're doing) - 'ssl' : ssl_ctx() if args.ssl else None, - 'family' : 10 if args.v6 else 2, # 10 = AF_INET6 (IPv6), 2 = AF_INET (IPv4) - 'local_addr' : args.vhost if args.vhost else None # Can we just leave this as args.vhost? - } - self.reader, self.writer = await asyncio.wait_for(asyncio.open_connection(**options), 15) # 15 second timeout - if args.password: - await self.raw('PASS ' + args.password) # Rarely used, but IRCds may require this - await self.raw(f'USER {self.username} 0 * :{self.realname}') # These lines must be sent upon connection - await self.raw('NICK ' + self.nickname) # They are to identify the bot to the server - while not self.reader.at_eof(): - data = await asyncio.wait_for(self.reader.readuntil(b'\r\n'), 300) # 5 minute ping timeout - await self.handle(data.decode('utf-8').strip()) # Handle the data received from the IRC server - except Exception as ex: - logging.error(f'failed to connect to {args.server} ({str(ex)})') - finally: - await asyncio.sleep(30) # Wait 30 seconds before reconnecting - - async def handle(self, data: str): - ''' - Handle the data received from the IRC server. - - :param data: The data received from the IRC server. - ''' - try: - logging.info(data) - args = data.split() - if data.startswith('ERROR :Closing Link:'): - raise Exception('Cannot Connect') - if args[0] == 'PING': - await self.raw('PONG ' + args[1]) # Respond to the server's PING request with a PONG to prevent ping timeout - elif args[1] == '001': # RPL_WELCOME - await self.raw(f'MODE {self.nickname} +B') # Set user mode +B (Bot) - await asyncio.sleep(10) # Wait 10 seconds before joining the channel (required by some IRCds to wait before JOIN) - await self.raw(f'JOIN {self.channel} {self.channelkey}') - elif args[1] == '433': # ERR_NICKNAMEINUSE - self.nickname += '_' # If the nickname is already in use, append an underscore to the end of it - await self.raw('NICK ' + self.nickname) # Send the new nickname to the server - elif args[1] == 'KICK': - chan = args[2] - kicked = args[3] - if kicked == self.nickname: - await asyncio.sleep(3) - await self.raw(f'JOIN {chan}') - elif args[1] == 'PRIVMSG': - ident = args[0][1:] - nick = args[0].split('!')[0][1:] - target = args[2] - msg = ' '.join(args[3:])[1:] - arguments = msg.split() - bandageamount = '0' - if target == self.nickname: - pass # Handle private messages here - if target.startswith('#'): # Channel message - if msg.startswith('!'): - try: - if time.time() - config.throttle.last < config.throttle.cmd and config.throttle.lastnick == nick: - if not config.throttle.slow: - config.throttle.slow = True - await bot.sendmsg(config.irc.channel, color("Slow down homie!!", red)) - - else: - config.throttle.slow = False - config.throttle.lastnick = nick - - if arguments[0] == '!hug': - await bot.sendmsg(target, f'[XOXO Hugger9000... {nick} hugs {arguments[1]}]') - if arguments[0] == '!admins': - for i in config.irc.admins: - await bot.sendmsg(target, f'[Admins: ' + color(i, red) + ']') - if arguments[0] == '!shop': - await shop() - if arguments[0] == '!buy' and arguments[1] != None: - if arguments[1] == 'weapon': - await buyweapon(nick) - elif arguments[1] == 'ammo': - await buyammo(nick) - - elif arguments[1] == 'bandages': - if len(arguments) <= 2 or int(arguments[2]) == 0: - await bot.sendmsg(config.irc.channel, '[You must specify amount of bandages (greater than 0) to purchase]') - else: - await buybandages(nick, int(arguments[2])) - - if arguments[0] == '!shoot': - await shoot(arguments[1], nick) - if arguments[0] == '!reload': - await reload(nick) - if arguments[0] == '!ammo': - await ammo(nick) - if arguments[0] == '!heal': - await heal(nick) - if arguments[0] == '!revive': - await revive(nick) - if arguments[0] == '!help': - await bot.sendmsg(config.irc.channel, '[Command List]') - await bot.sendmsg(config.irc.channel, '[!help - shows commands]') - await bot.sendmsg(config.irc.channel, '[!register - Register your player]') - await bot.sendmsg(config.irc.channel, '[!profile - Shows Profile Stats [!profile username]') - await bot.sendmsg(config.irc.channel, '[!punch - Fight [!punch username]') - await bot.sendmsg(config.irc.channel, '[!shoot - Shoot if you own a weapon]') - await bot.sendmsg(config.irc.channel, '[!bank - Returns Bank Balance]') - await bot.sendmsg(config.irc.channel, '[!buy [weapon, ammo, bandages ]') - await bot.sendmsg(config.irc.channel, '[!reload - Reloads Weapon]') - await bot.sendmsg(config.irc.channel, '[!ammo - Show Ammunition Amounts]') - await bot.sendmsg(config.irc.channel, '[!revive - Brings you back to health if dead]') - await bot.sendmsg(config.irc.channel, '[!heal - Use bandages to regain health]') - await bot.sendmsg(config.irc.channel, ' ') - await bot.sendmsg(config.irc.channel, '[Admin Command List]') - await bot.sendmsg(config.irc.channel, '[!setlevel - !setlevel username Level (1 to 5)]') - await bot.sendmsg(config.irc.channel, '[!adduser - Force create a user]') - await bot.sendmsg(config.irc.channel, '[!remove - Removes a player]') - await bot.sendmsg(config.irc.channel, '[!removeweapon - Remove user weapon]') - if arguments[0] == '!bank': - await getmoney(nick) - if nick in config.irc.admins: - #await self.sendmsg(target, f'{nick} is an ' + color('Admin!', red)) - if arguments[0] == '!removeweapon': - await removeweapon(nick) - if arguments[0] == '!adduser': - name = arguments[1] - c.execute(f"SELECT rowid FROM users WHERE name = (:name)", {'name': name}) - - data=c.fetchone() - if data is None: - await bot.sendmsg(config.irc.channel, 'Registering Player: %s'%name) - await createuser(name) - await profile(name) - else: - await bot.sendmsg(config.irc.channel, f'{color("Player already exists!", red)}') - - if arguments[0] == '!remove': - logging.debug('remove user') - name = arguments[1] - c.execute(f"SELECT rowid FROM users WHERE name= (:name)", {'name': name}) - data=c.fetchone() - if data != None: - await bot.sendmsg(config.irc.channel, f'[Removing {color(name, red)} from database]') - await removeuser(name) - else: - await bot.sendmsg(config.irc.channel, f'[User does not exist]') - - if arguments[0] == '!setlevel': - await setlevel(arguments[1], arguments[2]) - if arguments[0] == '!register': - c.execute(f"SELECT rowid FROM users WHERE name = (:name)", {'name': nick}) - - data=c.fetchone() - if data is None: - await bot.sendmsg(config.irc.channel, 'Registering Player: %s'%nick) - await createuser(nick) - await profile(nick) - else: - await bot.sendmsg(config.irc.channel, f'{color("Player already exists!", red)}') - if arguments[0] == '!profile': - try: - await profile(arguments[1]) - except: - await profile(nick) - if arguments[0] == '!punch': - - await punch(arguments[1].lower(), nick) - if msg == '!hello': - await self.sendmsg(target, f'Hello {nick}! Do you like ' + color('colors?', green)) - - config.throttle.last = time.time() - except Exception as ex: - if time.time() - config.throttle.last < config.throttle.cmd: - if not config.throttle.slow: - await bot.sendmsg(config.irc.channel, color('Slow down nerd!', red)) - config.throttle.slow = True - config.throttle.last = time.time() - - #except (UnicodeDecodeError, UnicodeEncodeError): - #pass # Some IRCds allow invalid UTF-8 characters, this is a very important exception to catch - except Exception as ex: - logging.exception(f'Unknown error has occured! ({ex})') - - -def setup_logger(log_filename: str, to_file: bool = False): - ''' - Set up logging to console & optionally to file. - - :param log_filename: The filename of the log file - ''' - sh = logging.StreamHandler() - sh.setFormatter(logging.Formatter('%(asctime)s | %(levelname)9s | %(message)s', '%I:%M %p')) - if to_file: - fh = logging.handlers.RotatingFileHandler(log_filename+'.log', maxBytes=250000, backupCount=3, encoding='utf-8') # Max size of 250KB, 3 backups - fh.setFormatter(logging.Formatter('%(asctime)s | %(levelname)9s | %(filename)s.%(funcName)s.%(lineno)d | %(message)s', '%Y-%m-%d %I:%M %p')) # We can be more verbose in the log file - logging.basicConfig(level=logging.NOTSET, handlers=(sh,fh)) - else: - logging.basicConfig(level=logging.NOTSET, handlers=(sh,)) - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description="Connect to an IRC server.") # The arguments without -- are required arguments. - parser.add_argument("server", help="The IRC server address.") - parser.add_argument("channel", help="The IRC channel to join.") - parser.add_argument("--password", help="The password for the IRC server.") - parser.add_argument("--port", type=int, help="The port number for the IRC server.") # Port is optional, will default to 6667/6697 depending on SSL. - parser.add_argument("--ssl", action="store_true", help="Use SSL for the connection.") - parser.add_argument("--v4", action="store_true", help="Use IPv4 for the connection.") - parser.add_argument("--v6", action="store_true", help="Use IPv6 for the connection.") - parser.add_argument("--key", default="", help="The key (password) for the IRC channel, if required.") - parser.add_argument("--vhost", help="The VHOST to use for connection.") - args = parser.parse_args() - config.irc.channel = args.channel - if args.key: - config.irc.channelkey = args.key - print(f"Connecting to {args.server}:{args.port} (SSL: {args.ssl}) and joining {args.channel} (Key: {args.key or 'None'})") - - setup_logger('skeleton', to_file=True) # Optionally, you can log to a file, change to_file to False to disable this. - - bot = Bot() # We define this here as an object so we can call it from an outside function if we need to. - +#!/usr/bin/env python +# FightBot IRC bot - based on acidvegas skeleton in python +import argparse +import asyncio +import logging +import logging.handlers +import ssl +import sqlite3 +import random +import time + +# Formatting Control Characters / Color Codes +bold = '\x02' +italic = '\x1D' +underline = '\x1F' +reverse = '\x16' +reset = '\x0f' +white = '00' +black = '01' +blue = '02' +green = '03' +red = '04' +brown = '05' +purple = '06' +orange = '07' +yellow = '08' +light_green = '09' +cyan = '10' +light_cyan = '11' +light_blue = '12' +pink = '13' +grey = '14' +light_grey = '15' +conn = sqlite3.connect('data.db') +c = conn.cursor() + + +def createtable(): + c.execute('''CREATE TABLE if not exists users ( + name text unique, + level integer, + experience integer, + health integer, + attack integer, + defense integer, + money integer, + healthmax integer + +)''') + c.execute('''CREATE TABLE if not exists weapons ( + name text unique, + weaponheld integer, + clip integer, + ammunition integer, + expire integer + +)''') + c.execute('''CREATE TABLE if not exists items ( + name text unique, + bandages integer + )''') + c.execute('''CREATE TABLE if not exists stats ( + name text unique, + kills integer, + deaths integer + )''') + + +class Users: + def __init__(self, name, level, experience, health, attack, defense, money, healthmax): + self.name = name + self.level = level + self.experience = experience + self.health = health + self.attack = attack + self.defense = defense + self.money = money + self.healthmax = healthmax + +class Weapons: + def __init__(self, name, weaponheld, clip, ammunition): + self.name = name + self.weaponheld = weaponheld + self.clip = clip + self.ammunition = ammunition + self.expire = 0 +class Items: + def __init__(self, name, bandages): + self.name = name + self.bandages = bandages +async def addkillstat(name): + c.execute(f'SELECT rowid FROM stats WHERE name=(:name)', {'name': name}) + checkrow=c.fetchone() + if checkrow == None: + kills = 1 + deaths = 0 + c.execute(f'INSERT OR REPLACE INTO stats VALUES (:name, :kills, :deaths)', {'name': name, 'kills': kills, 'deaths': deaths}) + conn.commit() + await bot.sendmsg(config.irc.channel, f'[Player {color(name, light_green)} has a total of {color(kills, red)} kills!]') + + else: + c.execute(f'SELECT * FROM stats WHERE name=(:name)', {'name': name}) + getkills=c.fetchall() + for retrieve in getkills: + kills = retrieve[1] + 1 + + c.execute(f'UPDATE stats SET KILLS = (:kills) WHERE name=(:name)', {'kills': kills, 'name': name}) + conn.commit() + await bot.sendmsg(config.irc.channel, f'[Player {color(name, light_green)} has a total of {color(kills, red)} kills!]') + +async def adddeathstat(name): + c.execute(f'SELECT rowid FROM stats WHERE name=(:name)', {'name': name}) + checkrow=c.fetchone() + if checkrow == None: + kills = 0 + deaths = 1 + c.execute(f'INSERT OR REPLACE INTO stats VALUES (:name, :kills, :deaths)', {'name': name, 'kills': kills, 'deaths': deaths}) + conn.commit() + await bot.sendmsg(config.irc.channel, f'[Opponent Player {color(name, red)} has died {color(deaths, red)} times!]') + + else: + c.execute(f'SELECT * FROM stats WHERE name=(:name)', {'name': name}) + getkills=c.fetchall() + for retrieve in getkills: + kills = retrieve[1] + deaths = retrieve[2] + 1 + + c.execute(f'UPDATE stats SET DEATHS = (:deaths) WHERE name=(:name)', {'deaths': deaths, 'name': name}) + conn.commit() + await bot.sendmsg(config.irc.channel, f'[Player {color(name, red)} has died {color(deaths, red)} times!]') + + +async def buybandages(name, amount): + if amount == 0 or amount == None: + await bot.sendmsg(config.irc.channel, f'[Must specify how many bandages you want... !buy bandages ]') + c.execute(f'SELECT rowid FROM items WHERE name=(:name)', {'name': name}) + checkrow=c.fetchone() + if checkrow == None: + bandages = 0 + c.execute(f'INSERT OR REPLACE INTO items VALUES (:name, :bandages)', {'name': name, 'bandages': bandages}) + conn.commit() + shopamount = amount * 50 + c.execute(f'SELECT * FROM items WHERE name=(:name)', {'name': name}) + look = c.fetchall() + + for band in look: + bandages = band[1] + + c.execute(f'SELECT * FROM users WHERE name=(:name)', {'name': name}) + usermoney = c.fetchall() + for grabmoney in usermoney: + money = grabmoney[6] + if money >= shopamount: + await bot.sendmsg(config.irc.channel, f'[You have enough money [${money:,}] to purchase [{amount}] bandages! Cost is ${shopamount:,}]') + else: + await bot.sendmsg(config.irc.channel, f'[You do {color("NOT", red)} have enough funds!]') + return + bandages = band[1] + bandagestotal = bandages + amount + c.execute(f'UPDATE ITEMS set BANDAGES = (:bandages) WHERE NAME = (:name)', {'bandages': bandagestotal, 'name': name}) + conn.commit() + money = money - shopamount + c.execute(f'UPDATE users set MONEY = (:money) WHERE NAME = (:name)', {'money': money, 'name': name}) + conn.commit() +async def heal(name): + + + c.execute(f'SELECT * from USERS WHERE name= (:name)', {'name': name}) + newtest=c.fetchall() + for userinfo in newtest: + health = userinfo[3] + if health <= 0: + await bot.sendmsg(config.irc.channel, f'[You are dead... !revive to bring yourself back]') + return + c.execute(f'SELECT rowid FROM items WHERE name = (:name)', {'name': name}) + havebandages=c.fetchone() + if havebandages == None: + await bot.sendmsg(config.irc.channel, f'[You do not have any bandages... !buy bandages ]') + return + c.execute(f'SELECT * FROM items WHERE name = (:name)', {'name': name}) + bandaids = c.fetchall() + for bandages in bandaids: + if bandages[1] <= 0: + await bot.sendmsg(config.irc.channel, f'[You do not have any bandages... !buy bandages ]') + return + maxhealth = userinfo[7] + if health == maxhealth: + await bot.sendmsg(config.irc.channel, f'[You already at FULL HEALTH]') + return + newhealth = health + 25 + if newhealth >= maxhealth: + health = maxhealth + c.execute(f'UPDATE USERS set HEALTH = (:health) where NAME = (:name)', {'health': health, 'name': name}) + conn.commit() + await bot.sendmsg(config.irc.channel, f'[Player healed {color("+25", light_green)} to MAX health {color(health, light_green)}]') + else: + c.execute(f'UPDATE USERS set HEALTH = (:health) where NAME = (:name)', {'health': newhealth, 'name': name}) + conn.commit() + await bot.sendmsg(config.irc.channel, f'[Player healed {color("+25", light_green)} to health {color(newhealth, light_green)}]') + + + c.execute(f'SELECT * FROM items WHERE name=(:name)', {'name': name}) + bandaids=c.fetchall() + for checkitems in bandaids: + bandages = checkitems[1] + bandages = bandages - 1 + c.execute(f'UPDATE ITEMS set BANDAGES = (:bandages) WHERE name = (:name)', {'bandages': bandages, 'name': name}) + conn.commit() +async def checkexist(player): + + c.execute(f"SELECT rowid FROM users WHERE name=(:name)", {'name': player}) + + data=c.fetchone() + if data is None: + await bot.sendmsg(config.irc.channel, 'Invalid Player: %s'%player) + return False + else: + return True +async def reload(nick): + c.execute(f"SELECT rowid FROM users WHERE name=(:name)", {'name': nick}) + data=c.fetchone() + + if data == None: + logging.debug('User is trying to reload without having an account') + await bot.sendmsg(config.irc.channel, f'[User {nick} does not have an account]') + return + + c.execute(f"SELECT * FROM weapons WHERE name=(:name)", {'name': nick}) + data=c.fetchall() + name = nick + for check in data: + hasweapon = check[1] + if hasweapon == False: + logging.debug('User does not have weapon') + await bot.sendmsg(config.irc.channel, f'[You do not currently have a weapon.. !buy weapon]') + return + + maxclip = 30 + clip = check[2] + ammunition = check[3] + if ammunition <= 0: + await bot.sendmsg(config.irc.channel, f'!buy ammo') + return + clipadd = 30 - clip + if ammunition >= clipadd: + ammunition = ammunition - clipadd + clip = clip + clipadd + else: + clip = clip + ammunition + ammunition = 0 + + logging.debug(f'[Current clip ammunition is at {clip} rounds and backup ammunition is at {ammunition} magazine rouunds!]') + + await bot.sendmsg(config.irc.channel, f'[Current clip has {clip} rounds out of {maxclip} mag ammo size and {ammunition} in the arsenal!]') + c.execute(f"UPDATE WEAPONS set CLIP = (:clip) WHERE NAME = (:name)", {'clip': clip, 'name': nick}) + conn.commit() + c.execute(f"UPDATE WEAPONS set AMMUNITION = (:ammunition) WHERE NAME = (:name)", {'ammunition': ammunition, 'name': name}) + conn.commit() +async def shoot(player, nick): + check = await checkexist(player) + if check is False: + return + else: + if player == nick: + logging.debug('Player cannot attack oneself') + await bot.sendmsg(config.irc.channel, '[Error: {1}]'.format(0,color('Cannot Attack Yourself', red))) + return + + c.execute(f'SELECT rowid FROM weapons WHERE name=(:name)', {'name': nick}) + checkrow=c.fetchone() + if checkrow == None: + await bot.sendmsg(config.irc.channel, f'[Error: {color("No Weapons", red)}] - !buy weapon') + return + c.execute(f"SELECT * FROM users WHERE name=(:name)", {'name': nick}) + healthcheck = c.fetchall() + for checkalive in healthcheck: + alive = checkalive[3] + if alive <= 0: + await bot.sendmsg(config.irc.channel, f'[Error: {color("You Are Dead... !revive", red)}]') + return + c.execute(f"SELECT * FROM users WHERE name=(:name)", {'name': player}) + playerhealthcheck = c.fetchall() + for checkalive in playerhealthcheck: + health = checkalive[3] + if health <= 0: + logging.debug('Player targeted is DEAD') + await bot.sendmsg(config.irc.channel, f'[Player targeted is {color("DEAD", light_blue)}]') + return + + c.execute(f"SELECT * FROM weapons WHERE name=(:name)", {'name': nick}) + weapons = c.fetchall() + for reg in weapons: + + name = nick + weaponheld = reg[1] + expire = reg[4] + c.execute(f"SELECT rowid FROM weapons WHERE name=(:name)", {'name': name}) + + if weaponheld == 0: + await bot.sendmsg(config.irc.channel, 'You do not own a weapon!') + return + clip = reg[2] + + ammunition = reg[3] + + if clip == 0: + logging.debug('Weapon out of ammo! !buy ammo and !reload') + c.execute("INSERT OR REPLACE INTO weapons VALUES (:name, :weaponheld, :clip, :ammunition, :expire)", {'name': nick, 'weaponheld': weaponheld, 'clip': clip, 'ammunition': ammunition, 'expire': expire}) + + conn.commit() + await bot.sendmsg(config.irc.channel, f'{color("OUT OF AMMO - !reload", red)}') + else: + c.execute("SELECT * FROM weapons WHERE name=(:name)", {'name': name}) + checkexpire=c.fetchall() + for expiring in checkexpire: + expires = expiring[4] + if expires == 300: + logging.debug('User weapon has expired Weapon and Ammo Purged. !buy weapon') + await bot.sendmsg(config.irc.channel, f'[Player weapon has expired... purging weapon! for a new one]') + c.execute('''UPDATE WEAPONS set WEAPONHELD = False, + CLIP = 0, + AMMUNITION = 0, + EXPIRE = 0 + WHERE name = (:name)''', {'name': name}) + conn.commit() + return + + clip = clip - 3 + c.execute("INSERT OR REPLACE INTO weapons VALUES (:name, :weaponheld, :clip, :ammunition, :expire)", {'name': nick, 'weaponheld': weaponheld, 'clip': clip, 'ammunition': ammunition, 'expire': expire}) + + conn.commit() + + shooter = c.execute("SELECT * FROM users WHERE name=(:name)", {'name': player}) + for reg in shooter: + playerhealth = reg[3] + damage = random.randint(80, 120) + damage = min(damage, int(playerhealth)) + + playerhealth = int(playerhealth) - int(damage) + expire = expire + 1 + c.execute("UPDATE WEAPONS set EXPIRE = (:expire) where NAME = (:name)", {'expire': expire, 'name': name}) + conn.commit() + if playerhealth <= 0: + await bot.sendmsg(config.irc.channel, '[Player {1} killed {2} and did {3} damage]'.format(0, color(nick, light_green), color(player, red), color(int(damage), light_green))) + await addmoney(nick) + await addkillstat(nick) + await adddeathstat(player) + playerhealth = 0 + c.execute('UPDATE USERS set HEALTH = (:health) where NAME = (:name)', {'health': playerhealth, 'name': player}) + conn.commit() + return + c.execute('UPDATE USERS set HEALTH = (:health) where NAME = (:name)', {'health': playerhealth, 'name': player}) + conn.commit() + #await bot.sendmsg(config.irc.channel, f'[{player} health is now {playerhealth} and took {damage} damage!]') + await bot.sendmsg(config.irc.channel, '[Character: {1}] shot at [{2}] with an M16 and did [{3}] damage!'.format(0, color(nick, light_green), color(player, red), color(int(damage), green))) + + + await bot.sendmsg(config.irc.channel, f'[Remaining clip magazine rounds: {clip}]') +async def shop(): + logging.debug('Printing shop items!') + await bot.sendmsg(config.irc.channel, f'[Shop Accessories]') + await bot.sendmsg(config.irc.channel, f'[!buy weapon - purchase a 3-round burst gun (note: weapon has a quality of 300 trigger limit)]') + await bot.sendmsg(config.irc.channel, f'[!buy ammo - buy ammunition (+60 rounds) for your weapon]') + await bot.sendmsg(config.irc.channel, f'[!buy bandages ]') + # await bot.sendmsg(config.irc.channel, f'[!buy bandages - buys bandages for health] {color("* not done yet", red)}') + +async def buyammo(nick): + c.execute(f"SELECT * FROM weapons WHERE name=:name", {'name': nick}) + weapons = c.fetchall() + c.execute(f"SELECT * FROM users WHERE name=:name", {'name': nick}) + user = c.fetchall() + for reg in user: + name = nick + money = reg[6] + newmoney = money - 50 + c.execute("UPDATE USERS set MONEY = (:money) where NAME = (:name)", {'money': newmoney, 'name': name}) + conn.commit() + await bot.sendmsg(config.irc.channel, f'[Player {name} purchased 60 rounds of ammunition!]') + for weps in weapons: + + ammunition = weps[3] + weaponheld = weps[1] + clip = weps[2] + ammunition += 60 + expire = weps[4] + c.execute("INSERT OR REPLACE INTO weapons VALUES (:name, :weaponheld, :clip, :ammunition, :expire)", {'name': nick, 'weaponheld': weaponheld, 'clip': clip, 'ammunition': ammunition, 'expire': expire}) + conn.commit() + await bot.sendmsg(config.irc.channel, f'[Player {nick} weapon ammunition is now {ammunition}]') + +async def removeweapon(nick): + remweapon = Weapons(nick, 0, 0, 0) + + c.execute("UPDATE WEAPONS set WEAPONHELD = (:weaponheld) where NAME = (:name)", {'weaponheld': 0, 'name': nick}) + conn.commit() + logging.debug('Removed weapon') + +async def buyweapon(nick): + c.execute(f"SELECT * FROM weapons WHERE name=:name", {'name': nick}) + weapons = c.fetchall() + c.execute(f"SELECT * FROM users WHERE name=:name", {'name': nick}) + user = c.fetchall() + for regs in user: + name = nick + money = regs[6] + for weapon in weapons: + weaponheld = weapon[1] + if weaponheld == 1: + await bot.sendmsg(config.irc.channel, "[Weapon is already held, !buy ammo for more ammunition]") + logging.debug('Weapon is already held, returning') + return + clip = 30 + ammunition = 60 + money = money - 500 + + c.execute("UPDATE USERS set MONEY = (:money) where NAME = (:name)", {'money': money, 'name': nick}) + conn.commit() + logging.debug(f'Attempting to buy Weapon for {nick}') + weaponheld = True + + await bot.sendmsg(config.irc.channel, f"[Player: {nick} has purchased a gun for $500! Loaded clip of {clip} rounds!]") + logging.debug('Buying weapon') + expire = 0 + c.execute("INSERT OR REPLACE INTO weapons VALUES (:name, :weaponheld, :clip, :ammunition, :expire)", {'name': nick, 'weaponheld': weaponheld, 'clip': clip, 'ammunition': ammunition, 'expire': expire}) + conn.commit() + +async def removeuser(nick): + logging.debug(f'Removing user {nick}') + name = nick + c.execute('''DELETE FROM users WHERE name=?''',(name,)) + conn.commit() + c.execute('''DELETE FROM items WHERE name=?''',(name,)) + conn.commit() + c.execute('''DELETE FROM weapons WHERE name=?''',(name,)) + conn.commit() + c.execute('''DELETE FROM stats WHERE name=?''',(name,)) + conn.commit() + logging.debug(f'Removed user {nick}') + +async def createuser(nick): + + logging.debug(f'Attemping to create user {nick}') + reguser = Users(nick, 1, 500, 500, 100, 100, 5000, 500) + + logging.debug(f'User {nick} added to database') + + c.execute("INSERT OR REPLACE INTO users VALUES (:name, :level, :experience, :health, :attack, :defense, :money, :healthmax)", {'name': nick, 'level': reguser.level, 'experience': reguser.experience, 'health': reguser.health, 'attack': reguser.attack, 'defense': reguser.defense, 'money': reguser.money, 'healthmax': reguser.healthmax}) + conn.commit() + c.execute(f'SELECT rowid FROM stats WHERE name=(:name)', {'name': nick}) + checkrow=c.fetchone() + if checkrow == None: + kills = 0 + deaths = 0 + c.execute(f'INSERT OR REPLACE INTO stats VALUES (:name, :kills, :deaths)', {'name': nick, 'kills': kills, 'deaths': deaths}) + conn.commit() + #await bot.sendmsg(config.irc.channel, f'[Player {color(name, light_green)} has a total of {color(kills, red)} kills!]') +async def setlevel(nick, level): + if level == '1': + experience = '500' + health = '500' + attack = '100' + defense = '100' + healthmax = '500' + c.execute(f'''UPDATE USERS set LEVEL = (:level), + EXPERIENCE = (:experience), + HEALTH = (:health), + ATTACK = (:attack), + DEFENSE = (:defense), + HEALTHMAX = (:healthmax) + where NAME = (:name)''', {'level': level, 'experience': experience, 'health': health, 'attack': attack, 'defense': defense, 'name': nick, 'healthmax': healthmax}) + conn.commit() + await bot.sendmsg(config.irc.channel, f"[Player: {nick} is now level {color(level, red)}]") + + elif level == '2': + experience = '1000' + health = '1000' + attack = '150' + defense = '150' + healthmax = '1000' + c.execute(f'''UPDATE USERS set LEVEL = (:level), + EXPERIENCE = (:experience), + HEALTH = (:health), + ATTACK = (:attack), + DEFENSE = (:defense), + HEALTHMAX = (:healthmax) + where NAME = (:name)''', {'level': level, 'experience': experience, 'health': health, 'attack': attack, 'defense': defense, 'name': nick, 'healthmax': healthmax}) + conn.commit() + await bot.sendmsg(config.irc.channel, f"[Player: {nick} is now level {color(level, red)}]") + + + elif level == '3': + experience = '2000' + health = '1500' + attack = '175' + defense = '175' + healthmax = '1500' + c.execute(f'''UPDATE USERS set LEVEL = (:level), + EXPERIENCE = (:experience), + HEALTH = (:health), + ATTACK = (:attack), + DEFENSE = (:defense), + HEALTHMAX = (:healthmax) + where NAME = (:name)''', {'level': level, 'experience': experience, 'health': health, 'attack': attack, 'defense': defense, 'name': nick, 'healthmax': healthmax}) + conn.commit() + await bot.sendmsg(config.irc.channel, f"[Player: {nick} is now level {color(level, red)}]") + + elif level == '4': + experience = '3000' + health = '2000' + attack = '200' + defense = '200' + healthmax = '2000' + c.execute(f'''UPDATE USERS set LEVEL = (:level), + EXPERIENCE = (:experience), + HEALTH = (:health), + ATTACK = (:attack), + DEFENSE = (:defense), + HEALTHMAX = (:healthmax) + where NAME = (:name)''', {'level': level, 'experience': experience, 'health': health, 'attack': attack, 'defense': defense, 'name': nick, 'healthmax': healthmax}) + conn.commit() + await bot.sendmsg(config.irc.channel, f"[Player: {nick} is now level {color(level, red)}]") + + elif level == '5': + experience = '5000' + health = '3000' + attack = '225' + defense = '225' + healthmax = '3000' + c.execute(f'''UPDATE USERS set LEVEL = (:level), + EXPERIENCE = (:experience), + HEALTH = (:health), + ATTACK = (:attack), + DEFENSE = (:defense), + HEALTHMAX = (:healthmax) + where NAME = (:name)''', {'level': level, 'experience': experience, 'health': health, 'attack': attack, 'defense': defense, 'name': nick, 'healthmax': healthmax}) + conn.commit() + await bot.sendmsg(config.irc.channel, f"[Player: {nick} is now level {color(level, red)}]") + elif int(level) > 5: + await bot.sendmsg(config.irc.channel, "[Error: Invalid Level]") + return + +async def closesql(): + conn.close() +class combat: + class attacker: + name = '' + attack = '' + class defender: + name = '' + defense = '' + health = '' + +async def punch(player, nick): + check = await checkexist(player) + if check is False: + return + else: + for name in (nick): + c.execute(f"SELECT * FROM users WHERE name=:name", {'name': nick}) + attacker = c.fetchall() + c.execute(f"SELECT * FROM users WHERE name=:name", {'name': player}) + defender = c.fetchall() + if nick == player: + await bot.sendmsg(config.irc.channel, '[Error: {1}]'.format(0,color('Cannot Attack Yourself', red))) + return + for att in attacker: + combat.attacker.name = att[0] + combat.attacker.attack = att[4] + combat.attacker.health = att[3] + if combat.attacker.health == 0: + await bot.sendmsg(config.irc.channel, '[Error: You Are {1}!]'.format(0, color('Dead', red))) + return + for defend in defender: + combat.defender.name = defend[0] + combat.defender.defense = defend[5] + combat.defender.health = defend[3] + playerhealth = combat.defender.health + + if combat.defender.health <= 0: + await bot.sendmsg(config.irc.channel, f'[Player targeted is {color("DEAD", light_blue)}]') + return + playerdef = combat.defender.defense + playerattack = combat.attacker.attack + critical_multiplier = 1.1 if random.random() < 0.10 else 1.0 + effective_defense = int(playerdef) * random.uniform(0.9, 1.1) + effective_attack = int(playerattack) * random.uniform(1.0, 1.1) + damage = effective_attack * (50 / (50 + effective_defense)) * critical_multiplier + damage = min(damage, int(playerhealth)) + + combat.defender.health = int(playerhealth) - int(damage) + c.execute(f'''UPDATE USERS set HEALTH = (:health) where NAME = (:name)''', {'health': combat.defender.health, 'name': combat.defender.name}) + + conn.commit() + if combat.defender.health <= 0: + await bot.sendmsg(config.irc.channel, '[Player {1} killed {2} and did {3} damage]'.format(0, color(nick, light_green), color(player, red), color(int(damage), light_green))) + await addmoney(nick) + await addkillstat(nick) + await adddeathstat(player) + combat.defender.health = 0 + return + await bot.sendmsg(config.irc.channel, '[Character: {1}] Punched [{2}] and did [{3}] damage!'.format(0, color(nick, light_green), color(player, red), color(int(damage), green))) + + + c.execute(f'''UPDATE USERS set HEALTH = (:health) where NAME = (:name)''', {'health': combat.defender.health, 'name': combat.defender.name}) + + conn.commit() + +async def profile(nick): + + + check = await checkexist(nick) + if check is False: + return + try: + c.execute(f"SELECT * FROM users WHERE name=(:name)", {'name': nick}) + reg = c.fetchall() + for regs in reg: + name = regs[0] + level = regs[1] + experience = regs[2] + health = regs[3] + attack = regs[4] + defense = regs[5] + money = regs[6] + healthmax = regs[7] + c.execute(f'SELECT * FROM stats WHERE name=(:name)', {'name': name}) + grabstats=c.fetchall() + for stats in grabstats: + kills = stats[1] + deaths = stats[2] + await bot.sendmsg(config.irc.channel, f'[Player: {color(name, light_green)}] [Level: {color(level, red)}] [Experience: {color(experience, blue)}] [Health: {color(health, light_green)}/{color(healthmax, green)}] [Att/Def: {color(attack, light_green)}/{color(defense, red)}] [Money: {color(money, light_blue)}] [Kills: {color(kills, light_blue)}] [Deaths: {color(deaths, red)}]') + + except Exception as ex: + print('Error {0}'.format(0, ex)) + #bot.sendmsg(config.irc.channel, '[Error: No Such User]') + +async def revive(nick): + check = await checkexist(nick) + if check is False: + return + + c.execute("SELECT * FROM users WHERE name=(:name)", {'name': nick}) + + checkhealth=c.fetchall() + + for amount in checkhealth: + health = amount[3] + max = amount[7] + if health <= 0: + c.execute("UPDATE USERS set HEALTH = (:health) WHERE NAME = (:name)", {'health': max, 'name': nick}) + logging.debug('test') + conn.commit() + await bot.sendmsg(config.irc.channel, f'[Player {color(nick,light_green)} has been revived!]') + else: + await bot.sendmsg(config.irc.channel, f'[You are not DEAD! No reviving the living!]') +class config: + class irc: + server = 'irc.supernets.org' + port = 6667 + username = 'vortex' + realname = 'FightBot by vorteckz' + nickname = 'FightBot' + channel = '#dev' + channelkey = 'test' + admins = {'vortex', 'vorteckz','acidvegas','peanuter'} + class throttle: + cmd = 0.5 + msg = 0.5 + reconnect = 10 + rejoin = 3 + last = 0 + slow = False + lastnick = None + +def color(msg: str, foreground: str, background: str='') -> str: + ''' + Color a string with the specified foreground and background colors. + + :param msg: The string to color. + :param foreground: The foreground color to use. + :param background: The background color to use. + ''' + return f'\x03{foreground},{background}{msg}{reset}' if background else f'\x03{foreground}{msg}{reset}' + +def ssl_ctx() -> ssl.SSLContext: + '''Create a SSL context for the connection.''' + ctx = ssl.create_default_context() + #ctx.verify_mode = ssl.CERT_NONE # Comment out this line to verify hosts + #ctx.load_cert_chain('/path/to/cert', password='loldongs') + return ctx +async def getmoney(nick): + c.execute(f"SELECT * FROM users WHERE name=(:name)", {'name': nick}) + moneygrab = c.fetchall() + for money in moneygrab: + moneyamount = money[6] + writemoney = f'{moneyamount:,}' + await bot.sendmsg(config.irc.channel, f'[Bank Balance: ${color(writemoney, light_blue)}]') +async def getbandages(nick): + name = nick + c.execute(f'SELECT rowid FROM items WHERE name=(:name)', {'name': nick}) + data=c.fetchone() + if data is None: + bandages = 0 + c.execute(f'INSERT OR REPLACE INTO items VALUES (:name, :bandages)', {'name': name, 'bandages': bandages}) + conn.commit() + c.execute(f"SELECT * FROM items WHERE name=(:name)", {'name': nick}) + bandages = c.fetchall() + for bandage in bandages: + bandageamount = bandage[1] + if bandageamount == None: + logging.debug('test') + bandageamount = 0 + writebandageamount = f'{bandageamount:,}' + await bot.sendmsg(config.irc.channel, f'[Bandages: {color(writebandageamount, red)}]') + +async def ammo(nick): + c.execute(f'SELECT rowid FROM users WHERE name=(:name)', {'name': nick}) + exist = c.fetchone() + + if exist is None: + await bot.sendmsg(config.irc.channel, f'[User {nick} does not have an account!]') + return + c.execute(f"SELECT * FROM weapons WHERE name=(:name)", {'name': nick}) + checkammo = c.fetchall() + + for ammo in checkammo: + hasweapon = ammo[1] + if hasweapon == False: + await bot.sendmsg(config.irc.channel, f'[You do not currently have a weapon.. !buy weapon]') + return + ammoclipcount = ammo[2] + ammomagcount = ammo[3] + await bot.sendmsg(config.irc.channel, f"[Ammo Count] [Current Clip Holding: {ammoclipcount}] [Arsenal Magazine Rounds: {ammomagcount}]") +async def addmoney(nick): + c.execute(f"SELECT * FROM users WHERE name=:name", {'name': nick}) + + moneygrab = c.fetchall() + + for money in moneygrab: + moneyamount = money[6] + profit = 500 + moneyamount += profit + moneyamountformat = f'{moneyamount:,}' + await bot.sendmsg(config.irc.channel, f'[You gained ${color(profit, blue)}!] [Bank Balance: ${color(moneyamountformat, light_blue)}]') + c.execute(f'''UPDATE USERS set MONEY = (:money) where NAME = (:name)''', {'money': moneyamount, 'name': nick}) + conn.commit() + + + +class Bot(): + def __init__(self): + self.nickname = config.irc.nickname + self.username = config.irc.username + self.realname = config.irc.realname + self.channel = config.irc.channel + self.channelkey = config.irc.channelkey + self.reader = None + self.writer = None + + createtable() + + async def action(self, chan: str, msg: str): + ''' + Send an ACTION to the IRC server. + + :param chan: The channel to send the ACTION to. + :param msg: The message to send to the channel. + ''' + await self.sendmsg(chan, f'\x01ACTION {msg}\x01') + + async def raw(self, data: str): + ''' + Send raw data to the IRC server. + + :param data: The raw data to send to the IRC server. (512 bytes max including crlf) + ''' + self.writer.write(data[:510].encode('utf-8') + b'\r\n') + + async def sendmsg(self, target: str, msg: str): + ''' + Send a PRIVMSG to the IRC server. + + :param target: The target to send the PRIVMSG to. (channel or user) + :param msg: The message to send to the target. + ''' + try: + await self.raw(f'PRIVMSG {target} :{msg}') + + time.sleep(config.throttle.msg) + except: + await bot.sendmsg(config.irc.channel, "Slow down homie!!") + + async def connect(self): + '''Connect to the IRC server.''' + while True: + try: + options = { + 'host' : args.server, + 'port' : args.port if args.port else 6697 if args.ssl else 6667, + 'limit' : 1024, # Buffer size in bytes (don't change this unless you know what you're doing) + 'ssl' : ssl_ctx() if args.ssl else None, + 'family' : 10 if args.v6 else 2, # 10 = AF_INET6 (IPv6), 2 = AF_INET (IPv4) + 'local_addr' : args.vhost if args.vhost else None # Can we just leave this as args.vhost? + } + self.reader, self.writer = await asyncio.wait_for(asyncio.open_connection(**options), 15) # 15 second timeout + if args.password: + await self.raw('PASS ' + args.password) # Rarely used, but IRCds may require this + await self.raw(f'USER {self.username} 0 * :{self.realname}') # These lines must be sent upon connection + await self.raw('NICK ' + self.nickname) # They are to identify the bot to the server + while not self.reader.at_eof(): + data = await asyncio.wait_for(self.reader.readuntil(b'\r\n'), 300) # 5 minute ping timeout + await self.handle(data.decode('utf-8').strip()) # Handle the data received from the IRC server + except Exception as ex: + logging.error(f'failed to connect to {args.server} ({str(ex)})') + finally: + await asyncio.sleep(30) # Wait 30 seconds before reconnecting + + async def handle(self, data: str): + ''' + Handle the data received from the IRC server. + + :param data: The data received from the IRC server. + ''' + try: + logging.info(data) + args = data.split() + if data.startswith('ERROR :Closing Link:'): + raise Exception('Cannot Connect') + if args[0] == 'PING': + await self.raw('PONG ' + args[1]) # Respond to the server's PING request with a PONG to prevent ping timeout + elif args[1] == '001': # RPL_WELCOME + await self.raw(f'MODE {self.nickname} +B') # Set user mode +B (Bot) + await asyncio.sleep(10) # Wait 10 seconds before joining the channel (required by some IRCds to wait before JOIN) + await self.raw(f'JOIN {self.channel} {self.channelkey}') + elif args[1] == '433': # ERR_NICKNAMEINUSE + self.nickname += '_' # If the nickname is already in use, append an underscore to the end of it + await self.raw('NICK ' + self.nickname) # Send the new nickname to the server + elif args[1] == 'KICK': + chan = args[2] + kicked = args[3] + if kicked == self.nickname: + await asyncio.sleep(3) + await self.raw(f'JOIN {chan}') + elif args[1] == 'PRIVMSG': + ident = args[0][1:] + nick = args[0].split('!')[0][1:].lower() + target = args[2] + msg = ' '.join(args[3:])[1:] + arguments = msg.split() + bandageamount = '0' + if target == self.nickname: + pass # Handle private messages here + if target.startswith('#'): # Channel message + if msg.startswith('!'): + try: + if time.time() - config.throttle.last < config.throttle.cmd and config.throttle.lastnick == nick: + if not config.throttle.slow: + config.throttle.slow = True + await bot.sendmsg(config.irc.channel, color("Slow down homie!!", red)) + + else: + config.throttle.slow = False + config.throttle.lastnick = nick + + if arguments[0] == '!hug': + await bot.sendmsg(target, f'[XOXO Hugger9000... {nick} hugs {arguments[1]}]') + if arguments[0] == '!admins': + for i in config.irc.admins: + await bot.sendmsg(target, f'[Admins: ' + color(i, red) + ']') + if arguments[0] == '!shop': + await shop() + if arguments[0] == '!buy' and arguments[1] != None: + if arguments[1] == 'weapon': + await buyweapon(nick) + elif arguments[1] == 'ammo': + await buyammo(nick) + elif arguments[1] == 'bandages': + if len(arguments) <= 2 or int(arguments[2]) == 0: + await bot.sendmsg(config.irc.channel, '[You must specify amount of bandages (greater than 0) to purchase]') + else: + await buybandages(nick, int(arguments[2])) + + if arguments[0] == '!shoot': + await shoot(arguments[1].lower(), nick) + if arguments[0] == '!reload': + await reload(nick) + if arguments[0] == '!ammo': + await ammo(nick) + if arguments[0] == '!heal': + await heal(nick) + if arguments[0] == '!revive': + await revive(nick) + if arguments[0] == '!help': + await bot.sendmsg(config.irc.channel, '[Command List]') + await bot.sendmsg(config.irc.channel, '[!help - shows commands]') + await bot.sendmsg(config.irc.channel, '[!register - Register your player]') + await bot.sendmsg(config.irc.channel, '[!profile - Shows Profile Stats [!profile username]') + await bot.sendmsg(config.irc.channel, '[!punch - Fight [!punch username]') + await bot.sendmsg(config.irc.channel, '[!shoot - Shoot if you own a weapon]') + await bot.sendmsg(config.irc.channel, '[!bank - Returns Bank Balance]') + await bot.sendmsg(config.irc.channel, '[!buy [weapon, ammo, bandages ]') + await bot.sendmsg(config.irc.channel, '[!reload - Reloads Weapon]') + await bot.sendmsg(config.irc.channel, '[!ammo - Show Ammunition Amounts]') + await bot.sendmsg(config.irc.channel, '[!bandages - Shows Bandage Amounts]') + await bot.sendmsg(config.irc.channel, '[!revive - Brings you back to health if dead]') + await bot.sendmsg(config.irc.channel, '[!heal - Use bandages to regain health]') + await bot.sendmsg(config.irc.channel, ' ') + await bot.sendmsg(config.irc.channel, '[Admin Command List]') + await bot.sendmsg(config.irc.channel, '[!setlevel - !setlevel username Level (1 to 5)]') + await bot.sendmsg(config.irc.channel, '[!adduser - Force create a user]') + await bot.sendmsg(config.irc.channel, '[!remove - Removes a player]') + await bot.sendmsg(config.irc.channel, '[!removeweapon - Remove user weapon]') + if arguments[0] == '!bank': + await getmoney(nick) + if arguments[0] == '!bandages': + await getbandages(nick) + + if nick in config.irc.admins: + #await self.sendmsg(target, f'{nick} is an ' + color('Admin!', red)) + if arguments[0] == '!removeweapon': + await removeweapon(nick) + if arguments[0] == '!adduser': + name = arguments[1].lower() + + c.execute(f"SELECT rowid FROM users WHERE name = (:name)", {'name': name}) + + data=c.fetchone() + if data is None: + await bot.sendmsg(config.irc.channel, '[Registering Player: %s]'%name) + await createuser(name) + await profile(name) + else: + await bot.sendmsg(config.irc.channel, f'{color("[Player already exists!]", red)}') + + if arguments[0] == '!remove': + logging.debug('remove user') + name = arguments[1].lower() + c.execute(f"SELECT rowid FROM users WHERE name= (:name)", {'name': name}) + data=c.fetchone() + if data != None: + await bot.sendmsg(config.irc.channel, f'[Removing {color(name, red)} from database]') + await removeuser(name) + else: + await bot.sendmsg(config.irc.channel, f'[User does not exist]') + + if arguments[0] == '!setlevel': + await setlevel(arguments[1].lower(), arguments[2]) + if arguments[0] == '!register': + c.execute(f"SELECT rowid FROM users WHERE name = (:name)", {'name': nick}) + + data=c.fetchone() + if data is None: + await bot.sendmsg(config.irc.channel, f'[Registering Player: %s]'%nick) + await createuser(nick) + await profile(nick) + else: + await bot.sendmsg(config.irc.channel, f'{color("[Player already exists!]", red)}') + if arguments[0] == '!profile': + try: + await profile(arguments[1].lower()) + except: + await profile(nick) + if arguments[0] == '!punch': + await punch(arguments[1].lower(), nick) + config.throttle.last = time.time() + except Exception as ex: + if time.time() - config.throttle.last < config.throttle.cmd: + if not config.throttle.slow: + await bot.sendmsg(config.irc.channel, color('Slow down homie!', red)) + config.throttle.slow = True + config.throttle.last = time.time() + + #except (UnicodeDecodeError, UnicodeEncodeError): + #pass # Some IRCds allow invalid UTF-8 characters, this is a very important exception to catch + except Exception as ex: + logging.exception(f'Unknown error has occured! ({ex})') + + +def setup_logger(log_filename: str, to_file: bool = False): + ''' + Set up logging to console & optionally to file. + + :param log_filename: The filename of the log file + ''' + sh = logging.StreamHandler() + sh.setFormatter(logging.Formatter('%(asctime)s | %(levelname)9s | %(message)s', '%I:%M %p')) + if to_file: + fh = logging.handlers.RotatingFileHandler(log_filename+'.log', maxBytes=250000, backupCount=3, encoding='utf-8') # Max size of 250KB, 3 backups + fh.setFormatter(logging.Formatter('%(asctime)s | %(levelname)9s | %(filename)s.%(funcName)s.%(lineno)d | %(message)s', '%Y-%m-%d %I:%M %p')) # We can be more verbose in the log file + logging.basicConfig(level=logging.NOTSET, handlers=(sh,fh)) + else: + logging.basicConfig(level=logging.NOTSET, handlers=(sh,)) + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description="Connect to an IRC server.") # The arguments without -- are required arguments. + parser.add_argument("server", help="The IRC server address.") + parser.add_argument("channel", help="The IRC channel to join.") + parser.add_argument("--password", help="The password for the IRC server.") + parser.add_argument("--port", type=int, help="The port number for the IRC server.") # Port is optional, will default to 6667/6697 depending on SSL. + parser.add_argument("--ssl", action="store_true", help="Use SSL for the connection.") + parser.add_argument("--v4", action="store_true", help="Use IPv4 for the connection.") + parser.add_argument("--v6", action="store_true", help="Use IPv6 for the connection.") + parser.add_argument("--key", default="", help="The key (password) for the IRC channel, if required.") + parser.add_argument("--vhost", help="The VHOST to use for connection.") + args = parser.parse_args() + config.irc.channel = args.channel + if args.key: + config.irc.channelkey = args.key + print(f"Connecting to {args.server}:{args.port} (SSL: {args.ssl}) and joining {args.channel} (Key: {args.key or 'None'})") + + setup_logger('skeleton', to_file=True) # Optionally, you can log to a file, change to_file to False to disable this. + + bot = Bot() # We define this here as an object so we can call it from an outside function if we need to. + asyncio.run(bot.connect()) \ No newline at end of file