WIP: Реализация точек полёта для стартовых локаций #1

Draft
gasaichan wants to merge 7 commits from taxis into master
7 changed files with 194 additions and 101 deletions
Showing only changes of commit df143b0bf1 - Show all commits
+1 -1
View File
@@ -47,7 +47,7 @@ if (!(Test-Path $TOOL)) {
# --- Build MPQ archives into dist/ # --- Build MPQ archives into dist/
Write-Host "Building MPQ archives from src/ -> dist/..." Write-Host "Building MPQ archives from src/ -> dist/..."
& $TOOL $SRC_DIR $DIST_DIR & $TOOL build-mpq $SRC_DIR $DIST_DIR
if ($LASTEXITCODE -ne 0) { if ($LASTEXITCODE -ne 0) {
Write-Error "MPQ build failed!" Write-Error "MPQ build failed!"
exit 1 exit 1
+2
View File
@@ -1 +1,3 @@
target/ target/
.sqlx/
.env
+68 -2
View File
@@ -624,6 +624,17 @@ dependencies = [
"simd-adler32", "simd-adler32",
] ]
[[package]]
name = "mio"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
dependencies = [
"libc",
"wasi",
"windows-sys 0.61.2",
]
[[package]] [[package]]
name = "num-bigint" name = "num-bigint"
version = "0.4.6" version = "0.4.6"
@@ -730,6 +741,12 @@ dependencies = [
"base64ct", "base64ct",
] ]
[[package]]
name = "pin-project-lite"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[[package]] [[package]]
name = "pkcs1" name = "pkcs1"
version = "0.7.5" version = "0.7.5"
@@ -1055,6 +1072,16 @@ dependencies = [
"digest", "digest",
] ]
[[package]]
name = "signal-hook-registry"
version = "1.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
dependencies = [
"errno",
"libc",
]
[[package]] [[package]]
name = "signature" name = "signature"
version = "2.2.0" version = "2.2.0"
@@ -1077,6 +1104,16 @@ version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "socket2"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
dependencies = [
"libc",
"windows-sys 0.61.2",
]
[[package]] [[package]]
name = "spin" name = "spin"
version = "0.9.8" version = "0.9.8"
@@ -1149,6 +1186,34 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "tokio"
version = "1.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
dependencies = [
"bytes",
"libc",
"mio",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys 0.61.2",
]
[[package]]
name = "tokio-macros"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "tool" name = "tool"
version = "0.1.0" version = "0.1.0"
@@ -1156,15 +1221,16 @@ dependencies = [
"clap", "clap",
"env_logger", "env_logger",
"log", "log",
"tokio",
"walkdir", "walkdir",
"wow-mpq", "wow-mpq",
] ]
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.19.0" version = "1.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
+2 -1
View File
@@ -4,8 +4,9 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
clap = "4.6.1" clap = { version = "4.6.1", features = ["derive"] }
env_logger = "0.11.10" env_logger = "0.11.10"
log = "0.4.30" log = "0.4.30"
tokio = { version = "1.52.3", features = ["full"] }
walkdir = "2.5.0" walkdir = "2.5.0"
wow-mpq = "0.6.4" wow-mpq = "0.6.4"
+100
View File
@@ -0,0 +1,100 @@
use clap::Args;
use log::info;
use std::{
error::Error,
fs,
path::{Path, PathBuf},
};
use walkdir::WalkDir;
use wow_mpq::{ArchiveBuilder, FormatVersion, ListfileOption, compression::flags};
#[derive(Args, Debug)]
pub struct BuildMpqCommand {
input_dir: PathBuf,
destination_dir: PathBuf,
}
pub fn execute(args: BuildMpqCommand) -> Result<(), Box<dyn Error>> {
let data_dir = args.input_dir.join("Data");
if !data_dir.exists() {
return Err(format!("Data directory not found at {}", data_dir.display()).into());
}
info!("Found Data directory at {}", data_dir.display());
for entry in fs::read_dir(&data_dir)? {
let entry = entry?;
let path = entry.path();
if !path.is_dir() {
continue;
}
let dir_name = entry.file_name().to_string_lossy().to_string();
if dir_name.starts_with("ruRU") {
for sub_entry in fs::read_dir(&path)? {
let sub_entry = sub_entry?;
let sub_path = sub_entry.path();
let sub_name = sub_entry.file_name().to_string_lossy().to_string();
let destination = args
.destination_dir
.join("Data")
.join(&dir_name)
.join(&sub_name);
let _ = build_mpq(&sub_path, &destination);
}
continue;
}
let destination = args.destination_dir.join("Data").join(&dir_name);
let _ = build_mpq(&path, &destination)?;
}
Ok(())
}
fn build_mpq(input_dir: &Path, destination: &Path) -> Result<(), Box<dyn Error>> {
info!(
"Packing MPQ from {} to {}",
input_dir.display(),
destination.display()
);
let mut destination = destination.to_path_buf();
destination.set_extension("MPQ");
if let Some(parent) = destination.parent() {
fs::create_dir_all(parent)?;
}
let mut builder = ArchiveBuilder::new()
.version(FormatVersion::V2)
.block_size(7)
.default_compression(flags::ZLIB)
.listfile_option(ListfileOption::Generate);
let base = input_dir.canonicalize()?;
for entry in WalkDir::new(&base)
.into_iter()
.filter_map(|e| e.ok())
.filter(|e| e.file_type().is_file())
{
let absolute_path = entry.path().canonicalize()?;
let relative_path = absolute_path.strip_prefix(&base)?;
builder = builder.add_file(&absolute_path, &relative_path.to_string_lossy().to_string());
}
let _ = builder.build(&destination);
info!("Successfully packed {}", destination.display());
Ok(())
}
+1
View File
@@ -0,0 +1 @@
pub mod build_mpq;
+19 -96
View File
@@ -1,118 +1,41 @@
use clap::Parser; mod commands;
use clap::{Parser, Subcommand};
use log::{error, info}; use log::{error, info};
use std::error::Error; use std::error::Error;
use std::fs;
use std::path::{Path, PathBuf};
use walkdir::WalkDir;
use wow_mpq::compression::flags;
use wow_mpq::{ArchiveBuilder, FormatVersion, ListfileOption};
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
struct Args { struct Cli {
input_dir: PathBuf, #[command(subcommand)]
command: Commands,
destination_dir: PathBuf,
} }
fn main() { #[derive(Subcommand, Debug)]
enum Commands {
BuildMpq(commands::build_mpq::BuildMpqCommand),
}
#[tokio::main]
async fn main() {
env_logger::builder() env_logger::builder()
.filter_level(log::LevelFilter::Debug) .filter_level(log::LevelFilter::Debug)
.format_target(false) .format_target(false)
.format_timestamp(None) .format_timestamp(None)
.init(); .init();
let args = Args::parse(); let args = Cli::parse();
if let Err(err) = run(args) { if let Err(err) = run(args).await {
error!("{}", err); error!("{}", err);
std::process::exit(1); std::process::exit(1);
} }
} }
fn run(args: Args) -> Result<(), Box<dyn Error>> { async fn run(args: Cli) -> Result<(), Box<dyn Error>> {
info!("Starting tool..."); info!("Starting tool...");
let data_dir = args.input_dir.join("Data"); return match args.command {
if !data_dir.exists() { Commands::BuildMpq(args) => commands::build_mpq::execute(args),
return Err(format!("Data directory not found at {}", data_dir.display()).into()); };
}
info!("Found Data directory at {}", data_dir.display());
for entry in fs::read_dir(&data_dir)? {
let entry = entry?;
let path = entry.path();
if !path.is_dir() {
continue;
}
let dir_name = entry.file_name().to_string_lossy().to_string();
if dir_name.starts_with("ruRU") {
for sub_entry in fs::read_dir(&path)? {
let sub_entry = sub_entry?;
let sub_path = sub_entry.path();
let sub_name = sub_entry.file_name().to_string_lossy().to_string();
let destination = args
.destination_dir
.join("Data")
.join(&dir_name)
.join(&sub_name);
let _ = build_mpq(&sub_path, &destination);
}
continue;
}
let destination = args.destination_dir.join("Data").join(&dir_name);
let _ = build_mpq(&path, &destination)?;
}
Ok(())
}
fn build_mpq(input_dir: &Path, destination: &Path) -> Result<(), Box<dyn Error>> {
info!(
"Packing MPQ from {} to {}",
input_dir.display(),
destination.display()
);
let mut destination = destination.to_path_buf();
destination.set_extension("MPQ");
if let Some(parent) = destination.parent() {
fs::create_dir_all(parent)?;
}
let mut builder = ArchiveBuilder::new()
.version(FormatVersion::V2)
.block_size(7)
.default_compression(flags::ZLIB)
.listfile_option(ListfileOption::Generate);
let base = input_dir.canonicalize()?;
for entry in WalkDir::new(&base)
.into_iter()
.filter_map(|e| e.ok())
.filter(|e| e.file_type().is_file())
{
let absolute_path = entry.path().canonicalize()?;
let relative_path = absolute_path.strip_prefix(&base)?;
builder = builder.add_file(&absolute_path, &relative_path.to_string_lossy().to_string());
}
let _ = builder.build(&destination);
info!("Successfully packed {}", destination.display());
Ok(())
} }