Results 1 to 1 of 1
  1. #1
    Duke's Avatar
    Join Date
    Apr 2014
    Gender
    male
    Posts
    266
    Reputation
    61
    Thanks
    26
    My Mood
    Asleep

    Post Python D!sc0rd merchant, private ticket, and backup bot

    Something I cooked up for someone, it went way out of the scope and I spent way too much time on it to not share it with other people. Still a WIP and there are some things I still need to fix/add/remove, especially the recovery feature. Lmk how atrocious my code is, and don't tell me that I need more comments, because I know I do xD

    You can probably presume what is censored.

    Features:
    • Type -ticket to create private channel for author and admins
    • Send a custom intro to each new ticket
    • Customer can send information to be stored locally on bot host's computer (and off of *******)
    • Retrieve ticket data through the bot console, private message, or post it back into the ticket channel
    • Send an invoice for bitcoin, and automatically detect when paid and close the ticket, deleting channel and any ticket information from host computer
    • Generate a list of all member ******* names



    Code:
    """A bot to list all members of a server as well as make ticket channels"""
    import csv
    import sys
    import time
    import re
    import *******
    import datetime
    import asyncio
    import requests
    import os
    import threading
    import platform
    import sqlite3
    import urllib.request
    from *******.ext import commands
    from *******.ex*****mmands import Bot
    from electrum import bitcoin
    from electrum import keystore
    if platform.system() == "Windows":
        from win32com.client import Dispatch
    
    
    # Global Constants
    token = '0'
    command_prefix = '-'
    bot_name = "Duke's Bot"
    seeds = {}
    progress_bar = None
    bot = None
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    conn = None
    c = None
    
    
    # Create files and directories
    if not os.path.isdir('database/'):
        os.mkdir('database/')
    if not os.path.isfile('database/data.db'):
        conn = sqlite3.connect('database/data.db')
        c = conn.cursor()
        c.execute('''CREATE TABLE servers
                     (serverid TEXT, servername TEXT, prefix TEXT, ticketnumber INT, intro TEXT)''')
        c.execute('''CREATE TABLE IF NOT EXISTS Addresses 
        (serverid TEXT, address TEXT, balance REAL, ticket INT)''')
        conn.commit()
    else:
        conn = sqlite3.connect('database/data.db')
        c = conn.cursor()
    if not os.path.isdir('settings/'):
        os.mkdir('settings/')
    if not os.path.isfile('settings/vers.txt'):
        ticket_create = open("settings/vers.txt", "w+")
        ticket_create.write('0')
        ticket_create.close()
    if not os.path.isfile('settings/settings.txt'):
        conf_create = open("settings/settings.txt", "w+")
        command_prefix = input('What would you like your prefix to be? Leave blank for default. ')
        if (command_prefix.isalpha() and len(command_prefix) == 1) or command_prefix.isdigit():
            print("That prefix is too dangerous. Reverting to default")
            command_prefix = "-"
        conf_create.write('#Your bot token. Please follow TO GET A token directions in README.txt to get a token\n' + token
                          + '#Your bot prefix\n' + command_prefix)
        conf_create.close()
        input('Please follow TO GET A token directions in README.txt to get a token')
        sys.exit(0)
    
    
    # Get all constants
    num_lines = 0
    with open('settings/settings.txt') as fp:
        line = fp.readline()
        while line:
            if line[0] is not '' and line[0] is not '#':
                num_lines += 1
            line = fp.readline()
        fp.seek(0)
        line = fp.readline()
        while line:
            if token is '0' and line[0] is not '#' and line is not '':
                token = line[:-1]
            elif command_prefix is '' and line[0] is not '#' and line is not '':
                command_prefix = line
            line = fp.readline()
    opener = urllib.request.build_opener()
    opener.addheaders = [('User-agent', 'Mozilla/5.0')]
    urllib.request.install_opener(opener)
    if len(token) < 14:
        input('Please follow TO GET A token directions in README.txt to get a token')
        sys.exit(0)
    bot = Bot(command_prefix=command_prefix)
    
    
       @bot.event
    async def on_ready():
        print('Logged in as')
        print(bot.user.name + ' displayed as ' + bot_name)
        print(bot.user.id)
        print("Prefix: " + command_prefix)
        print('------')
        print('Ready to work')
        for server in bot.servers:
            c.execute('''SELECT serverid FROM servers WHERE serverid=?''', (server.id,))
            got = c.fetchone()
            if got is None:
                c.execute('''INSERT INTO servers(servername, serverid, prefix, ticketnumber, intro)
                                      VALUES(?,?,?,?,?)''', (server.name, server.id, '-', 0, None))
            query = '''CREATE TABLE IF NOT EXISTS {} (ticket INT PRIMARY KEY, channelid TEXT, userid TEXT, username 
            TEXT, content TEXT, address TEXT, requiredbtc REAL, dollaramnt REAL, 
            senttime TEXT, messageid TEXT)'''.format(combine_server_string(server))
            c.execute(query)
            c.execute('''CREATE TABLE IF NOT EXISTS Addresses (serverid TEXT, 
            address TEXT, balance REAL, ticket INT)''')
            conn.commit()
        await bot.change_presence(game=*******.Game(name="you heathens writhe", type=3))
        await bot.edit_profile(username=bot_name)
        if platform.system() == "Windows":
            user_name = os.getenv('username')
            desktop = 'C:\\Users\\' + user_name + '\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\'
            if not os.path.isfile(desktop + 'mbot.ink'):
                path = os.path.join(desktop, "mbot.lnk")
                target = os.getcwd() + "\\main.exe"
                working_dir = os.getcwd()
                shell = Dispatch('WScript.Shell')
                shortcut = shell.CreateShortCut(path)
                shortcut.Targetpath = target
                shortcut.WorkingDirectory = working_dir
                shortcut.save()
        threading.Timer(10, check_payments).start()
    
    
       @bot.event
    async def on_server_join(server):
        c.execute('''INSERT INTO servers(servername, serverid, prefix, ticketnumber, intro)
                                          VALUES(?,?,?,?,?)''', (server.name, server.id, '-', 0, None))
        query = '''CREATE TABLE IF NOT EXISTS {} (ticket INT PRIMARY KEY, channelid TEXT, userid TEXT,
                username TEXT, content TEXT, address TEXT, requiredbtc REAL, dollaramnt REAL, 
            senttime TEXT, messageid TEXT)'''.format(combine_server_string(server))
        c.execute(query)
        conn.commit()
    
    
       @bot.event
    async def on_command_error(error, ctx):
        print("Error on: " + ctx.message.content)
        if isinstance(error, commands.CommandNotFound):
            return
        else:
            print(error)
    
    
       @bot.command(pass_context=True)
    async def ticket(ctx):
        """Opens up a new ticket channel"""
        if ctx.message.channel.name == "tickets":
            await bot.delete_message(ctx.message)
            server = ctx.message.server
            author_id = ctx.message.author.id
            author_name = str(await bot.get_user_info(author_id))
            c.execute('''SELECT ticketnumber FROM servers WHERE serverid=?''', (server.id,))
            number = c.fetchone()[0]
            c.execute('''SELECT intro FROM servers WHERE serverid=?''', (server.id,))
            server_intro = c.fetchone()[0]
            everyone = *******.PermissionOverwrite(read_messages=False)
            mine = *******.PermissionOverwrite(read_messages=True)
            test = await bot.create_channel(server, str(number), (server.default_role, everyone),
                                            (ctx.message.author, mine))
            if server_intro is not None:
                try:
                    await bot.send_message(test, "Hello. Please copy, paste and fill out the following form.\n"
                                           + "```" + command_prefix + "send " + server_intro + "```")
                except:
                    print("I couldn't send the intro to channel, sending to author")
                    await bot.send_message(ctx.message.author,
                                           "Hello. Please copy, paste and fill out the following form in the ticket\n"
                                           + "```" + command_prefix + "send " + server_intro + "```")
            c.execute('''UPDATE servers SET ticketnumber = ? WHERE serverid=? ''', (str(number+1), server.id,))
            cleaned_name = re.sub("[^0-9a-zA-Z# '.!?]+", '', author_name)
            query = '''INSERT INTO {} (ticket, channelid, userid, username)
                                          VALUES(?,?,?,?)'''.format(combine_server_string(server))
            c.execute(query, (str(number), str(test.id), str(author_id), cleaned_name,))
            conn.commit()
        else:
            await bot.send_message(ctx.message.author, "Please use the correct channel labeled 'tickets'")
    
    
       @bot.command(pass_context=True)
    async def intro(ctx):
        """Adds/ updates the ticket channel welcome message"""
        if ctx.message.author.server_permissions.administrator:
            message_content = ctx.message.content[len(command_prefix)+6:]
            c.execute('''UPDATE servers SET intro = ? WHERE serverid = ? ''',
                      (message_content, ctx.message.server.id,))
            conn.commit()
            await bot.say("Updated.")
        await bot.delete_message(ctx.message)
    
    
       @bot.command(pass_context=True)
    async def prefix(ctx):
        """Changes the prefix to enact the bot"""
        if ctx.message.author.server_permissions.administrator:
            new_prefix = (ctx.message.content[len(command_prefix)+7:])
            server_id = ctx.message.server.id
            if (new_prefix.isalpha() and len(new_prefix) == 1) or new_prefix.isdigit():
                await bot.send_message(ctx.message.channel, "That prefix is too dangerous. Please choose another.")
            else:
                c.execute('''UPDATE servers SET ticketnumber = ? WHERE serverid = ? ''', (new_prefix, server_id,))
                conn.commit()
                await bot.send_message(ctx.message.channel, "My future prefix will be: " + new_prefix)
        else:
            await bot.say("You do not have permissions for that.")
        await bot.delete_message(ctx.message)
    
    
       @bot.command(pass_context=True)
    async def send(ctx):
        """Stores local copy of ticket data. Can also append new data to an old ticket"""
        await bot.delete_message(ctx.message)
        server = ctx.message.server
        query = '''SELECT content FROM {} WHERE channelid = ?'''.format(combine_server_string(server))
        c.execute(query, (ctx.message.channel.id,))
        old_content = c.fetchone()
        if old_content is None:
            await bot.say("Channel is not in my database.")
            return
        else:
            if old_content[0] is not None:
                new_content = old_content[0] + "Update at: " + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + "\n" \
                              + ctx.message.content[len(command_prefix)+5:] + "\n"
            else:
                new_content = ctx.message.content[len(command_prefix) + 5:] + '\n'
            query = '''UPDATE {} SET content = ? WHERE channelid = ?'''.format(combine_server_string(server))
            c.execute(query, (new_content, ctx.message.channel.id,))
            conn.commit()
            await bot.say(ctx.message.author.display_name + " I have received your message.")
    
    
       @bot.command(pass_context=True)
    async def close(ctx):
        """Deletes the channel and local ticket data"""
        if ctx.message.author.server_permissions.administrator:
            query = '''SELECT FROM {} WHERE channelid = ?'''.format(combine_server_string(ctx.message.server))
            c.execute(query, (ctx.message.channel.id,))
            check_exist = c.fetchone()
            if check_exist is not None:
                query = ''''DELETE FROM {} WHERE channelid=?'''.format(combine_server_string(ctx.message.server))
                c.execute(query, (ctx.message.channel.id,))
                await bot.delete_channel(ctx.message.channel)
            else:
                await bot.say("Channel not in database.")
                await bot.delete_message(ctx.message)
    
    
       @bot.command(pass_context=True)
    async def console(ctx):
        """Posts ticket data to the local console"""
        if ctx.message.author.server_permissions.administrator:
            await bot.delete_message(ctx.message)
            query = '''SELECT content FROM {} WHERE channelid = ?'''.format(combine_server_string(ctx.message.server))
            c.execute(query, (ctx.message.channel.id,))
            check_exist = c.fetchone()
            if check_exist is not None:
                print(check_exist[0])
            else:
                print("No data")
    
    
       @bot.command(pass_context=True)
    async def post(ctx):
        """Posts ticket data to the channel"""
        if ctx.message.author.server_permissions.administrator:
            await bot.delete_message(ctx.message)
            query = '''SELECT content FROM {} WHERE channelid = ?'''.format(combine_server_string(ctx.message.server))
            c.execute(query, (ctx.message.channel.id,))
            check_exist = c.fetchone()
            if check_exist is not None:
                await bot.say('```' + check_exist[0] + '```')
            else:
                await bot.say('No data')
    
    
       @bot.command(pass_context=True)
    async def private(ctx):
        """Pms ticket data to the admin"""
        if ctx.message.author.server_permissions.administrator:
            await bot.delete_message(ctx.message)
            query = '''SELECT content FROM {} WHERE channelid = ?'''.format(combine_server_string(ctx.message.server))
            c.execute(query, (ctx.message.channel.id,))
            check_exist = c.fetchone()
            if check_exist is not None:
                await bot.send_message(ctx.message.author, '```' + check_exist[0] + '```')
            else:
                await bot.say('No data')
    
    
       @bot.command(pass_context=True)
    async def ids(ctx):
        """Returns a CSV file of all users on the server. May take some time."""
        if ctx.message.author.server_permissions.administrator:
            await bot.request_offline_members(ctx.message.server)
            print("This may take a while.")
            before = time.time()
            nicknames = [m.id for m in ctx.message.server.members]
            with open('ids.csv', mode='w', encoding='utf-8', newline='') as f:
                writer = csv.writer(f, dialect='excel')
                for v in nicknames:
                    writer.writerow([await bot.get_user_info(v)])
            after = time.time()
            await bot.send_file(ctx.message.author, 'ids.csv', filename='ids.csv',
                                content="Also saved locally in ids.csv. Compiled in {:.4}ms.".format((after - before)*1000))
    
    
       @bot.command(pass_context=True)
    async def sendids(ctx):
        """Sends a pm to all users on previously generated ids.txt"""
        if ctx.message.author.server_permissions.administrator:
            if os.path.isfile('ids.txt'):
                f = open('ids.txt')
                id_line = f.readline()
                while line:
                    recip = await bot.get_user_info(id_line)
                    try:
                        time.sleep(.1)
                        await bot.send_message(recip, ctx.message.content[len(command_prefix)+8:])
                    except:
                        print('Can not send to ' + recip)
                    id_line = f.readline()
                f.close()
            else:
                bot.send_message(ctx.message.author, "You haven't generated an ids.txt file. Run ```" + command_prefix
                                 + 'textids```')
                print("You haven't generated an ids.txt file. Run '''" + command_prefix + 'textids```')
    
    
       @bot.command(pass_context=True)
    async def textids(ctx):
        """Generate a local text file of ids"""
        if ctx.message.author.server_permissions.administrator:
            await bot.request_offline_members(ctx.message.server)
            id_numbers = [m.id for m in ctx.message.server.members]
            all_ids = ''
            for v in id_numbers:
                if all_ids == '':
                    all_ids = v
                else:
                    all_ids = all_ids + '\n' + v
            f = open('ids.txt', "w")
            f.write(all_ids)
            f.close()
    
    
       @bot.event
    async def on_message(ctx):
        if ctx.channel.name == 'tickets' and not ctx.author.server_permissions.administrator and not\
                ct*****ntent == command_prefix + 'ticket':
            await bot.send_message(ctx.author, "You may only post " + command_prefix + 'ticket in the ticket channel')
            await bot.delete_message(ctx)
        else:
            await bot.process_commands(ctx)
    
    
       @bot.command(pass_context=True)
    async def done(ctx):
        """Work in progress system to automatically accept btc"""
        if ctx.message.author.server_permissions.administrator:
            server = ctx.message.server
            c.execute('''SELECT address FROM Addresses WHERE (serverid=? and
                     ticket IS NULL)''', (server.id,))
            addr = c.fetchone()
            if addr is not None:
                dollars_due = float(re.sub("[^0-9.]+", '', ctx.message.content[len(command_prefix)+5:]))
                amount_due = dollars_to_btc(dollars_due)
                msg = await bot.say('Please send ' + str(amount_due) + ' bitcoin to ' + addr[0] + ' within 60 minutes')
                query = '''UPDATE {} SET address=?,  requiredbtc=?, dollaramnt=?, senttime=?,
                 messageid=? WHERE channelid=?'''.format(combine_server_string(server))
                sent_time = time.time()
                msg_id = msg.id
                c.execute(query, (addr[0], amount_due, dollars_due, sent_time, msg_id, ctx.message.channel.id))
                query = '''SELECT ticket FROM {} WHERE channelid = ?'''.format(combine_server_string(ctx.message.server))
                c.execute(query, (ctx.message.channel.id,))
                ticket_number = c.fetchone()[0]
                c.execute('''UPDATE Addresses SET ticket=? WHERE address=?''', (ticket_number, addr[0]))
                conn.commit()
            else:
                await bot.say('Please generate some (more?) addresses.')
    
    
       @bot.command(pass_context=True)
    async def seed(ctx):
        """Add 50 receiving addresses to the database. RUN ONCE"""
        await bot.delete_message(ctx.message)
        if ctx.message.author is ctx.message.server.owner:
            c.execute('''SELECT address FROM Addresses WHERE serverid=?''', (ctx.message.server.id,))
            already_ran = c.fetchone()
            if already_ran is None:
                server = ctx.message.server
                server_id = server.id
                k = keystore.from_seed(ctx.message.content[len(command_prefix) + 5:], '', False)
                for x in range(0, 49):
                    addr = bitcoin.pubkey_to_address('p2pkh', k.derive_pubkey(False, x))
                    addr_balance = get_balance(addr)
                    c.execute('''INSERT INTO Addresses (serverid, address, balance)
                                                          VALUES(?,?,?)''', (server_id, addr, addr_balance,))
                conn.commit()
                await bot.send_message(ctx.message.author, "50 btc addresses have been generated and stored.")
            else:
                await bot.say("Addresses already generated.")
    
    
    async def delete_channel(channel_id):
        await bot.delete_channel(channel_id)
    
    
    async def update_payment(message_id, channel_id, new_btc, address, author_id, server_id):
        await bot.http.delete_message(channel_id, message_id, server_id)
        await bot.http.edit_message(message_id, channel_id, "<@" + author_id + "> Please send the updated amount of " +
                                    new_btc + " to " + address, server_id)
        await bot.http.send_message(channel_id, "<@" + author_id + ">", server_id)
    
    
    async def payment_time_left(channel_id, message_id, amount_due, address, sent_time):
        time_left = 60 - round((time.time() - float(sent_time)) / 60)
        await bot.http.edit_message(message_id, channel_id, 'Please send ' + str(amount_due) + ' bitcoin to ' + address +
                                    ' within ' + str(time_left) + ' minutes')
    
    
    def combine_server_string(server):
        return '[' + clean_string(server.name) + ":" + server.id + ']'
    
    
    def get_balance(address):
        response = requests.get("https://bitaps.com/api/address/" + address)
        if response.status_code != 200:
            return None
        balance = round(float(response.json()['confirmed_balance'] / 100000000), 5)
        return balance
    
    
    def dollars_to_btc(dollars_due):
        bitcoin_api_url = 'https://api.coinmarketcap.com/v1/ticker/bitcoin/'
        response = requests.get(bitcoin_api_url)
        response_json = response.json()
        btc_price = float(response_json[0]['price_usd'])
        return round(dollars_due / btc_price, 4)
    
    
    def clean_string(string):
        cleaned_string = re.sub("[^0-9a-zA-Z ']+", '', string)
        return cleaned_string
    
    
    def check_payments():
        conn2 = sqlite3.connect('database/data.db')
        c2 = conn2.cursor()
        for server in bot.servers:
            query = '''SELECT * FROM {} WHERE requiredbtc IS NOT NULL'''.format(combine_server_string(server))
            required = c2.execute(query)
            for k in required:
                channel_id = k[1]
                addr = k[5]
                required_btc = k[6]
                dollars_due = k[7]
                sent_time = k[8]
                message_id = k[9]
                c2.execute('''SELECT balance FROM Addresses WHERE address=?''', (addr,))
                start_balance = c2.fetchone()[0]
                if (float(start_balance) + float(get_balance(addr))) > float(required_btc):
                    print("Ticket paid")
                    query = '''DELETE FROM {} WHERE address=?'''.format(combine_server_string(server))
                    c2.execute(query, (addr,))
                    asyncio.run_coroutine_threadsafe(delete_channel(channel_id), loop)
                elif float(time.time()) > float(sent_time) + 3600:
                    print("Ticket out of time")
                    new_btc = dollars_to_btc(dollars_due)
                    asyncio.run_coroutine_threadsafe(update_payment(message_id, channel_id, new_btc, addr, k[3],
                                                                    server.id), loop)
                    query = '''UPDATE {} SET requiredbtc=?, senttime=? 
                    WHERE channelid=?'''.format(combine_server_string(server))
                    c2.execute(query, (new_btc, time.time(), channel_id))
                else:
                    print("Updating ticket time left")
                    asyncio.run_coroutine_threadsafe(payment_time_left(channel_id, message_id,
                                                                       required_btc, addr, sent_time), loop)
        threading.Timer(60, check_payments).start()
    
    
    if __name__ == '__main__':
        bot.run(token)
    Last edited by Duke; 03-26-2019 at 12:13 PM.
    01110000 01110011 01110100 01100101 01100010 01101001 01101110 01010011 01000100 01110010 01000100 01010111 00110111 01110001 01110110

Similar Threads

  1. [Solved] Private injectors and hacks.
    By XxMahxX in forum CrossFire Help
    Replies: 5
    Last Post: 09-17-2012, 10:04 AM
  2. How to disable VAC in Private matches and Zombies
    By wasaka1 in forum Call of Duty Black OPS Tutorials
    Replies: 5
    Last Post: 12-24-2010, 01:07 AM
  3. [Request] Metin2RO/uk private servers...and more
    By ReKinu in forum Hack Requests
    Replies: 0
    Last Post: 07-05-2010, 05:02 PM
  4. 3 siggys-Spiderman, Saving Private Ryan, and an Irish siggy
    By m164life in forum Art & Graphic Design
    Replies: 9
    Last Post: 04-26-2008, 04:59 AM
  5. Selling private bypass and hack for runescape account 60+ and money
    By whomper in forum Trade Accounts/Keys/Items
    Replies: 2
    Last Post: 07-24-2007, 04:56 AM