aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml13
-rw-r--r--src/core/manifest.rs31
-rw-r--r--src/core/mod.rs1
-rw-r--r--src/main.rs39
-rw-r--r--src/ui/mod.rs16
5 files changed, 87 insertions, 13 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 82ec8c2..18f5ebb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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
+}