basic_minecraft/
minecraft.rs1use std::{path::Path, process::Stdio};
2
3use anyhow::Result;
4use dmclc5::{minecraft::schemas::VersionList, utils::DownloadAllMessage, LauncherContext, StdioUserInterface};
5use tokio::{process::Command, sync::mpsc};
6
7async fn handle_msg(msg: DownloadAllMessage, count: &mut usize) {
8 match msg {
9 Ok((c, async_fetcher::FetchEvent::ContentLength(len))) => {
10 *count += 1;
11 println!("{} start: {len} ({count})", c.0.display());
12 },
13 Ok((c, async_fetcher::FetchEvent::Fetched)) => {
14 *count -= 1;
15 println!("{} end ({count})", c.0.display());
16 },
17 Ok((_, async_fetcher::FetchEvent::Fetching)) => (),
18 Ok((c, async_fetcher::FetchEvent::Progress(prog))) => {
19 println!("{} fetching: {prog}", c.0.display());
20 },
21 Ok((c, async_fetcher::FetchEvent::Retrying))=> {
22 println!("{} retrying", c.0.display());
23 },
24 Err((c, e)) => {
25 *count -= 1;
26 println!("{} error {e} ({count})", c.0.display());
27 }
28 }
29}
30
31async fn real_main() -> Result<()> {
32 let vers = VersionList::get_list().await?;
33 let launcher = {
34 let mut launcher = LauncherContext::new(Path::new("./test"), StdioUserInterface).await?;
35 launcher.bmclapi_mirror = Some("bmclapi2.bangbang93.com".into());
36 launcher
37 };
38 let (tx, mut rx) = mpsc::unbounded_channel();
39 let message_handler = async move {
40 let mut count = 0;
41 while let Some(next) = rx.recv().await {
42 handle_msg(next, &mut count).await;
43 }
44 };
45 let mc = vers.find_by_id("1.20.6").unwrap().install(&launcher, "1.20.6", tx);
46 let mc = tokio::join!(message_handler, mc).1?;
47 let account = &mut *launcher.account_types["offline"].new();
48 account.login(&launcher).await?;
49 if let Some(c) = &mc.extra_data.before_command {
50 let command: Vec<&str> = c.split(" ").collect();
51 Command::new(command[0])
52 .args(&command[1..])
53 .stdout(Stdio::inherit())
54 .stderr(Stdio::inherit())
55 .stdin(Stdio::null())
56 .current_dir(mc.get_cwd())
57 .spawn()?.wait().await?;
58 }
59 let (tx, mut rx) = mpsc::unbounded_channel();
60 let msg_handler = async move {
61 let mut count = 0;
62 while let Some(next) = rx.recv().await {
63 handle_msg(next, &mut count).await;
64 }
65 };
66 let args = mc.launch_args(account, tx);
67 let args = tokio::join!(msg_handler, args).1?;
68 Command::new(mc.extra_data.with_java.as_ref().map_or("java", String::as_str))
69 .args(args)
70 .stdout(Stdio::inherit())
71 .stderr(Stdio::inherit())
72 .stdin(Stdio::null())
73 .current_dir(mc.get_cwd())
74 .spawn()?.wait().await?;
75 Ok(())
76}
77
78#[tokio::main]
79async fn main() {
80 real_main().await.unwrap();
81}