X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=addon.c;h=7ebd165756645a7979a06efdbb3377006143570f;hb=fbc68c65e01838feb77f47b30994b45fcc39ebaf;hp=7e03050c9435f8d6e20ffde6314dc77f58e5c147;hpb=22f62f001f21d1b91fefd9fc495c122d9ddf205a;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/addon.c b/addon.c index 7e03050..7ebd165 100644 --- a/addon.c +++ b/addon.c @@ -7,16 +7,40 @@ #include "steam.h" #include "workshop.h" -static u32 addon_count( enum addon_type type ){ - return addon_system.registry_type_counts[ type ]; +static u32 addon_count( enum addon_type type, u32 ignoreflags ){ + if( ignoreflags ){ + u32 typecount = 0, count = 0; + for( u32 i=0; typecountalias.type == type ){ + typecount ++; + + if( reg->flags & ignoreflags ) + continue; + + count ++; + } + } + + return count; + } + else + return addon_system.registry_type_counts[ type ]; } + /* these kind of suck, oh well. */ -static addon_reg *get_addon_from_index(enum addon_type type, u32 index){ - u32 count = 0; - for( u32 i=0; countalias.type == type ){ + typecount ++; + + if( reg->flags & ignoreflags ) + continue; + if( index == count ) return reg; @@ -43,7 +67,11 @@ static u32 get_index_from_addon( enum addon_type type, addon_reg *a ){ } static u32 addon_match( addon_alias *alias ){ - u32 foldername_djb2 = vg_strdjb2( alias->foldername ); + if( alias->type == k_addon_type_none ) return 0xffffffff; + + u32 foldername_djb2 = 0; + if( !alias->workshop_id ) + foldername_djb2 = vg_strdjb2( alias->foldername ); u32 count = 0; for( u32 i=0; counttype]; i++ ){ @@ -69,7 +97,10 @@ static u32 addon_match( addon_alias *alias ){ return 0xffffffff; } -static void addon_alias_uid( addon_alias *alias, char buf[76] ){ +/* + * Create a string version of addon alias in buf + */ +static void addon_alias_uid( addon_alias *alias, char buf[ADDON_UID_MAX] ){ if( alias->workshop_id ){ snprintf( buf, 128, "sr%03d-steam-"PRINTF_U64, alias->type, alias->workshop_id ); @@ -80,6 +111,76 @@ static void addon_alias_uid( addon_alias *alias, char buf[76] ){ } } +/* + * equality check + */ +static int addon_alias_eq( addon_alias *a, addon_alias *b ){ + if( a->type == b->type ){ + if( a->workshop_id == b->workshop_id ){ + if( a->workshop_id ) + return 1; + else + return !strcmp( a->foldername, b->foldername ); + } + else + return 0; + } + else return 0; +} + +/* + * make alias represent NULL. + */ +static void invalidate_addon_alias( addon_alias *alias ){ + alias->type = k_addon_type_none; + alias->workshop_id = 0; + alias->foldername[0] = '\0'; +} + +/* + * parse uid to alias. returns 1 if successful + */ +static int addon_uid_to_alias( const char *uid, addon_alias *alias ){ +/* 1 + * 01234567890123 + * sr&&&-@@@@@-#* + * | | | + * type | id + * | + * location + */ + if( strlen(uid) < 13 ){ + invalidate_addon_alias( alias ); + return 0; + } + if( !((uid[0] == 's') && (uid[1] == 'r')) ){ + invalidate_addon_alias( alias ); + return 0; + } + + char type[4]; + memcpy( type, uid+2, 3 ); + type[3] = '\0'; + alias->type = atoi(type); + + char location[6]; + memcpy( location, uid+6, 5 ); + location[5] = '\0'; + + if( !strcmp(location,"steam") ) + alias->workshop_id = atoll( uid+12 ); + else if( !strcmp(location,"local") ){ + alias->workshop_id = 0; + vg_strncpy( uid+12, alias->foldername, 64, k_strncpy_always_add_null ); + } + else{ + invalidate_addon_alias( alias ); + return 0; + } + + return 1; +} + static void addon_system_init( void ){ u32 reg_size = sizeof(addon_reg)*ADDON_MOUNTED_MAX; addon_system.registry = vg_linear_alloc( vg_mem.rtmemory, reg_size ); @@ -153,6 +254,7 @@ static addon_reg *addon_alloc_reg( PublishedFileId_t workshop_id, } addon_reg *reg = &addon_system.registry[ addon_system.registry_count ]; + reg->flags = 0; reg->metadata_len = 0; reg->cache_id = 0; reg->state = k_addon_state_indexed; @@ -229,14 +331,11 @@ static addon_reg *addon_mount_workshop_folder( PublishedFileId_t workshop_id, } enum addon_type type = k_addon_type_none; - vg_msg root = {0}; - root.buf = reg->metadata; - root.len = reg->metadata_len; - root.max = sizeof(reg->metadata); + vg_msg msg; + vg_msg_init( &msg, reg->metadata, reg->metadata_len ); - vg_msg workshop = root; - if( vg_msg_seekframe( &workshop, "workshop", k_vg_msg_first )){ - type = vg_msg_seekkvu32( &workshop, "type", k_vg_msg_first ); + if( vg_msg_seekframe( &msg, "workshop" )){ + type = vg_msg_getkvu32( &msg, "type", 0 ); } if( type == k_addon_type_none ){ @@ -281,10 +380,8 @@ static addon_reg *addon_mount_local_addon( const char *folder, if( reg->metadata_len == 0 ){ /* create our own content commands */ - vg_msg msg = {0}; - msg.buf = reg->metadata; - msg.len = 0; - msg.max = sizeof(reg->metadata); + vg_msg msg; + vg_msg_init( &msg, reg->metadata, sizeof(reg->metadata) ); u32 content_count = 0; @@ -317,7 +414,7 @@ static addon_reg *addon_mount_local_addon( const char *folder, if( !content_count ) return NULL; if( msg.error == k_vg_msg_error_OK ) - reg->metadata_len = msg.cur; + reg->metadata_len = msg.cur.co; else{ vg_error( "Error creating metadata: %d\n", msg.error ); return NULL; @@ -425,16 +522,30 @@ static void addon_mount_content_folder( enum addon_type type, /* * write the full path of the addon's folder into the vg_str */ -static int addon_get_content_folder( addon_reg *reg, vg_str *folder ){ +static int addon_get_content_folder( addon_reg *reg, vg_str *folder, int async){ if( reg->alias.workshop_id ){ - vg_async_item *call = - vg_async_alloc( sizeof(struct async_workshop_filepath_info) ); - struct async_workshop_filepath_info *info = call->payload; + struct async_workshop_filepath_info *info = NULL; + vg_async_item *call = NULL; + + if( async ){ + call = vg_async_alloc( sizeof(struct async_workshop_filepath_info) ); + info = call->payload; + } + else + info = alloca( sizeof(struct async_workshop_filepath_info) ); + info->buf = folder->buffer; info->id = reg->alias.workshop_id; info->len = folder->len; - vg_async_dispatch( call, async_workshop_get_filepath ); - vg_async_stall(); /* too bad! */ + + if( async ){ + vg_async_dispatch( call, async_workshop_get_filepath ); + vg_async_stall(); /* too bad! */ + } + else { + async_workshop_get_filepath( info, 0 ); + } + if( info->buf[0] == '\0' ){ vg_error( "Failed SteamAPI_GetItemInstallInfo(" PRINTF_U64 ")\n", reg->alias.workshop_id ); @@ -463,8 +574,8 @@ static int addon_get_content_folder( addon_reg *reg, vg_str *folder ){ static u16 addon_cache_fetch( enum addon_type type, u32 reg_index ){ addon_reg *reg = NULL; - if( reg_index < addon_count( type ) ){ - reg = get_addon_from_index( type, reg_index ); + if( reg_index < addon_count( type, 0 ) ){ + reg = get_addon_from_index( type, reg_index, 0 ); if( reg->cache_id ) return reg->cache_id; } @@ -482,8 +593,8 @@ static u16 addon_cache_alloc( enum addon_type type, u32 reg_index ){ struct addon_cache_entry *new_entry = vg_pool_item( &cache->pool, new_id ); addon_reg *reg = NULL; - if( reg_index < addon_count( type ) ) - reg = get_addon_from_index( type, reg_index ); + if( reg_index < addon_count( type, 0 ) ) + reg = get_addon_from_index( type, reg_index, 0 ); if( new_entry ){ if( new_entry->reg_ptr ) @@ -547,12 +658,10 @@ static int addon_cache_load_request( enum addon_type type, u16 id, * --------------------------------- */ vg_str content_path = folder; - vg_msg root = {0}; - root.buf = reg->metadata; - root.len = reg->metadata_len; - root.max = sizeof(reg->metadata); + vg_msg msg; + vg_msg_init( &msg, reg->metadata, reg->metadata_len ); - const char *kv_content = vg_msg_seekkvstr( &root, "content", 0 ); + const char *kv_content = vg_msg_getkvstr( &msg, "content" ); if( kv_content ){ vg_strcat( &content_path, "/" ); vg_strcat( &content_path, kv_content ); @@ -613,7 +722,7 @@ static void addon_cache_load_loop(void){ vg_info( "process cache load request (%u#%u, reg:%u)\n", type, id, entry->reg_index ); - if( entry->reg_index >= addon_count(type) ){ + if( entry->reg_index >= addon_count(type,0) ){ /* should maybe have a different value for this case */ entry->state = k_addon_cache_state_none; SDL_AtomicUnlock( &addon_system.sl_cache_using_resources ); @@ -623,12 +732,12 @@ static void addon_cache_load_loop(void){ SDL_AtomicUnlock( &addon_system.sl_cache_using_resources ); /* continue with the request */ - addon_reg *reg = get_addon_from_index( type, entry->reg_index ); + addon_reg *reg = get_addon_from_index( type, entry->reg_index, 0 ); entry->reg_ptr = reg; vg_str folder; vg_strnull( &folder, path_buf, 4096 ); - if( addon_get_content_folder( reg, &folder ) ){ + if( addon_get_content_folder( reg, &folder, 1 ) ){ if( addon_cache_load_request( type, id, reg, folder ) ){ vg_async_call( async_addon_setstate, entry, k_addon_cache_state_loaded ); @@ -678,6 +787,23 @@ static u16 addon_cache_create_viewer( enum addon_type type, u16 reg_id ){ return cache_id; } +static u16 addon_cache_create_viewer_from_uid( enum addon_type type, + char uid[ADDON_UID_MAX] ){ + addon_alias q; + if( !addon_uid_to_alias( uid, &q ) ) return 0; + if( q.type != type ) return 0; + + u32 reg_id = addon_match( &q ); + + if( reg_id == 0xffffffff ){ + vg_warn( "We dont have the addon '%s' installed.\n", uid ); + return 0; + } + else { + return addon_cache_create_viewer( type, reg_id ); + } +} + static void addon_cache_watch( enum addon_type type, u16 cache_id ){ if( !cache_id ) return;