basic bot
This commit is contained in:
58
.gitignore
vendored
Normal file
58
.gitignore
vendored
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
visualstudio/x64
|
||||||
|
visualstudio/Win32
|
||||||
|
visualstudio/.vs
|
||||||
|
starcraft/bwapi-data/*
|
||||||
|
starcraft/characters/*
|
||||||
|
starcraft/maps/*
|
||||||
|
starcraft/*.exe
|
||||||
|
starcraft/*.snp
|
||||||
|
starcraft/*.bat
|
||||||
|
starcraft/*.dll
|
||||||
|
starcraft/*.ini
|
||||||
|
starcraft/*.MPQ
|
||||||
|
starcraft/*.mpq
|
||||||
|
starcraft/Errors
|
||||||
|
starcraftfull
|
||||||
|
*.sdf
|
||||||
|
*.suo
|
||||||
|
*.opensdf
|
||||||
|
*.dll
|
||||||
|
*.o
|
||||||
|
*.pd_
|
||||||
|
*.bwta
|
||||||
|
*.db
|
||||||
|
*.ipch
|
||||||
|
*.opendb
|
||||||
|
*.db-shm
|
||||||
|
*.db-wal
|
||||||
|
*.zip
|
||||||
|
*.iobj
|
||||||
|
*.ipdb
|
||||||
|
*.map
|
||||||
|
*.pdb
|
||||||
|
*.ilk
|
||||||
|
*.ERR
|
||||||
|
bin/StarterBot_d.exe
|
||||||
|
bin/StarterBot_d.exe
|
||||||
|
bin/ReplayData.txt
|
||||||
|
bin/ReplayParser.exe
|
||||||
|
bin/RunReplayParserAndStarcraft.bat
|
||||||
|
bin/replaydata
|
||||||
|
# Linux
|
||||||
|
bin_linux/src
|
||||||
|
!libgcc_s_dw2-1.dll
|
||||||
|
!libstdc++-6.dll
|
||||||
|
|
||||||
|
|
||||||
|
starcraft/
|
||||||
|
starcraft
|
||||||
|
Starcraft.zip
|
||||||
|
.wine/
|
||||||
|
|
||||||
|
bin_linux/StarterBot.exe
|
||||||
|
bin_linux/
|
||||||
|
# Nix
|
||||||
|
result
|
||||||
|
result-*
|
||||||
|
.direnv/
|
||||||
|
.envrc.cache
|
||||||
59
.vscode/settings.json
vendored
Normal file
59
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
{
|
||||||
|
"files.exclude": {
|
||||||
|
"**/target/**": true,
|
||||||
|
"**/starcraft/**": true,
|
||||||
|
"**/starcraft": true,
|
||||||
|
"**/.wine/**": true,
|
||||||
|
"**/.wine": true,
|
||||||
|
"**/wine/**": true,
|
||||||
|
"**/bin_linux/**": true,
|
||||||
|
"**/bin_linux": true,
|
||||||
|
"**/.direnv/**": true,
|
||||||
|
"**/.direnv": true
|
||||||
|
},
|
||||||
|
"files.watcherExclude": {
|
||||||
|
"**/target/**": true,
|
||||||
|
"**/node_modules/**": true,
|
||||||
|
"**/.git/**": true,
|
||||||
|
"**/wine/**": true,
|
||||||
|
"**/.wine/**": true,
|
||||||
|
"**/.wine": true,
|
||||||
|
"**/bin_linux/**": true,
|
||||||
|
"**/bin_linux": true,
|
||||||
|
"**/starcraft/**": true,
|
||||||
|
"**/starcraft": true,
|
||||||
|
"**/.direnv/**": true,
|
||||||
|
"**/.direnv": true
|
||||||
|
},
|
||||||
|
"search.exclude": {
|
||||||
|
"**/target/**": true,
|
||||||
|
"**/node_modules/**": true,
|
||||||
|
"**/wine/**": true,
|
||||||
|
"**/.wine/**": true,
|
||||||
|
"**/bin_linux/**": true,
|
||||||
|
"**/starcraft/**": true,
|
||||||
|
"**/.direnv/**": true
|
||||||
|
},
|
||||||
|
"rust-analyzer.files.exclude": [
|
||||||
|
"starcraft",
|
||||||
|
".wine",
|
||||||
|
"bin_linux",
|
||||||
|
"src",
|
||||||
|
".direnv",
|
||||||
|
"wine"
|
||||||
|
],
|
||||||
|
"rust-analyzer.linkedProjects": ["protossbot/Cargo.toml"],
|
||||||
|
"rust-analyzer.cargo.target": "x86_64-pc-windows-gnu",
|
||||||
|
"rust-analyzer.cargo.features": "all",
|
||||||
|
"rust-analyzer.check.allTargets": false,
|
||||||
|
"rust-analyzer.check.features": "all",
|
||||||
|
"cSpell.words": [
|
||||||
|
"chokepoint",
|
||||||
|
"onframe",
|
||||||
|
"pathing",
|
||||||
|
"Protoss",
|
||||||
|
"rsbwapi",
|
||||||
|
"Zerg",
|
||||||
|
"Zergling"
|
||||||
|
]
|
||||||
|
}
|
||||||
99
flake.lock
generated
Normal file
99
flake.lock
generated
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1768886240,
|
||||||
|
"narHash": "sha256-C2TjvwYZ2VDxYWeqvvJ5XPPp6U7H66zeJlRaErJKoEM=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "80e4adbcf8992d3fd27ad4964fbb84907f9478b0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-stable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1751274312,
|
||||||
|
"narHash": "sha256-/bVBlRpECLVzjV19t5KMdMFWSwKLtb5RyXdjz3LJT+g=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "50ab793786d9de88ee30ec4e4c24fb4236fc2674",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-24.11",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"nixpkgs-stable": "nixpkgs-stable",
|
||||||
|
"rust-overlay": "rust-overlay"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rust-overlay": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1769050281,
|
||||||
|
"narHash": "sha256-1H8DN4UZgEUqPUA5ecHOufLZMscJ4IlcGaEftaPtpBY=",
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"rev": "6deef0585c52d9e70f96b6121207e1496d4b0c49",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
187
flake.nix
Normal file
187
flake.nix
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
{
|
||||||
|
description = "Broodwar Wine Bot - StarCraft Broodwar AI bot with Rust and BWAPI";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-24.11";
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
rust-overlay = {
|
||||||
|
url = "github:oxalica/rust-overlay";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, nixpkgs-stable, flake-utils, rust-overlay }:
|
||||||
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
|
let
|
||||||
|
overlays = [ (import rust-overlay) ];
|
||||||
|
pkgs = import nixpkgs {
|
||||||
|
inherit system overlays;
|
||||||
|
};
|
||||||
|
pkgs-stable = import nixpkgs-stable {
|
||||||
|
inherit system;
|
||||||
|
};
|
||||||
|
|
||||||
|
rustToolchain = pkgs.rust-bin.stable.latest.default.override {
|
||||||
|
targets = [ "x86_64-pc-windows-gnu" ];
|
||||||
|
extensions = [ "rust-src" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
mingwPkgs = pkgs.pkgsCross.mingwW64;
|
||||||
|
mingwCC = mingwPkgs.stdenv.cc;
|
||||||
|
|
||||||
|
# Get GCC version dynamically
|
||||||
|
gccVersion = mingwPkgs.stdenv.cc.cc.version;
|
||||||
|
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
rustToolchain
|
||||||
|
mingwCC
|
||||||
|
];
|
||||||
|
|
||||||
|
nativeBuildInputs = with pkgs; [
|
||||||
|
pkg-config
|
||||||
|
clang
|
||||||
|
llvmPackages.libclang
|
||||||
|
];
|
||||||
|
|
||||||
|
shellEnv = {
|
||||||
|
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = "${mingwCC}/bin/x86_64-w64-mingw32-gcc";
|
||||||
|
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUSTFLAGS = "-L ${mingwPkgs.windows.pthreads}/lib";
|
||||||
|
CC_x86_64_pc_windows_gnu = "${mingwCC}/bin/x86_64-w64-mingw32-gcc";
|
||||||
|
CXX_x86_64_pc_windows_gnu = "${mingwCC}/bin/x86_64-w64-mingw32-g++";
|
||||||
|
AR_x86_64_pc_windows_gnu = "${mingwCC}/bin/x86_64-w64-mingw32-ar";
|
||||||
|
|
||||||
|
LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
|
||||||
|
|
||||||
|
# Bindgen configuration for MinGW cross-compilation
|
||||||
|
# Tell bindgen to use mingw headers, not Linux headers
|
||||||
|
BINDGEN_EXTRA_CLANG_ARGS = pkgs.lib.concatStringsSep " " [
|
||||||
|
"--target=x86_64-w64-mingw32"
|
||||||
|
# Use -isystem to add includes with lower priority than -I
|
||||||
|
# This allows the mingw headers to find clang intrinsics
|
||||||
|
"-isystem${pkgs.llvmPackages.libclang.lib}/lib/clang/${pkgs.llvmPackages.libclang.version}/include"
|
||||||
|
"-isystem${mingwCC.cc}/include/c++/${gccVersion}"
|
||||||
|
"-isystem${mingwCC.cc}/include/c++/${gccVersion}/x86_64-w64-mingw32"
|
||||||
|
"-isystem${mingwCC.cc}/include/c++/${gccVersion}/backward"
|
||||||
|
"-isystem${mingwPkgs.windows.mingw_w64_headers}/include"
|
||||||
|
"-isystem${mingwPkgs.windows.pthreads}/include"
|
||||||
|
"-D_WIN32"
|
||||||
|
"-D_WIN64"
|
||||||
|
];
|
||||||
|
|
||||||
|
# Set target for bindgen
|
||||||
|
TARGET = "x86_64-pc-windows-gnu";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Build script
|
||||||
|
buildScript = pkgs.writeShellScriptBin "build-protossbot" ''
|
||||||
|
set -e
|
||||||
|
cd protossbot
|
||||||
|
cargo build --target x86_64-pc-windows-gnu --release
|
||||||
|
'';
|
||||||
|
|
||||||
|
buildDebugScript = pkgs.writeShellScriptBin "build-protossbot-debug" ''
|
||||||
|
set -e
|
||||||
|
cd protossbot
|
||||||
|
cargo build --target x86_64-pc-windows-gnu
|
||||||
|
'';
|
||||||
|
|
||||||
|
cleanScript = pkgs.writeShellScriptBin "clean-protossbot" ''
|
||||||
|
cd protossbot
|
||||||
|
cargo clean
|
||||||
|
echo "✓ Cleaned build artifacts"
|
||||||
|
'';
|
||||||
|
|
||||||
|
checkScript = pkgs.writeShellScriptBin "check-protossbot" ''
|
||||||
|
cd protossbot
|
||||||
|
cargo check --target x86_64-pc-windows-gnu
|
||||||
|
'';
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
devShells.default = pkgs.mkShell (shellEnv // {
|
||||||
|
buildInputs = buildInputs ++ nativeBuildInputs ++ [
|
||||||
|
buildScript
|
||||||
|
buildDebugScript
|
||||||
|
cleanScript
|
||||||
|
checkScript
|
||||||
|
|
||||||
|
# Additional development tools
|
||||||
|
pkgs.cargo-watch
|
||||||
|
pkgs.cargo-edit
|
||||||
|
pkgs.rust-analyzer
|
||||||
|
|
||||||
|
# Wine from stable nixpkgs
|
||||||
|
pkgs-stable.wineWowPackages.stable
|
||||||
|
|
||||||
|
# Script dependencies
|
||||||
|
pkgs.unzip
|
||||||
|
pkgs.curl
|
||||||
|
pkgs.p7zip
|
||||||
|
pkgs.wget
|
||||||
|
pkgs.xorg.xorgserver
|
||||||
|
];
|
||||||
|
|
||||||
|
shellHook = ''
|
||||||
|
echo "Available commands"
|
||||||
|
echo " build-protossbot - Build release version for Windows"
|
||||||
|
echo " build-protossbot-debug - Build debug version for Windows"
|
||||||
|
echo " check-protossbot - Quick check without building"
|
||||||
|
echo " clean-protossbot - Clean build artifacts"
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
|
||||||
|
packages = {
|
||||||
|
# Build the Windows executable
|
||||||
|
protossbot = pkgs.stdenv.mkDerivation {
|
||||||
|
pname = "protossbot";
|
||||||
|
version = "0.1.0";
|
||||||
|
src = ./protossbot;
|
||||||
|
|
||||||
|
nativeBuildInputs = nativeBuildInputs ++ buildInputs;
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
export HOME=$TMPDIR
|
||||||
|
${pkgs.lib.concatStringsSep "\n"
|
||||||
|
(pkgs.lib.mapAttrsToList
|
||||||
|
(name: value: "export ${name}=\"${value}\"")
|
||||||
|
shellEnv)}
|
||||||
|
|
||||||
|
cargo build --release --target x86_64-pc-windows-gnu --locked
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp target/x86_64-pc-windows-gnu/release/protossbot.exe $out/bin/
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
default = self.packages.${system}.protossbot;
|
||||||
|
};
|
||||||
|
|
||||||
|
apps = {
|
||||||
|
build = {
|
||||||
|
type = "app";
|
||||||
|
program = "${buildScript}/bin/build-protossbot";
|
||||||
|
};
|
||||||
|
|
||||||
|
build-debug = {
|
||||||
|
type = "app";
|
||||||
|
program = "${buildDebugScript}/bin/build-protossbot-debug";
|
||||||
|
};
|
||||||
|
|
||||||
|
clean = {
|
||||||
|
type = "app";
|
||||||
|
program = "${cleanScript}/bin/clean-protossbot";
|
||||||
|
};
|
||||||
|
|
||||||
|
check = {
|
||||||
|
type = "app";
|
||||||
|
program = "${checkScript}/bin/check-protossbot";
|
||||||
|
};
|
||||||
|
|
||||||
|
default = self.apps.${system}.build;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
14
protossbot/.cargo/config.toml
Normal file
14
protossbot/.cargo/config.toml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[build]
|
||||||
|
# Target 64-bit Windows for modern tournament compatibility
|
||||||
|
target = "x86_64-pc-windows-gnu"
|
||||||
|
|
||||||
|
[target.x86_64-pc-windows-gnu]
|
||||||
|
# Linker and rustflags will be set by Nix flake via environment variables:
|
||||||
|
# - CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER
|
||||||
|
# - CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUSTFLAGS
|
||||||
|
# Falls back to system linker if not in Nix shell
|
||||||
|
linker = "x86_64-w64-mingw32-gcc"
|
||||||
|
|
||||||
|
[env]
|
||||||
|
# TARGET environment variable helps bindgen know we're cross-compiling
|
||||||
|
TARGET = "x86_64-pc-windows-gnu"
|
||||||
16
protossbot/.gitignore
vendored
Normal file
16
protossbot/.gitignore
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Rust
|
||||||
|
/target/
|
||||||
|
**/*.rs.bk
|
||||||
|
*.pdb
|
||||||
|
Cargo.lock
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
20
protossbot/Cargo.toml
Normal file
20
protossbot/Cargo.toml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
[package]
|
||||||
|
name = "rustbot"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rsbwapi = "3.6.3"
|
||||||
|
axum = { version = "0.7", features = ["ws"] }
|
||||||
|
tokio = { version = "1", features = ["full"] }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
serde_yaml = "0.9"
|
||||||
|
tokio-tungstenite = "0.24"
|
||||||
|
futures-util = "0.3"
|
||||||
|
tower-http = { version = "0.6", features = ["fs", "cors"] }
|
||||||
|
rand = "0.8"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
opt-level = 3
|
||||||
|
lto = true
|
||||||
23
protossbot/build.sh
Executable file
23
protossbot/build.sh
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
# Set up environment for cross-compilation
|
||||||
|
export CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc
|
||||||
|
export CC_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc
|
||||||
|
export CXX_x86_64_pc_windows_gnu=x86_64-w64-mingw32-g++
|
||||||
|
export AR_x86_64_pc_windows_gnu=x86_64-w64-mingw32-ar
|
||||||
|
|
||||||
|
# Set include path for bindgen - add C++ standard library and GCC include paths
|
||||||
|
export BINDGEN_EXTRA_CLANG_ARGS="-I/usr/lib/gcc/x86_64-w64-mingw32/13-posix/include/c++ -I/usr/lib/gcc/x86_64-w64-mingw32/13-posix/include/c++/x86_64-w64-mingw32 -I/usr/lib/gcc/x86_64-w64-mingw32/13-posix/include -I/usr/x86_64-w64-mingw32/include"
|
||||||
|
|
||||||
|
# Build for Windows target
|
||||||
|
echo "Building..."
|
||||||
|
cargo build --target x86_64-pc-windows-gnu
|
||||||
|
|
||||||
|
# Check if build was successful
|
||||||
|
if [ -f "target/x86_64-pc-windows-gnu/debug/rustbot.exe" ]; then
|
||||||
|
echo "Build successful: target/x86_64-pc-windows-gnu/debug/rustbot.exe"
|
||||||
|
else
|
||||||
|
echo "Build failed!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
69
protossbot/src/bot.rs
Normal file
69
protossbot/src/bot.rs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use rsbwapi::*;
|
||||||
|
|
||||||
|
use crate::game_state::GameState;
|
||||||
|
|
||||||
|
impl AiModule for RustBot {
|
||||||
|
fn on_start(&mut self, game: &Game) {
|
||||||
|
// SAFETY: rsbwapi uses interior mutability (RefCell) for the command queue.
|
||||||
|
// enable_flag only adds a command to the queue.
|
||||||
|
// This cast is safe in the single-threaded BWAPI callback context.
|
||||||
|
unsafe {
|
||||||
|
let game_ptr = game as *const Game as *mut Game;
|
||||||
|
(*game_ptr).enable_flag(Flag::UserInput as i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Game started on map: {}", game.map_file_name());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_frame(&mut self, game: &Game) {
|
||||||
|
// println!("Frame {}", game.get_frame_count());
|
||||||
|
let Ok(mut locked_state) = self.game_state.lock() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_unit_create(&mut self, game: &Game, unit: Unit) {
|
||||||
|
if game.get_frame_count() < 1 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
println!("unit created: {:?}", unit.get_type());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_unit_morph(&mut self, game: &Game, unit: Unit) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_unit_destroy(&mut self, _game: &Game, unit: Unit) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_unit_complete(&mut self, game: &Game, unit: Unit) {
|
||||||
|
let Some(player) = game.self_() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_end(&mut self, _game: &Game, is_winner: bool) {
|
||||||
|
if is_winner {
|
||||||
|
println!("Victory!");
|
||||||
|
} else {
|
||||||
|
println!("Defeat!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub struct RustBot {
|
||||||
|
game_state: Arc<Mutex<GameState>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RustBot {
|
||||||
|
pub fn new(game_state: Arc<Mutex<GameState>>) -> Self {
|
||||||
|
Self {
|
||||||
|
game_state,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
protossbot/src/game_state.rs
Normal file
14
protossbot/src/game_state.rs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
|
||||||
|
pub struct GameState {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Default for GameState {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
protossbot/src/main.rs
Normal file
15
protossbot/src/main.rs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
mod bot;
|
||||||
|
pub mod game_state;
|
||||||
|
|
||||||
|
use bot::RustBot;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
use game_state::GameState;
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Starting RustBot...");
|
||||||
|
|
||||||
|
let game_state = Arc::new(Mutex::new(GameState::default()));
|
||||||
|
|
||||||
|
rsbwapi::start(move |_game| RustBot::new(game_state.clone() ));
|
||||||
|
}
|
||||||
60
run.sh
Executable file
60
run.sh
Executable file
@@ -0,0 +1,60 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
SCRIPTS_PATH="${SCRIPT_DIR}/scripts"
|
||||||
|
|
||||||
|
export WINEPREFIX="$SCRIPT_DIR/.wine"
|
||||||
|
export WINEARCH=win64
|
||||||
|
export DISPLAY=:0
|
||||||
|
export WINEDLLOVERRIDES="mscoree,mshtml="
|
||||||
|
export WINEDEBUG=-all
|
||||||
|
|
||||||
|
# Cleanup function to ensure processes are killed on exit
|
||||||
|
cleanup() {
|
||||||
|
echo ""
|
||||||
|
echo "Cleaning up processes..."
|
||||||
|
if [ -n "$XVFB_PID" ] && kill -0 $XVFB_PID 2>/dev/null; then
|
||||||
|
echo "Stopping Xvfb..."
|
||||||
|
kill $XVFB_PID 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
if [ -n "$BOT_PID" ] && kill -0 $BOT_PID 2>/dev/null; then
|
||||||
|
echo "Stopping protossbot..."
|
||||||
|
kill $BOT_PID 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
killall StarCraft.exe
|
||||||
|
echo "Cleanup complete."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Register cleanup function to run on script exit (success or failure)
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
if [ ! -d "$WINEPREFIX" ]; then
|
||||||
|
wine wineboot --init
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Starting Xvfb virtual display..."
|
||||||
|
Xvfb :0 -auth ~/.Xauthority -screen 0 640x480x24 > /dev/null 2>&1 &
|
||||||
|
XVFB_PID=$!
|
||||||
|
|
||||||
|
cd scripts
|
||||||
|
./4-configure-bwapi.sh
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
echo "Building protossbot..."
|
||||||
|
# build-protossbot-debug
|
||||||
|
nix develop -c build-protossbot-debug
|
||||||
|
echo "Starting protossbot..."
|
||||||
|
cd "$SCRIPT_DIR/protossbot"
|
||||||
|
|
||||||
|
RUST_BACKTRACE=1 RUST_BACKTRACE=full wine target/x86_64-pc-windows-gnu/debug/protossbot.exe &
|
||||||
|
BOT_PID=$!
|
||||||
|
echo "protossbot started (PID: $BOT_PID)"
|
||||||
|
|
||||||
|
|
||||||
|
echo "Launching StarCraft with BWAPI via Chaoslauncher..."
|
||||||
|
cd "$SCRIPT_DIR/starcraft/BWAPI/Chaoslauncher"
|
||||||
|
wine Chaoslauncher.exe
|
||||||
|
|
||||||
|
echo "StarCraft closed."
|
||||||
1
rustfmt.toml
Normal file
1
rustfmt.toml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
tab_spaces = 2
|
||||||
33
scripts/1-download-starcraft.sh
Executable file
33
scripts/1-download-starcraft.sh
Executable file
@@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Get workspace directory (parent of scripts directory)
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
INSTALL_DIR="${PROJECT_DIR}/starcraft"
|
||||||
|
|
||||||
|
STARCRAFT_URL="http://files.theabyss.ru/sc/starcraft.zip"
|
||||||
|
TEMP_ZIP="/tmp/starcraft.zip"
|
||||||
|
|
||||||
|
echo "========================================"
|
||||||
|
echo "Step 1: Download StarCraft"
|
||||||
|
echo "========================================"
|
||||||
|
|
||||||
|
if [ -f "${INSTALL_DIR}/StarCraft.exe" ]; then
|
||||||
|
echo "✓ StarCraft is already installed in ${INSTALL_DIR}!"
|
||||||
|
echo "Skipping download."
|
||||||
|
echo ""
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
if ! curl -L "${STARCRAFT_URL}" -o "${TEMP_ZIP}"; then
|
||||||
|
echo "ERROR: Download failed!"
|
||||||
|
echo "You may need to download manually from: ${STARCRAFT_URL}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "${INSTALL_DIR}"
|
||||||
|
unzip -q "${TEMP_ZIP}" -d "${INSTALL_DIR}"
|
||||||
|
|
||||||
|
rm "${TEMP_ZIP}"
|
||||||
|
fi
|
||||||
63
scripts/2-install-bwapi.sh
Executable file
63
scripts/2-install-bwapi.sh
Executable file
@@ -0,0 +1,63 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
echo "========================================"
|
||||||
|
echo "Step 2: Installing BWAPI"
|
||||||
|
echo "========================================"
|
||||||
|
|
||||||
|
# Get workspace directory (parent of scripts directory)
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
export SC_DIR="${PROJECT_DIR}/starcraft"
|
||||||
|
BWAPI_VERSION="4.4.0"
|
||||||
|
BWAPI_ARCHIVE="BWAPI.7z"
|
||||||
|
BWAPI_URL="https://github.com/bwapi/bwapi/releases/download/v${BWAPI_VERSION}/${BWAPI_ARCHIVE}"
|
||||||
|
|
||||||
|
# Check if BWAPI is already installed
|
||||||
|
if [ -d "${SC_DIR}/BWAPI" ] && [ -f "${SC_DIR}/BWAPI/Chaoslauncher/Chaoslauncher.exe" ]; then
|
||||||
|
echo "✓ BWAPI is already installed!"
|
||||||
|
echo "Skipping installation."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "${SC_DIR}" ]; then
|
||||||
|
echo "ERROR: StarCraft directory not found at ${SC_DIR}"
|
||||||
|
echo "Please install StarCraft first or set SC_DIR environment variable"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "${SC_DIR}/StarCraft.exe" ]; then
|
||||||
|
echo "ERROR: StarCraft.exe not found in ${SC_DIR}"
|
||||||
|
echo "Please ensure StarCraft is properly installed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
TEMP_DIR=$(mktemp -d)
|
||||||
|
trap "rm -rf ${TEMP_DIR}" EXIT
|
||||||
|
|
||||||
|
cd "${TEMP_DIR}"
|
||||||
|
|
||||||
|
echo "Downloading BWAPI ${BWAPI_VERSION}..."
|
||||||
|
wget -q --show-progress "${BWAPI_URL}" || {
|
||||||
|
echo "ERROR: Failed to download BWAPI archive"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
7z x -y "${BWAPI_ARCHIVE}" -obwapi_extracted > /dev/null || {
|
||||||
|
echo "ERROR: Failed to extract BWAPI archive"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cd bwapi_extracted
|
||||||
|
|
||||||
|
ls -alh Release_Binary
|
||||||
|
|
||||||
|
cp -r Release_Binary "${SC_DIR}/BWAPI"
|
||||||
|
|
||||||
|
cp -r Release_Binary/Starcraft/bwapi-data "${SC_DIR}/bwapi-data"
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Create necessary subdirectories
|
||||||
52
scripts/3-download-standard-maps.sh
Executable file
52
scripts/3-download-standard-maps.sh
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Get workspace directory (parent of scripts directory)
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
MAPS_DIR="${PROJECT_DIR}/starcraft/maps/BroodWar"
|
||||||
|
TEMP_DIR="/tmp/sc_standard_maps"
|
||||||
|
|
||||||
|
echo "========================================"
|
||||||
|
echo "Step 3: Download Standard Maps"
|
||||||
|
echo "========================================"
|
||||||
|
|
||||||
|
# Create directories
|
||||||
|
mkdir -p "${MAPS_DIR}"
|
||||||
|
mkdir -p "${TEMP_DIR}"
|
||||||
|
|
||||||
|
# Check if maps already exist
|
||||||
|
EXISTING_MAPS=$(find "${MAPS_DIR}" -maxdepth 1 -type f \( -name "*.scm" -o -name "*.scx" -o -name "*.SCM" -o -name "*.SCX" \) ! -name "ICCup*" 2>/dev/null | wc -l)
|
||||||
|
|
||||||
|
if [ "$EXISTING_MAPS" -gt 10 ]; then
|
||||||
|
echo "✓ Found $EXISTING_MAPS standard maps already installed."
|
||||||
|
echo "Skipping download. Delete maps to re-download."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Downloading standard StarCraft Broodwar maps..."
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Downloading SSCAIT map pack..."
|
||||||
|
ALT_MAPS_URL="https://sscaitournament.com/files/sscai_map_pack.zip"
|
||||||
|
TEMP_ZIP="${TEMP_DIR}/maps.zip"
|
||||||
|
|
||||||
|
if curl -L -f "${ALT_MAPS_URL}" -o "${TEMP_ZIP}" 2>/dev/null; then
|
||||||
|
echo "Extracting maps..."
|
||||||
|
unzip -q -o "${TEMP_ZIP}" -d "${TEMP_DIR}" 2>/dev/null || true
|
||||||
|
|
||||||
|
# Move extracted maps to the maps directory
|
||||||
|
find "${TEMP_DIR}" -type f \( -name "*.sc?" -o -name "*.SC?" \) | while read -r map; do
|
||||||
|
filename=$(basename "$map")
|
||||||
|
if [ ! -f "${MAPS_DIR}/${filename}" ]; then
|
||||||
|
cp "$map" "${MAPS_DIR}/"
|
||||||
|
echo " ✓ Extracted ${filename}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "SSCAIT map pack not available"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
rm -rf "${TEMP_DIR}"
|
||||||
402
scripts/4-configure-bwapi.sh
Executable file
402
scripts/4-configure-bwapi.sh
Executable file
@@ -0,0 +1,402 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "========================================"
|
||||||
|
echo "Step 4: Configure BWAPI"
|
||||||
|
echo "========================================"
|
||||||
|
|
||||||
|
# Paths
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
PREFERENCES_FILE="${PREFERENCES_FILE:-$SCRIPT_DIR/bwapi-preferences.yml}"
|
||||||
|
BWAPI_INI_PATH="${BWAPI_INI_PATH:-$PROJECT_DIR/starcraft/bwapi-data/bwapi.ini}"
|
||||||
|
|
||||||
|
# Check if already configured (if bwapi.ini exists and preferences haven't changed)
|
||||||
|
if [ -f "$BWAPI_INI_PATH" ]; then
|
||||||
|
echo "✓ BWAPI configuration file already exists."
|
||||||
|
echo "Updating configuration from preferences..."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if preferences file exists
|
||||||
|
if [ ! -f "$PREFERENCES_FILE" ]; then
|
||||||
|
echo "Error: Preferences file not found: $PREFERENCES_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Function to read YAML value (simple parser for our use case)
|
||||||
|
read_yaml_value() {
|
||||||
|
local key="$1"
|
||||||
|
local default="${2:-}"
|
||||||
|
# Read value, ignoring comments and empty lines
|
||||||
|
local value=$(grep "^${key}:" "$PREFERENCES_FILE" | head -1 | sed 's/^[^:]*:[[:space:]]*//' | sed 's/^"\(.*\)"$/\1/')
|
||||||
|
echo "${value:-$default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to read YAML array values
|
||||||
|
read_yaml_array() {
|
||||||
|
local key="$1"
|
||||||
|
grep -A 20 "^${key}:" "$PREFERENCES_FILE" | grep '^[[:space:]]*-[[:space:]]' | sed 's/^[[:space:]]*-[[:space:]]*//' | grep -v '^#'
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Reading preferences from: $PREFERENCES_FILE"
|
||||||
|
|
||||||
|
# Read configuration values
|
||||||
|
AUTO_MENU=$(read_yaml_value "auto_menu" "SINGLE_PLAYER")
|
||||||
|
MAP=$(read_yaml_value "map" "maps/BroodWar/(2)Benzene.scm")
|
||||||
|
PLAYER_RACE=$(read_yaml_value "player_race" "Zerg")
|
||||||
|
ENEMY_COUNT=$(read_yaml_value "enemy_count" "1")
|
||||||
|
GAME_TYPE=$(read_yaml_value "game_type" "MELEE")
|
||||||
|
AUTO_RESTART=$(read_yaml_value "auto_restart" "OFF")
|
||||||
|
SAVE_REPLAY=$(read_yaml_value "save_replay" "maps/replays/%BOTNAME6%/\$Y \$b \$d/%MAP%_%BOTRACE%%ALLYRACES%vs%ENEMYRACES%_\$H\$M\$S.rep")
|
||||||
|
WINDOWED=$(read_yaml_value "windowed" "OFF")
|
||||||
|
WINDOW_LEFT=$(read_yaml_value "window_left" "1556")
|
||||||
|
WINDOW_TOP=$(read_yaml_value "window_top" "704")
|
||||||
|
WINDOW_WIDTH=$(read_yaml_value "window_width" "640")
|
||||||
|
WINDOW_HEIGHT=$(read_yaml_value "window_height" "480")
|
||||||
|
SOUND=$(read_yaml_value "sound" "ON")
|
||||||
|
SCREENSHOTS=$(read_yaml_value "screenshots" "gif")
|
||||||
|
DROP_PLAYERS=$(read_yaml_value "drop_players" "ON")
|
||||||
|
SHARED_MEMORY=$(read_yaml_value "shared_memory" "ON")
|
||||||
|
HOLIDAY=$(read_yaml_value "holiday" "ON")
|
||||||
|
AI_MODULE=$(read_yaml_value "ai_module" "bwapi-data/AI/ExampleAIModule.dll")
|
||||||
|
AI_MODULE_DEBUG=$(read_yaml_value "ai_module_debug" "bwapi-data/AI/ExampleAIModuled.dll")
|
||||||
|
TOURNAMENT_MODULE=$(read_yaml_value "tournament_module" "")
|
||||||
|
|
||||||
|
# Optional settings
|
||||||
|
SPEED_OVERRIDE=$(read_yaml_value "speed_override" "")
|
||||||
|
SEED_OVERRIDE=$(read_yaml_value "seed_override" "")
|
||||||
|
CONSOLE_ATTACH_STARTUP=$(read_yaml_value "console_attach_on_startup" "FALSE")
|
||||||
|
CONSOLE_ALLOC_STARTUP=$(read_yaml_value "console_alloc_on_startup" "FALSE")
|
||||||
|
CONSOLE_ATTACH_AUTO=$(read_yaml_value "console_attach_auto" "TRUE")
|
||||||
|
CONSOLE_ALLOC_AUTO=$(read_yaml_value "console_alloc_auto" "TRUE")
|
||||||
|
WAIT_MIN_PLAYERS=$(read_yaml_value "wait_for_min_players" "2")
|
||||||
|
WAIT_MAX_PLAYERS=$(read_yaml_value "wait_for_max_players" "8")
|
||||||
|
WAIT_TIME=$(read_yaml_value "wait_for_time" "60000")
|
||||||
|
DOUBLE_SIZE=$(read_yaml_value "double_size" "ON")
|
||||||
|
|
||||||
|
# Read computer races array
|
||||||
|
COMPUTER_RACES=()
|
||||||
|
while IFS= read -r race; do
|
||||||
|
[ -n "$race" ] && COMPUTER_RACES+=("$race")
|
||||||
|
done < <(read_yaml_array "computer_races")
|
||||||
|
|
||||||
|
# Set enemy races with defaults
|
||||||
|
ENEMY_RACE="${COMPUTER_RACES[0]:-Terran}"
|
||||||
|
ENEMY_RACE_1="${COMPUTER_RACES[0]:-Default}"
|
||||||
|
ENEMY_RACE_2="${COMPUTER_RACES[1]:-Default}"
|
||||||
|
ENEMY_RACE_3="${COMPUTER_RACES[2]:-Default}"
|
||||||
|
ENEMY_RACE_4="${COMPUTER_RACES[3]:-Default}"
|
||||||
|
ENEMY_RACE_5="${COMPUTER_RACES[4]:-Default}"
|
||||||
|
ENEMY_RACE_6="${COMPUTER_RACES[5]:-Default}"
|
||||||
|
ENEMY_RACE_7="${COMPUTER_RACES[6]:-Default}"
|
||||||
|
|
||||||
|
echo "Configuring BWAPI at: $BWAPI_INI_PATH"
|
||||||
|
|
||||||
|
# Create directory if it doesn't exist
|
||||||
|
mkdir -p "$(dirname "$BWAPI_INI_PATH")"
|
||||||
|
|
||||||
|
# Prepare conditional config lines
|
||||||
|
if [ -n "$SEED_OVERRIDE" ]; then
|
||||||
|
SEED_LINE="seed_override = $SEED_OVERRIDE"
|
||||||
|
else
|
||||||
|
SEED_LINE=";seed_override = 123456789"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$SPEED_OVERRIDE" ]; then
|
||||||
|
SPEED_LINE="speed_override = $SPEED_OVERRIDE"
|
||||||
|
else
|
||||||
|
SPEED_LINE=";speed_override = -1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate bwapi.ini content in one go
|
||||||
|
cat > "$BWAPI_INI_PATH" << EOF
|
||||||
|
[ai]
|
||||||
|
; Paths and revisions for AI
|
||||||
|
; - Use commas to specify AI for multiple instances.
|
||||||
|
; - If there are more instances than the amount of
|
||||||
|
; DLLs specified, then the last entry is used.
|
||||||
|
; - Example: SomeAI.dll, SecondInstance.dll, ThirdInstance.dll
|
||||||
|
; - Absolute paths are acceptable.
|
||||||
|
ai = $AI_MODULE
|
||||||
|
ai_dbg = $AI_MODULE_DEBUG
|
||||||
|
|
||||||
|
; Used only for tournaments
|
||||||
|
; Tournaments can only be run in RELEASE mode
|
||||||
|
tournament = $TOURNAMENT_MODULE
|
||||||
|
|
||||||
|
[auto_menu]
|
||||||
|
; auto_menu = OFF | SINGLE_PLAYER | LAN | BATTLE_NET
|
||||||
|
; for replays, just set the map to the path of the replay file
|
||||||
|
auto_menu = $AUTO_MENU
|
||||||
|
|
||||||
|
; character_name = FIRST | WAIT | <other>
|
||||||
|
; if FIRST (default), use the first character in the list
|
||||||
|
; if WAIT, stop at this screen
|
||||||
|
; else the character with the given value is used/created
|
||||||
|
character_name = FIRST
|
||||||
|
|
||||||
|
; pause_dbg = ON | OFF
|
||||||
|
; This specifies if auto_menu will pause until a debugger is attached to the process.
|
||||||
|
; Only works in DEBUG mode.
|
||||||
|
pause_dbg = OFF
|
||||||
|
|
||||||
|
; lan_mode = Same as the text that appears in the multiplayer connection list
|
||||||
|
; Examples: Local Area Network (UDP), Local PC, Direct IP
|
||||||
|
lan_mode = Local Area Network (UDP)
|
||||||
|
|
||||||
|
; auto_restart = ON | OFF
|
||||||
|
; if ON, BWAPI will automate through the end of match screen and start the next match
|
||||||
|
; if OFF, BWAPI will pause at the end of match screen until you manually click OK,
|
||||||
|
; and then BWAPI resume menu automation and start the next match
|
||||||
|
auto_restart = $AUTO_RESTART
|
||||||
|
|
||||||
|
; map = path to map to host relative to Starcraft folder, i.e. map = maps/(2)Boxer.scm
|
||||||
|
; leaving this field blank will join a game instead of creating it
|
||||||
|
; The filename(NOT the path) can also contain wildcards, example: maps/(?)*.sc?
|
||||||
|
; A ? is a wildcard for a single character and * is a wildcard for a string of characters
|
||||||
|
map = $MAP
|
||||||
|
|
||||||
|
; game = name of the game to join | JOIN_FIRST
|
||||||
|
; i.e. game = BWAPI will join the game called "BWAPI"
|
||||||
|
; and game = JOIN_FIRST will join the first game in the list.
|
||||||
|
; If the game does not exist and the "map" entry is not blank, then the game will be created instead
|
||||||
|
; If this entry is blank, then it will follow the rules of the "map" entry
|
||||||
|
game =
|
||||||
|
|
||||||
|
; mapiteration = RANDOM | SEQUENCE
|
||||||
|
; type of iteration that will be done on a map name with a wildcard
|
||||||
|
mapiteration = RANDOM
|
||||||
|
|
||||||
|
; race = Terran | Protoss | Zerg | Random
|
||||||
|
; - Use commas to specify race for each AI module when running multiple instances.
|
||||||
|
; - If there are more instances than the amount of
|
||||||
|
; races specified, then the last entry is used.
|
||||||
|
; - To be used in conjunction with multiple AI modules
|
||||||
|
; - Example: Terran, Protoss, Terran, Zerg
|
||||||
|
race = $PLAYER_RACE
|
||||||
|
|
||||||
|
; enemy_count = 1-7, for 1v1 games, set enemy_count = 1
|
||||||
|
; only used in single player games
|
||||||
|
enemy_count = $ENEMY_COUNT
|
||||||
|
|
||||||
|
; enemy_race = Terran | Protoss | Zerg | Random | RandomTP | RandomTZ | RandomPZ | RandomTPZ
|
||||||
|
; only used in single player games
|
||||||
|
enemy_race = $ENEMY_RACE
|
||||||
|
|
||||||
|
; enemy_race_# = Default
|
||||||
|
; Values for enemy_race are acceptable, Default will use the value specified in enemy_race
|
||||||
|
enemy_race_1 = $ENEMY_RACE_1
|
||||||
|
enemy_race_2 = $ENEMY_RACE_2
|
||||||
|
enemy_race_3 = $ENEMY_RACE_3
|
||||||
|
enemy_race_4 = $ENEMY_RACE_4
|
||||||
|
enemy_race_5 = $ENEMY_RACE_5
|
||||||
|
enemy_race_6 = $ENEMY_RACE_6
|
||||||
|
enemy_race_7 = $ENEMY_RACE_7
|
||||||
|
|
||||||
|
;game_type = TOP_VS_BOTTOM | MELEE | FREE_FOR_ALL | ONE_ON_ONE | USE_MAP_SETTINGS | CAPTURE_THE_FLAG
|
||||||
|
; | GREED | SLAUGHTER | SUDDEN_DEATH | TEAM_MELEE | TEAM_FREE_FOR_ALL | TEAM_CAPTURE_THE_FLAG
|
||||||
|
game_type = $GAME_TYPE
|
||||||
|
|
||||||
|
; game_type_extra = Text that appears in the drop-down list below the Game Type drop-down list.
|
||||||
|
; If empty, the Starcraft default will be used.
|
||||||
|
; The following are the game types that use this setting, and corresponding example values
|
||||||
|
; TOP_VS_BOTTOM 3 vs 1 | 2 vs 2 | 1 vs 3 | # vs #
|
||||||
|
; GREED 2500 | 5000 | 7500 | 10000
|
||||||
|
; SLAUGHTER 15 | 30 | 45 | 60
|
||||||
|
; TEAM_MELEE 2 | 3 | 4 | 5 | 6 | 7 | 8
|
||||||
|
; TEAM_FREE_FOR_ALL 2 | 3 | 4 | 5 | 6 | 7 | 8
|
||||||
|
; TEAM_CAPTURE_THE_FLAG 2 | 3 | 4 | 5 | 6 | 7 | 8
|
||||||
|
game_type_extra =
|
||||||
|
|
||||||
|
; save_replay = path to save replay to
|
||||||
|
; Accepts all environment variables including custom variables. See wiki for more info.
|
||||||
|
save_replay = $SAVE_REPLAY
|
||||||
|
|
||||||
|
; wait_for_min_players = #
|
||||||
|
; # of players to wait for in a network game before starting.
|
||||||
|
; This includes the BWAPI player. The game will start immediately when it is full.
|
||||||
|
wait_for_min_players = $WAIT_MIN_PLAYERS
|
||||||
|
|
||||||
|
; wait_for_max_players = #
|
||||||
|
; Start immediately when the game has reached # players.
|
||||||
|
; This includes the BWAPI player. The game will start immediately when it is full.
|
||||||
|
wait_for_max_players = $WAIT_MAX_PLAYERS
|
||||||
|
|
||||||
|
; wait_for_time = #
|
||||||
|
; The time in milliseconds (ms) to wait after the game has met the min_players requirement.
|
||||||
|
; The game will start immediately when it is full.
|
||||||
|
wait_for_time = $WAIT_TIME
|
||||||
|
|
||||||
|
[config]
|
||||||
|
; holiday = ON | OFF
|
||||||
|
; This will apply special easter eggs to the game when it comes time for a holiday.
|
||||||
|
holiday = $HOLIDAY
|
||||||
|
|
||||||
|
; shared_memory = ON | OFF
|
||||||
|
; This is specifically used to disable shared memory (BWAPI Server) in the Windows Emulator "WINE"
|
||||||
|
; Setting this to OFF will disable the BWAPI Server, default is ON
|
||||||
|
; MUST be ON for client bots to connect
|
||||||
|
shared_memory = $SHARED_MEMORY
|
||||||
|
|
||||||
|
; console_* = TRUE | FALSE
|
||||||
|
; Used for getting a console for displaying text written to stdout and stderr, and read from stdin.
|
||||||
|
; console_attach_*
|
||||||
|
; Allows BWAPI to attach to the parent process' console. i.e. if the parent
|
||||||
|
; has a console, output will be displayed on that console, and that console
|
||||||
|
; also kept open even if the parent dies.
|
||||||
|
; console_alloc_*
|
||||||
|
; Allows BWAPI to allocate it's own system console window. Not executed if
|
||||||
|
; corresponding console_attach_* is enabled and succeeds.
|
||||||
|
; console_*_on_startup
|
||||||
|
; Executes when BWAPI.dll is first attached to Starcraft.
|
||||||
|
; console_*_auto
|
||||||
|
; Executes when something is written to std::cout or std::cerr,
|
||||||
|
; and no console was successfully attached/allocated on startup.
|
||||||
|
console_attach_on_startup = $CONSOLE_ATTACH_STARTUP
|
||||||
|
console_alloc_on_startup = $CONSOLE_ALLOC_STARTUP
|
||||||
|
console_attach_auto = $CONSOLE_ATTACH_AUTO
|
||||||
|
console_alloc_auto = $CONSOLE_ALLOC_AUTO
|
||||||
|
|
||||||
|
[window]
|
||||||
|
; These values are saved automatically when you move, resize, or toggle windowed mode
|
||||||
|
|
||||||
|
; windowed = ON | OFF
|
||||||
|
; This causes BWAPI to enter windowed mode when it is injected.
|
||||||
|
windowed = $WINDOWED
|
||||||
|
|
||||||
|
; left, top
|
||||||
|
; Determines the position of the window
|
||||||
|
left = $WINDOW_LEFT
|
||||||
|
top = $WINDOW_TOP
|
||||||
|
|
||||||
|
; width, height
|
||||||
|
; Determines the width and height of the client area and not the window itself
|
||||||
|
width = $WINDOW_WIDTH
|
||||||
|
height = $WINDOW_HEIGHT
|
||||||
|
|
||||||
|
[starcraft]
|
||||||
|
; Game sound engine = ON | OFF
|
||||||
|
sound = $SOUND
|
||||||
|
; Screenshot format = gif | pcx | tga | bmp
|
||||||
|
screenshots = $SCREENSHOTS
|
||||||
|
|
||||||
|
; Random seed override. This uses a fixed seed at the start of the game so that if played out the exact same way,
|
||||||
|
; the same occurrences will happen every time. This value must be a decimal integer.
|
||||||
|
;
|
||||||
|
; When this key is commented out, Starcraft will use the system time as a seed. This is the default behaviour.
|
||||||
|
;
|
||||||
|
; Note: This option affects both single AND multi-player modes (for game hosts only). This means that hosting a multi-player
|
||||||
|
; game with this option enabled will distribute this fixed seed to all other players in the game.
|
||||||
|
$SEED_LINE
|
||||||
|
|
||||||
|
; Speed override. This overrides the default game speed setting and prevents bots from changing the game speed.
|
||||||
|
; Enabling this option causes it to take effect. The value is the number of milliseconds per frame. A negative
|
||||||
|
; value uses the game's default speed value.
|
||||||
|
$SPEED_LINE
|
||||||
|
|
||||||
|
; drop_players = ON | OFF
|
||||||
|
; This specifies if BWAPI should drop other players from the game when the timeout dialog reaches 0. Players
|
||||||
|
; usually time out when there are connection issues or their client is not responding. Setting this to OFF
|
||||||
|
; will cause BWAPI to wait an infinite amount of time until the player reconnects.
|
||||||
|
drop_players = $DROP_PLAYERS
|
||||||
|
EOF
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Configure W-MODE to enable/disable 2x view based on preferences
|
||||||
|
WMODE_INI="${PROJECT_DIR}/starcraft/wmode.ini"
|
||||||
|
if [ -f "$WMODE_INI" ]; then
|
||||||
|
if [ "$DOUBLE_SIZE" = "ON" ]; then
|
||||||
|
sed -i 's/^DblSizeMode=.*/DblSizeMode=1/' "$WMODE_INI"
|
||||||
|
else
|
||||||
|
sed -i 's/^DblSizeMode=.*/DblSizeMode=0/' "$WMODE_INI"
|
||||||
|
fi
|
||||||
|
echo "Configured W-MODE for 2x view"
|
||||||
|
else
|
||||||
|
echo "Creating wmode.ini with 2x view enabled"
|
||||||
|
cat > "$WMODE_INI" << 'EOF'
|
||||||
|
[W-MODE]
|
||||||
|
|
||||||
|
; What settings do you want to save when you exit StarCraft?
|
||||||
|
|
||||||
|
; Save WindowClientX?
|
||||||
|
; Default value: 1
|
||||||
|
SaveWindowClientX=1
|
||||||
|
; Save WindowClientY?
|
||||||
|
; Default value: 1
|
||||||
|
SaveWindowClientY=1
|
||||||
|
; Save WindowClientXDblSized?
|
||||||
|
; Default value: 1
|
||||||
|
SaveWindowClientXDblSized=1
|
||||||
|
; Save WindowClientYDblSized?
|
||||||
|
; Default value: 1
|
||||||
|
SaveWindowClientYDblSized=1
|
||||||
|
; Save ClipCursor?
|
||||||
|
; Default value: 0
|
||||||
|
SaveClipCursor=0
|
||||||
|
; Save doublesize mode?
|
||||||
|
; Default value: 1
|
||||||
|
SaveDblSizeMode=1
|
||||||
|
; Save EnableWindowMove?
|
||||||
|
; Default value: 1
|
||||||
|
SaveEnableWindowMove=1
|
||||||
|
; Save AlwaysOnTop?
|
||||||
|
; Default value: 1
|
||||||
|
SaveAlwaysOnTop=1
|
||||||
|
; Save DisableControls?
|
||||||
|
; Default value: 1
|
||||||
|
SaveDisableControls=1
|
||||||
|
|
||||||
|
; X and Y coordinates of the StarCraft game screen.
|
||||||
|
; (Upper left corner of client area.)
|
||||||
|
; Default values: center the game screen on the desktop.
|
||||||
|
; If you don't specify the WindowClientX value then
|
||||||
|
; the window will be centered horizontally.
|
||||||
|
; Omitting WindowClientY will cause the window to
|
||||||
|
; be centered vertically.
|
||||||
|
WindowClientX=30
|
||||||
|
WindowClientY=30
|
||||||
|
; X and Y coordinates of the StarCraft game screen in
|
||||||
|
; doublesize mode.
|
||||||
|
WindowClientXDblSized=30
|
||||||
|
WindowClientYDblSized=30
|
||||||
|
|
||||||
|
; Cursor clip (Toggle hotkey: ALT+F1)
|
||||||
|
; Default value: 0
|
||||||
|
ClipCursor=0
|
||||||
|
; Doublesize mode (Toggle hotkey: ALT+F9)
|
||||||
|
; Default value: 0
|
||||||
|
DblSizeMode=1
|
||||||
|
; Enable window move (Toggle hotkey: ALT+F10)
|
||||||
|
; Default value: 1
|
||||||
|
EnableWindowMove=1
|
||||||
|
; Enable always-on-top mode (Toggle hotkey: ALT+F11)
|
||||||
|
; Default value: 0
|
||||||
|
AlwaysOnTop=0
|
||||||
|
; Disable all controls in the caption of the StarCraft
|
||||||
|
; window. Disable the screensaver when the sc window is
|
||||||
|
; active. Window can not be closed with ALT+F4.
|
||||||
|
; (Toggle hotkey: ALT+F12)
|
||||||
|
; Default value: 0
|
||||||
|
DisableControls=0
|
||||||
|
|
||||||
|
; Limit the maximum frame/sec to reach better performance.
|
||||||
|
; This is extremely useful because during replays with
|
||||||
|
; fastest x 4 speed the frame rate raises to the skies and
|
||||||
|
; MaxFps limits to 100 the number of blits that require
|
||||||
|
; 8bit -> desktop resolution conversion of the StarCraft
|
||||||
|
; screen image.
|
||||||
|
; Default and recommended value: 100
|
||||||
|
; You can set it to higher value on faster machines.
|
||||||
|
; Minimum value: 30 (less than 100 isn't recommended)
|
||||||
|
MaxFps=100
|
||||||
|
|
||||||
|
; Enables StarCraft to mute all sound when the main window
|
||||||
|
; loses focus.
|
||||||
|
; Default value: 0
|
||||||
|
MuteNotFocused=0
|
||||||
|
EOF
|
||||||
|
echo "✓ Created wmode.ini"
|
||||||
|
fi
|
||||||
49
scripts/5-configure-registry.sh
Executable file
49
scripts/5-configure-registry.sh
Executable file
@@ -0,0 +1,49 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
echo "========================================"
|
||||||
|
echo "Step 5: Run StarCraft"
|
||||||
|
echo "========================================"
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
|
||||||
|
export WINEPREFIX="$PROJECT_DIR/.wine"
|
||||||
|
export WINEARCH=win64
|
||||||
|
export DISPLAY=:0
|
||||||
|
export WINEDLLOVERRIDES="mscoree,mshtml="
|
||||||
|
export WINEDEBUG=-all
|
||||||
|
|
||||||
|
|
||||||
|
INSTALL_DIR="$PROJECT_DIR/starcraft"
|
||||||
|
|
||||||
|
SC_WIN_PATH="$(winepath -w "$INSTALL_DIR" 2>/dev/null || echo "Z:${INSTALL_DIR}" | sed 's/\//\\\\/g')\\\\"
|
||||||
|
|
||||||
|
# if wine REG QUERY "HKEY_LOCAL_MACHINE\\SOFTWARE\\Blizzard Entertainment\\Starcraft" /v InstallPath >/dev/null 2>&1; then
|
||||||
|
# echo "Registry already configured, skipping..."
|
||||||
|
# exit 0
|
||||||
|
# fi
|
||||||
|
|
||||||
|
echo "Configuring registry..."
|
||||||
|
# Core registry entries
|
||||||
|
wine REG ADD "HKEY_LOCAL_MACHINE\\SOFTWARE\\Blizzard Entertainment\\Starcraft" \
|
||||||
|
/v InstallPath /t REG_EXPAND_SZ /d "${SC_WIN_PATH}" /f 2>/dev/null || true
|
||||||
|
|
||||||
|
wine REG ADD "HKEY_LOCAL_MACHINE\\SOFTWARE\\Blizzard Entertainment\\Starcraft" \
|
||||||
|
/v Program /t REG_EXPAND_SZ /d "${SC_WIN_PATH}StarCraft.exe" /f 2>/dev/null || true
|
||||||
|
|
||||||
|
# Disable Intro
|
||||||
|
wine REG ADD "HKEY_CURRENT_USER\\Software\\Blizzard Entertainment\\Starcraft" /v "Intro" /t REG_SZ /d "0" /f 2>/dev/null || true
|
||||||
|
wine REG ADD "HKEY_CURRENT_USER\\Software\\Blizzard Entertainment\\Starcraft" /v "IntroX" /t REG_SZ /d "0" /f 2>/dev/null || true
|
||||||
|
wine REG ADD "HKEY_CURRENT_USER\\Software\\Blizzard Entertainment\\Starcraft" /v "Tip" /t REG_SZ /d "0" /f 2>/dev/null || true
|
||||||
|
|
||||||
|
# Chaoslauncher configuration
|
||||||
|
SC_CHAOS_PATH=$(winepath -w "$INSTALL_DIR" | sed 's/\\/\\\\/g')
|
||||||
|
wine REG ADD "HKEY_CURRENT_USER\\Software\\Chaoslauncher\\Launcher" /v "ScPath" /t REG_SZ /d "${SC_CHAOS_PATH}" /f 2>/dev/null || true
|
||||||
|
wine REG ADD "HKEY_CURRENT_USER\\Software\\Chaoslauncher\\Launcher" /v "GameVersion" /t REG_SZ /d "Starcraft 1.16.1" /f 2>/dev/null || true
|
||||||
|
wine REG ADD "HKEY_CURRENT_USER\\Software\\Chaoslauncher\\Launcher" /v "RunScOnStartup" /t REG_SZ /d "1" /f 2>/dev/null || true
|
||||||
|
|
||||||
|
# Enable BWAPI 4.4.0 Injector plugin by default
|
||||||
|
wine REG ADD "HKEY_CURRENT_USER\\Software\\Chaoslauncher\\PluginsEnabled" /v "BWAPI 4.4.0 Injector [RELEASE]" /t REG_SZ /d "1" /f 2>/dev/null || true
|
||||||
|
wine REG ADD "HKEY_CURRENT_USER\\Software\\Chaoslauncher\\PluginsEnabled" /v "W-MODE 1.02" /t REG_SZ /d "1" /f 2>/dev/null || true
|
||||||
78
scripts/bwapi-preferences.yml
Normal file
78
scripts/bwapi-preferences.yml
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
auto_menu: SINGLE_PLAYER
|
||||||
|
# auto_menu: OFF
|
||||||
|
# auto_menu: LAN
|
||||||
|
# auto_menu: BATTLE_NET
|
||||||
|
|
||||||
|
map: maps/BroodWar/(2)Benzene.scx
|
||||||
|
# map: maps/BroodWar/IceHunter.scm
|
||||||
|
# map: maps/(2)Boxer.scm
|
||||||
|
|
||||||
|
player_race: Zerg
|
||||||
|
# player_race: Terran
|
||||||
|
# player_race: Protoss
|
||||||
|
# player_race: Random
|
||||||
|
|
||||||
|
enemy_count: 1
|
||||||
|
enemy_count: 2
|
||||||
|
|
||||||
|
computer_races:
|
||||||
|
- Random
|
||||||
|
# - Terran
|
||||||
|
# - Zerg
|
||||||
|
# - Random
|
||||||
|
# - Default
|
||||||
|
# - Default
|
||||||
|
# - Default
|
||||||
|
|
||||||
|
game_type: MELEE
|
||||||
|
# game_type: TEAM_MELEE
|
||||||
|
|
||||||
|
auto_restart: OFF
|
||||||
|
# auto_restart: ON
|
||||||
|
|
||||||
|
save_replay: "maps/replays/%BOTNAME6%/$Y $b $d/%MAP%_%BOTRACE%%ALLYRACES%vs%ENEMYRACES%_$H$M$S.rep"
|
||||||
|
|
||||||
|
windowed: OFF
|
||||||
|
# windowed: ON
|
||||||
|
|
||||||
|
window_left: 1556
|
||||||
|
window_top: 704
|
||||||
|
window_width: 640
|
||||||
|
window_height: 480
|
||||||
|
|
||||||
|
# sound: ON
|
||||||
|
sound: OFF
|
||||||
|
|
||||||
|
screenshots: gif
|
||||||
|
|
||||||
|
drop_players: OFF
|
||||||
|
|
||||||
|
shared_memory: ON
|
||||||
|
|
||||||
|
holiday: ON
|
||||||
|
|
||||||
|
# AI module paths
|
||||||
|
# ai_module: bwapi-data/AI/ExampleAIModule.dll
|
||||||
|
# ai_module_debug: bwapi-data/AI/ExampleAIModuled.dll
|
||||||
|
# Tournament module (only for tournaments in RELEASE mode)
|
||||||
|
# tournament_module:
|
||||||
|
|
||||||
|
# Network game settings
|
||||||
|
# wait_for_min_players: 2
|
||||||
|
# wait_for_max_players: 8
|
||||||
|
# wait_for_time: 60000
|
||||||
|
|
||||||
|
# Console settings: TRUE | FALSE
|
||||||
|
# console_attach_on_startup: FALSE
|
||||||
|
# console_alloc_on_startup: FALSE
|
||||||
|
# console_attach_auto: TRUE
|
||||||
|
# console_alloc_auto: TRUE
|
||||||
|
|
||||||
|
# Speed override (-1 for default, or milliseconds per frame)
|
||||||
|
# speed_override: -1
|
||||||
|
|
||||||
|
# Random seed override (decimal integer, commented = use system time)
|
||||||
|
# seed_override: 123456789
|
||||||
|
|
||||||
|
double_size: ON
|
||||||
|
# double_size: OFF
|
||||||
41
setup.sh
Executable file
41
setup.sh
Executable file
@@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
SCRIPTS_PATH="${SCRIPT_DIR}/scripts"
|
||||||
|
|
||||||
|
export WINEPREFIX="$SCRIPT_DIR/.wine"
|
||||||
|
export WINEARCH=win64
|
||||||
|
export DISPLAY=:0
|
||||||
|
export WINEDLLOVERRIDES="mscoree,mshtml="
|
||||||
|
export WINEDEBUG=-all
|
||||||
|
|
||||||
|
if [ ! -d "$WINEPREFIX" ]; then
|
||||||
|
wine wineboot --init
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Starting Xvfb virtual display..."
|
||||||
|
Xvfb :0 -auth ~/.Xauthority -screen 0 640x480x24 > /dev/null 2>&1 &
|
||||||
|
XVFB_PID=$!
|
||||||
|
|
||||||
|
|
||||||
|
for script in "${SCRIPTS_PATH}"/[0-9]-*.sh; do
|
||||||
|
if [ -f "$script" ]; then
|
||||||
|
script_name=$(basename "$script")
|
||||||
|
echo ""
|
||||||
|
echo "Running: $script_name"
|
||||||
|
echo "-----------------------------------------"
|
||||||
|
chmod +x "$script"
|
||||||
|
"$script"
|
||||||
|
exit_code=$?
|
||||||
|
if [ $exit_code -ne 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "❌ Error: $script_name failed with exit code $exit_code"
|
||||||
|
exit $exit_code
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Setup Complete"
|
||||||
Reference in New Issue
Block a user