#define VG_GAME
#include "vg/vg.h"
#include "vg/vg_steam_ugc.h"
+#include "vg/vg_msg.h"
#include "ent_skateshop.h"
#include "world.h"
#include "player.h"
#include "menu.h"
#include "pointcloud.h"
#include "highscores.h"
+#include "steam.h"
/*
* Checks string equality but does a hash check first
struct registry_board *other =
&global_skateshop.registry[ min_board->registry_id ];
- vg_info( "Deallocating board: '%s'\n", min_board, other->filename );
+ vg_info( "Deallocating board: '%s'\n", min_board, other->foldername );
player_board_unload( &min_board->board );
other->cache_ptr = NULL;
if( reg ){
vg_info( "Allocating board (reg:%u) '%s'\n",
- registry_index, reg->filename );
+ registry_index, reg->foldername );
}
else{
vg_info( "Pre-allocating board (reg:%u) 'null'\n", registry_index );
reg->cache_ptr = cache_ptr;
SDL_AtomicUnlock( &global_skateshop.sl_cache_access );
- vg_success( "Async board loaded (%s)\n", reg->filename );
+ vg_success( "Async board loaded (%s)\n", reg->foldername );
}
/*
*/
VG_STATIC void workshop_visibile_load_loop_thread( void *_args )
{
- char path[1024];
+ char path_buf[4096];
+ vg_str folder;
+
for( u32 i=0; i<SKATESHOP_BOARD_CACHE_MAX; i++ ){
struct cache_board *cache_ptr = &global_skateshop.cache[i];
vg_async_alloc( sizeof(struct async_workshop_filepath_info) );
struct async_workshop_filepath_info *info = call->payload;
- info->buf = path;
+ info->buf = path_buf;
info->id = reg->workshop_id;
- info->len = vg_list_size(path) - strlen("/board.mdl")-1;
+ info->len = vg_list_size(path_buf);
vg_async_dispatch( call, async_workshop_get_filepath );
vg_async_stall(); /* too bad! */
- if( path[0] == '\0' ){
- SDL_AtomicLock( &global_skateshop.sl_cache_access );
- cache_ptr->state = k_cache_board_state_none;
- SDL_AtomicUnlock( &global_skateshop.sl_cache_access );
-
+ if( path_buf[0] == '\0' ){
vg_error( "Failed SteamAPI_GetItemInstallInfo(" PRINTF_U64 ")\n",
reg->workshop_id );
- continue;
- }
- else{
- strcat( path, "/board.mdl" );
+
+ goto file_is_broken;
}
+
+ folder.buffer = path_buf;
+ folder.i = strlen(path_buf);
+ folder.len = 4096;
}
else{
- snprintf( path, 256, "models/boards/%s", reg->filename );
+ vg_strnull( &folder, path_buf, 4096 );
+ vg_strcat( &folder, "boards/" );
+ vg_strcat( &folder, reg->foldername );
+ }
+
+ vg_str meta_path = folder;
+ vg_strcat( &meta_path, "/addon.inf" );
+
+ if( !vg_strgood( &meta_path ) ) {
+ vg_error( "Metadata path too long\n" );
+ goto file_is_broken;
+ }
+
+ u8 meta[512];
+ FILE *fp = fopen( meta_path.buffer, "rb" );
+
+ if( !fp ) goto file_is_broken;
+
+ u32 l = fread( meta, 1, 512, fp );
+ if( l != 512 ){
+ if( !feof(fp) ){
+ fclose(fp);
+ vg_error( "unknown error codition" );
+ goto file_is_broken;
+ }
+ }
+ fclose(fp);
+
+ /* load content files
+ * --------------------------------- */
+
+ vg_str content_path = folder;
+
+ vg_msg msg;
+ vg_msg_init( &msg, meta, l );
+ 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 );
+ break;
+ }
+ }
+ }
+ if( !vg_strgood( &content_path ) ) {
+ vg_error( "Metadata path too long\n" );
+ goto file_is_broken;
}
- player_board_load( &cache_ptr->board, path );
+ player_board_load( &cache_ptr->board, content_path.buffer );
vg_async_call( skateshop_async_board_loaded, cache_ptr, 0 );
+ continue;
+
+file_is_broken:;
+ SDL_AtomicLock( &global_skateshop.sl_cache_access );
+ cache_ptr->state = k_cache_board_state_none;
+ SDL_AtomicUnlock( &global_skateshop.sl_cache_access );
}
else
SDL_AtomicUnlock( &global_skateshop.sl_cache_access );
vg_async_stall();
for( u32 j=0; j<workshop_count; j++ ){
+ /* check for existance in both our caches
+ * ----------------------------------------------------------*/
PublishedFileId_t id = workshop_ids[j];
-
for( u32 i=0; i<global_skateshop.t1_registry_count; i++ ){
struct registry_board *reg = &global_skateshop.registry[i];
goto next_file_workshop;
}
}
+ for( u32 i=0; i<global_skateshop.t1_world_registry_count; i++ ){
+ struct registry_world *reg = &global_skateshop.world_registry[i];
- if( global_skateshop.t1_registry_count == SKATESHOP_REGISTRY_MAX ){
- vg_error( "You have too many boards installed!\n" );
- break;
+ if( reg->workshop_id == id ){
+ reg->state = k_registry_board_state_indexed;
+ goto next_file_workshop;
+ }
}
+ /* new one, lets find out what type it is
+ * ---------------------------------------------------------------*/
vg_info( "new listing from the steam workshop!: "PRINTF_U64"\n", id );
+ vg_async_item *call1 =
+ vg_async_alloc( sizeof(struct async_workshop_filepath_info) );
- struct registry_board *reg = &global_skateshop.registry[
- global_skateshop.t1_registry_count ++ ];
+ char path[ 4096 ];
- reg->cache_ptr = NULL;
- snprintf( reg->filename, 64, PRINTF_U64, id );
- reg->filename_hash = vg_strdjb2( reg->filename );
- reg->workshop_id = id;
- reg->state = k_registry_board_state_indexed;
+ struct async_workshop_filepath_info *info = call1->payload;
+ info->buf = path;
+ info->id = id;
+ info->len = vg_list_size(path);
+ vg_async_dispatch( call1, async_workshop_get_filepath );
+ vg_async_stall(); /* too bad! */
- workshop_file_info_clear( ®->workshop );
- strcpy( reg->workshop.title, "Workshop file" );
+ vg_info( "%s\n", path );
+ vg_str folder = {.buffer = path, .i=strlen(path), .len=4096};
+ vg_str meta_path = folder;
+ vg_strcat( &meta_path, "/addon.inf" );
+ if( !vg_strgood( &meta_path ) ){
+ vg_error( "The metadata path is too long\n" );
+ goto next_file_workshop;
+ }
- /* load the metadata off the disk */
- vg_async_item *call =
- vg_async_alloc( sizeof(struct async_workshop_filepath_info) );
+ u8 meta[512];
+ FILE *fp = fopen( meta_path.buffer, "rb" );
+ if( !fp ){
+ vg_error( "Could not open the '%s'\n", meta_path.buffer );
+ goto next_file_workshop;
+ }
- const char *meta_file = "/board.mdl.inf";
- char path[ 1024 ];
- struct async_workshop_filepath_info *info = call->payload;
- info->buf = path;
- info->id = reg->workshop_id;
- info->len = vg_list_size(path) - strlen(meta_file)-1;
- vg_async_dispatch( call, async_workshop_get_filepath );
- vg_async_stall(); /* too bad! */
+ u32 l = fread( meta, 1, 512, fp );
+ if( l != 512 ){
+ if( !feof(fp) ){
+ fclose(fp);
+ vg_error( "unknown error codition" );
+ goto next_file_workshop;
+ }
+ }
+ fclose(fp);
+
+ enum workshop_file_type type = k_workshop_file_type_none;
+ vg_msg msg;
+ vg_msg_init( &msg, meta, l );
+
+ 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;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if( type == k_workshop_file_type_none ){
+ vg_error( "Cannot determine addon type\n" );
+ goto next_file_workshop;
+ }
+
+ /* now that we have the type
+ * ------------------------------------------------------------------*/
+
+ if( type == k_workshop_file_type_board ){
+ if( global_skateshop.t1_registry_count == SKATESHOP_REGISTRY_MAX ){
+ vg_error( "You have too many boards installed!\n" );
+ goto next_file_workshop;
+ }
+
+ struct registry_board *reg = &global_skateshop.registry[
+ global_skateshop.t1_registry_count ++ ];
+
+ reg->cache_ptr = NULL;
+ snprintf( reg->foldername, 64, PRINTF_U64, id );
+ reg->foldername_hash = vg_strdjb2( reg->foldername );
+ reg->workshop_id = id;
+ reg->state = k_registry_board_state_indexed;
+ }
+ else if( type == k_workshop_file_type_world ){
+ if( global_skateshop.t1_world_registry_count == SKATESHOP_WORLDS_MAX ){
+ vg_error( "You have too many worlds installed!\n" );
+ goto next_file_workshop;
+ }
- strcat( path, meta_file );
- workshop_load_metadata( path, ®->workshop );
+ struct registry_world *reg = &global_skateshop.world_registry[
+ global_skateshop.t1_world_registry_count ++ ];
+
+ snprintf( reg->foldername, 64, PRINTF_U64, id );
+ reg->foldername_hash = vg_strdjb2( reg->foldername );
+ reg->type = k_world_load_type_workshop;
+ reg->workshop_id = id;
+ reg->state = k_registry_board_state_indexed;
+ }
next_file_workshop:;
}
reg->state = k_registry_board_state_indexed_absent;
}
+#if 0
/*
* Local disk scan
*/
reg->cache_ptr = NULL;
vg_strncpy( file.name, reg->filename, 64, k_strncpy_always_add_null );
+#if 0
vg_strncpy( file.name, reg->workshop.title,
64, k_strncpy_always_add_null );
+#endif
reg->filename_hash = hash;
reg->workshop_id = 0;
reg->state = k_registry_board_state_indexed;
+
+#if 0
reg->workshop.author = 0;
strcpy( reg->workshop.author_name, "custom" );
+#endif
}
next_file: tinydir_next( &dir );
}
tinydir_close(&dir);
+#endif
if( steam_ready ) workshop_steam_scan();
PersonaStateChange_t *info = (PersonaStateChange_t *)msg->m_pubParam;
ISteamFriends *hSteamFriends = SteamAPI_SteamFriends();
+#if 0
if( info->m_nChangeFlags & k_EPersonaChangeName ){
for( u32 i=0; i<global_skateshop.registry_count; i++ ){
struct registry_board *reg = &global_skateshop.registry[i];
}
}
}
+#endif
}
/*
struct registry_board *reg =
&global_skateshop.registry[cache_ptr->registry_id];
+
+#if 0
struct workshop_file_info *info = ®->workshop;
/* Skin title
mlocal[3][2] = 0.0f;
m4x3_mul( mtext, mlocal, mmdl );
font3d_simple_draw( &gui.font, 0, info->author_name, &main_camera, mmdl );
+#endif
}
VG_STATIC void skateshop_render_charshop(void)