diff options
| -rw-r--r-- | Cargo.toml | 13 | ||||
| -rw-r--r-- | src/core/manifest.rs | 31 | ||||
| -rw-r--r-- | src/core/mod.rs | 1 | ||||
| -rw-r--r-- | src/main.rs | 39 | ||||
| -rw-r--r-- | src/ui/mod.rs | 16 |
5 files changed, 87 insertions, 13 deletions
@@ -4,12 +4,15 @@ version = "0.1.0" edition = "2021" [dependencies] -gtk = "0.9" # 用于自绘制UI的GTK库 -serde = { version = "1.0", features = ["derive"] } # 用于序列化和反序列化 -toml = "0.5" # 用于配置文件解析 -log = "0.4" # 用于日志记录 -env_logger = "0.9" # 用于环境日志记录 +gtk = "0.9" +serde = { version = "1.0", features = ["derive"] } +toml = "0.5" +log = "0.4" +env_logger = "0.9" glib-sys = "0.20.7" +tokio = { version = "1.49.0", features = ["full"] } +reqwest = { version = "0.13.1", features = ["json", "blocking"] } +serde_json = "1.0.149" [profile.dev] opt-level = 0 diff --git a/src/core/manifest.rs b/src/core/manifest.rs new file mode 100644 index 0000000..1450e77 --- /dev/null +++ b/src/core/manifest.rs @@ -0,0 +1,31 @@ +use serde::Deserialize; +use std::error::Error; + +#[derive(Debug, Deserialize)] +pub struct VersionManifest { + pub latest: Latest, + pub versions: Vec<Version>, +} + +#[derive(Debug, Deserialize)] +pub struct Latest { + pub release: String, + pub snapshot: String, +} + +#[derive(Debug, Deserialize)] +pub struct Version { + pub id: String, + #[serde(rename = "type")] + pub type_: String, + pub url: String, + pub time: String, + #[serde(rename = "releaseTime")] + pub release_time: String, +} + +pub async fn fetch_version_manifest() -> Result<VersionManifest, Box<dyn Error>> { + let url = "https://piston-meta.mojang.com/mc/game/version_manifest_v2.json"; + let resp = reqwest::get(url).await?.json::<VersionManifest>().await?; + Ok(resp) +} diff --git a/src/core/mod.rs b/src/core/mod.rs new file mode 100644 index 0000000..640fc64 --- /dev/null +++ b/src/core/mod.rs @@ -0,0 +1 @@ +pub mod manifest; diff --git a/src/main.rs b/src/main.rs index 31e87da..9161263 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,39 @@ +mod core; mod launcher; mod ui; +use tokio::sync::mpsc; +use tokio::runtime::Runtime; +use std::thread; + fn main() { - // 初始化UI模块 - ui::init(); + // channel for UI -> Backend + let (tx, mut rx) = mpsc::channel(32); + + // Spawn Tokio runtime in a background thread + thread::spawn(move || { + let rt = Runtime::new().unwrap(); + rt.block_on(async move { + println!("Backend started"); + while let Some(msg) = rx.recv().await { + match msg { + ui::UiEvent::StartGame => { + println!("Backend received StartGame"); + match core::manifest::fetch_version_manifest().await { + Ok(manifest) => { + println!("Fetched manifest. Latest release: {}", manifest.latest.release); + println!("Latest snapshot: {}", manifest.latest.snapshot); + } + Err(e) => { + eprintln!("Error fetching manifest: {}", e); + } + } + } + } + } + }); + }); - // 启动器模块的逻辑 - launcher::start(); -}
\ No newline at end of file + // Run UI on main thread (must be main thread for GTK on some platforms) + ui::init(tx); +} diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 778eeee..3ee1e6a 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1,7 +1,12 @@ use gtk::prelude::*; use gtk::{Button, Window, WindowType}; +use tokio::sync::mpsc::Sender; -pub fn init() { +pub enum UiEvent { + StartGame, +} + +pub fn init(tx: Sender<UiEvent>) { if gtk::init().is_err() { println!("Failed to initialize GTK."); return; @@ -12,8 +17,13 @@ pub fn init() { window.set_default_size(350, 70); let button = Button::with_label("开始游戏"); - button.connect_clicked(|_| { + let tx_clone = tx.clone(); + button.connect_clicked(move |_| { println!("开始游戏按钮被点击"); + // Use blocking_send because we are in a synchronous callback + if let Err(e) = tx_clone.blocking_send(UiEvent::StartGame) { + eprintln!("Failed to send event: {}", e); + } }); window.add(&button); @@ -26,4 +36,4 @@ pub fn init() { window.show_all(); gtk::main(); -}
\ No newline at end of file +} |