2023-10-11 23:14:57 +00:00
#!/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 <amount>] ' )
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 <amount number>] ' )
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 <amount number>] ' )
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! <!buy 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 <amount>] ' )
# 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 ' \x01 ACTION { 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 <enemy> - Fight [!punch username] ' )
await bot . sendmsg ( config . irc . channel , ' [!shoot <enemy> - Shoot if you own a weapon] ' )
await bot . sendmsg ( config . irc . channel , ' [!bank - Returns Bank Balance] ' )
await bot . sendmsg ( config . irc . channel , ' [!buy <item> [weapon, ammo, bandages <amount>] ' )
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 <user> - Force create a user] ' )
await bot . sendmsg ( config . irc . channel , ' [!remove <user> - Removes a player] ' )
await bot . sendmsg ( config . irc . channel , ' [!removeweapon <user> - 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.
2023-10-11 19:20:16 +00:00
asyncio . run ( bot . connect ( ) )