def bootstrap_python_bot(bot_name, directory): sanitized_name = convert_to_filename(bot_name) bot_directory = Path(directory or '.') top_dir = bot_directory / sanitized_name if os.path.exists(top_dir): raise FileExistsError(f'There is already a bot named {sanitized_name}, please choose a different name!') with tempfile.TemporaryDirectory() as tmpdirname: tmpdir = Path(tmpdirname) print('created temporary directory', tmpdir) download_and_extract_zip( download_url='https://github.com/RLBot/RLBotPythonExample/archive/master.zip', local_folder_path=tmpdir) safe_move(tmpdir / 'RLBotPythonExample-master', top_dir) bundle = scan_directory_for_bot_configs(top_dir).pop() config_file = bundle.config_path python_file = bundle.python_file replace_all(config_file, r'name = .*$', 'name = ' + bot_name) # This is intended to open the example python file in the default system editor for .py files. # Hopefully this will be VS Code or notepad++ or something. If it gets executed as a python script, no harm done. # This is in a try/except so no error is raised if the user does not have any editor associated with .py files. try: os.startfile(python_file) except OSError: print(f"You have no default program to open .py files. Your new bot is located at {os.path.abspath(top_dir)}") return config_file
def bootstrap_rust_bot(bot_name, directory): sanitized_name = convert_to_filename(bot_name) bot_directory = Path(directory or '.') top_dir = bot_directory / sanitized_name if os.path.exists(top_dir): raise FileExistsError(f'There is already a bot named {sanitized_name}, please choose a different name!') with tempfile.TemporaryDirectory() as tmpdirname: tmpdir = Path(tmpdirname) print('created temporary directory', tmpdir) download_and_extract_zip( download_url='https://github.com/NicEastvillage/RLBotRustTemplateBot/archive/master.zip', local_folder_path=tmpdir) safe_move(tmpdir / 'RLBotRustTemplateBot-master', top_dir) bundle = scan_directory_for_bot_configs(top_dir).pop() config_file = bundle.config_path replace_all(config_file, r'name = .*$', f'name = {bot_name}') replace_all(config_file, r'path = .*$', f'path = ../target/debug/{bot_name}.exe') cargo_toml_file = top_dir / 'Cargo.toml' replace_all(cargo_toml_file, r'name = .*$', f'name = "{bot_name}"') replace_all(cargo_toml_file, r'authors = .*$', f'authors = []') # This is intended to open the main module in the default system editor for .rs files. # Hopefully this will be VS Code or notepad++ or something. try: os.startfile(top_dir / 'src' / 'main.rs') except OSError: print(f"You have no default program to open .rs files. Your new bot is located at {os.path.abspath(top_dir)}") return config_file
def download_bot_pack(): # See https://docs.google.com/document/d/10uCWwHDQYJGMGeoaW1pZu1KvRnSgm064oWL2JVx4k4M/edit?usp=sharing # To learn how the bot pack file is hosted and maintained. download_and_extract_zip( download_url= "https://drive.google.com/uc?export=download&id=1OOisnGpxD48x_oAOkBmzqNdkB5POQpiV", local_zip_path="RLBotPack.zip", local_folder_path=".") bot_folder_settings['folders'][os.path.abspath("./RLBotPack")] = { 'visible': True } settings.setValue(BOT_FOLDER_SETTINGS_KEY, bot_folder_settings) settings.sync()
def bootstrap_python_hivemind(hive_name, directory): sanitized_name = convert_to_filename(hive_name) bot_directory = Path(directory or '.') top_dir = bot_directory / sanitized_name if os.path.exists(top_dir): raise FileExistsError( f'There is already a bot named {sanitized_name}, please choose a different name!' ) with tempfile.TemporaryDirectory() as tmpdirname: tmpdir = Path(tmpdirname) print('created temporary directory', tmpdir) download_and_extract_zip( download_url= 'https://github.com/RLBot/RLBotPythonHivemindExample/archive/master.zip', local_folder_path=tmpdir) safe_move(tmpdir / 'RLBotPythonHivemindExample-master', top_dir) config_file = top_dir / 'config.cfg' drone_file = top_dir / 'src' / 'drone.py' hive_file = top_dir / 'src' / 'hive.py' replace_all(config_file, r'name = .*$', f'name = {hive_name}') replace_all(drone_file, r'hive_name = .*$', f'hive_name = "{hive_name} Hivemind"') replace_all( drone_file, r'hive_key = .*$', f'hive_key = "{random.randint(100000, 999999) + hash(hive_name)}"') replace_all(hive_file, r'class .*\(PythonHivemind\)', f'class {hive_name}Hivemind(PythonHivemind)') # This is intended to open the example python file in the default system editor for .py files. # Hopefully this will be VS Code or notepad++ or something. If it gets executed as a python script, no harm done. # This is in a try/except so no error is raised if the user does not have any editor associated with .py files. try: os.startfile(hive_file) except OSError: print( f"You have no default program to open .py files. Your new bot is located at {os.path.abspath(top_dir)}" ) return config_file
def bootstrap_scratch_bot(bot_name, directory): sanitized_name = convert_to_filename(bot_name) bot_directory = Path(directory or '.') top_dir = bot_directory / sanitized_name if os.path.exists(top_dir): raise FileExistsError( f'There is already a bot named {sanitized_name}, please choose a different name!' ) with tempfile.TemporaryDirectory() as tmpdirname: tmpdir = Path(tmpdirname) print('created temporary directory', tmpdir) download_and_extract_zip( download_url= 'https://github.com/RLBot/RLBotScratchInterface/archive/gui-friendly.zip', local_folder_path=tmpdir) safe_move(tmpdir / 'RLBotScratchInterface-gui-friendly', top_dir) # Choose appropriate file names based on the bot name code_dir = top_dir / sanitized_name sb3_filename = f'{sanitized_name}.sb3' sb3_file = code_dir / sb3_filename config_filename = f'{sanitized_name}.cfg' config_file = code_dir / config_filename replace_all( top_dir / 'rlbot.cfg', r'(participant_config_\d = ).*$', r'\1' + os.path.join(sanitized_name, config_filename).replace('\\', '\\\\')) # We're assuming that the file structure / names in RLBotScratchInterface will not change. # Semi-safe assumption because we're looking at a gui-specific git branch which ought to be stable. safe_move(top_dir / 'scratch_bot', code_dir) safe_move(code_dir / 'my_scratch_bot.sb3', sb3_file) safe_move(code_dir / 'my_scratch_bot.cfg', config_file) replace_all(config_file, r'name = .*$', 'name = ' + bot_name) replace_all(config_file, r'sb3file = .*$', 'sb3file = ' + sb3_filename) replace_all(config_file, r'port = .*$', 'port = ' + str(random.randint(20000, 65000))) return config_file
def bootstrap_python_bot(bot_name, directory): sanitized_name = convert_to_filename(bot_name) bot_directory = Path(directory or '.') with tempfile.TemporaryDirectory() as tmpdirname: tmpdir = Path(tmpdirname) print('created temporary directory', tmpdir) download_and_extract_zip( download_url= 'https://github.com/RLBot/RLBotPythonExample/archive/master.zip', local_zip_path=tmpdir / 'RLBotPythonExample.zip', local_folder_path=tmpdir) try: move(tmpdir / 'RLBotPythonExample-master', bot_directory / sanitized_name) except FileExistsError: return { 'error': f'There is already a bot named {sanitized_name}, please choose a different name!' } # Choose appropriate file names based on the bot name code_dir = bot_directory / sanitized_name / sanitized_name python_file = code_dir / f'{sanitized_name}.py' config_file = code_dir / f'{sanitized_name}.cfg' # We're making some big assumptions here that the file structure / names in RLBotPythonExample will not change. move(bot_directory / sanitized_name / 'python_example', code_dir) move(code_dir / 'python_example.py', python_file) move(code_dir / 'python_example.cfg', config_file) # Update the config file to point to the renamed files, and show the correct bot name. # This is not an ideal way of modifying the config file, because: # - It uses our custom ConfigObject class, which is limited / buggy, and we should be moving away from it # - The ConfigObject class is not capable of 'round-tripping', i.e. if you parse a config file and then # write it again, the comment lines will not be preserved. # - It can still write comments, but only if they have a 'description' that has been added programmatically # (see base_create_agent_configurations). # # One route is to add 'description' items for all the stuff we care about, including the stuff here # https://github.com/RLBot/RLBotPythonExample/blob/master/python_example/python_example.cfg#L11-L27 # so that the resulting file is sortof the same (might have slightly different formatting). That's annoying # and hard to maintain though, and again we'd be investing more in this custom config class that I would # prefer to get rid of. # # Alternatives: # # Use the configobj library https://configobj.readthedocs.io/en/latest/configobj.html # - I tried this in https://github.com/IamEld3st/RLBotGUI/commit/a30308940dd5a0e4a45db6ccc088e6e75a9f69f0 # which worked well for me, but people reported issues during installation. If we can get the installation # ironed out, it will be a nice solution for modifying cfg files in general. # # Do a simple find-and-replace in the file # - Very crude, but it can be reliable if we use specific commit hashes like I did in # https://github.com/IamEld3st/RLBotGUI/commit/a30308940dd5a0e4a45db6ccc088e6e75a9f69f0 # - It would get us up and running with the new features until we can figure out a proper config modification # solution. raw_bot_config = configparser.RawConfigParser() raw_bot_config.read(config_file, encoding='utf8') agent_config = BaseAgent.base_create_agent_configurations() agent_config.parse_file(raw_bot_config) agent_config.set_value(BOT_CONFIG_MODULE_HEADER, BOT_NAME_KEY, bot_name) agent_config.set_value(BOT_CONFIG_MODULE_HEADER, PYTHON_FILE_KEY, f'{sanitized_name}.py') with open(config_file, 'w', encoding='utf8') as f: f.write(str(agent_config)) # This is intended to open the example python file in the default system editor for .py files. # Hopefully this will be VS Code or notepad++ or something. If it gets executed as a python script, no harm done. os.startfile(python_file) return config_file