From: hgn Date: Sat, 27 May 2023 04:18:58 +0000 (+0100) Subject: sorta ready X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=92ba950580dd4877935e90682cd4f66fead8fed2;hp=fee9867cee40c393a7142178039e8bcda964e004;p=carveJwlIkooP6JGAAIwe30JlM.git sorta ready --- 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 */ diff --git a/addon.h b/addon.h index d28db0c..65e88e1 100644 --- a/addon.h +++ b/addon.h @@ -40,10 +40,13 @@ static addon_reg *get_addon_from_index(enum workshop_file_type type, u32 index); static u32 get_index_from_addon( enum workshop_file_type type, addon_reg *a ); /* scanning routines */ -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_STATIC void addon_mount_workshop_items(void); VG_STATIC void async_addon_reg_update( void *data, u32 size ); +VG_STATIC addon_reg *addon_mount_local_addon( const char *folder, + enum workshop_file_type type, + const char *content_ext ); #endif /* ADDON_H */ diff --git a/build.c b/build.c index 6d3b521..6af9096 100644 --- a/build.c +++ b/build.c @@ -65,30 +65,27 @@ void build_game( enum compiler compiler ) vg_msg_wkvstr( &descriptor, "location", "USA" ); vg_msg_wkvstr( &descriptor, "content", "main.mdl" ); - if( descriptor.error == k_vg_msg_error_OK ){ - FILE *fp = fopen( "maps_src/mp_spawn/addon.inf", "wb" ); - fwrite( descriptor_buf, descriptor.cur, 1, fp ); - fclose( fp ); - - vg_msg recvtest; - vg_msg_init( &recvtest, descriptor_buf, descriptor.cur ); - - vg_msg_cmd cmd; - while( vg_msg_next( &recvtest, &cmd ) ){ - if( cmd.code == k_vg_msg_code_frame ){ - vg_info( "FRAME: [%u]%s\n", cmd.key_djb2, cmd.key ); - } - else if( cmd.code == k_vg_msg_code_endframe ){ - vg_info( "ENDFRAME\n" ); - } - else if( cmd.code == k_vg_msg_code_kvstring ){ - vg_info( "KVSTR: [%u]%s: [%u]%s\n", cmd.key_djb2, cmd.key, - cmd.value_djb2, - (const char *)cmd.value._buf ); - } - } + /* method 2 */ +#if 0 + vg_info( "TRYING OUT METHOD 2 BINGO BONGO\n" ); + vg_msg root; + vg_msg_init( &root, descriptor_buf, descriptor.cur ); + + vg_msg workshop = root; + if( vg_msg_seekframe( &workshop, "workshop", k_vg_msg_first )){ + const char *err = vg_msg_seekkvstr(&workshop,"NOT HERE",k_vg_msg_first); + const char *author = vg_msg_seekkvstr(&workshop,"author",k_vg_msg_first); + const char *title = vg_msg_seekkvstr(&workshop,"title",k_vg_msg_first); + + vg_info( "TITLE: %s\n", title ); + vg_info( "AUTHOR: %s\n", author ); + vg_info( "and error code is: %s\n", err ); } + const char *content = vg_msg_seekkvstr(&root, "content", k_vg_msg_first); + vg_info( "CONTENT: %s\n", content ); +#endif + vg_build(); compiled_something = 1; } diff --git a/ent_skateshop.c b/ent_skateshop.c index fafd376..47d8de2 100644 --- a/ent_skateshop.c +++ b/ent_skateshop.c @@ -182,29 +182,22 @@ VG_STATIC void workshop_visibile_load_loop(void) vg_str content_path = folder; - int found = 0; - vg_msg msg; - vg_msg_init( &msg, cache_ptr->reg_ptr->metadata, + vg_msg root; + vg_msg_init( &root, cache_ptr->reg_ptr->metadata, cache_ptr->reg_ptr->metadata_len ); - vg_msg_cmd cmd; - while( vg_msg_next( &msg, &cmd ) ){ - if( (msg.depth == 0) && (cmd.code == k_vg_msg_code_kvstring) ){ - if( VG_STRDJB2_EQ( "content", cmd.key, cmd.key_djb2 ) ){ - vg_strcat( &content_path, "/" ); - vg_strcat( &content_path, cmd.value._buf ); - found = 1; - break; - } - } - } - if( !vg_strgood( &content_path ) ) { - vg_error( "Metadata path too long\n" ); + const char *kv_content = vg_msg_seekkvstr( &root, "content", 0 ); + if( kv_content ){ + vg_strcat( &content_path, "/" ); + vg_strcat( &content_path, kv_content ); + } + else{ + vg_error( "No content paths in metadata\n" ); goto file_is_broken; } - if( !found ){ - vg_error( "No content paths in metadata\n" ); + if( !vg_strgood( &content_path ) ) { + vg_error( "Metadata path too long\n" ); goto file_is_broken; } @@ -225,7 +218,7 @@ file_is_broken:; VG_STATIC void world_scan_thread( void *_args ){ - addon_mount_local_folder( k_workshop_file_type_world, "maps", ".mdl" ); + addon_mount_content_folder( k_workshop_file_type_world, "maps", ".mdl" ); addon_mount_workshop_items(); vg_async_call( async_addon_reg_update, NULL, 0 ); skaterift_end_op(); @@ -240,7 +233,7 @@ VG_STATIC void skateshop_op_world_scan(void){ } VG_STATIC void board_scan_thread( void *_args ){ - addon_mount_local_folder( k_workshop_file_type_board, "boards", ".mdl" ); + addon_mount_content_folder( k_workshop_file_type_board, "boards", ".mdl" ); addon_mount_workshop_items(); vg_async_call( async_addon_reg_update, NULL, 0 ); vg_async_stall(); @@ -514,8 +507,10 @@ VG_STATIC void global_skateshop_preupdate(void) browseable = 1; } - if( skaterift.async_op == k_async_op_none ){ - gui_helper_action( button_display_string(k_srbind_maccept), "load" ); + if( (skaterift.async_op == k_async_op_none) && + global_skateshop.selected_world_id > 0 ){ + gui_helper_action( button_display_string(k_srbind_maccept), + "open rift" ); loadable = 1; } @@ -550,7 +545,7 @@ VG_STATIC void global_skateshop_preupdate(void) /* automatically load in clouds */ if( loadable && button_down( k_srbind_maccept ) ){ - vg_info( "Select world (%u)\n", + vg_info( "Select rift (%u)\n", global_skateshop.selected_world_id ); skaterift_change_world( reg->foldername ); return; @@ -691,6 +686,7 @@ fade_out:; } struct cache_board *cache_ptr = skateshop_selected_cache_if_loaded(); + if( !cache_ptr ){ global_skateshop.render.item_title = ""; global_skateshop.render.item_desc = ""; @@ -699,23 +695,13 @@ fade_out:; if( global_skateshop.render.reg_id != global_skateshop.selected_board_id ){ addon_reg *reg = cache_ptr->reg_ptr; - 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_kvstring ){ - if( VG_STRDJB2_EQ( "title", cmd.key, cmd.key_djb2 ) ){ - global_skateshop.render.item_title = cmd.value._buf; - } - } - } - } - } + vg_msg root; + vg_msg_init( &root, reg->metadata, reg->metadata_len ); + + vg_msg workshop = root; + if( vg_msg_seekframe( &workshop, "workshop", 0 ) ){ + const char *title = vg_msg_seekkvstr( &workshop, "title", 0 ); + if( title ) global_skateshop.render.item_title = title; } global_skateshop.render.reg_id = global_skateshop.selected_board_id; @@ -745,7 +731,8 @@ fade_out:; mlocal[3][1] = 0.0f; mlocal[3][2] = 0.0f; m4x3_mul( mtext, mlocal, mmdl ); - font3d_simple_draw( &gui.font, 0, "JA", &main_camera, mmdl ); + font3d_simple_draw( &gui.font, 0, global_skateshop.render.item_desc, + &main_camera, mmdl ); } VG_STATIC void skateshop_render_charshop(void) @@ -762,6 +749,20 @@ VG_STATIC void skateshop_render_worldshop(void) *mark_info = mdl_arritm( &world->ent_marker, mdl_entity_id_id(shop->boards.id_info)); + if( global_skateshop.render.world_reg != global_skateshop.selected_world_id){ + addon_reg *reg = get_addon_from_index( k_workshop_file_type_world, + global_skateshop.selected_world_id ); + vg_msg root; + vg_msg_init( &root, reg->metadata, reg->metadata_len ); + vg_msg workshop = root; + if( vg_msg_seekframe( &workshop, "workshop", 0 ) ){ + global_skateshop.render.world_title = vg_msg_seekkvstr( &workshop, + "title", 0 ); + } + global_skateshop.render.world_loc = vg_msg_seekkvstr(&root,"location",0); + global_skateshop.render.world_reg = global_skateshop.selected_world_id; + } + /* Text */ char buftext[128], bufsubtext[128]; vg_str info, subtext; @@ -780,13 +781,13 @@ VG_STATIC void skateshop_render_worldshop(void) info.buffer[info.i++] = ' '; info.buffer[info.i] = '\0'; - vg_strcat( &info, "AFAWJFKAW" ); + vg_strcat( &info, global_skateshop.render.world_title ); if( skaterift.async_op == k_async_op_world_loading || skaterift.async_op == k_async_op_world_preloading ){ vg_strcat( &subtext, "Loading..." ); } else{ - vg_strcat( &subtext, "No information" ); + vg_strcat( &subtext, global_skateshop.render.world_loc ); } } else{ diff --git a/ent_skateshop.h b/ent_skateshop.h index 03f0544..ceefc8b 100644 --- a/ent_skateshop.h +++ b/ent_skateshop.h @@ -49,10 +49,13 @@ struct{ struct { const char *item_title, *item_desc; u32 reg_id; + + const char *world_title, *world_loc; + u32 world_reg; } render; } -static global_skateshop={.render={.reg_id=0xffffffff}}; +static global_skateshop={.render={.reg_id=0xffffffff,.world_reg=0xffffffff}}; VG_STATIC void global_skateshop_exit(void); VG_STATIC void watch_cache_board( struct cache_board *ptr ); diff --git a/font.h b/font.h index b1185f9..77eae7c 100644 --- a/font.h +++ b/font.h @@ -176,7 +176,7 @@ VG_STATIC void font3d_draw( struct font3d_render *render ) if( !c0 ) break; ent_glyph *glyph0 = font3d_glyph( render->font, render->variant_id, c0 ), - *glyph1; + *glyph1 = NULL; /* multibyte characters */ if( c0 >= 1 && c0 < k_SRglyph_ascii_min ){ @@ -242,6 +242,8 @@ VG_STATIC float font3d_simple_draw( font3d *font, u32 variant_id, const char *text, camera *cam, m4x3f transform ) { + if( !text ) return 0.0f; + struct font3d_render render; font3d_begin( font, variant_id, cam, transform, &render ); render.u8pch = (u8*)text; @@ -252,6 +254,7 @@ float font3d_simple_draw( font3d *font, u32 variant_id, const char *text, VG_STATIC float font3d_string_width( font3d *font, u32 variant_id, const char *text ) { + if( !text ) return 0.0f; float width = 0.0f; for( int i=0;; i++ ){ u32 c = text[i]; diff --git a/gui.h b/gui.h index 99345c1..c057ce6 100644 --- a/gui.h +++ b/gui.h @@ -35,6 +35,7 @@ void gui_draw(void) ortho.mtx.p[3][3] = 1.0f; m4x3_identity( ortho.transform ); camera_update_view( &ortho ); + m4x4_mul( ortho.mtx.p, ortho.mtx.v, ortho.mtx.pv ); /* HACK */ camera_finalize( &ortho ); gui.factive = vg_lerpf( gui.factive, gui.helper_count?1.0f:0.0f, diff --git a/maps_src/mp_spawn/addon.inf b/maps_src/mp_spawn/addon.inf deleted file mode 100644 index 2530093..0000000 Binary files a/maps_src/mp_spawn/addon.inf and /dev/null differ diff --git a/maps_src/mp_spawn/main.mdl b/maps_src/mp_spawn/main.mdl index 8978cf2..097b6bd 100644 Binary files a/maps_src/mp_spawn/main.mdl and b/maps_src/mp_spawn/main.mdl differ diff --git a/skaterift.c b/skaterift.c index c8da6ad..50939ae 100644 --- a/skaterift.c +++ b/skaterift.c @@ -157,6 +157,37 @@ VG_STATIC void vg_load(void) world_loader.location = k_world_load_type_local; world_load_mdl( "maps/mp_spawn/main.mdl" ); + /* Completing addon registrations + * ------------------------------------- + */ + vg_msg msg; + + /* understate diy. */ + addon_reg *spawn = addon_mount_local_addon( "maps/mp_spawn", + k_workshop_file_type_world, + ".mdl" ); + vg_msg_init( &msg, spawn->metadata, sizeof(spawn->metadata) ); + vg_msg_frame( &msg, "workshop" ); + vg_msg_wkvstr( &msg, "title", "Understate DIY" ); + vg_msg_end_frame( &msg ); + vg_msg_wkvstr( &msg, "location", "USA" ); + spawn->metadata_len = msg.cur; + + /* mtzero island */ + addon_reg *mtzero = addon_mount_local_addon( "maps/mp_mtzero", + k_workshop_file_type_world, + ".mdl" ); + vg_msg_init( &msg, mtzero->metadata, sizeof(mtzero->metadata) ); + vg_msg_frame( &msg, "workshop" ); + vg_msg_wkvstr( &msg, "title", "Mt.Zero Island" ); + vg_msg_end_frame( &msg ); + vg_msg_wkvstr( &msg, "location", "Australia" ); + mtzero->metadata_len = msg.cur; + global_skateshop.selected_world_id=1; + global_skateshop.pointcloud_world_id=1; + skateshop_preview_loader_thread( mtzero ); /* HACK */ + + vg_async_call( async_addon_reg_update, NULL, 0 ); vg_console_load_autos(); menu_link(); diff --git a/workshop.c b/workshop.c index a2fe1fe..61a4899 100644 --- a/workshop.c +++ b/workshop.c @@ -769,31 +769,25 @@ VG_STATIC void workshop_op_download_and_view_submission( int result_index ) u32 len = strlen(metadata_str); vg_info( "Metadata: %s\n", metadata_str ); vg_str_bin( metadata_str, metadata_buf, len ); - vg_msg msg; - vg_msg_init( &msg, metadata_buf, len/2 ); + vg_msg root; + vg_msg_init( &root, metadata_buf, len/2 ); - 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 ) ){ - workshop_form.submission.type = cmd.value._u32; - workshop_form.submission.submission_type_selection.value = cmd.value._u32; - } - } - else if( cmd.code == k_vg_msg_code_kvstring ){ - if( VG_STRDJB2_EQ( "folder", cmd.key, cmd.key_djb2 ) ){ - vg_strncpy( cmd.value._buf, - workshop_form.addon_folder, - sizeof(workshop_form.addon_folder), - k_strncpy_always_add_null ); - } - } - } - } + vg_msg workshop; + 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 ){ + u32 u = kv_type.value._u32; + workshop_form.submission.type = u; + workshop_form.submission.submission_type_selection.value = u; + } + + const char *kv_folder = vg_msg_seekkvstr( &workshop, "folder", + k_vg_msg_first ); + if( kv_folder ){ + vg_strncpy( kv_folder, workshop_form.addon_folder, + sizeof(workshop_form.addon_folder), + k_strncpy_always_add_null ); } } }