-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathget_games.rs
More file actions
215 lines (178 loc) · 7.1 KB
/
Copy pathget_games.rs
File metadata and controls
215 lines (178 loc) · 7.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
use anyhow::{Ok, Result, bail};
use egui::Context;
use log::{debug, info};
use maxima::{core::{service_layer::{ServiceGame, ServiceGameHubCollection, ServiceGameImagesRequestBuilder, ServiceHeroBackgroundImageRequestBuilder, ServiceLayerClient, SERVICE_REQUEST_GAMEIMAGES, SERVICE_REQUEST_GETHEROBACKGROUNDIMAGE}, LockedMaxima}, util::native::maxima_dir};
use std::{fs, sync::mpsc::Sender};
use crate::{
bridge_thread::{InteractThreadGameListResponse, MaximaLibResponse}, ui_image::UIImageCacheLoaderCommand, GameDetailsWrapper, GameInfo
};
fn get_preferred_bg_hero(heroes: &Option<ServiceGameHubCollection>) -> Option<String> {
if heroes.is_none() {
return None
}
let bg = heroes.as_ref().unwrap().items().get(0);
if bg.is_none() {
return None;
}
let bg = bg.as_ref().unwrap().hero_background();
if let Some(img) = bg.aspect_10x3_image() {
return Some(img.path().clone());
}
if let Some(img) = bg.aspect_2x1_image() {
return Some(img.path().clone());
}
if let Some(img) = bg.aspect_16x9_image() {
return Some(img.path().clone());
}
None
}
async fn get_preferred_hero_image(images: &Option<ServiceGame>) -> Option<String> {
if images.is_none() {
return None;
}
let key_art = images.as_ref().unwrap().key_art();
if key_art.is_none() {
return None;
}
let key_art = key_art.as_ref().unwrap();
debug!("{:?}", key_art);
if let Some(img) = key_art.aspect_10x3_image() {
return Some(img.path().clone());
}
if let Some(img) = key_art.aspect_2x1_image() {
return Some(img.path().clone());
}
if let Some(img) = key_art.aspect_16x9_image() {
return Some(img.path().clone());
}
None
}
fn get_logo_image(images: &Option<ServiceGame>) -> Option<String> {
if images.is_none() {
return None;
}
let logo_set = images.as_ref().unwrap().primary_logo();
if logo_set.is_none() {
return None;
}
let largest_logo = logo_set.as_ref().unwrap().largest_image();
if largest_logo.is_none() {
return None;
}
Some(largest_logo.as_ref().unwrap().path().to_string())
}
async fn handle_images(slug: String, locale: String, has_hero: bool, has_logo: bool, channel: Sender<UIImageCacheLoaderCommand>, service_layer: ServiceLayerClient) -> Result<()> {
debug!("handling image downloads for {}", &slug);
let g_images = if has_hero && has_logo { None } else {
service_layer
.request(SERVICE_REQUEST_GAMEIMAGES, ServiceGameImagesRequestBuilder::default()
.should_fetch_context_image(!has_logo)
.should_fetch_backdrop_images(!has_hero)
.game_slug(slug.clone())
.locale(locale.clone())
.build()?).await?
};
if !has_hero {
if let Some(hero) = get_preferred_hero_image(&g_images).await {
channel.send(UIImageCacheLoaderCommand::ProvideRemote(crate::ui_image::UIImageType::Hero(slug.clone()), hero)).unwrap()
}
}
if !has_logo {
if let Some(logo) = get_logo_image(&g_images) {
channel.send(UIImageCacheLoaderCommand::ProvideRemote(crate::ui_image::UIImageType::Logo(slug), logo))?
} else {
channel.send(UIImageCacheLoaderCommand::Stub(crate::ui_image::UIImageType::Logo(slug)))?
}
}
Ok(())
}
pub async fn get_games_request(
maxima_arc: LockedMaxima,
channel: Sender<MaximaLibResponse>,
channel1: Sender<UIImageCacheLoaderCommand>,
ctx: &Context,
) -> Result<()> {
debug!("recieved request to load games");
let mut maxima = maxima_arc.lock().await;
let service_layer = maxima.service_layer().clone();
let locale = maxima.locale().short_str().to_owned();
let logged_in = maxima.auth_storage().lock().await.current().is_some();
if !logged_in {
bail!("Ignoring request to load games, not logged in.");
}
let owned_games = maxima.mut_library().games().await;
if owned_games.len() <= 0 {
return Ok(());
}
for game in owned_games {
let slug = game.base_offer().slug().clone();
info!("processing {}", &slug);
// it'd be better if we could do this in the task but by then the info is long gone
let h_images: Option<ServiceGameHubCollection> = {
service_layer.request(SERVICE_REQUEST_GETHEROBACKGROUNDIMAGE,
ServiceHeroBackgroundImageRequestBuilder::default()
.game_slug(slug.clone())
.locale(locale.clone())
.build()?).await?
};
let game_info = GameInfo {
slug: slug.clone(),
offer: game.base_offer().offer().offer_id().to_string(),
name: game.name(),
details: GameDetailsWrapper::Unloaded,
bg_video: if let Some(imgs) = &h_images {
if let Some(vid) = imgs.items().get(0).unwrap().background_video() {
vid.url().clone()
} else { None }
} else { None },
dlc: game.extra_offers().clone(),
installed: game.base_offer().installed().await,
has_cloud_saves: game.base_offer().offer().has_cloud_save(),
};
let settings = crate::GameSettings {
//TODO: eventually support cloud saves, the option is here for that but for now, keep it disabled in ui!
cloud_saves: true,
launch_args: String::new(),
exe_override: String::new(),
};
let res = MaximaLibResponse::GameInfoResponse(InteractThreadGameListResponse {
game: game_info,
settings
});
channel.send(res)?;
let background_hero = maxima_dir()
.unwrap()
.join("cache/ui/images/")
.join(&slug)
.join("background.jpg");
let game_hero = maxima_dir()
.unwrap()
.join("cache/ui/images/")
.join(&slug)
.join("hero.jpg");
let game_logo = maxima_dir()
.unwrap()
.join("cache/ui/images/")
.join(&slug)
.join("logo.png");
let has_hero = fs::metadata(&game_hero).is_ok();
let has_logo = fs::metadata(&game_logo).is_ok();
let has_background = fs::metadata(&background_hero).is_ok();
if !has_hero || !has_logo{
//we're like 20 tasks deep i swear but this shit's gonna be real fast, trust
let slug_send = slug.clone();
let locale_send = locale.clone();
let channel_send = channel1.clone();
let service_layer_send = service_layer.clone();
tokio::task::spawn(async move { handle_images(slug_send, locale_send, has_hero, has_logo, channel_send, service_layer_send).await });
tokio::task::yield_now().await;
}
if !has_background {
if let Some(background_image) = get_preferred_bg_hero(&h_images) {
channel1.send(UIImageCacheLoaderCommand::ProvideRemote(crate::ui_image::UIImageType::Background(slug.clone()), background_image)).unwrap()
}
}
egui::Context::request_repaint(&ctx);
}
Ok(())
}