X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=addon.c;h=29b24a020ba59bf01fba14f3c3fc17f8d564d623;hb=9fb26bfce5b8130703a8c31818783912c2b3dfac;hp=aa9c00e0f68e84c4188fc212864173ac53defa87;hpb=fee9867cee40c393a7142178039e8bcda964e004;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/addon.c b/addon.c index aa9c00e..29b24a0 100644 --- a/addon.c +++ b/addon.c @@ -127,7 +127,7 @@ VG_STATIC int addon_try_load_metadata( addon_reg *reg, vg_str folder_path ){ return 1; } -VG_STATIC void addon_mount_finish( addon_reg *reg ){ +VG_STATIC void addon_print_info( addon_reg *reg ){ vg_info( "addon_reg #%u{\n", addon_system.registry_count ); vg_info( " type: %d\n", reg->type ); vg_info( " workshop_id: " PRINTF_U64 "\n", reg->workshop_id ); @@ -135,57 +135,121 @@ VG_STATIC void addon_mount_finish( addon_reg *reg ){ vg_info( " metadata_len: %u\n", reg->metadata_len ); vg_info( " userdata: %p\n", reg->userdata ); vg_info( "}\n" ); +} +VG_STATIC void addon_mount_finish( addon_reg *reg ){ addon_system.registry_count ++; } /* * Mount a fully packaged addon, one that certainly has a addon.inf */ -VG_STATIC void addon_mount_workshop_folder( PublishedFileId_t workshop_id, - vg_str folder_path ) +VG_STATIC addon_reg *addon_mount_workshop_folder( PublishedFileId_t workshop_id, + vg_str folder_path ) { addon_reg *reg = addon_alloc_reg( workshop_id, k_workshop_file_type_none ); - if( !reg ) return; + if( !reg ) return NULL; if( !addon_try_load_metadata( reg, folder_path ) ){ - return; + return NULL; } - /* TODO: we definitely need a different, robust interface for this - * - * msg_frame f = msg_get_frame( hello ) - * msg_kv kv = get_kv( f, "" ); - * if( kv.type == unsigned ) - * ... - */ - enum workshop_file_type type = k_workshop_file_type_none; - vg_msg msg; - vg_msg_init( &msg, reg->metadata, reg->metadata_len ); - vg_msg_cmd cmd; - while( vg_msg_next( &msg, &cmd ) ){ - if( (msg.depth == 1) && (cmd.code == k_vg_msg_code_frame) ){ - if( VG_STRDJB2_EQ( "workshop", cmd.key, cmd.key_djb2 ) ){ - u32 depth = msg.depth; - while( (msg.depth == depth) && vg_msg_next( &msg, &cmd ) ){ - if( cmd.code & k_vg_msg_code_unsigned ){ - if( VG_STRDJB2_EQ( "type", cmd.key, cmd.key_djb2 ) ){ - type = cmd.value._u32; - } - } - } - } + vg_msg root; + vg_msg_init( &root, reg->metadata, reg->metadata_len ); + vg_msg workshop = root; + if( vg_msg_seekframe( &workshop, "workshop", k_vg_msg_first )){ + vg_msg_cmd kv_type = vg_msg_seekkv( &workshop, "type", k_vg_msg_first ); + if( kv_type.code & k_vg_msg_code_integer ){ + type = kv_type.value._u32; } } if( type == k_workshop_file_type_none ){ vg_error( "Cannot determine addon type\n" ); - return; + return NULL; } reg->type = type; addon_mount_finish( reg ); + return reg; +} + +/* + * Mount a local folder. may or may not have addon.inf + */ +VG_STATIC addon_reg *addon_mount_local_addon( const char *folder, + enum workshop_file_type type, + const char *content_ext ) +{ + char folder_path_buf[4096]; + vg_str folder_path; + vg_strnull( &folder_path, folder_path_buf, 4096 ); + vg_strcat( &folder_path, folder ); + + const char *folder_name = vg_strch( &folder_path, '/' ); + u32 folder_hash = vg_strdjb2(folder_name); + for( u32 i=0; itype == type) && (reg->foldername_hash == folder_hash) ){ + if( !strcmp( reg->foldername, folder_name ) ){ + reg->state = k_addon_state_indexed; + return NULL; + } + } + } + + addon_reg *reg = addon_alloc_reg( 0, type ); + if( !reg ) return NULL; + addon_set_foldername( reg, folder_name ); + addon_try_load_metadata( reg, folder_path ); + + if( reg->metadata_len == 0 ){ + /* create our own content commands */ + vg_msg msg; + vg_msg_init( &msg, reg->metadata, sizeof(reg->metadata) ); + + u32 content_count = 0; + + vg_strcat( &folder_path, "" ); + vg_warn( "Creating own metadata for: %s\n", folder_path.buffer ); + + vg_dir subdir; + if( !vg_dir_open(&subdir, folder_path.buffer) ){ + vg_error( "Failed to open '%s'\n", folder_path.buffer ); + return NULL; + } + + while( vg_dir_next_entry(&subdir) ){ + if( vg_dir_entry_type(&subdir) == k_vg_entry_type_file ){ + const char *fname = vg_dir_entry_name(&subdir); + vg_str file = folder_path; + vg_strcat( &file, "/" ); + vg_strcat( &file, fname ); + if( !vg_strgood( &file ) ) continue; + + char *ext = vg_strch( &file, '.' ); + if( !ext ) continue; + if( strcmp(ext,content_ext) ) continue; + + vg_msg_wkvstr( &msg, "content", fname ); + content_count ++; + } + } + vg_dir_close(&subdir); + + if( !content_count ) return NULL; + if( msg.error == k_vg_msg_error_OK ) + reg->metadata_len = msg.cur; + else{ + vg_error( "Error creating metadata: %d\n", msg.error ); + return NULL; + } + } + + addon_mount_finish( reg ); + return reg; } /* @@ -221,8 +285,6 @@ VG_STATIC void addon_mount_workshop_items(void){ } } - /* new one, lets find out what type it is - * ---------------------------------------------------------------*/ vg_async_item *call1 = vg_async_alloc( sizeof(struct async_workshop_filepath_info) ); @@ -245,9 +307,9 @@ next_file_workshop:; * Scan a local content folder for addons. It must find at least one file with * the specified content_ext to be considered. */ -VG_STATIC void addon_mount_local_folder( enum workshop_file_type type, - const char *base_folder, - const char *content_ext ) +VG_STATIC void addon_mount_content_folder( enum workshop_file_type type, + const char *base_folder, + const char *content_ext ) { vg_info( "Mounting addons(type:%d) matching skaterift/%s/*/*%s\n", type, base_folder, content_ext ); @@ -271,8 +333,6 @@ VG_STATIC void addon_mount_local_folder( enum workshop_file_type type, const char *d_name = vg_dir_entry_name(&dir); vg_str folder = path; - char *folder_name = folder.buffer+folder.i; - if( strlen( d_name ) > ADDON_FOLDERNAME_MAX ){ vg_warn( "folder too long: %s\n", d_name ); continue; @@ -281,97 +341,10 @@ VG_STATIC void addon_mount_local_folder( enum workshop_file_type type, vg_strcat( &folder, d_name ); if( !vg_strgood( &folder ) ) continue; - int present = 0; - u32 folder_hash = vg_strdjb2(folder_name); - for( u32 i=0; itype == type) && (reg->foldername_hash == folder_hash) ){ - if( !strcmp( reg->foldername, folder_name ) ){ - reg->state = k_addon_state_indexed; - present = 1; - break; - } - } - } - - if( !present ){ - addon_reg *reg = addon_alloc_reg( 0, type ); - if( !reg ) continue; - addon_set_foldername( reg, folder_name ); - addon_try_load_metadata( reg, folder ); - - if( reg->metadata_len == 0 ){ - /* create our own content commands */ - vg_msg msg; - vg_msg_init( &msg, reg->metadata, sizeof(reg->metadata) ); - - u32 content_count = 0; - - vg_strcat( &folder, "" ); - vg_warn( "Creating own metadata for: %s\n", folder.buffer ); - - vg_dir subdir; - if( !vg_dir_open(&subdir, folder.buffer) ){ - vg_error( "Failed to open '%s'\n", folder.buffer ); - continue; - } - - while( vg_dir_next_entry(&subdir) ){ - if( vg_dir_entry_type(&subdir) == k_vg_entry_type_file ){ - const char *fname = vg_dir_entry_name(&subdir); - vg_str file = folder; - vg_strcat( &file, "/" ); - vg_strcat( &file, fname ); - if( !vg_strgood( &file ) ) continue; - - char *ext = vg_strch( &file, '.' ); - if( !ext ) continue; - if( strcmp(ext,content_ext) ) continue; - - vg_msg_wkvstr( &msg, "content", fname ); - content_count ++; - } - } - vg_dir_close(&subdir); - - if( !content_count ){ - continue; - } - - if( msg.error == k_vg_msg_error_OK ) - reg->metadata_len = msg.cur; - else{ - vg_error( "Error creating metadata: %d\n", msg.error ); - continue; - } - } - - addon_mount_finish( reg ); - } + addon_mount_local_addon( folder.buffer, type, content_ext ); } } vg_dir_close(&dir); } -#if 0 -/* - * Async thread which scans local files for addons, as well as scheduling - * synchronous calls to the workshop - * - * Call this from in the loader thread. - */ -VG_STATIC void addon_system_scan_all(void){ - for( u32 i=0; istate = k_addon_state_indexed_absent; - } - - if( steam_ready ) addon_mount_workshop_items(); - - vg_async_call( addon_async_reg_update, NULL, 0 ); - vg_async_stall(); -} -#endif - #endif /* ADDON_C */