-
Notifications
You must be signed in to change notification settings - Fork 106
Description
`mod args;
mod game_data;
mod hasher;
mod model;
mod dir;
mod listen_msg;
use std::{borrow::Cow, fs, path::PathBuf};
use rust_embed::RustEmbed;
use tao::{event::Event, event_loop::{ControlFlow, EventLoop}, window::WindowBuilder};
use wry::{http::Response, Error as WryError, WebView, WebViewBuilder};
use crate::{args::get_args, dir::get_base_dir, game_data::get_game_data_path, hasher::verify_and_cache_assets, listen_msg::listen_for_asset_ready_messages};
#[derive(RustEmbed)]
#[folder = "assets/"]
struct Asset;
//런처 보안 구조
/**일렉트론이 게임 시작하면 game_id, package_id 제공 -> 런처는 manifest기반 정보로 압축해제된 파일을 즉시 열고 해시 후 캐싱하고 바로 삭제
-> 동적으로 다운로드된 다른 파일들도 전부 적용 -> 그럼 한번만 보안검사 하고 더이상 보안검사 필요없음
-> 유저가 게임을 종료해도 어차피 게임을 다시 시작하면 또 동적 다운로드 및 검사 시작
*/
fn main() -> wry::Result<()> {
let (game_id, package_id) = match get_args() {
Some((game_id, package_id)) => (game_id, package_id),
None => {
eprintln!("❌ 실행 시 --game-id 와 --package-id 인자를 넘겨야 합니다.");
std::process::exit(1);
}
};
let asset_dir = get_base_dir()
.join(game_id.clone())
.join(package_id.clone());
let cache = verify_and_cache_assets(&asset_dir)
.map_err(|e| wry::Error::from(std::io::Error::new(std::io::ErrorKind::Other, e)))?;
// 2. index.html 경로 구성
let game_path = get_game_data_path(&game_id, &package_id);
let index_path = game_path.join("index.html");
// 3. HTML 파일 읽기
let html_content = fs::read_to_string(&index_path).unwrap_or_else(|err| {
eprintln!("❌ index.html 로드 실패: {}\n 경로 : {}", err, &index_path.to_string_lossy());
std::process::exit(1);
});
std::thread::spawn(move || {
listen_for_asset_ready_messages();
});
// 4. WebView 초기화
let event_loop = EventLoop::new();
let window = WindowBuilder::new().with_title("Rust Game Launcher").build(&event_loop).expect("윈도우 생성 실패");
let _webview: WebView = WebViewBuilder::new(&window)
.with_html(&html_content)
.with_custom_protocol("game".to_string(), move |request| {
print!("aaaa");
let uri: String = request.uri().to_string().replace("game://", "");
let file_path = PathBuf::from(&uri);
if let Some(buffer) = cache.get(&uri) {
let content_type = if uri.ends_with("./js") {
"application/javascript"
} else {
"application/octet-stream"
};
Response::builder()
.status(200)
.header("Content-Type", content_type)
.header(
wry::http::header::ACCESS_CONTROL_ALLOW_ORIGIN,
wry::http::HeaderValue::from_static("*"),
)
.body(Cow::Owned(buffer.clone()))
.expect("failed to build cached response")
} else {
let full_path = asset_dir.join(file_path);
let content = fs::read(&full_path).unwrap_or_else(|_| b"Not Found".to_vec());
let content_type = if uri.ends_with(".glb") {
"model/gltf-binary"
} else {
"application/octet-stream"
};
let status = if content == b"Not Found".to_vec() { 404 } else { 200 };
Response::builder()
.status(status)
.header("Content-Type", content_type)
.header(
wry::http::header::ACCESS_CONTROL_ALLOW_ORIGIN,
wry::http::HeaderValue::from_static("*"),
)
.body(Cow::Owned(content))
.expect("failed to build disk file response")
}
})
.build()?;
// 5. 이벤트 루프 실행
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Wait;
if let Event::WindowEvent { .. } = event {
// 여기서 ESC나 윈도우 종료 감지해도 됨
}
});
}`
This is my code, but I have tried many different methods and I get this error over and over again: net::ERR_UNKNOWN_URL_SCHEME. I can't find a solution on the internet