Example #1
0
 def load_template(self):
     """ Load an existing config file or use the packaged examples"""
     if functions.main_is_frozen():
         self._configpath = os.environ['ALLUSERSPROFILE'] + '\\BigBrotherBot\\'
     else:
         self._configpath = 'b3\\'
     if self._set_parser == 'bfbc2':
         _dflttemplate = self._configpath + 'conf\\b3.bfbc2_example.xml'
     elif self._set_parser == 'moh':
         _dflttemplate = self._configpath + 'conf\\b3.moh_example.xml'
     else:
         _dflttemplate = self._configpath + 'conf\\b3.distribution.xml'
     if self._template != '':
         # means we just backed-up an old config with the same name
         _result = self.raw_default("Do you want to use the values from the backed-up config (%s)?"
                                    %(self._template), "yes")
         if _result != 'yes':
             self._template = self.raw_default("Load values from an existing configfile", _dflttemplate)
     else:
         self._template = self.raw_default("Load values from an existing configfile", _dflttemplate)
     self._template = self.getAbsolutePath(self._template)
     self.tree = ElementTree()
     try:
         self.tree.parse(self._template)
         return True
     except Exception, msg:
         #self.add_buffer('Could not parse xml file: %s\n' % msg)
         # backed up config file must be corrupt or not completed last setup, reset it to the default
         self.add_buffer('Your previous config file was either empty, corrupt or not finished.\
          Suggest we load the default...\n')
         self._template = ''
         return False
Example #2
0
    def load_template(self):
        """ Load an existing config file or use the packaged examples"""
        if os.path.exists('b3/conf'):
            self._configpath = 'b3/'
        # perhaps setup is executed directly
        elif os.path.exists('conf/'):
            self._configpath = ''
        elif functions.main_is_frozen():
            self._configpath = os.environ['ALLUSERSPROFILE'] + '/BigBrotherBot/'
        else:
            self._configpath = self.raw_default(
                "Could not locate the config folder, please provide the full path (using /)"
            ).rstrip('/') + '/'

        # load the template based on the parser the user just chose
        _dflttemplate = self._configpath + 'conf/templates/b3.' + self._set_parser + '.tpl'
        self._templatevar = 'template'
        if not os.path.exists(_dflttemplate):
            _dflttemplate = self._configpath + 'conf/b3.distribution.xml'
            self._templatevar = 'distribution'

        if self._template != '':
            # means we just backed-up an old config with the same name
            _result = self.raw_default(
                "Do you want to use the values from the backed-up config (%s)?"
                % (self._template), "yes")
            if _result != 'yes':
                self._template = self.raw_default(
                    "Load values from a template", _dflttemplate)
            else:
                self._templatevar = 'backup'
        else:
            self._template = self.raw_default("Load values from a template",
                                              _dflttemplate)

        self._template = self.getAbsolutePath(self._template)
        self.tree = ElementTree()
        try:
            self.tree.parse(self._template)
            return True
        except Exception, msg:
            self.add_buffer('Could not parse xml file: %s\n' % msg)
            # backed up config file must be corrupt or not completed last setup, reset it to the default
            self.add_buffer(
                'Your previous config file was either empty, corrupt or not finished.\
             I Suggest we load the default...\n')
            self._template = ''
            return False
Example #3
0
    def load_template(self):
        """ Load an existing config file or use the packaged examples"""
        if os.path.exists("b3/conf"):
            self._configpath = "b3/"
        # perhaps setup is executed directly
        elif os.path.exists("conf/"):
            self._configpath = ""
        elif functions.main_is_frozen():
            self._configpath = os.environ["ALLUSERSPROFILE"] + "/BigBrotherBot/"
        else:
            self._configpath = (
                self.raw_default("Could not locate the config folder, please provide the full path (using /)").rstrip(
                    "/"
                )
                + "/"
            )

        # load the template based on the parser the user just chose
        _dflttemplate = self._configpath + "conf/templates/b3." + self._set_parser + ".tpl"
        self._templatevar = "template"
        if not os.path.exists(_dflttemplate):
            _dflttemplate = self._configpath + "conf/b3.distribution.xml"
            self._templatevar = "distribution"

        if self._template != "":
            # means we just backed-up an old config with the same name
            _result = self.raw_default(
                "Do you want to use the values from the backed-up config (%s)?" % (self._template), "yes"
            )
            if _result != "yes":
                self._template = self.raw_default("Load values from a template", _dflttemplate)
            else:
                self._templatevar = "backup"
        else:
            self._template = self.raw_default("Load values from a template", _dflttemplate)

        self._template = self.getAbsolutePath(self._template)
        self.tree = ElementTree()
        try:
            self.tree.parse(self._template)
            return True
        except Exception, msg:
            self.add_buffer("Could not parse xml file: %s\n" % msg)
            # backed up config file must be corrupt or not completed last setup, reset it to the default
            self.add_buffer(
                "Your previous config file was either empty, corrupt or not finished.\
             I Suggest we load the default...\n"
            )
            self._template = ""
            return False
Example #4
0
    def load_template(self):
        """ Load an existing config file or use the packaged examples"""
        if os.path.exists('b3/conf'):
            self._configpath = 'b3/'
        # perhaps setup is executed directly
        elif os.path.exists('conf/'):
            self._configpath = ''
        elif functions.main_is_frozen():
            self._configpath = os.environ['ALLUSERSPROFILE'] + '/BigBrotherBot/'
        else:
            self._configpath = self.raw_default(
                "Could not locate the config folder, please provide the full path (using /)").rstrip('/') + '/'

        # load the template based on the parser the user just chose
        _dflttemplate = self._configpath + 'conf/templates/b3.' + self._set_parser + '.tpl'
        self._templatevar = 'template'
        if not os.path.exists(_dflttemplate):
            _dflttemplate = self._configpath + 'conf/b3.distribution.xml'
            self._templatevar = 'distribution'

        if self._template != '':
            # means we just backed-up an old config with the same name
            _result = self.raw_default("Do you want to use the values from the backed-up config (%s)?"
                                       % (self._template), "yes")
            if _result != 'yes':
                self._template = self.raw_default("Load values from a template", _dflttemplate)
            else:
                self._templatevar = 'backup'
        else:
            self._template = self.raw_default("Load values from a template", _dflttemplate)

        self._template = self.getAbsolutePath(self._template)
        self.tree = ElementTree()
        try:
            self.tree.parse(self._template)
            return True
        except Exception, msg:
            self.add_buffer('Could not parse xml file: %s\n' % msg)
            # backed up config file must be corrupt or not completed last setup, reset it to the default
            self.add_buffer('Your previous config file was either empty, corrupt or not finished.\
             I Suggest we load the default...\n')
            self._template = ''
            return False
Example #5
0
class Setup:
    _pver = sys.version.split()[0]
    _indentation = '    '
    _config = r'b3/conf/b3.xml'
    _template = ''
    _templatevar = ''
    _buffer = ''
    _equaLength = 15
    ## @todo bfbc2 and moh need to be added later when parsers correctly implemented pb.
    _PBSupportedParsers = ['cod', 'cod2', 'cod4', 'cod5', 'cod6', 'cod7']
    _frostBite = ['bfbc2', 'moh', 'bf3']

    def __init__(self, config=None):
        if config:
            self._config = config
        elif self.getB3Path() != "":
            self._config = self.getB3Path() + r'/conf/b3.xml'
        print self._config
        self.introduction()
        self.clearscreen()
        self._outputFile = self.raw_default("Location and name of the new configfile", self._config)
        self._outputTempFile = tempfile.NamedTemporaryFile(delete=False)
        #Creating Backup
        self.backupFile(self._outputFile)
        self.runSetup()
        # copy the config to it's final version
        shutil.copy(self._outputTempFile.name, self._outputFile)
        try:
            # try to delete the tempfile. this fails on Windows in some cases
            os.unlink(self._outputTempFile.name)
        except:
            pass
        raise SystemExit('Restart B3 or reconfigure B3 using option: -s')

    def runSetup(self):
        """ The main function that handles the setup steps """
        global xml
        xml = XMLWriter(self._outputTempFile)

        # write appropriate header
        xml.declaration()
        xml.comment("\n This file is generated by the B3 setup Procedure.\n\
 If you want to regenerate this file and make sure the format is\n\
 correct, you can invoke the setup procedure with the\n\
 command : b3_run -s b3.xml\n\n\
 This is B3 main config file (the one you specify when you run B3 with the\n\
 command : b3_run -c b3.xml)\n\n\
 For any change made in this config file, you have to restart the bot.\n\
 Whenever you can specify a file/directory path, the following shortcuts\n\
 can be used :\n\
  @b3 : the folder where B3 code is installed in\n\
  @conf : the folder containing this config file\n")

        # first level
        configuration = xml.start("configuration")
        xml.data("\n\t")

        # B3 settings
        self.add_buffer('--B3 SETTINGS---------------------------------------------------\n')
        xml.start("settings", name="b3")
        self.add_set("parser", "",
                     "Define your game: altitude/bf3/bfbc2/cod/cod2/cod4/cod5/cod6/cod7/etpro/homefront/iourt41/moh/oa081/smg/sof2/wop/wop15/")

        # set a template xml file to read existing settings from
        _result = False
        while not _result:
            _result = self.load_template()
            if _result:
                self.add_buffer('Configuration values from [%s] loaded successfully\n' % (self._template))
                break

        # getting database info, test it and set up the tables
        self.add_set("database", self.read_element('b3', 'database', 'mysql://*****:*****@localhost/b3'),
                     "Your database info: [mysql]://[db-user]:[db-password]@[db-server[:port]]/[db-name]")
        self.add_buffer('Testing and Setting Up Database...\n')
        # try to install the tables if they do not exist
        _sqlfiles = ['@b3/sql/b3.sql', 'b3/sql/b3.sql', 'sql/b3.sql']
        _sqlc = 0
        _sqlresult = 'notfound'
        while _sqlresult == 'notfound' and _sqlc < len(_sqlfiles):
            _sqlresult = self.executeSql(_sqlfiles[_sqlc], self._set_database)
            _sqlc += 1
        if _sqlresult == 'notfound':
            # still not found? prompt for the complete path and filename
            _sqlfile = self.raw_default('I could not find b3/sql/b3.sql. Please provide the full path and filename.')
            _sqlresult = self.executeSql(_sqlfile, self._set_database)
        if _sqlresult in ['notfound', 'couldnotopen']:
            # still no luck? giving up...
            self.add_buffer(
                'I give up, I could not find or open SQL file, you will need to import the database tables manually')

        self.add_set("bot_name", self.read_element('b3', 'bot_name', 'b3'), "Name of the bot")
        self.add_set("bot_prefix", self.read_element('b3', 'bot_prefix', '^0(^2b3^0)^7:'),
                     "Ingame messages are prefixed with this code, you can use colorcodes")
        self.add_set("time_format", self.read_element('b3', 'time_format', '%I:%M%p %Z %m/%d/%y'))
        self.add_set("time_zone", self.read_element('b3', 'time_zone', 'CST'),
                     "The timezone your bot is in")
        self.add_set("log_level", self.read_element('b3', 'log_level', '9'),
                     "How much detail in the logfile: 9 = verbose, 10 = debug, 21 = bot, 22 = console")
        self.add_set("logfile", self.read_element('b3', 'logfile', 'b3.log'),
                     "Name of the logfile the bot will generate")
        xml.data("\n\t")
        xml.end()
        xml.data("\n\t")

        # BFBC2 specific settings
        if self._set_parser == 'bfbc2':
            self.add_buffer('\n--BFBC2 SPECIFIC SETTINGS---------------------------------------\n')
            xml.start("settings", name="bfbc2")
            self.add_set("max_say_line_length", self.read_element('bfbc2', 'max_say_line_length', '100'),
                         "how long do you want the lines to be restricted to in the chat zone. (maximum length is 100)")
            xml.data("\n\t")
            xml.end()
            xml.data("\n\t")

        # MOH specific settings
        if self._set_parser == 'moh':
            self.add_buffer('\n--MOH SPECIFIC SETTINGS-----------------------------------------\n')
            xml.start("settings", name="moh")
            self.add_set("max_say_line_length", self.read_element('moh', 'max_say_line_length', '100'),
                         "how long do you want the lines to be restricted to in the chat zone. (maximum length is 100)")
            xml.data("\n\t")
            xml.end()
            xml.data("\n\t")

        # server settings
        self.add_buffer('\n--GAME SERVER SETTINGS------------------------------------------\n')
        xml.start("settings", name="server")

        # Frostbite specific
        if self._set_parser in self._frostBite:
            self.add_set("public_ip", self.read_element('server', 'public_ip', ''),
                         "The IP address of your gameserver")
            self.add_set("port", self.read_element('server', 'port', ''),
                         "The port people use to connect to your gameserver")
            self.add_set("rcon_ip", self.read_element('server', 'rcon_ip', ''),
                         "The IP of your gameserver B3 will connect to in order to send RCON commands. Usually the same as the public_ip")
            self.add_set("rcon_port", self.read_element('server', 'rcon_port', ''),
                         "The port of your gameserver that B3 will connect to in order to send RCON commands. NOT the same as the normal port.")
            self.add_set("rcon_password", self.read_element('server', 'rcon_password', ''),
                         "The RCON password of your gameserver.")
            self.add_set("timeout", self.read_element('server', 'timeout', '3'),
                         "RCON timeout", silent=True)

        # Homefront specific
        elif self._set_parser == 'homefront':
            self.add_set("public_ip", self.read_element('server', 'public_ip', ''),
                         "The IP address of your gameserver")
            self.add_set("port", self.read_element('server', 'port', ''),
                         "The port people use to connect to your gameserver")
            self.add_set("rcon_ip", self.read_element('server', 'rcon_ip', ''),
                         "The IP of your gameserver B3 will connect to in order to send RCON commands. Usually the same as the public_ip")
            self.add_set("rcon_port", self.read_element('server', 'rcon_port', ''),
                         "The port of your gameserver that B3 will connect to in order to send RCON commands. NOT the same as the normal port.")
            self.add_set("rcon_password", self.read_element('server', 'rcon_password', ''),
                         "The RCON password of your gameserver.")

        # Q3A specific
        else:
            self.add_set("rcon_password", self.read_element('server', 'rcon_password', ''),
                         "The RCON pass of your gameserver")
            self.add_set("port", self.read_element('server', 'port', ''),
                         "The port the server is running on")
            # check if we can run cod7 remote gamelog retrieval
            if version.LooseVersion(self._pver) < version.LooseVersion('2.6.0') and self._set_parser == 'cod7':
                self.add_buffer('\nERROR:\n  You are running python ' + self._pver +
                                ', remote log functionality\n  is not available prior to python version 2.6.0\nYou need to update to python version 2.6+ before you can run B3 for CoD7!')
                self.testExit()
            elif self._set_parser == 'cod7':
                self.add_buffer(
                    '\nNOTE: You\'re gamelog must be set to this format:\nhttp://logs.gameservers.com/127.0.0.1:1024/xxxxx-1234-5678-9012-xxxxx')
            # determine if ftp functionality is available
            elif version.LooseVersion(self._pver) < version.LooseVersion('2.6.0'):
                self.add_buffer('\n  NOTE for game_log:\n  You are running python ' + self._pver +
                                ', ftp functionality\n  is not available prior to python version 2.6.0\n')
            else:
                self.add_buffer('\n  NOTE for game_log:\n  You are running python ' + self._pver +
                                ', the gamelog may also be\n  ftp-ed or http-ed in.\n  Define game_log like this:\n   ftp://[ftp-user]:[ftp-password]@[ftp-server]/path/to/games_mp.log\n  Or for web access (you can use htaccess to secure):\n   http://serverhost/path/to/games_mp.log\n')
            self.add_set("game_log", self.read_element('server', 'game_log', ''),
                         "The gameserver generates a logfile, put the path and name here")
            self.add_set("public_ip", self.read_element('server', 'public_ip', ''),
                         "The public IP your gameserver is residing on")
            self.add_set("rcon_ip", self.read_element('server', 'rcon_ip', ''),
                         "The IP the bot can use to send RCON commands to (127.0.0.1 when on the same box)")
            # configure default performances parameters
            self.add_set("delay", self.read_element('server', 'delay', '0.33'),
                         "Delay between each log reading. Set a higher value to consume less disk resources or bandwidth if you remotely connect (ftp or http remote log access)"
                         , silent=True)
            self.add_set("lines_per_second", self.read_element('server', 'lines_per_second', '50'),
                         "Number of lines to process per second. Set a lower value to consume less CPU resources",
                         silent=True)

        # determine if PunkBuster is supported
        if self._set_parser in self._PBSupportedParsers:
            self.add_set("punkbuster", "on", "Is the gameserver running PunkBuster Anticheat: on/off")
        else:
            self.add_set("punkbuster", "off", "Is the gameserver running PunkBuster Anticheat: on/off", silent=True)

        xml.data("\n\t")
        xml.end()
        xml.data("\n\t")

        # update channel settings
        self.add_buffer('\n--UPDATE CHANNEL-------------------------------------------------\n')
        self.add_buffer("""
  B3 checks if a new version is available at startup against 3 different channels. Choose the
  channel you want to check against.

  Available channels are :
    stable : will only show stable releases of B3
    beta : will also check if a beta release is available
    dev : will also check if a development release is available

""")
        xml.start("settings", name="update")
        xml.data("\n\t\t")
        xml.comment("""B3 checks if a new version is available at startup. Choose here what channel you want to check against.
            Available channels are :
                stable : will only show stable releases of B3
                beta   : will also check if a beta release is available
                dev    : will also check if a development release is available
            If you don't know what channel to use, use 'stable'
        """)
        xml.data("\t\t")
        self.add_set("channel", self.read_element('update', 'channel', 'stable'), "stable, beta or dev")
        xml.data("\n\t")
        xml.end()
        xml.data("\n\t")

        # autodoc settings
        self.add_buffer('\n--AUTODOC-------------------------------------------------------\n')
        xml.start("settings", name="autodoc")
        xml.data("\n\t\t")
        xml.comment("Autodoc will generate a user documentation for all B3 commands")
        xml.data("\t\t")
        xml.comment("by default, a html documentation is created in your conf folder")
        self.add_set("type", self.read_element('autodoc', 'type', 'html'), "html, htmltable or xml")
        self.add_set("maxlevel", self.read_element('autodoc', 'maxlevel', '100'),
                     "if you want to exclude commands reserved for higher levels")
        self.add_set("destination", self.read_element('autodoc', 'destination', ''),
                     "Destination can be a file or a ftp url")
        xml.data("\n\t")
        xml.end()
        xml.data("\n\t")

        # messages settings
        self.add_buffer('\n--MESSAGES------------------------------------------------------\n')
        xml.start("settings", name="messages")
        # in this section we also need to check if we have old version messages! they contain: %s
        if '%s' in self.read_element('messages', 'kicked_by', '%s'):
            self.add_set("kicked_by", "$clientname^7 was kicked by $adminname^7 $reason")
        else:
            self.add_set("kicked_by",
                         self.read_element('messages', 'kicked_by', '$clientname^7 was kicked by $adminname^7 $reason'))

        if '%s' in self.read_element('messages', 'kicked', '%s'):
            self.add_set("kicked", "$clientname^7 was kicked $reason")
        else:
            self.add_set("kicked", self.read_element('messages', 'kicked', '$clientname^7 was kicked $reason'))

        if '%s' in self.read_element('messages', 'banned_by', '%s'):
            self.add_set("banned_by", "$clientname^7 was banned by $adminname^7 $reason")
        else:
            self.add_set("banned_by",
                         self.read_element('messages', 'banned_by', '$clientname^7 was banned by $adminname^7 $reason'))

        if '%s' in self.read_element('messages', 'banned', '%s'):
            self.add_set("banned", "$clientname^7 was banned $reason")
        else:
            self.add_set("banned", self.read_element('messages', 'banned', '$clientname^7 was banned $reason'))

        if '%s' in self.read_element('messages', 'temp_banned_by', '%s'):
            self.add_set("temp_banned_by", "$clientname^7 was temp banned by $adminname^7 for $banduration^7 $reason")
        else:
            self.add_set("temp_banned_by", self.read_element('messages', 'temp_banned_by',
                                                             '$clientname^7 was temp banned by $adminname^7 for $banduration^7 $reason'))

        if '%s' in self.read_element('messages', 'temp_banned', '%s'):
            self.add_set("temp_banned", "$clientname^7 was temp banned for $banduration^7 $reason")
        else:
            self.add_set("temp_banned", self.read_element('messages', 'temp_banned',
                                                          '$clientname^7 was temp banned for $banduration^7 $reason'))

        if '%s' in self.read_element('messages', 'unbanned_by', '%s'):
            self.add_set("unbanned_by", "$clientname^7 was un-banned by $adminname^7 $reason")
        else:
            self.add_set("unbanned_by", self.read_element('messages', 'unbanned_by',
                                                          '$clientname^7 was un-banned by $adminname^7 $reason'))

        if '%s' in self.read_element('messages', 'unbanned', '%s'):
            self.add_set("unbanned", "$clientname^7 was un-banned $reason")
        else:
            self.add_set("unbanned", self.read_element('messages', 'unbanned', '$clientname^7 was un-banned $reason'))

        xml.data("\n\t")
        xml.end()
        xml.data("\n\t")

        # plugins settings
        self.add_buffer('\n--PLUGIN CONFIG PATH--------------------------------------------\n')
        xml.start("settings", name="plugins")
        self.add_set("external_dir", self.read_element('plugins', 'external_dir', '@b3/extplugins'))
        xml.data("\n\t")
        xml.end()
        xml.data("\n\t")

        # plugins
        self.add_buffer('\n--INSTALLING PLUGINS--------------------------------------------\n')
        xml.start("plugins")
        xml.data("\n\t\t")
        xml.comment(
            "plugin order is important. Plugins that add new in-game commands all depend on the admin plugin. Make sure to have the admin plugin before them.")
        self.autoinstallplugins = self.raw_default("Do you want to (auto)install all plugins?", "yes")
        if self.autoinstallplugins == 'yes':
            self.read_plugins('plugins')
            # check if we are using a template
            if self._templatevar == 'template':
                self.installextplugins = self.raw_default(
                    "Would you like me to download and install extra, game specific plugins?", "no")
                if self.installextplugins == 'yes':
                    self.read_plugins('extplugins')
        else:
            self.add_plugin("censor", "@conf/plugin_censor.xml")
            self.add_plugin("spamcontrol", "@conf/plugin_spamcontrol.xml")
            self.add_plugin("admin", "@conf/plugin_admin.xml", explanation="the admin plugin is compulsory.",
                            prompt=False)
            self.add_plugin("tk", "@conf/plugin_tk.xml")
            self.add_plugin("stats", "@conf/plugin_stats.xml")
            self.add_plugin("pingwatch", "@conf/plugin_pingwatch.xml")
            self.add_plugin("adv", "@conf/plugin_adv.xml")
            self.add_plugin("status", "@conf/plugin_status.xml")
            self.add_plugin("welcome", "@conf/plugin_welcome.xml")
            if self._set_punkbuster == "on":
                self.add_plugin("punkbuster", "@conf/plugin_punkbuster.xml")
                xml.data("\n\t\t")
            else:
                xml.data("\n\t\t")
                xml.comment("The punkbuster plugin was not installed since punkbuster is not supported or disabled.")
                xml.data("\t\t")

            # ext plugins
            xml.comment(
                "The next plugins are external, 3rd party plugins and should reside in the external_dir. Example:")
            xml.data("\t\t")
            xml.comment("plugin config=\"@b3/extplugins/conf/newplugin.xml\" name=\"newplugin\"")
            _result = self.add_plugin("xlrstats", self._set_external_dir + "/conf/xlrstats.xml", default="no")
            if _result:
                self.executeSql('@b3/sql/xlrstats.sql', self._set_database)

        # final comments
        xml.data("\n\t\t")
        xml.comment("You can add new/custom plugins to this list using the same form as above.")
        xml.data("\t")
        xml.end()

        xml.data("\n")
        xml.close(configuration)
        xml.flush()
        self.add_buffer('\n--FINISHED CONFIGURATION----------------------------------------\n')
        self.testExit(_question='Done, [Enter] to finish setup')


    def load_template(self):
        """ Load an existing config file or use the packaged examples"""
        if os.path.exists('b3/conf'):
            self._configpath = 'b3/'
        # perhaps setup is executed directly
        elif os.path.exists('conf/'):
            self._configpath = ''
        elif functions.main_is_frozen():
            self._configpath = os.environ['ALLUSERSPROFILE'] + '/BigBrotherBot/'
        else:
            self._configpath = self.raw_default(
                "Could not locate the config folder, please provide the full path (using /)").rstrip('/') + '/'

        # load the template based on the parser the user just chose
        _dflttemplate = self._configpath + 'conf/templates/b3.' + self._set_parser + '.tpl'
        self._templatevar = 'template'
        if not os.path.exists(_dflttemplate):
            _dflttemplate = self._configpath + 'conf/b3.distribution.xml'
            self._templatevar = 'distribution'

        if self._template != '':
            # means we just backed-up an old config with the same name
            _result = self.raw_default("Do you want to use the values from the backed-up config (%s)?"
                                       % (self._template), "yes")
            if _result != 'yes':
                self._template = self.raw_default("Load values from a template", _dflttemplate)
            else:
                self._templatevar = 'backup'
        else:
            self._template = self.raw_default("Load values from a template", _dflttemplate)

        self._template = self.getAbsolutePath(self._template)
        self.tree = ElementTree()
        try:
            self.tree.parse(self._template)
            return True
        except Exception, msg:
            self.add_buffer('Could not parse xml file: %s\n' % msg)
            # backed up config file must be corrupt or not completed last setup, reset it to the default
            self.add_buffer('Your previous config file was either empty, corrupt or not finished.\
             I Suggest we load the default...\n')
            self._template = ''
            return False
Example #6
0
class Setup:
    _pver = sys.version.split()[0]
    _indentation = '    '
    _config = r'bbk/conf/bbk.xml'
    _template = ''
    _templatevar = ''
    _buffer = ''
    _equaLength = 15
    ## @todo bfbc2 and moh need to be added later when parsers correctly implemented pb.
    _PBSupportedParsers = ['YolOps2']

    def __init__(self, config=None):
        if config:
            self._config = config
        elif self.getBBKPath() != "":
            self._config = self.getBBKPath() + r'/conf/bbk.xml'
        print self._config
        self.introduction()
        self.clearscreen()
        self._outputFile = self.raw_default("Location and name of the new configfile", self._config)
        self._outputTempFile = tempfile.NamedTemporaryFile(delete=False)
        #Creating Backup
        self.backupFile(self._outputFile)
        self.runSetup()
        # copy the config to it's final version
        shutil.copy(self._outputTempFile.name, self._outputFile)
        try:
            # try to delete the tempfile. this fails on Windows in some cases
            os.unlink(self._outputTempFile.name)
        except:
            pass
        raise SystemExit('Restart BBK or reconfigure BBK using option: -s')

    def runSetup(self):
        """ The main function that handles the setup steps """
        global xml
        xml = XMLWriter(self._outputTempFile, "UTF-8")

        # write appropriate header
        xml.declaration()
        xml.comment("\n This file is generated by the BBK setup Procedure.\n\
  @bbk : the folder where BBK code is installed in\n\
  @conf : the folder containing this config file\n")

        # first level
        configuration = xml.start("configuration")
        xml.data("\n\t")

        # B3 settings
        self.add_buffer('--BBK SETTINGS---------------------------------------------------\n')
        xml.start("settings", name="bbk")
        self.add_set("parser", "",
                     """\
Define your game: YolOps2/someone later""")

        # set a template xml file to read existing settings from
        _result = False
        while not _result:
            _result = self.load_template()
            if _result:
                self.add_buffer('Configuration values from [%s] loaded successfully\n' % (self._template))
                break

        # getting database info, test it and set up the tables
        self.add_set("database", self.read_element('bbk', 'database', 'mysql://*****:*****@localhost/bbk'),
                     "Your database info: [mysql]://[db-user]:[db-password]@[db-server[:port]]/[db-name]")
        self.add_buffer('Testing and Setting Up Database...\n')
        # try to install the tables if they do not exist
        _sqlfiles = ['@bbk/sql/bbk.sql', 'bbk/sql/bbk.sql', 'sql/bbk.sql']
        _sqlc = 0
        _sqlresult = 'notfound'
        while _sqlresult == 'notfound' and _sqlc < len(_sqlfiles):
            _sqlresult = self.executeSql(_sqlfiles[_sqlc], self._set_database)
            _sqlc += 1
        if _sqlresult == 'notfound':
            # still not found? prompt for the complete path and filename
            _sqlfile = self.raw_default('I could not find bbk/sql/bbk.sql. Please provide the full path and filename.')
            _sqlresult = self.executeSql(_sqlfile, self._set_database)
        if _sqlresult in ['notfound', 'couldnotopen']:
            # still no luck? giving up...
            self.add_buffer(
                'I give up, I could not find or open SQL file, you will need to import the database tables manually')

        self.add_set("bot_name", self.read_element('bbk', 'bot_name', 'bbk'), "Name of the bot")
        self.add_set("bot_prefix", self.read_element('bbk', 'bot_prefix', '^0(^2b3^0)^7:'),
                     "Ingame messages are prefixed with this code, you can use colorcodes", allow_blank=True)
        self.add_set("time_format", self.read_element('bbk', 'time_format', '%I:%M%p %Z %m/%d/%y'))
        self.add_set("time_zone", self.read_element('bbk', 'time_zone', 'CST'),
                     "The timezone your bot is in")
        self.add_set("log_level", self.read_element('bbk', 'log_level', '9'),
                     "How much detail in the logfile: 9 = verbose, 10 = debug, 21 = bot, 22 = console")
        self.add_set("logfile", self.read_element('bbk', 'logfile', 'bbk.log'),
                     "Name of the logfile the bot will generate")
        xml.data("\n\t")
        xml.end()
        xml.data("\n\t")

        # server settings
        self.add_buffer('\n--GAME SERVER SETTINGS------------------------------------------\n')
        xml.start("settings", name="server")

        # determine if PunkBuster is supported
        if self._set_parser in self._PBSupportedParsers:
            self.add_set("punkbuster", "on", "Is the gameserver running PunkBuster Anticheat: on/off")
        else:
            self.add_set("punkbuster", "off", "Is the gameserver running PunkBuster Anticheat: on/off", silent=True)

        xml.data("\n\t")
        xml.end()
        xml.data("\n\t")

        # autodoc settings
        self.add_buffer('\n--AUTODOC-------------------------------------------------------\n')
        xml.start("settings", name="autodoc")
        xml.data("\n\t\t")
        xml.comment("Autodoc will generate a user documentation for all BBK commands")
        xml.data("\t\t")
        xml.comment("by default, a html documentation is created in your conf folder")
        self.add_set("type", self.read_element('autodoc', 'type', 'html'), "html, htmltable or xml")
        self.add_set("maxlevel", self.read_element('autodoc', 'maxlevel', '100'),
                     "if you want to exclude commands reserved for higher levels")
        self.add_set("destination", self.read_element('autodoc', 'destination', ''),
                     "Destination can be a file or a ftp url")
        xml.data("\n\t")
        xml.end()
        xml.data("\n\t")

        # messages settings
        self.add_buffer('\n--MESSAGES------------------------------------------------------\n')
        xml.start("settings", name="messages")
        # in this section we also need to check if we have old version messages! they contain: %s
        if '%s' in self.read_element('messages', 'kicked_by', '%s'):
            self.add_set("kicked_by", "$clientname^7 was kicked by $adminname^7 $reason")
        else:
            self.add_set("kicked_by",
                         self.read_element('messages', 'kicked_by', '$clientname^7 was kicked by $adminname^7 $reason'))

        if '%s' in self.read_element('messages', 'kicked', '%s'):
            self.add_set("kicked", "$clientname^7 was kicked $reason")
        else:
            self.add_set("kicked", self.read_element('messages', 'kicked', '$clientname^7 was kicked $reason'))

        if '%s' in self.read_element('messages', 'banned_by', '%s'):
            self.add_set("banned_by", "$clientname^7 was banned by $adminname^7 $reason")
        else:
            self.add_set("banned_by",
                         self.read_element('messages', 'banned_by', '$clientname^7 was banned by $adminname^7 $reason'))

        if '%s' in self.read_element('messages', 'banned', '%s'):
            self.add_set("banned", "$clientname^7 was banned $reason")
        else:
            self.add_set("banned", self.read_element('messages', 'banned', '$clientname^7 was banned $reason'))

        if '%s' in self.read_element('messages', 'temp_banned_by', '%s'):
            self.add_set("temp_banned_by", "$clientname^7 was temp banned by $adminname^7 for $banduration^7 $reason")
        else:
            self.add_set("temp_banned_by", self.read_element('messages', 'temp_banned_by',
                                                             '$clientname^7 was temp banned by $adminname^7 for $banduration^7 $reason'))

        if '%s' in self.read_element('messages', 'temp_banned', '%s'):
            self.add_set("temp_banned", "$clientname^7 was temp banned for $banduration^7 $reason")
        else:
            self.add_set("temp_banned", self.read_element('messages', 'temp_banned',
                                                          '$clientname^7 was temp banned for $banduration^7 $reason'))

        if '%s' in self.read_element('messages', 'unbanned_by', '%s'):
            self.add_set("unbanned_by", "$clientname^7 was un-banned by $adminname^7 $reason")
        else:
            self.add_set("unbanned_by", self.read_element('messages', 'unbanned_by',
                                                          '$clientname^7 was un-banned by $adminname^7 $reason'))

        if '%s' in self.read_element('messages', 'unbanned', '%s'):
            self.add_set("unbanned", "$clientname^7 was un-banned $reason")
        else:
            self.add_set("unbanned", self.read_element('messages', 'unbanned', '$clientname^7 was un-banned $reason'))

        xml.data("\n\t")
        xml.end()
        xml.data("\n\t")

        # plugins settings
        self.add_buffer('\n--PLUGIN CONFIG PATH--------------------------------------------\n')
        xml.start("settings", name="plugins")
        self.add_set("external_dir", self.read_element('plugins', 'external_dir', '@bbk/extplugins'))
        xml.data("\n\t")
        xml.end()
        xml.data("\n\t")

        # plugins
        self.add_buffer('\n--INSTALLING PLUGINS--------------------------------------------\n')
        xml.start("plugins")
        xml.data("\n\t\t")
        xml.comment(
            "plugin order is important. Plugins that add new in-game commands all depend on the admin plugin. Make sure to have the admin plugin before them.")
        self.autoinstallplugins = self.raw_default("Do you want to (auto)install all plugins?", "yes")
        if self.autoinstallplugins == 'yes':
            self.read_plugins('plugins')
            # check if we are using a template
            if self._templatevar == 'template':
                self.installextplugins = self.raw_default(
                    "Would you like me to download and install extra, game specific plugins?", "no")
                if self.installextplugins == 'yes':
                    self.read_plugins('extplugins')
        else:
            self.add_plugin("censor", "@conf/plugin_censor.xml")
            self.add_plugin("spamcontrol", "@conf/plugin_spamcontrol.xml")
            self.add_plugin("admin", "@conf/plugin_admin.xml", explanation="the admin plugin is compulsory.",
                            prompt=False)
            self.add_plugin("tk", "@conf/plugin_tk.xml")
            self.add_plugin("stats", "@conf/plugin_stats.xml")
            self.add_plugin("pingwatch", "@conf/plugin_pingwatch.xml")
            self.add_plugin("adv", "@conf/plugin_adv.xml")
            self.add_plugin("status", "@conf/plugin_status.xml")
            self.add_plugin("welcome", "@conf/plugin_welcome.xml")
            if self._set_punkbuster == "on":
                self.add_plugin("punkbuster", "@conf/plugin_punkbuster.xml")
                xml.data("\n\t\t")
            else:
                xml.data("\n\t\t")
                xml.comment("The punkbuster plugin was not installed since punkbuster is not supported or disabled.")
                xml.data("\t\t")

            # ext plugins
            xml.comment(
                "The next plugins are external, 3rd party plugins and should reside in the external_dir. Example:")
            xml.data("\t\t")
            xml.comment("plugin config=\"@bbk/extplugins/conf/newplugin.xml\" name=\"newplugin\"")
            _result = self.add_plugin("xlrstats", self._set_external_dir + "/conf/xlrstats.xml", default="no")
            if _result:
                self.executeSql('@bbk/sql/xlrstats.sql', self._set_database)

        # final comments
        xml.data("\n\t\t")
        xml.comment("You can add new/custom plugins to this list using the same form as above.")
        xml.data("\t")
        xml.end()

        xml.data("\n")
        xml.close(configuration)
        xml.flush()
        self.add_buffer('\n--FINISHED CONFIGURATION----------------------------------------\n')
        self.testExit(_question='Done, [Enter] to finish setup')


    def load_template(self):
        """ Load an existing config file or use the packaged examples"""
        if os.path.exists('bbk/conf'):
            self._configpath = 'bbk/'
        # perhaps setup is executed directly
        elif os.path.exists('conf/'):
            self._configpath = ''
        elif functions.main_is_frozen():
            self._configpath = os.environ['ALLUSERSPROFILE'] + '/BigBrotherKlaoude/'
        else:
            self._configpath = self.raw_default(
                "Could not locate the config folder, please provide the full path (using /)").rstrip('/') + '/'

        # load the template based on the parser the user just chose
        _dflttemplate = self._configpath + 'conf/templates/bbk.' + self._set_parser + '.tpl'
        self._templatevar = 'template'
        if not os.path.exists(_dflttemplate):
            _dflttemplate = self._configpath + 'conf/bbk.distribution.xml'
            self._templatevar = 'distribution'

        if self._template != '':
            # means we just backed-up an old config with the same name
            _result = self.raw_default("Do you want to use the values from the backed-up config (%s)?"
                                       % (self._template), "yes")
            if _result != 'yes':
                self._template = self.raw_default("Load values from a template", _dflttemplate)
            else:
                self._templatevar = 'backup'
        else:
            self._template = self.raw_default("Load values from a template", _dflttemplate)

        self._template = self.getAbsolutePath(self._template)
        self.tree = ElementTree()
        try:
            self.tree.parse(self._template)
            return True
        except Exception, msg:
            self.add_buffer('Could not parse xml file: %s\n' % msg)
            # backed up config file must be corrupt or not completed last setup, reset it to the default
            self.add_buffer('Your previous config file was either empty, corrupt or not finished.\
             I Suggest we load the default...\n')
            self._template = ''
            return False
Example #7
0
class Setup:
    _pver = sys.version.split()[0]
    _indentation = '    '
    _config = 'b3/conf/b3.xml'
    _template = ''
    _buffer = ''
    _equaLength = 15
    ## @todo bfbc2 and moh need to be added later when parsers correctly implemented pb.
    _PBSupportedParsers = ['cod','cod2','cod4','cod5', 'cod6', 'cod7']
    _frostBite = ['bfbc2', 'moh']
 
    def __init__(self, config=None):
        if config:
            self._config = config
        elif self.getB3Path() != "":
            self._config = self.getB3Path() + "\\conf\\b3.xml"
        print self._config
        self.introduction()
        self.clearscreen()
        self._outputFile = self.raw_default("Location and name of the new configfile", self._config)
        #Creating Backup
        self.backupFile(self._outputFile)
        self.runSetup()
        raise SystemExit('Restart B3 or reconfigure B3 using option: -s')

    def runSetup(self):
        """ The main function that handles the setup steps """
        global xml
        xml = XMLWriter(self._outputFile)

        # write appropriate header
        xml.declaration()
        xml.comment("\n This file is generated by the B3 setup Procedure.\n\
 If you want to regenerate this file and make sure the format is\n\
 correct, you can invoke the setup procedure with the\n\
 command : b3_run -s b3.xml\n\n\
 This is B3 main config file (the one you specify when you run B3 with the\n\
 command : b3_run -c b3.xml)\n\n\
 For any change made in this config file, you have to restart the bot.\n\
 Whenever you can specify a file/directory path, the following shortcuts\n\
 can be used :\n\
  @b3 : the folder where B3 code is installed in\n\
  @conf : the folder containing this config file\n")

        # first level
        configuration = xml.start("configuration")
        xml.data("\n\t")

        # B3 settings
        self.add_buffer('--B3 SETTINGS---------------------------------------------------\n')
        xml.start("settings", name="b3")
        self.add_set("parser", "", "Define your game: cod/cod2/cod4/cod5/cod6/cod7/iourt41/etpro/wop/smg/bfbc2/moh/oa081")
        # set a template xml file to read existing settings from
        _result = False
        while not _result:
            _result = self.load_template()
            if _result:
                self.add_buffer('Configuration values from [%s] loaded successfully\n' %(self._template))
                break
        # getting database info, test it and set up the tables
        self.add_set("database", self.read_element('b3', 'database', 'mysql://*****:*****@localhost/b3'),
                     "Your database info: [mysql]://[db-user]:[db-password]@[db-server[:port]]/[db-name]")
        self.add_buffer('Testing and Setting Up Database...\n')
        # try to install the tables if they do not exist
        _sqlfiles = ['@b3/sql/b3.sql', 'b3/sql/b3.sql', 'sql/b3.sql']
        _sqlc = 0
        _sqlresult = 'notfound'
        while _sqlresult == 'notfound' and _sqlc < len(_sqlfiles):
            _sqlresult = self.executeSql(_sqlfiles[_sqlc])
            _sqlc += 1
        # still not found? prompt for the complete path and filename
        if _sqlresult == 'notfound':
            _sqlfile = self.raw_default('I could not find b3/sql/b3.sql. Please provide the full path and filename.')
            _sqlresult = self.executeSql(_sqlfile)
        # still no luck? giving up...
        if _sqlresult in ['notfound', 'couldnotopen']:
            self.add_buffer('I give up, I could not find or open SQL file, you will need to import the database tables manually')

        self.add_set("bot_name", self.read_element('b3', 'bot_name', 'b3'), "Name of the bot")
        self.add_set("bot_prefix", self.read_element('b3', 'bot_prefix', '^0(^2b3^0)^7:'),
                     "Ingame messages are prefixed with this code, you can use colorcodes")
        self.add_set("time_format", self.read_element('b3', 'time_format', '%I:%M%p %Z %m/%d/%y'))
        self.add_set("time_zone", self.read_element('b3', 'time_zone', 'CST'),
                     "The timezone your bot is in")
        self.add_set("log_level", self.read_element('b3', 'log_level', '9'),
                     "How much detail in the logfile: 9 = verbose, 10 = debug, 21 = bot, 22 = console")
        self.add_set("logfile", self.read_element('b3', 'logfile', 'b3.log'),
                     "Name of the logfile the bot will generate")
        xml.data("\n\t")
        xml.end()
        xml.data("\n\t")
        
        # BFBC2 specific settings
        if self._set_parser == 'bfbc2':
            self.add_buffer('\n--BFBC2 SPECIFIC SETTINGS---------------------------------------\n')
            xml.start("settings", name="bfbc2")
            self.add_set("max_say_line_length", self.read_element('bfbc2', 'max_say_line_length', '100'),
                         "how long do you want the lines to be restricted to in the chat zone. (maximum length is 100)")
            xml.data("\n\t")
            xml.end()
            xml.data("\n\t")

        # MOH specific settings
        if self._set_parser == 'moh':
            self.add_buffer('\n--MOH SPECIFIC SETTINGS-----------------------------------------\n')
            xml.start("settings", name="moh")
            self.add_set("max_say_line_length", self.read_element('moh', 'max_say_line_length', '100'),
                         "how long do you want the lines to be restricted to in the chat zone. (maximum length is 100)")
            xml.data("\n\t")
            xml.end()
            xml.data("\n\t")

        # server settings
        self.add_buffer('\n--GAME SERVER SETTINGS------------------------------------------\n')
        xml.start("settings", name="server")
        # Frostbite specific
        if self._set_parser in self._frostBite:
            self.add_set("public_ip", self.read_element('server', 'public_ip', ''),
                         "The IP address of your gameserver")
            self.add_set("port", self.read_element('server', 'port', ''),
                         "The port people use to connect to your gameserver")
            self.add_set("rcon_ip", self.read_element('server', 'rcon_ip', ''),
                         "The IP that the bot uses to send RCON commands. Usually the same as the public_ip")
            self.add_set("rcon_port", self.read_element('server', 'rcon_port', ''),
                         "The port that the bot uses to send RCON commands. NOT the same as the normal port.")
            self.add_set("rcon_password", self.read_element('server', 'rcon_password', ''),
                         "The RCON password of your gameserver.")
            self.add_set("timeout", self.read_element('server', 'timeout', '3'),
                         "RCON timeout", silent=True)
        # Q3Aa specific
        else:   
            self.add_set("rcon_password", self.read_element('server', 'rcon_password', ''),
                         "The RCON pass of your gameserver")
            self.add_set("port", self.read_element('server', 'port', ''),
                         "The port the server is running on")
            # check if we can run cod7 remote gamelog retrieval
            if version.LooseVersion(self._pver) < version.LooseVersion('2.6.0') and self._set_parser == 'cod7':
                self.add_buffer('\nERROR:\n  You are running python '+self._pver+
                                ', remote log functionality\n  is not available prior to python version 2.6.0\nYou need to update to python version 2.6+ before you can run B3 for CoD7!')
                self.testExit()
            elif self._set_parser == 'cod7':
                self.add_buffer('\nNOTE: You\'re gamelog must be set to this format:\nhttp://logs.gameservers.com/127.0.0.1:1024/xxxxx-1234-5678-9012-xxxxx')
            # determine if ftp functionality is available
            elif version.LooseVersion(self._pver) < version.LooseVersion('2.6.0'):
                self.add_buffer('\n  NOTE for game_log:\n  You are running python '+self._pver+
                                ', ftp functionality\n  is not available prior to python version 2.6.0\n')
            else:
                self.add_buffer('\n  NOTE for game_log:\n  You are running python '+self._pver+
                                ', the gamelog may also be\n  ftp-ed or http-ed in.\n  Define game_log like this:\n   ftp://[ftp-user]:[ftp-password]@[ftp-server]/path/to/games_mp.log\n  Or for web access (you can use htaccess to secure):\n   http://serverhost/path/to/games_mp.log\n')
            self.add_set("game_log", self.read_element('server', 'game_log', ''),
                         "The gameserver generates a logfile, put the path and name here")
            self.add_set("public_ip", self.read_element('server', 'public_ip', ''),
                         "The public IP your gameserver is residing on")
            self.add_set("rcon_ip", self.read_element('server', 'rcon_ip', ''),
                         "The IP the bot can use to send RCON commands to (127.0.0.1 when on the same box)")
            # configure default performances parameters
            self.add_set("delay", self.read_element('server', 'delay', '0.33'),
                         "Delay between each log reading. Set a higher value to consume less disk ressources or bandwidth if you remotely connect (ftp or http remote log access)", silent=True)
            self.add_set("lines_per_second", self.read_element('server', 'lines_per_second', '50'),
                         "Number of lines to process per second. Set a lower value to consume less CPU ressources",
                         silent=True)

        # determine if PunkBuster is supported
        if self._set_parser in self._PBSupportedParsers:
            self.add_set("punkbuster", "on", "Is the gameserver running PunkBuster Anticheat: on/off")
        else:
            self.add_set("punkbuster", "off", "Is the gameserver running PunkBuster Anticheat: on/off", silent=True)

        xml.data("\n\t")
        xml.end()
        xml.data("\n\t")

        # autodoc settings
        self.add_buffer('\n--AUTODOC-------------------------------------------------------\n')
        xml.start("settings", name="autodoc")
        xml.data("\n\t\t")
        xml.comment("Autodoc will generate a user documentation for all B3 commands") 
        xml.data("\t\t")
        xml.comment("by default, a html documentation is created in your conf folder")
        self.add_set("type", self.read_element('autodoc', 'type', 'html'), "html, htmltable or xml")
        self.add_set("maxlevel", self.read_element('autodoc', 'maxlevel', '100'),
                     "if you want to exclude commands reserved for higher levels")
        self.add_set("destination", self.read_element('autodoc', 'destination', ''),
                     "Destination can be a file or a ftp url")
        xml.data("\n\t")
        xml.end()
        xml.data("\n\t")

        # messages settings
        self.add_buffer('\n--MESSAGES------------------------------------------------------\n')
        xml.start("settings", name="messages")
        # in this section we also need to check if we have old version messages! they contain: %s
        if '%s' in self.read_element('messages', 'kicked_by', '%s'):
            self.add_set("kicked_by", "$clientname^7 was kicked by $adminname^7 $reason")
        else:
            self.add_set("kicked_by", self.read_element('messages', 'kicked_by', '$clientname^7 was kicked by $adminname^7 $reason'))

        if '%s' in self.read_element('messages', 'kicked', '%s'):
            self.add_set("kicked", "$clientname^7 was kicked $reason")
        else:
            self.add_set("kicked", self.read_element('messages', 'kicked', '$clientname^7 was kicked $reason'))

        if '%s' in self.read_element('messages', 'banned_by', '%s'):
            self.add_set("banned_by", "$clientname^7 was banned by $adminname^7 $reason")
        else:
            self.add_set("banned_by", self.read_element('messages', 'banned_by', '$clientname^7 was banned by $adminname^7 $reason'))

        if '%s' in self.read_element('messages', 'banned', '%s'):
            self.add_set("banned", "$clientname^7 was banned $reason")
        else:
            self.add_set("banned", self.read_element('messages', 'banned', '$clientname^7 was banned $reason'))

        if '%s' in self.read_element('messages', 'temp_banned_by', '%s'):
            self.add_set("temp_banned_by", "$clientname^7 was temp banned by $adminname^7 for $banduration^7 $reason")
        else:
            self.add_set("temp_banned_by", self.read_element('messages', 'temp_banned_by', '$clientname^7 was temp banned by $adminname^7 for $banduration^7 $reason'))

        if '%s' in self.read_element('messages', 'temp_banned', '%s'):
            self.add_set("temp_banned", "$clientname^7 was temp banned for $banduration^7 $reason")
        else:
            self.add_set("temp_banned", self.read_element('messages', 'temp_banned', '$clientname^7 was temp banned for $banduration^7 $reason'))

        if '%s' in self.read_element('messages', 'unbanned_by', '%s'):
            self.add_set("unbanned_by", "$clientname^7 was un-banned by $adminname^7 $reason")
        else:
            self.add_set("unbanned_by", self.read_element('messages', 'unbanned_by', '$clientname^7 was un-banned by $adminname^7 $reason'))

        if '%s' in self.read_element('messages', 'unbanned', '%s'):
            self.add_set("unbanned", "$clientname^7 was un-banned $reason")
        else:
            self.add_set("unbanned", self.read_element('messages', 'unbanned', '$clientname^7 was un-banned $reason'))

        xml.data("\n\t")
        xml.end()
        xml.data("\n\t")

        # plugins settings
        self.add_buffer('\n--PLUGIN CONFIG PATH--------------------------------------------\n')
        xml.start("settings", name="plugins")
        self.add_set("external_dir", self.read_element('plugins', 'external_dir', '@b3/extplugins'))
        xml.data("\n\t")
        xml.end()
        xml.data("\n\t")

        # plugins
        self.add_buffer('\n--INSTALLING PLUGINS--------------------------------------------\n')
        xml.start("plugins")
        xml.data("\n\t\t")
        xml.comment("plugin order is important. Plugins that add new in-game commands all depend on the admin plugin. Make sure to have the admin plugin before them.")
        self.autoinstallplugins = self.raw_default("Do you want to (auto)install all plugins from the template?", "yes")
        if self.autoinstallplugins == 'yes':
            self.read_plugins()
        else:
            self.add_plugin("censor", "@conf/plugin_censor.xml")
            self.add_plugin("spamcontrol", "@conf/plugin_spamcontrol.xml")
            self.add_plugin("admin", "@conf/plugin_admin.xml", explanation="the admin plugin is compulsory.", prompt=False)
            self.add_plugin("tk", "@conf/plugin_tk.xml")
            self.add_plugin("stats", "@conf/plugin_stats.xml")
            self.add_plugin("pingwatch", "@conf/plugin_pingwatch.xml")
            self.add_plugin("adv", "@conf/plugin_adv.xml")
            self.add_plugin("status", "@conf/plugin_status.xml")
            self.add_plugin("welcome", "@conf/plugin_welcome.xml")
            if self._set_punkbuster == "on":
                self.add_plugin("punkbuster", "@conf/plugin_punkbuster.xml")
                xml.data("\n\t\t")
            else:
                xml.data("\n\t\t")
                xml.comment("The punkbuster plugin was not installed since punkbuster is not supported or disabled.")
                xml.data("\t\t")

            # ext plugins
            xml.comment("The next plugins are external, 3rd party plugins and should reside in the external_dir. Example:")
            xml.data("\t\t")
            xml.comment("plugin config=\"@b3/extplugins/conf/newplugin.xml\" name=\"newplugin\"")
            _result = self.add_plugin("xlrstats", self._set_external_dir+"/conf/xlrstats.xml", default="no")
            if _result:
                self.executeSql('@b3/sql/xlrstats.sql')

            #self.add_plugin("registered", self._set_external_dir+"/conf/plugin_registered.xml", "Trying to download Registered", "http://www.bigbrotherbot.net/forums/downloads/?sa=downfile&id=22")
            #self.add_plugin("countryfilter", self._set_external_dir+"/conf/countryfilter.xml", "Trying to download Countryfilter", "http://github.com/xlr8or/b3-plugin-countryfilter/zipball/master")

        # final comments
        xml.data("\n\t\t")
        xml.comment("You can add new/custom plugins to this list using the same form as above.")
        xml.data("\t")
        xml.end()

        xml.data("\n")
        xml.close(configuration)
        self.add_buffer('\n--FINISHED CONFIGURATION----------------------------------------\n')

    def load_template(self):
        """ Load an existing config file or use the packaged examples"""
        if functions.main_is_frozen():
            self._configpath = os.environ['ALLUSERSPROFILE'] + '\\BigBrotherBot\\'
        else:
            self._configpath = 'b3\\'
        if self._set_parser == 'bfbc2':
            _dflttemplate = self._configpath + 'conf\\b3.bfbc2_example.xml'
        elif self._set_parser == 'moh':
            _dflttemplate = self._configpath + 'conf\\b3.moh_example.xml'
        else:
            _dflttemplate = self._configpath + 'conf\\b3.distribution.xml'
        if self._template != '':
            # means we just backed-up an old config with the same name
            _result = self.raw_default("Do you want to use the values from the backed-up config (%s)?"
                                       %(self._template), "yes")
            if _result != 'yes':
                self._template = self.raw_default("Load values from an existing configfile", _dflttemplate)
        else:
            self._template = self.raw_default("Load values from an existing configfile", _dflttemplate)
        self._template = self.getAbsolutePath(self._template)
        self.tree = ElementTree()
        try:
            self.tree.parse(self._template)
            return True
        except Exception, msg:
            #self.add_buffer('Could not parse xml file: %s\n' % msg)
            # backed up config file must be corrupt or not completed last setup, reset it to the default
            self.add_buffer('Your previous config file was either empty, corrupt or not finished.\
             Suggest we load the default...\n')
            self._template = ''
            return False