forked from RabbyDevs/rooms-launcher
174 lines
No EOL
5.9 KiB
Rust
174 lines
No EOL
5.9 KiB
Rust
use std::{fs::DirEntry, io::{Cursor, Write}, sync::Arc};
|
|
|
|
use directories::ProjectDirs;
|
|
use file_format::FileFormat;
|
|
use iced_video_player::Video;
|
|
use ::image::{DynamicImage, ImageReader};
|
|
use iced::{gradient, widget::container, Color};
|
|
use tempfile::NamedTempFile;
|
|
|
|
use crate::{LauncherBackground, PossibleGames};
|
|
|
|
use super::img_utils::round_image;
|
|
|
|
pub fn get_game_background(game: &PossibleGames) -> LauncherBackground {
|
|
let proj_dirs = ProjectDirs::from("com", "RabbyDevs", "rr-launcher").unwrap();
|
|
let background_bytes = get_background_file(&proj_dirs, game).unwrap();
|
|
let data = Arc::new(background_bytes);
|
|
let file_format = FileFormat::from_bytes(&*data);
|
|
|
|
if file_format.extension() == "mp4" {
|
|
let mut temp_file = NamedTempFile::new().unwrap();
|
|
temp_file.write_all(&data).unwrap();
|
|
|
|
let temp_path = temp_file.path().to_str().unwrap().to_string();
|
|
match Video::new(url::Url::from_file_path(temp_path).unwrap()) {
|
|
Ok(mut video) => {
|
|
video.set_looping(true);
|
|
LauncherBackground::Video(video)
|
|
},
|
|
Err(err) => {
|
|
panic!("{:#?}", err)
|
|
},
|
|
}
|
|
} else {
|
|
let img = ImageReader::new(Cursor::new(&*data))
|
|
.with_guessed_format()
|
|
.unwrap()
|
|
.decode()
|
|
.unwrap();
|
|
LauncherBackground::Image(img)
|
|
}
|
|
}
|
|
|
|
fn get_background_file(proj_dirs: &ProjectDirs, game: &PossibleGames) -> Result<Vec<u8>, std::io::Error> {
|
|
let game_dir = match game {
|
|
PossibleGames::WutheringWaves => proj_dirs.data_dir().join("kuro/wuwa"),
|
|
PossibleGames::ZenlessZoneZero => proj_dirs.data_dir().join("hoyoverse/zzz"),
|
|
PossibleGames::HonkaiStarRail => proj_dirs.data_dir().join("hoyoverse/hsr"),
|
|
PossibleGames::GenshinImpact => proj_dirs.data_dir().join("hoyoverse/gi"),
|
|
};
|
|
|
|
if !game_dir.exists() {
|
|
return Err(std::io::Error::new(
|
|
std::io::ErrorKind::NotFound,
|
|
format!("Game directory does not exist: {:?}", game_dir)
|
|
));
|
|
}
|
|
|
|
let entries = std::fs::read_dir(&game_dir)?;
|
|
|
|
for entry in entries {
|
|
let entry = entry?;
|
|
let file_name = entry.file_name().into_string().unwrap_or_default();
|
|
|
|
if file_name.starts_with("background_") {
|
|
return std::fs::read(entry.path());
|
|
}
|
|
}
|
|
|
|
Err(std::io::Error::new(
|
|
std::io::ErrorKind::NotFound,
|
|
format!("No background file found in {:?}", game_dir)
|
|
))
|
|
}
|
|
|
|
pub fn get_game_splash_dynamic_image(game: &PossibleGames) -> Option<DynamicImage> {
|
|
let proj_dirs = ProjectDirs::from("com", "RabbyDevs", "rr-launcher").unwrap();
|
|
let file_data = get_splash_file(&proj_dirs, game);
|
|
if let Some(data) = file_data {
|
|
let data_cursor = Cursor::new(data);
|
|
|
|
Some(ImageReader::new(data_cursor)
|
|
.with_guessed_format()
|
|
.unwrap()
|
|
.decode()
|
|
.unwrap())
|
|
} else {None}
|
|
}
|
|
|
|
pub fn get_game_icon_dynamic_image(game: &PossibleGames) -> DynamicImage {
|
|
let proj_dirs = ProjectDirs::from("com", "RabbyDevs", "rr-launcher").unwrap();
|
|
let file_data: &[u8] = match game {
|
|
PossibleGames::WutheringWaves => include_bytes!("../../resources/wutheringwaves-icon.png"),
|
|
PossibleGames::ZenlessZoneZero => &get_hoyo_game_icon_file(&proj_dirs, game),
|
|
PossibleGames::HonkaiStarRail => &get_hoyo_game_icon_file(&proj_dirs, game),
|
|
PossibleGames::GenshinImpact => &get_hoyo_game_icon_file(&proj_dirs, game),
|
|
};
|
|
|
|
let data_cursor = Cursor::new(file_data);
|
|
|
|
let img = ImageReader::new(data_cursor)
|
|
.with_guessed_format()
|
|
.unwrap()
|
|
.decode()
|
|
.unwrap()
|
|
.resize(128, 128, ::image::imageops::FilterType::Lanczos3);
|
|
|
|
round_image(img)
|
|
.unwrap()
|
|
}
|
|
|
|
fn get_hoyo_game_icon_file(proj_dirs: &ProjectDirs, game: &PossibleGames) -> Vec<u8> {
|
|
let game_abbrevation = match game {
|
|
PossibleGames::ZenlessZoneZero => "zzz",
|
|
PossibleGames::HonkaiStarRail => "hsr",
|
|
PossibleGames::GenshinImpact => "gi",
|
|
_ => panic!("Wuwa inputted in hoyo only func")
|
|
};
|
|
|
|
let data_dir = proj_dirs.data_dir().join(format!("hoyoverse/{}", game_abbrevation));
|
|
let icon: Option<DirEntry> = {
|
|
let mut icon = None;
|
|
for path in data_dir.read_dir().unwrap() {
|
|
let path = path.unwrap();
|
|
if path.file_name().into_string().unwrap().starts_with("icon_") {
|
|
icon = Some(path);
|
|
}
|
|
}
|
|
icon
|
|
};
|
|
|
|
std::fs::read(icon.expect("installation went wrong.").path()).unwrap()
|
|
}
|
|
|
|
fn get_splash_file(proj_dirs: &ProjectDirs, game: &PossibleGames) -> Option<Vec<u8>> {
|
|
let game_path = match game {
|
|
PossibleGames::ZenlessZoneZero => "hoyoverse/zzz",
|
|
PossibleGames::HonkaiStarRail => "hoyoverse/hsr",
|
|
PossibleGames::GenshinImpact => "hoyoverse/gi",
|
|
PossibleGames::WutheringWaves => "kuro/wuwa"
|
|
};
|
|
|
|
let data_dir = proj_dirs.data_dir().join(game_path);
|
|
let icon: Option<DirEntry> = {
|
|
let mut icon = None;
|
|
for path in data_dir.read_dir().unwrap() {
|
|
let path = path.unwrap();
|
|
if path.file_name().into_string().unwrap().starts_with("splash_") {
|
|
icon = Some(path);
|
|
}
|
|
}
|
|
icon
|
|
};
|
|
|
|
icon.map(|icon| std::fs::read(icon.path()).unwrap())
|
|
}
|
|
|
|
fn rad(deg: f32) -> f32 {
|
|
deg * std::f32::consts::PI / 180.0
|
|
}
|
|
|
|
pub fn style_container(direction: f32, use_gradient: bool) -> container::Style {
|
|
let angle = rad(direction);
|
|
let gradient: Option<iced::Background> = if use_gradient {
|
|
Some(gradient::Linear::new(angle)
|
|
.add_stop(0.0, Color::from_rgba8(0, 0, 0, 0.0))
|
|
.add_stop(0.75, Color::from_rgba8(0, 0, 0, 0.75)).into())
|
|
} else {None};
|
|
container::Style {
|
|
text_color: Color::from_rgba8(255, 255, 255, 1.0).into(),
|
|
background: gradient,
|
|
..container::Style::default()
|
|
}
|
|
} |