-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Bytekeeper
committed
Mar 12, 2022
1 parent
916da74
commit 242420a
Showing
11 changed files
with
454 additions
and
232 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
cargo build --release | ||
releng\7za a -pshotgun -- bwaishotgun.7z target/release/bwaishotgun.exe bots SNP_DirectIP.snp bwheadless.exe game.toml shotgun.toml | ||
releng\7za a -pshotgun -- bwaishotgun.7z target/release/bwaishotgun.exe bots tools NP_DirectIP.snp game.toml shotgun.toml | ||
releng\7za rn -pshotgun -- bwaishotgun.7z target/release/bwaishotgun.exe BWAIShotgun.exe |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,17 @@ | ||
# Map path | ||
map = 'C:\Something\StarCraft\map\SomeMap.scm' | ||
# Map path - relative to Starcraft | ||
map = 'maps\BroodWar\SomeMap.scm' | ||
|
||
# Game Type | ||
# Only Melee is supported currently, it takes a list of bots that should play and their respective name and race override | ||
# Ie. - this will run NitekatT 2 times, once it will play as protoss, the second instance will play using the bots preferred race (terran) | ||
game_type = { Melee = [{name = "NitekatT", race = "Protoss"}, {name = "NitekatT"}, {name = "MarineHell"}, {name = "ZergHell"}] } | ||
|
||
# This one will run NiteKatT and ZergHell in a window, so you can observe | ||
# Known bug: If the game is hosted by a headful bot, it will not be created automatically - you'll have to click 'create' | ||
#game_type = { Melee = [{name = "NitekatT", race = "Protoss", headful = true}, {name = "MarineHell"}, {name = "ZergHell", headful = true}] } | ||
|
||
# Want to join the fray? Uncomment this and open a game | ||
# human_host = true | ||
# human_host = true | ||
|
||
# Only relevant, when not hosting: Uncomment to set the game speed to "fastest" instead of "as fast as possible" | ||
# human_speed = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
use anyhow::bail; | ||
use std::fs::read_dir; | ||
use std::path::{Path, PathBuf}; | ||
use std::process::Command; | ||
|
||
#[derive(Debug)] | ||
pub enum Binary { | ||
Dll(PathBuf), | ||
Jar(PathBuf), | ||
Exe(PathBuf), | ||
} | ||
|
||
impl Binary { | ||
pub(crate) fn from_path(path: &Path) -> Option<Self> { | ||
path.extension() | ||
.and_then(|ext| ext.to_str()) | ||
.and_then(|ext| { | ||
let mut ext = ext.to_string(); | ||
ext.make_ascii_lowercase(); | ||
let result = match ext.as_str() { | ||
"dll" => Binary::Dll(path.to_path_buf()), | ||
"jar" => Binary::Jar(path.to_path_buf()), | ||
"exe" => Binary::Exe(path.to_path_buf()), | ||
_ => return None, | ||
}; | ||
Some(result) | ||
}) | ||
} | ||
|
||
pub(crate) fn search(search_path: &Path) -> anyhow::Result<Self> { | ||
let mut executable = None; | ||
for file in read_dir(search_path)?.flatten() { | ||
let path = file.path(); | ||
if let Some(detected_binary) = Binary::from_path(&path) { | ||
executable = Some(match (executable, detected_binary) { | ||
(None, dll @ Binary::Dll(_)) | (Some(dll @ Binary::Dll(_)), Binary::Jar(_)) => { | ||
dll | ||
} | ||
(None, jar @ Binary::Jar(_)) => jar, | ||
(None, exe @ Binary::Exe(_)) | ||
| (Some(Binary::Dll(_) | Binary::Jar(_)), exe @ Binary::Exe(_)) => exe, | ||
_ => bail!( | ||
"Found multiple binary candidates in '{}', please select one in 'bot.toml'", | ||
search_path.to_string_lossy() | ||
), | ||
}) | ||
} | ||
} | ||
match executable { | ||
None => bail!("No binary found in '{}'", search_path.to_string_lossy()), | ||
Some(x) => Ok(x), | ||
} | ||
} | ||
} | ||
|
||
pub trait LaunchBuilder { | ||
fn build_command(&self, bot_binary: &Binary) -> anyhow::Result<Command>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
use crate::botsetup::LaunchBuilder; | ||
use crate::{tools_folder, Binary, BwapiIni, Race}; | ||
use anyhow::{anyhow, ensure}; | ||
use std::fs::File; | ||
use std::path::PathBuf; | ||
use std::process::Command; | ||
|
||
pub enum BwHeadlessConnectMode { | ||
Host { map: String, player_count: usize }, | ||
Join, | ||
} | ||
|
||
pub struct BwHeadless { | ||
pub starcraft_exe: PathBuf, | ||
/// Folder containing bwapi-data/AI | ||
pub bot_base_path: PathBuf, | ||
pub bot_name: String, | ||
pub race: Race, | ||
pub game_name: String, | ||
pub connect_mode: BwHeadlessConnectMode, | ||
} | ||
|
||
impl LaunchBuilder for BwHeadless { | ||
fn build_command(&self, bot_binary: &Binary) -> anyhow::Result<Command> { | ||
ensure!( | ||
self.starcraft_exe.exists(), | ||
"Could not find 'StarCraft.exe'" | ||
); | ||
let bwapi_data = self.bot_base_path.join("bwapi-data"); | ||
ensure!( | ||
bwapi_data.exists(), | ||
"Missing '{}' - please read the instructions on how to setup a bot.", | ||
bwapi_data.to_string_lossy() | ||
); | ||
let bwapi_dll = bwapi_data.join("BWAPI.dll"); | ||
ensure!( | ||
bwapi_dll.exists(), | ||
"Could not find '{}'", | ||
bwapi_dll.to_string_lossy() | ||
); | ||
|
||
let bwheadless = tools_folder().join("bwheadless.exe"); | ||
ensure!( | ||
bwheadless.exists(), | ||
r"Could not find '{}'. Please make sure to extract all files, or check your antivirus software.", | ||
tools_folder().to_string_lossy() | ||
); | ||
let bwapi_ini = bwapi_data.join("bwapi.ini"); | ||
let mut bwapi_ini_file = File::create(&bwapi_ini)?; | ||
BwapiIni { | ||
ai_module: Some(match &bot_binary { | ||
Binary::Dll(x) => x.to_string_lossy().to_string(), | ||
Binary::Exe(_) | Binary::Jar(_) => "".to_string(), | ||
}), | ||
..Default::default() | ||
} | ||
.write(&mut bwapi_ini_file)?; | ||
|
||
let mut cmd = Command::new(bwheadless); | ||
cmd.arg("-e").arg(&self.starcraft_exe); | ||
cmd.arg("-g").arg(&self.game_name); | ||
cmd.arg("-r").arg(&self.race.to_string()); | ||
cmd.arg("-l").arg(bwapi_dll); | ||
cmd.arg("--installpath").arg(&self.bot_base_path); | ||
cmd.arg("-n").arg(&self.bot_name); | ||
// Newer versions of BWAPI no longer use the registry key (aka installpath) - but allow overriding the bwapi_ini location. | ||
cmd.env("BWAPI_CONFIG_INI", &*bwapi_ini.to_string_lossy()); | ||
cmd.current_dir(&self.bot_base_path); | ||
let starcraft_path = self | ||
.starcraft_exe | ||
.parent() | ||
.ok_or(anyhow!("Folder containing 'StarCraft.exe' not found"))?; | ||
|
||
match &self.connect_mode { | ||
BwHeadlessConnectMode::Host { map, player_count } => { | ||
cmd.arg("-m").arg(starcraft_path.join(map)); | ||
cmd.arg("-h").arg(player_count.to_string()); | ||
} | ||
BwHeadlessConnectMode::Join => {} | ||
} | ||
Ok(cmd) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
use crate::botsetup::{Binary, LaunchBuilder}; | ||
use crate::{tools_folder, AutoMenu, BwapiConnectMode, BwapiIni, Race}; | ||
use anyhow::ensure; | ||
use std::fs::File; | ||
use std::path::PathBuf; | ||
use std::process::Command; | ||
|
||
pub enum InjectoryConnectMode { | ||
Host { map: String, player_count: usize }, | ||
Join, | ||
} | ||
|
||
pub struct Injectory { | ||
pub starcraft_exe: PathBuf, | ||
/// Folder containing bwapi-data/AI | ||
pub bot_base_path: PathBuf, | ||
pub player_name: String, | ||
pub game_name: String, | ||
pub race: Race, | ||
pub connect_mode: InjectoryConnectMode, | ||
pub wmode: bool, | ||
pub game_speed: i32, | ||
} | ||
|
||
impl LaunchBuilder for Injectory { | ||
fn build_command(&self, bot_binary: &Binary) -> anyhow::Result<Command> { | ||
ensure!( | ||
self.starcraft_exe.exists(), | ||
"Could not find 'StarCraft.exe'" | ||
); | ||
let bwapi_data = self.bot_base_path.join("bwapi-data"); | ||
ensure!( | ||
bwapi_data.exists(), | ||
"Missing '{}' - please read the instructions on how to setup a bot.", | ||
bwapi_data.to_string_lossy() | ||
); | ||
let bwapi_dll = bwapi_data.join("BWAPI.dll"); | ||
ensure!( | ||
bwapi_dll.exists(), | ||
"Could not find '{}'", | ||
bwapi_dll.to_string_lossy() | ||
); | ||
let injectory = tools_folder().join("injectory_x86.exe"); | ||
ensure!( | ||
injectory.exists(), | ||
r"Could not find '{}'. Please make sure to extract all files, or check your antivirus software.", | ||
tools_folder().to_string_lossy() | ||
); | ||
let bwapi_ini = bwapi_data.join("bwapi.ini"); | ||
let mut bwapi_ini_file = File::create(&bwapi_ini)?; | ||
BwapiIni { | ||
ai_module: Some(match &bot_binary { | ||
Binary::Dll(x) => x.to_string_lossy().to_string(), | ||
Binary::Exe(_) | Binary::Jar(_) => "".to_string(), | ||
}), | ||
auto_menu: match &self.connect_mode { | ||
InjectoryConnectMode::Host { map, player_count } => AutoMenu::AutoMenu { | ||
name: self.player_name.clone(), | ||
game_name: self.game_name.clone(), | ||
race: self.race, | ||
connect_mode: BwapiConnectMode::Host { | ||
map: map.clone(), | ||
player_count: *player_count, | ||
}, | ||
}, | ||
InjectoryConnectMode::Join => AutoMenu::AutoMenu { | ||
name: self.player_name.clone(), | ||
game_name: self.game_name.clone(), | ||
race: self.race, | ||
connect_mode: BwapiConnectMode::Join, | ||
}, | ||
}, | ||
game_speed: self.game_speed, | ||
} | ||
.write(&mut bwapi_ini_file)?; | ||
let mut cmd = Command::new(injectory); | ||
cmd.arg("-l").arg(&self.starcraft_exe); | ||
cmd.arg("-i").arg(bwapi_dll); | ||
if self.wmode { | ||
cmd.arg(tools_folder().join("WMode.dll")); | ||
} | ||
cmd.arg("--wait-for-exit").arg("--kill-on-exit"); | ||
// Newer versions of BWAPI no longer use the registry key (aka installpath) - but allow overriding the bwapi_ini location. | ||
// Note that injectory does NOT do any registry trickery (bwheadless does) - so old bots (< 4.x) will most likely not work. | ||
cmd.env("BWAPI_CONFIG_INI", &*bwapi_ini.to_string_lossy()); | ||
cmd.current_dir(&self.bot_base_path); | ||
Ok(cmd) | ||
} | ||
} |
Oops, something went wrong.