diff --git a/RLBotCS/ManagerTools/ConfigParser.cs b/RLBotCS/ManagerTools/ConfigParser.cs index 0174e59..a5e01e1 100644 --- a/RLBotCS/ManagerTools/ConfigParser.cs +++ b/RLBotCS/ManagerTools/ConfigParser.cs @@ -76,6 +76,7 @@ public static class Fields public const string AgentRootDir = "root_dir"; public const string AgentRunCommand = "run_command"; public const string AgentRunCommandLinux = "run_command_linux"; + public const string AgentEnvironment = "environment"; public const string AgentHivemind = "hivemind"; public const string LoadoutBlueTable = "blue_loadout"; @@ -260,6 +261,33 @@ private string GetRunCommand(TomlTable runnableSettings) #endif } + private List GetEnvironment(TomlTable runnableSettings) + { + TomlTable environment = GetValue( + runnableSettings, + Fields.AgentEnvironment, + [] + ); + + List variables = []; + using (_context.Begin(Fields.AgentEnvironment)) + { + foreach (var (key, rawValue) in environment) + { + if (rawValue is not string value) + { + throw new InvalidCastException( + $"{_context.ToStringWithEnd(key)} has value {rawValue}, but a value of type String was expected." + ); + } + + variables.Add(new() { Name = key, Value = value }); + } + } + + return variables; + } + private ScriptConfigurationT LoadScriptConfig(string scriptConfigPath) { TomlTable scriptToml = LoadTomlFile(scriptConfigPath); @@ -276,6 +304,7 @@ private ScriptConfigurationT LoadScriptConfig(string scriptConfigPath) GetValue(settings, Fields.AgentRootDir, "") ), RunCommand = GetRunCommand(settings), + Environment = GetEnvironment(settings), AgentId = GetValue(settings, Fields.AgentAgentId, ""), }; } @@ -511,6 +540,7 @@ bool autoStart Name = nameOverride ?? GetValue(settings, Fields.AgentName, ""), Loadout = loadout, RunCommand = autoStart ? GetRunCommand(settings) : "", + Environment = GetEnvironment(settings), Hivemind = GetValue(settings, Fields.AgentHivemind, false), RootDir = rootDir, }; diff --git a/RLBotCS/ManagerTools/ConfigValidator.cs b/RLBotCS/ManagerTools/ConfigValidator.cs index 147bbdf..e7b00de 100644 --- a/RLBotCS/ManagerTools/ConfigValidator.cs +++ b/RLBotCS/ManagerTools/ConfigValidator.cs @@ -101,6 +101,7 @@ bool surpressWarnings bot.Name ??= ""; bot.RunCommand ??= ""; bot.RootDir ??= ""; + bot.Environment ??= []; bot.Loadout ??= new(); bot.Loadout.LoadoutPaint ??= new(); @@ -239,6 +240,7 @@ private static bool ValidateScripts( script.Name ??= ""; script.RunCommand ??= ""; script.RootDir ??= ""; + script.Environment ??= []; script.ScriptId = $"{script.AgentId}/{Team.Scripts}/{i}".GetHashCode(); if (agentIdTracker.TryGetValue(script.AgentId, out var existing)) diff --git a/RLBotCS/ManagerTools/LaunchManager.cs b/RLBotCS/ManagerTools/LaunchManager.cs index 6291410..5a4f622 100644 --- a/RLBotCS/ManagerTools/LaunchManager.cs +++ b/RLBotCS/ManagerTools/LaunchManager.cs @@ -143,6 +143,17 @@ private static Process RunCommandInShell(string command) return process; } + private static void ApplyEnvironment( + ProcessStartInfo startInfo, + List environment + ) + { + foreach (var variable in environment) + { + startInfo.EnvironmentVariables[variable.Name] = variable.Value; + } + } + private static void LaunchGameViaLegendary() { Process legendary = RunCommandInShell( @@ -186,6 +197,7 @@ int rlbotSocketsPort Process botProcess = RunCommandInShell(details.RunCommand); botProcess.StartInfo.WorkingDirectory = details.RootDir; + ApplyEnvironment(botProcess.StartInfo, details.Environment); botProcess.StartInfo.EnvironmentVariables["RLBOT_AGENT_ID"] = details.AgentId; botProcess.StartInfo.EnvironmentVariables["RLBOT_SERVER_PORT"] = rlbotSocketsPort.ToString(); @@ -233,6 +245,7 @@ int rlbotSocketsPort if (script.RootDir != "") scriptProcess.StartInfo.WorkingDirectory = script.RootDir; + ApplyEnvironment(scriptProcess.StartInfo, script.Environment); scriptProcess.StartInfo.EnvironmentVariables["RLBOT_AGENT_ID"] = script.AgentId; scriptProcess.StartInfo.EnvironmentVariables["RLBOT_SERVER_PORT"] = rlbotSocketsPort.ToString(); diff --git a/RLBotCS/RLBotCS.csproj b/RLBotCS/RLBotCS.csproj index bf19692..ec069c3 100644 --- a/RLBotCS/RLBotCS.csproj +++ b/RLBotCS/RLBotCS.csproj @@ -84,6 +84,13 @@ > + + + diff --git a/RLBotCSTests/ConfigParserTest.cs b/RLBotCSTests/ConfigParserTest.cs index 1fd9619..853ec95 100644 --- a/RLBotCSTests/ConfigParserTest.cs +++ b/RLBotCSTests/ConfigParserTest.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; using RLBot.Flat; using RLBotCS.ManagerTools; @@ -179,10 +180,24 @@ public void Overrides() PlayerConfigurationT player = mc.PlayerConfigurations[0]; Assert.AreEqual("New Bot Name", player.Variety.AsCustomBot().Name); - Assert.IsNull(player.Variety.AsCustomBot().Loadout); + CustomBotT bot = player.Variety.AsCustomBot(); + Assert.IsNull(bot.Loadout); + Assert.AreEqual("bot-value", bot.Environment.Single(e => e.Name == "BOT_ENV").Value); + Assert.AreEqual( + "bot-shared", + bot.Environment.Single(e => e.Name == "SHARED_ENV").Value + ); ScriptConfigurationT script = mc.ScriptConfigurations[0]; Assert.AreEqual("Normal Test Script", script.Name); // Not overriden + Assert.AreEqual( + "script-value", + script.Environment.Single(e => e.Name == "SCRIPT_ENV").Value + ); + Assert.AreEqual( + "script-shared", + script.Environment.Single(e => e.Name == "SHARED_ENV").Value + ); } [TestMethod] diff --git a/RLBotCSTests/TestTomls/normal.bot.toml b/RLBotCSTests/TestTomls/normal.bot.toml index d4b62c9..5ba9211 100644 --- a/RLBotCSTests/TestTomls/normal.bot.toml +++ b/RLBotCSTests/TestTomls/normal.bot.toml @@ -6,6 +6,10 @@ run_command_linux = "python bot.py" loadout_file = "loadout.toml" logo_file = "normal_logo.png" +[settings.environment] +BOT_ENV = "bot-value" +SHARED_ENV = "bot-shared" + [details] description = "This is a normal test bot" fun_fact = "knock knock ..." diff --git a/RLBotCSTests/TestTomls/normal.script.toml b/RLBotCSTests/TestTomls/normal.script.toml index 5a638c6..ff41c93 100644 --- a/RLBotCSTests/TestTomls/normal.script.toml +++ b/RLBotCSTests/TestTomls/normal.script.toml @@ -6,6 +6,10 @@ run_command_linux = "python script.py" loadout_file = "loadout.toml" logo_file = "normal_logo.png" +[settings.environment] +SCRIPT_ENV = "script-value" +SHARED_ENV = "script-shared" + [details] description = "This is a normal test script" fun_fact = "knock knock ..." diff --git a/flatbuffers-schema b/flatbuffers-schema index a83ce10..c2648b4 160000 --- a/flatbuffers-schema +++ b/flatbuffers-schema @@ -1 +1 @@ -Subproject commit a83ce106ed599303d8e5b5e6084687a0665f7edf +Subproject commit c2648b4fa30d9d3b228466d51746c84ee2f20a6c diff --git a/generate-flatbuffers-mac.sh b/generate-flatbuffers-mac.sh new file mode 100755 index 0000000..45194b1 --- /dev/null +++ b/generate-flatbuffers-mac.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +cd "$(dirname "$0")" + +echo Generating flatbuffers header file... + +./flatbuffers-schema/binaries/flatc_mac --gen-all --csharp --gen-object-api --gen-onefile -o ./FlatBuffer ./flatbuffers-schema/schema/rlbot.fbs + +# the file produced is called rlbot_generated.cs, rename it to RLBot.cs after removing the old one +rm -f ./FlatBuffer/RLBot.cs +mv ./FlatBuffer/rlbot_generated.cs ./FlatBuffer/RLBot.cs +sed -i '' 's/rlbot\.flat/RLBot.Flat/g' ./FlatBuffer/RLBot.cs + +echo Done.