1- use std:: path:: { Path , PathBuf } ;
1+ use std:: { path:: Path , sync :: Arc } ;
22
3- use futures:: { StreamExt , future:: join_all} ;
3+ use futures:: { FutureExt , StreamExt , future:: join_all} ;
44use image:: { create_image_decoder, parse_image_data} ;
55use mongodb:: bson:: doc;
66use rocket:: { Build , Data , Rocket , State , data:: ToByteUnit , fs:: FileServer , serde:: json:: Json } ;
7+ use tokio:: sync:: RwLock ;
78use tokio_util:: codec:: FramedRead ;
89
910use crate :: { MarsAPIState , database:: { Database , models:: level:: { Level , LevelRecords } } , http:: map:: payload:: MapLoadOneRequest , util:: { auth:: AuthorizationToken , error:: ApiErrorResponder , r#macro:: unwrap_helper, stream:: LengthPrefixedDataDecoder , time:: get_u64_time_millis} } ;
@@ -17,14 +18,16 @@ async fn add_maps(
1718 maps : Json < Vec < MapLoadOneRequest > > ,
1819 _auth_guard : AuthorizationToken
1920) -> Json < Vec < Level > > {
20- let mut map_list = maps. 0 ;
21- debug ! ( "maps incoming are {:?}" , & map_list) ;
21+ let map_list = maps. 0 ;
2222 let map_list_length = map_list. len ( ) ;
2323 let time_millis = get_u64_time_millis ( ) ;
2424 let mut maps_to_save : Vec < Level > = Vec :: new ( ) ;
2525
2626 let query_tasks : Vec < _ > = map_list. iter ( ) . map ( |map| {
27- state. database . find_by_name :: < Level > ( & map. name )
27+ state. database . find_by_fields :: < Level > (
28+ map. slug . as_ref ( ) . unwrap_or ( & map. name ) ,
29+ vec ! [ String :: from( "slug" ) , String :: from( "nameLower" ) ]
30+ )
2831 } ) . collect ( ) ;
2932 let level_docs = join_all ( query_tasks) . await ;
3033 for ( map, level_opt) in map_list. into_iter ( ) . zip ( level_docs) {
@@ -44,6 +47,7 @@ async fn add_maps(
4447 id : map. id ,
4548 name : map. name ,
4649 name_lower : lowercase_map_name,
50+ slug : map. slug ,
4751 version : map. version ,
4852 gamemodes : map. gamemodes ,
4953 loaded_at : time_millis,
@@ -57,8 +61,23 @@ async fn add_maps(
5761 } ) ;
5862 }
5963
60- let save_tasks : Vec < _ > = maps_to_save. iter ( ) . map ( |map| { state. database . save ( map) } ) . collect ( ) ;
61- join_all ( save_tasks) . await ;
64+
65+ let tasks = {
66+ let mut all_tasks = Vec :: new ( ) ;
67+ let save_tasks : Vec < _ > =
68+ maps_to_save. iter ( ) . map ( |map| { state. database . save ( map) . boxed ( ) } ) . collect ( ) ;
69+ let update_map_state = {
70+ let rwlock = state. map_state . last_update . clone ( ) ;
71+ async move {
72+ let mut timestamp = rwlock. write ( ) . await ;
73+ * timestamp = time_millis;
74+ } . boxed ( )
75+ } ;
76+ all_tasks. extend ( save_tasks) ;
77+ all_tasks. push ( update_map_state) ;
78+ all_tasks
79+ } ;
80+ join_all ( tasks) . await ;
6281
6382 info ! ( "Received {} maps. Updating {} maps." , map_list_length, maps_to_save. len( ) ) ;
6483 Json ( state. database . get_all_documents ( ) . await )
@@ -97,7 +116,7 @@ async fn add_map_images(
97116
98117#[ get( "/" ) ]
99118async fn get_all_maps ( state : & State < MarsAPIState > ) -> Json < Vec < Level > > {
100- Json ( state. database . get_all_documents :: < Level > ( ) . await )
119+ Json ( state. database . get_all_active_maps ( * state . map_state . last_update . read ( ) . await ) . await )
101120}
102121
103122#[ get( "/<map_id>" ) ]
@@ -106,15 +125,9 @@ async fn get_map_by_id(state: &State<MarsAPIState>, map_id: &str) -> Result<Json
106125 Ok ( Json ( map) )
107126}
108127
109- fn get_map_images_directory ( state : & State < MarsAPIState > ) -> Option < PathBuf > {
110- match state. config . options . images_path . as_ref ( ) {
111- Some ( path) => {
112- let mut p = PathBuf :: new ( ) ;
113- p. push ( path) ;
114- Some ( p)
115- } ,
116- None => None
117- }
128+ #[ derive( Clone ) ]
129+ pub struct MapState {
130+ pub last_update : Arc < RwLock < u64 > >
118131}
119132
120133pub fn mount ( build : Rocket < Build > , state : & MarsAPIState ) -> Rocket < Build > {
0 commit comments