irccex- fantasy cryptocurrency exchange for irc |
git clone git://git.acid.vegas/irccex.git |
Log | Files | Refs | Archive | README | LICENSE |
irc.py (29785B)
1 #!/usr/bin/env python 2 # IRC Cryptocurrency Exchange (IRCCEX) - Developed by acidvegas in Python (https://git.acid.vegas/irccex) 3 # irc.py 4 5 ''' 6 if using_too_many_if_statements == True: 7 use_more = True 8 else: 9 use_alot_more = True 10 ''' 11 12 import datetime 13 import os 14 import pickle 15 import random 16 import socket 17 import threading 18 import time 19 20 import config 21 import constants 22 import functions 23 from coinmarketcap import CoinMarketCap 24 25 if config.connection.ssl: 26 import ssl 27 28 def color(msg, foreground, background=None): 29 if background: 30 return f'{constants.color}{foreground},{background}{msg}{constants.reset}' 31 else: 32 return f'{constants.color}{foreground}{msg}{constants.reset}' 33 34 class IRC(object): 35 def __init__(self): 36 self.db = {'bank':dict(),'pool':0.0,'round':1,'score':dict(),'start':datetime.date.today(),'verify':dict(),'wallet':dict()} 37 self.last = 0 38 self.last_backup = time.strftime('%I:%M') 39 self.maintenance = False 40 self.reward = {'reward':0,'rewards':0,'status':False} 41 self.slow = False 42 self.sock = None 43 self.start = time.time() 44 45 def run(self): 46 if os.path.isfile('db.pkl'): 47 with open('db.pkl', 'rb') as db_file: 48 self.db = pickle.load(db_file) 49 print('[+] - Restored database!') 50 Loops.start_loops() 51 self.connect() 52 53 def connect(self): 54 try: 55 self.create_socket() 56 self.sock.connect((config.connection.server, config.connection.port)) 57 self.register() 58 except socket.error as ex: 59 print('[!] - Failed to connect to IRC server! (' + str(ex) + ')') 60 Events.disconnect() 61 else: 62 self.listen() 63 64 def create_socket(self): 65 self.sock = socket.socket(AF_INET6) if config.connection.ipv6 else socket.socket() 66 if config.connection.vhost: 67 self.sock.bind((config.connection.vhost, 0)) 68 if config.connection.ssl: 69 ctx = ssl.SSLContext() 70 if config.cert.file: 71 ctx.load_cert_chain(config.cert.file, password=config.cert.password) 72 if config.connection.ssl_verify: 73 ctx.check_hostname = True 74 ctx.load_default_certs() 75 self.sock = ctx.wrap_socket(self.sock, server_hostname=config.connection.server) 76 else: 77 self.sock = ctx.wrap_socket(self.sock) 78 79 def listen(self): 80 buffer = str() 81 last = time.time() 82 while True: 83 try: 84 data = self.sock.recv(1024).decode('utf-8') 85 buffer += data 86 if data: 87 last = time.time() 88 else: 89 if time.time() - last > 120: 90 break 91 while '\r\n' in buffer: 92 line = buffer.split('\r\n')[0] 93 buffer = buffer.split('\r\n', 1)[1] 94 print('[~] - ' + line) 95 if len(line.split()) >= 2: 96 Events.handle(line) 97 except (UnicodeDecodeError,UnicodeEncodeError): 98 pass 99 except Exception as ex: 100 print('[!] - Unexpected error occured. (' + str(ex) + ')') 101 break 102 Events.disconnect() 103 104 def register(self): 105 if config.login.network: 106 Commands.raw('PASS ' + config.login.network) 107 Commands.raw(f'USER {config.ident.username} 0 * :{config.ident.realname}') 108 Commands.nick(config.ident.nickname) 109 110 class Commands: 111 def action(chan, msg): 112 Commands.sendmsg(chan, f'\x01ACTION {msg}\x01') 113 114 def check_nick(nick, chan): 115 if nick in Bot.db['wallet']: 116 return True 117 else: 118 if nick in Bot.db['verify']: 119 Commands.error(chan, 'Your account is not verified!', 'try again later') 120 else: 121 Commands.error(chan, 'You don\'t have an account!', 'use !register to make an account') 122 return False 123 124 def cleanup(nick): 125 for symbol in [symbol for symbol in Bot.db['wallet'][nick] if not Bot.db['wallet'][nick][symbol]]: 126 del Bot.db['wallet'][nick][symbol] 127 if not Bot.db['wallet'][nick]: 128 del Bot.db['wallet'][nick] 129 130 def error(target, data, reason=None): 131 if reason: 132 Commands.sendmsg(target, '[{0}] {1} {2}'.format(color('!', constants.red), data, color('({0})'.format(reason), constants.grey))) 133 else: 134 Commands.sendmsg(target, '[{0}] {1}'.format(color('!', constants.red), data)) 135 136 def identify(nick, password): 137 Commands.sendmsg('NickServ', f'identify {nick} {password}') 138 139 def join_channel(chan, key=None): 140 Commands.raw(f'JOIN {chan} {key}') if key else Commands.raw('JOIN ' + chan) 141 142 def mode(target, mode): 143 Commands.raw(f'MODE {target} {mode}') 144 145 def nick(nick): 146 Commands.raw('NICK ' + nick) 147 148 def notice(target, msg): 149 Commands.raw(f'NOTICE {target} :{msg}') 150 151 def oper(user, password): 152 Commands.raw(f'OPER {user} {password}') 153 154 def raw(msg): 155 Bot.sock.send(bytes(msg + '\r\n', 'utf-8')) 156 157 def sendmsg(target, msg): 158 Commands.raw(f'PRIVMSG {target} :{msg}') 159 time.sleep(config.throttle.msg) 160 161 class Events: 162 def connect(): 163 if config.connection.modes: 164 Commands.mode(config.ident.nickname, '+' + config.connection.modes) 165 if config.login.nickserv: 166 Commands.identify(config.ident.nickname, config.login.nickserv) 167 if config.login.operator: 168 Commands.oper(config.ident.username, config.login.operator) 169 Commands.join_channel(config.connection.channel, config.connection.key) 170 171 def disconnect(): 172 Bot.sock.close() 173 time.sleep(config.throttle.reconnect) 174 Bot.connect() 175 176 def invite(chan): 177 if chan == config.connection.channel: 178 Commands.join_channel(config.connection.channel, config.connection.key) 179 180 def kick(chan, kicked): 181 if kicked == config.ident.nickname and chan == config.connection.channel: 182 time.sleep(config.throttle.rejoin) 183 Commands.join_channel(chan, config.connection.key) 184 185 def message(nick, chan, msg): 186 if chan == config.connection.channel: 187 try: 188 if msg[:1] in '!@$': 189 if time.time() - Bot.last < config.throttle.cmd: 190 if not Bot.slow: 191 Bot.slow = True 192 Commands.sendmsg(chan, color('Slow down nerd!', constants.red)) 193 else: 194 Bot.slow = False 195 args = msg.split() 196 if Bot.maintenance and args[0] in ('!cashout','!send','!trade'): 197 Commands.error(chan, 'Exchange is down for scheduled maintenance!', 'try again later') 198 else: 199 if args[0] == '!cashout': 200 if Commands.check_nick(nick, chan): 201 if 'USD' not in Bot.db['wallet'][nick]: 202 Commands.error(chan, 'Insufficent funds.', 'you have no USD in your account') 203 elif Bot.db['wallet'][nick]['USD'] < config.limits.cashout: 204 Commands.error(chan, 'Insufficent funds.', f'${config.limits.cashout:,} minimum') 205 else: 206 profit = Bot.db['wallet'][nick]['USD']-config.limits.init 207 amount = functions.fee(profit, config.fees.cashout) 208 cashout_msg = msg[9:][:100] if len(args) > 1 else Bot.db['bank'][nick][1] if nick in Bot.db['bank'] else 'IM RICH BITCH !!!' 209 Bot.db['bank'][nick] = (Bot.db['bank'][nick][0]+amount, cashout_msg) if nick in Bot.db['bank'] else (amount, cashout_msg) 210 Bot.db['pool'] += profit-amount 211 Bot.db['wallet'][nick]['USD'] = config.limits.init 212 Commands.sendmsg(chan, 'Cashed out {0} to your bank account! {1}'.format(color('${:,}'.format(int(amount)), constants.green), color('(current balance: ${:,})'.format(int(Bot.db['bank'][nick][0])), constants.grey))) 213 elif len(args) == 1: 214 if msg == '@irccex': 215 Commands.sendmsg(chan, constants.bold + 'IRC Cryptocurrency Exchange (IRCCEX) - Developed by acidvegas in Python - https://github.com/acidvegas/irccex') 216 elif msg == '@stats': 217 bank_total = 0 218 global_data = CMC._global() 219 ticker_data = CMC._ticker() 220 wallet_total = 0 221 for item in Bot.db['bank']: 222 bank_total += Bot.db['bank'][item][0] 223 for user in Bot.db['wallet']: 224 for symbol in Bot.db['wallet'][user]: 225 value = Bot.db['wallet'][user][symbol] if symbol == 'USD' else ticker_data[symbol]['price']*Bot.db['wallet'][user][symbol] 226 wallet_total += value 227 Commands.sendmsg(chan, '[{0}]'.format(color('Bot', constants.cyan))) 228 Commands.sendmsg(chan, ' {0} {1}'.format(color('Backup :', constants.white), Bot.last_backup)) 229 Commands.sendmsg(chan, ' {0} {1}'.format(color('Round :', constants.white), Bot.db['round'])) 230 Commands.sendmsg(chan, ' {0} {1}'.format(color('Uptime :', constants.white), functions.uptime(Bot.start))) 231 Commands.sendmsg(chan, '[{0}]'.format(color('Market', constants.cyan))) 232 Commands.sendmsg(chan, ' {0} {1}%'.format(color('BTC Dominance :', constants.white), global_data['btc_dominance'])) 233 Commands.sendmsg(chan, ' {0} {1}%'.format(color('ETH Dominance :', constants.white), global_data['eth_dominance'])) 234 Commands.sendmsg(chan, ' {0} {1:,}'.format(color('Cryptocurrencies :', constants.white), global_data['cryptocurrencies'])) 235 Commands.sendmsg(chan, ' {0} {1:,}'.format(color('Exchanges :', constants.white), global_data['exchanges'])) 236 Commands.sendmsg(chan, ' {0} ${1:,}'.format(color('Market Cap :', constants.white), global_data['market_cap'])) 237 Commands.sendmsg(chan, ' {0} ${1:,}'.format(color('Volume :', constants.white), global_data['volume'])) 238 Commands.sendmsg(chan, '[{0}]'.format(color('Round', constants.cyan))) 239 Commands.sendmsg(chan, ' {0} {1} {2}'.format(color('Accounts :', constants.white), '{:,}'.format(len(Bot.db['wallet'])), color('(${:,})'.format(int(wallet_total)), constants.grey))) 240 Commands.sendmsg(chan, ' {0} {1} {2}'.format(color('Bank :', constants.white), '{:,}'.format(len(Bot.db['bank'])), color('(${:,})'.format(int(bank_total)), constants.grey))) 241 Commands.sendmsg(chan, ' {0} ${1:,}'.format(color('Reward Pool :', constants.white), int(Bot.db['pool']))) 242 Commands.sendmsg(chan, ' {0} {1:,}'.format(color('Unverified :', constants.white), len(Bot.db['verify']))) 243 elif msg.startswith('$'): 244 msg = msg.upper() 245 if ',' in msg: 246 seen = set() 247 coins = [x for x in list(msg[1:].split(','))[:10] if not (x in seen or seen.add(x))] 248 data = [CMC._ticker()[coin] for coin in coins if coin in CMC._ticker()] 249 if data: 250 if len(data) == 1: 251 Commands.sendmsg(chan, functions.coin_info(data[0])) 252 else: 253 for line in functions.coin_table(data): 254 Commands.sendmsg(chan, line) 255 else: 256 Commands.error(chan, 'Invalid cryptocurrency names!') 257 else: 258 coin = msg[1:] 259 if not coin.split('.')[0].isdigit(): 260 if coin in CMC._ticker(): 261 Commands.sendmsg(chan, functions.coin_info(CMC._ticker()[coin])) 262 else: 263 Commands.error(chan, 'Invalid cryptocurrency name!') 264 elif msg == '!bang' and Bot.reward['status']: 265 if Commands.check_nick(nick, chan): 266 amount = functions.fee(Bot.reward['reward'], float('0.{0:02}'.format(functions.random_int(5,15)))) if Bot.reward['rewards'] else Bot.db['pool'] 267 Bot.db['wallet'][nick]['USD'] = Bot.db['wallet'][nick]['USD']+amount if 'USD' in Bot.db['wallet'][nick] else amount 268 Bot.db['pool'] -= amount 269 if Bot.db['pool']: 270 Commands.sendmsg(chan, 'You won {0}!'.format(color('${:,}'.format(amount), constants.green))) 271 Bot.reward['rewards'] -= 1 272 else: 273 Commands.sendmsg(chan, 'You won the big {0}!'.format(color('${:,}'.format(amount), constants.green))) 274 Bot.reward = {'reward':0,'rewards':0,'status':False} 275 elif msg == '!bank': 276 if nick in Bot.db['bank']: 277 clean_bank = dict() 278 for item in Bot.db['bank']: 279 clean_bank[item] = Bot.db['bank'][item][0] 280 richest = sorted(clean_bank, key=clean_bank.get, reverse=True) 281 Commands.sendmsg(chan, '[{0}] {1} {2} {3}'.format(color('{:02}'.format(richest.index(nick)+1), constants.pink), nick, color('${:,}'.format(int(Bot.db['bank'][nick][0])), constants.green), Bot.db['bank'][nick][1])) 282 else: 283 Commands.error(chan, 'You don\'t have any money in the bank!', 'use !cashout to put money in the bank') 284 elif msg == '!portfolio': 285 if Commands.check_nick(nick, chan): 286 total = 0 287 for symbol in Bot.db['wallet'][nick]: 288 value = Bot.db['wallet'][nick][symbol] if symbol == 'USD' else CMC._ticker()[symbol]['price']*Bot.db['wallet'][nick][symbol] 289 total += value 290 Commands.sendmsg(chan, color('${:,}'.format(int(total)), constants.green)) 291 elif msg == '!register': 292 if nick not in Bot.db['verify'] and nick not in Bot.db['wallet']: 293 Bot.db['verify'][nick] = time.time() 294 Commands.sendmsg(chan, 'Welcome to the IRC Cryptocurrency Exchange! ' + color('(please wait 24 hours while we verify your documents)', constants.grey)) 295 else: 296 Commands.error(chan, 'Failed to register an account!', 'you already have an account') 297 elif msg == '!rich': 298 if Bot.db['bank']: 299 clean_bank = dict() 300 for item in Bot.db['bank']: 301 clean_bank[item] = Bot.db['bank'][item][0] 302 richest = sorted(clean_bank, key=clean_bank.get, reverse=True)[:10] 303 for user in richest: 304 _user = f'{user[:1]}{constants.reset}{user[1:]}' 305 Commands.sendmsg(chan, '[{0}] {1} {2} {3}'.format(color('{:02}'.format(richest.index(user)+1), constants.pink), _user.ljust(15), color('${:,}'.format(int(Bot.db['bank'][user][0])).ljust(13), constants.green), Bot.db['bank'][user][1])) 306 Commands.sendmsg(chan, '^ this could be u but u playin...') 307 else: 308 Commands.error(chan, 'Yall broke...') 309 elif msg == '!score': 310 if nick in Bot.db['score']: 311 clean_bank = dict() 312 for item in Bot.db['score']: 313 clean_bank[item] = Bot.db['score'][item][0] 314 top = sorted(clean_bank, key=clean_bank.get, reverse=True) 315 Commands.sendmsg(chan, '[{0}] {1} {2} {3}'.format(color('{:02}'.format(top.index(nick)+1), constants.pink), nick, color(str(Bot.db['score'][nick][0]), constants.cyan), color('${:,}'.format(int(Bot.db['score'][nick][1])), constants.green))) 316 else: 317 Commands.error(chan, 'You don\'t have any points!', 'be in the top 10 at the end of the month when the current round ends to get points') 318 elif msg == '!scores': 319 if Bot.db['score']: 320 clean_score = dict() 321 for item in Bot.db['score']: 322 clean_score[item] = Bot.db['score'][item][0] 323 top = sorted(clean_score, key=clean_score.get, reverse=True)[:10] 324 for user in top: 325 Commands.sendmsg(chan, '[{0}] {1} {2} {3}'.format(color('{:02}'.format(top.index(user)+1), constants.pink), user.ljust(15), color(str(Bot.db['score'][user][0]).ljust(5), constants.cyan), color('${:,}'.format(int(Bot.db['score'][nick][1])), constants.green))) 326 Commands.sendmsg(chan, '^ this could be u but u playin...') 327 else: 328 Commands.error(chan, 'Yall broke...') 329 elif msg == '!top': 330 data = list(CMC._ticker().values())[:10] 331 for line in functions.coin_table(data): 332 Commands.sendmsg(chan, line) 333 elif msg == '!wallet': 334 if Commands.check_nick(nick, chan): 335 Commands.sendmsg(chan, color(' Symbol Amount Value ', constants.black, constants.light_grey)) 336 total = 0 337 for symbol in Bot.db['wallet'][nick]: 338 amount = Bot.db['wallet'][nick][symbol] 339 if symbol == 'USD': 340 value = amount 341 elif symbol in CMC._ticker(): 342 value = CMC._ticker()[symbol]['price']*amount 343 else: # CLEAN THIS UP - TEMP FIX FOR ERRORS ON !wallet reported by sht, ji, and others... 344 value = 'JACKED' 345 if value == 'JACKED': 346 Commands.sendmsg(chan, symbol + ' was JACKED sucka!') 347 del Bot.db['wallet'][nick][symbol] 348 else: 349 Commands.sendmsg(chan, f' {symbol.ljust(8)} | {str(functions.clean_float(amount)).rjust(20)} | {str(functions.clean_value(value)).rjust(20)}') 350 total += float(value) 351 Commands.sendmsg(chan, color(f' Total: {str(functions.clean_value(total)).rjust(27)}', constants.black, constants.light_grey)) 352 elif len(args) == 2: 353 if args[0] in ('!bottom','!top'): 354 option = args[1].lower() 355 if option not in ('1h','24h','7d','value','volume'): 356 Commands.error(chan, 'Invalid option!', 'valid options are 1h, 24h, 7d, value & volume') 357 else: 358 data = dict() 359 for item in CMC._ticker(): 360 data[item] = float(CMC._ticker()[item]['percent'][option]) 361 data = sorted(data, key=data.get, reverse=True) 362 data = data[-10:] if args[0] == '!bottom' else data[:10] 363 data = [CMC._ticker()[coin] for coin in data] 364 for line in functions.coin_table(data): 365 Commands.sendmsg(chan, line) 366 elif len(args) == 3: 367 if args[0] == '!trade': 368 if Commands.check_nick(nick, chan): 369 pair = args[1].upper() 370 if len(pair.split('/')) == 2: 371 from_symbol, to_symbol = pair.split('/') 372 if from_symbol in Bot.db['wallet'][nick]: 373 amount = args[2].replace(',','') 374 if functions.is_amount(amount): 375 if amount == '*': 376 amount = Bot.db['wallet'][nick][from_symbol] 377 elif amount.startswith('$'): 378 amount = float(amount[1:]) if from_symbol == 'USD' else float(amount[1:])/CMC._ticker()[from_symbol]['price'] 379 else: 380 amount = float(amount) 381 usd_value = amount if from_symbol == 'USD' else CMC._ticker()[from_symbol]['price']*amount 382 if Bot.db['wallet'][nick][from_symbol] >= amount: 383 if usd_value >= config.limits.trade: 384 recv_amount = functions.fee(amount, config.fees.trade) 385 if functions.check_pair(from_symbol, to_symbol): 386 from_value = 1 if from_symbol == 'USD' else CMC._ticker()[from_symbol]['price'] 387 to_value = 1 if to_symbol == 'USD' else CMC._ticker()[to_symbol]['price'] 388 recv_amount = (recv_amount*from_value)/to_value 389 if to_symbol in Bot.db['wallet'][nick]: 390 Bot.db['wallet'][nick][from_symbol] -= amount 391 Bot.db['wallet'][nick][to_symbol] += recv_amount 392 Commands.cleanup(nick) 393 Bot.db['pool'] += usd_value-functions.fee(usd_value, config.fees.trade) 394 Commands.sendmsg(chan, 'Trade successful!') 395 else: 396 if len(Bot.db['wallet'][nick]) < config.limits.assets: 397 Bot.db['wallet'][nick][from_symbol] -= amount 398 Bot.db['wallet'][nick][to_symbol] = recv_amount 399 Commands.cleanup(nick) 400 Bot.db['pool'] += usd_value-functions.fee(usd_value, config.fees.trade) 401 Commands.sendmsg(chan, 'Trade successful!') 402 else: 403 Commands.error(chan, f'You can\'t hold more than {config.limits.assets} assets!') 404 else: 405 Commands.error(chan, 'Invalid trade pair!') 406 else: 407 Commands.error(chan, 'Invalid amount.', f'${config.limits.trade} minimum') 408 else: 409 Commands.error(chan, 'Insufficient funds.') 410 else: 411 Commands.error(chan, 'Invalid amount argument.') 412 else: 413 Commands.error(chan, 'Insufficient funds.') 414 else: 415 Commands.error(chan, 'Invalid trade pair.') 416 elif args[0] == '!value': 417 amount = args[1] 418 if functions.is_amount(amount, False): 419 amount = amount.replace(',','') 420 symbol = args[2].upper() 421 if symbol in CMC._ticker(): 422 value = CMC._ticker()[symbol]['price']*float(amount) 423 if value < 0.01: 424 Commands.sendmsg(chan, '{0} is worth {1}'.format(color(f'{amount} {symbol}', constants.white), color('${0:,.8f}'.format(value), constants.light_blue))) 425 else: 426 Commands.sendmsg(chan, '{0} is worth {1}'.format(color(f'{amount} {symbol}', constants.white), color('${0:,.2f}'.format(value), constants.light_blue))) 427 else: 428 Commands.error(chan, 'Invalid cryptocurrency name!') 429 else: 430 Commands.error(chan, 'Invalid amount!') 431 elif len(args) == 4: 432 if args[0] == '!send': 433 if Commands.check_nick(nick, chan): 434 total = 0 435 for symbol in Bot.db['wallet'][nick]: 436 total += Bot.db['wallet'][nick]['USD'] if symbol == 'USD' else CMC._ticker()[symbol]['price']*Bot.db['wallet'][nick][symbol] 437 if total >= config.limits.send: 438 receiver = args[1].lower() 439 if receiver in Bot.db['wallet']: 440 if nick != receiver: 441 amount = args[2].replace(',','') 442 symbol = args[3].upper() 443 if symbol in Bot.db['wallet'][nick]: 444 if functions.is_amount(amount): 445 amount = amount.replace(',','') 446 if amount == '*': 447 amount = Bot.db['wallet'][nick][symbol] 448 elif amount.startswith('$'): 449 amount = float(amount[1:]) if symbol == 'USD' else float(amount[1:])/CMC._ticker()[symbol]['price'] 450 else: 451 amount = float(amount) 452 usd_value = amount if symbol == 'USD' else CMC._ticker()[symbol]['price']*amount 453 if Bot.db['wallet'][nick][symbol] >= amount: 454 if usd_value >= config.limits.trade: 455 recv_amount = functions.fee(amount, config.fees.send) 456 if symbol in Bot.db['wallet'][receiver] or len(Bot.db['wallet'][receiver]) < config.limits.assets: 457 Bot.db['wallet'][receiver][symbol] = Bot.db['wallet'][receiver][symbol]+recv_amount if symbol in Bot.db['wallet'][receiver] else recv_amount 458 Bot.db['wallet'][nick][symbol] -= amount 459 Commands.cleanup(nick) 460 Bot.db['pool'] += usd_value-functions.fee(usd_value, config.fees.send) 461 Commands.sendmsg(receiver, '{0} just sent you {1} {2}! {3}'.format(color(nick, constants.light_blue), functions.clean_float(recv_amount), symbol, color('({0})'.format(functions.clean_value(usd_value)), constants.grey))) 462 Commands.sendmsg(chan, 'Sent!') 463 else: 464 Commands.error(chan, f'User can\'t hold more than {config.limits.assets} assets!') 465 else: 466 Commands.error(chan, 'Invalid send amount.', f'${config.limits.trade} minimum') 467 else: 468 Commands.error(chan, 'Insufficient funds.') 469 else: 470 Commands.error(chan, 'Invalid send amount.') 471 else: 472 Commands.error(chan, 'Insufficient funds.') 473 else: 474 Commands.error(chan, '...Really?') 475 elif receiver in Bot.db['verify']: 476 Commands.error(chan, 'User is not verified yet!') 477 else: 478 Commands.error(chan, 'User is not in the database.') 479 else: 480 Commands.error(chan, 'Insufficent funds!', f'${config.limits.send} minium') 481 Bot.last = time.time() 482 except Exception as ex: 483 if time.time() - Bot.last < config.throttle.cmd: 484 if not Bot.slow: 485 Commands.sendmsg(chan, color('Slow down nerd!', constants.red)) 486 Bot.slow = True 487 else: 488 Commands.error(chan, 'Command threw an exception.', ex) 489 Bot.last = time.time() 490 491 def nick_in_use(): 492 config.ident.nickname = 'IRCCEX_' + str(functions.random_int(10,99)) 493 Commands.nick(config.ident.nickname) 494 495 def handle(data): 496 args = data.split() 497 if data.startswith('ERROR :Closing Link:'): 498 raise Exception('Connection has closed.') 499 elif args[0] == 'PING': 500 Commands.raw('PONG ' + args[1][1:]) 501 elif args[1] == constants.RPL_WELCOME: 502 Events.connect() 503 elif args[1] == constants.ERR_NICKNAMEINUSE: 504 Events.nick_in_use() 505 elif args[1] == constants.INVITE and len(args) == 4: 506 chan = args[3][1:] 507 Events.invite(chan) 508 elif args[1] == constants.KICK and len(args) >= 4: 509 chan = args[2] 510 kicked = args[3] 511 Events.kick(chan, kicked) 512 elif args[1] == constants.PRIVMSG and len(args) >= 4: 513 chan = args[2] 514 nick = args[0].split('!')[0][1:].lower() 515 msg = ' '.join(args[3:])[1:] 516 Events.message(nick, chan, msg) 517 518 class Loops: 519 def start_loops(): 520 threading.Thread(target=Loops.backup).start() 521 threading.Thread(target=Loops.double_fees).start() 522 threading.Thread(target=Loops.maintenance).start() 523 threading.Thread(target=Loops.remind).start() 524 threading.Thread(target=Loops.reward).start() 525 threading.Thread(target=Loops.round).start() 526 threading.Thread(target=Loops.verify).start() 527 528 def backup(): 529 while True: 530 time.sleep(3600) # 1H 531 with open('db.pkl', 'wb') as db_file: 532 pickle.dump(Bot.db, db_file, pickle.HIGHEST_PROTOCOL) 533 Bot.last_backup = time.strftime('%I:%M') 534 print('[+] - Database backed up!') 535 536 def double_fees(): 537 original_fees = {'cashout':config.fees.cashout,'send':config.fees.send,'trade':config.fees.trade} 538 while True: 539 try: 540 time.sleep(functions.random_int(604800,864000)) # 7D - 10D 541 config.fees.cashout = original_fees['cashout']*2 542 config.fees.send = original_fees['send']*2 543 config.fees.trade = original_fees['trade']*2 544 Commands.action(config.connection.channel, color('Double fees have been activated!', constants.red)) 545 time.sleep(functions.random_int(86400, 259200)) # 1D - 3D 546 config.fees.cashout = original_fees['cashout']/2 547 config.fees.send = original_fees['send']/2 548 config.fees.trade = original_fees['trade']/2 549 Commands.notice(config.connection.channel, color('Double fees have been deactivated!', constants.red)) 550 except Exception as ex: 551 config.fees.cashout = original_fees['cashout'] 552 config.fees.send = original_fees['send'] 553 config.fees.trade = original_fees['trade'] 554 print('[!] - Error occured in the double fees loop! (' + str(ex) + ')') 555 556 def maintenance(): 557 while True: 558 try: 559 time.sleep(functions.random_int(604800,1209600)) # 7D - 14D 560 Bot.maintenance = True 561 Commands.action(config.connection.channel, color('Exchange is going down for scheduled maintenance!', constants.red)) 562 time.sleep(functions.random_int(3600, 86400)) # 1H - 1D 563 Bot.maintenance = False 564 Commands.notice(config.connection.channel, color('Maintenance complete! Exchange is back online!', constants.green)) 565 except Exception as ex: 566 Bot.maintenance = False 567 print('[!] - Error occured in the maintenance loop! (' + str(ex) + ')') 568 569 def remind(): 570 time.sleep(10) 571 while True: 572 try: 573 days = functions.month_days() 574 now = int(time.strftime('%-d')) 575 for dayz in (7,14,21): 576 if days-now == dayz: 577 Commands.notice(config.connection.channel, 'There is only {0} week(s) left until round {1} ends!'.format(color(str(int(dayz/7)), constants.cyan), color(str(Bot.db['round']), constants.cyan))) 578 break 579 except Exception as ex: 580 print('[!] - Error occured in the reminder loop! (' + str(ex) + ')') 581 finally: 582 time.sleep(86400) # 24H 583 584 def reward(): 585 while True: 586 try: 587 time.sleep(functions.random_int(86400, 259200)) # 1D - 3D 588 if not Bot.reward['status'] and not Bot.maintenance: 589 option = functions.random_int(25,50) 590 Bot.reward = {'reward':Bot.db['pool']/(option*2),'rewards':option,'status':True} 591 Commands.notice(config.connection.channel, 'There is {1} in the reward pool. Type {2} to grab some cash stacks!'.format(color('${:,}'.format(int(Bot.db['pool'])), constants.green), color('!bang', constants.light_blue))) 592 except Exception as ex: 593 print('[!] - Error occured in the reward loop! (' + str(ex) + ')') 594 595 def round(): 596 time.sleep(10) 597 while True: 598 try: 599 if time.strftime('%d') == '01': 600 Bot.maintenance = True 601 amount = 10 if len(Bot.db['bank']) >= 10 else len(Bot.db['bank']) 602 if amount: 603 clean_bank = dict() 604 for item in Bot.db['bank']: 605 clean_bank[item] = Bot.db['bank'][item][0] 606 richest = sorted(clean_bank, key=clean_bank.get, reverse=True)[:amount] 607 for nick in richest: 608 if nick in Bot.db['score']: 609 Bot.db['score'][nick] = (Bot.db['score'][nick][0]+(amount-richest.index(nick)), Bot.db['score'][nick][1]+Bot.db['bank'][nick][0]) 610 else: 611 Bot.db['score'][nick] = (amount-richest.index(nick), Bot.db['bank'][nick][0]) 612 Commands.notice(config.connection.channel, 'Round {0} is now over! Winners: {1}'.format(color(Bot.db['round'], constants.light_blue), color(', '.join(richest), constants.yellow))) 613 else: 614 Commands.notice(config.connection.channel, 'Round {0} is now over! Winners: {1}'.format(color(Bot.db['round'], constants.light_blue), color('None', constants.grey))) 615 Bot.db = {'bank':dict(),'pool':0.0,'round':Bot.db['round']+1,'score':Bot.db['score'],'verify':dict(),'wallet':dict()} 616 Commands.action(config.connection.channel, 'Round {0} starts NOW!'.format(color(Bot.db['round'], constants.light_blue))) 617 Bot.maintenance = False 618 except Exception as ex: 619 print('[!] - Error occured in the round loop! (' + str(ex) + ')') 620 finally: 621 time.sleep(86400) # 24H 622 623 def verify(): 624 time.sleep(10) 625 while True: 626 try: 627 if Bot.db['verify']: 628 for nick in [nick for nick in Bot.db['verify'] if time.time() - Bot.db['verify'][nick] >= 86400]: # 1D 629 Bot.db['wallet'][nick] = {'USD':config.limits.init} 630 del Bot.db['verify'][nick] 631 Commands.sendmsg(nick, f'Your account is now verified! Here is ${config.limits.init:,} to start trading!') 632 except Exception as ex: 633 print('[!] - Error occured in the verify loop! (' + str(ex) + ')') 634 finally: 635 time.sleep(3600) # 1H 636 637 Bot = IRC() 638 CMC = CoinMarketCap(config.CMC_API_KEY)