view weekly/all-time
authorhgn <hgodden00@gmail.com>
Mon, 30 Oct 2023 19:32:08 +0000 (19:32 +0000)
committerhgn <hgodden00@gmail.com>
Mon, 30 Oct 2023 19:32:08 +0000 (19:32 +0000)
13 files changed:
ent_route.c
gameserver.c
network.c
network.h
network_common.h
network_msg.h
world.c
world.h
world_load.c
world_routes.c
world_routes.h
world_sfd.c
world_sfd.h

index a11464093b6646c84838a9e5d110596a2d53f92e..1f0bbeddf401c3ed6763dbf0608e4ecc4d35194e 100644 (file)
@@ -35,9 +35,18 @@ static void ent_route_preupdate( ent_route *route, int active ){
 
    gui_helper_action( button_display_string( k_srbind_mleft ), "weekly" );
    gui_helper_action( button_display_string( k_srbind_mright ), "all time" );
-
    gui_helper_action( button_display_string( k_srbind_mback ), "exit" );
 
+   if( button_down( k_srbind_mleft ) ){
+      world_sfd.view_weekly = 1;
+      world_sfd_compile_active_scores();
+   }
+
+   if( button_down( k_srbind_mright ) ){
+      world_sfd.view_weekly = 0;
+      world_sfd_compile_active_scores();
+   }
+
    if( button_down( k_srbind_mback ) ){
       world_entity_unfocus();
       return;
index 840f9d08a40031a2b3e2111d89e552603535b133..20f4e323c5d1b79a9875b21f3ce92509da75d82f 100644 (file)
@@ -456,6 +456,62 @@ static u32 gameserver_get_current_week(void){
    return time(NULL) / (7*24*60*60);
 }
 
+static enum request_status gameserver_cat_table( 
+      vg_msg *msg, 
+      const char *mod, const char *route, u32 week, const char *alias )
+{
+   char table_name[ DB_TABLE_UID_MAX ];
+   if( !db_get_highscore_table_name( mod, route, week, table_name ) )
+      return k_request_status_out_of_memory;
+
+   char buf[512];
+   vg_str q;
+   vg_strnull( &q, buf, 512 );
+   vg_strcat( &q, "SELECT * FROM \"" );
+   vg_strcat( &q, table_name );
+   vg_strcat( &q, "\" ORDER BY time DESC LIMIT 10;" );
+   if( !vg_strgood(&q) )
+      return k_request_status_out_of_memory;
+
+   sqlite3_stmt *stmt = db_stmt( q.buffer );
+   if( !stmt )
+      return k_request_status_database_error;
+
+   vg_msg_frame( msg, alias );
+   for( u32 i=0; i<10; i ++ ){
+      int fc = sqlite3_step( stmt );
+
+      if( fc == SQLITE_ROW ){
+         i32 time = sqlite3_column_int( stmt, 1 );
+         i64 steamid_i64 = sqlite3_column_int64( stmt, 0 );
+         u64 steamid = *((u64 *)&steamid_i64);
+
+         if( steamid == k_connection_unauthorized )
+            continue;
+
+         vg_msg_frame( msg, "" );
+         vg_msg_wkvu32( msg, "time", time );
+         vg_msg_wkvu64( msg, "steamid", steamid );
+
+         char username[32];
+         if( db_getuserinfo( steamid, username, sizeof(username), NULL ) )
+            vg_msg_wkvstr( msg, "username", username );
+         vg_msg_end_frame( msg );
+      }
+      else if( fc == SQLITE_DONE ){
+         break;
+      }
+      else {
+         log_sqlite3( fc );
+         break;
+      }
+   }
+
+   sqlite3_finalize( stmt );
+   vg_msg_end_frame( msg );
+   return k_request_status_ok;
+}
+
 static void gameserver_process_user_request( db_request *db_req ){
    struct user_request_thread_data *inf = (void *)db_req->data;
    SteamNetworkingMessage_t *msg = inf->msg;
@@ -490,67 +546,17 @@ static void gameserver_process_user_request( db_request *db_req ){
       const char *route = vg_msg_getkvstr( &data, "route" );
       u32 week = vg_msg_getkvu32( &data, "week", 0 );
       
-      char table_name[ DB_TABLE_UID_MAX ];
-      if( !db_get_highscore_table_name( mod, route, week, table_name ) ){
-         gameserver_request_respond( k_request_status_out_of_memory,
-                                     res, NULL, msg );
-         return;
-      }
-
-      char buf[512];
-      vg_str q;
-      vg_strnull( &q, buf, 512 );
-      vg_strcat( &q, "SELECT * FROM \"" );
-      vg_strcat( &q, table_name );
-      vg_strcat( &q, "\" ORDER BY time DESC LIMIT 10;" );
-      if( !vg_strgood(&q) ) {
-         gameserver_request_respond( k_request_status_out_of_memory,
-                                     res, NULL, msg );
-         return;
+      if( week == NETWORK_LEADERBOARD_CURRENT_WEEK ){
+         gameserver_cat_table( &body, mod, route, 
+                               gameserver_get_current_week(), "rows_weekly" );
       }
-
-      sqlite3_stmt *stmt = db_stmt( q.buffer );
-
-      if( !stmt ){
-         gameserver_request_respond( k_request_status_database_error,
-                                     res, NULL, msg );
-         return;
-      }
-
-      vg_msg_frame( &body, "rows" );
-      for( u32 i=0; i<10; i ++ ){
-         int fc = sqlite3_step( stmt );
-
-         if( fc == SQLITE_ROW ){
-            i32 time = sqlite3_column_int( stmt, 1 );
-            i64 steamid_i64 = sqlite3_column_int64( stmt, 0 );
-            u64 steamid = *((u64 *)&steamid_i64);
-
-            if( steamid == k_connection_unauthorized )
-               continue;
-
-            vg_msg_frame( &body, "" );
-            vg_msg_wkvu32( &body, "time", time );
-            vg_msg_wkvu64( &body, "steamid", steamid );
-
-            char username[32];
-            if( db_getuserinfo( steamid, username, sizeof(username), NULL ) ){
-               vg_msg_wkvstr( &body, "username", username );
-            }
-
-            vg_msg_end_frame( &body );
-         }
-         else if( fc == SQLITE_DONE ){
-            break;
-         }
-         else {
-            log_sqlite3( fc );
-            break;
-         }
+      else if( week == NETWORK_LEADERBOARD_ALLTIME_AND_CURRENT_WEEK ){
+         gameserver_cat_table( &body, mod, route, 0, "rows" );
+         gameserver_cat_table( &body, mod, route, 
+                               gameserver_get_current_week(), "rows_weekly" );
       }
-
-      sqlite3_finalize( stmt );
-      vg_msg_end_frame( &body );
+      else 
+         gameserver_cat_table( &body, mod, route, week, "rows" );
 
       if( body.error != k_vg_msg_error_OK ){
          gameserver_request_respond( k_request_status_out_of_memory,
index b0ae67786542032c53b3ee7872d7e5357bdb9654..5d00d16c3b0fb43862b54fd2841491f4c6625ac2 100644 (file)
--- a/network.c
+++ b/network.c
@@ -3,7 +3,9 @@
 #include "network_msg.h"
 #include "network_common.h"
 #include "player_remote.h"
+#include "world.h"
 #include "world_sfd.h"
+#include "world_routes.h"
 
 static void scores_update(void);
 
@@ -149,8 +151,10 @@ static void network_send_username(void){
 }
 
 static void network_send_request( netmsg_request *req, vg_msg *body,
-                                  void (*callback)( netmsg_request *res, 
-                                                    vg_msg *body )){
+                                  void (*callback)( 
+                                     netmsg_request *res, vg_msg *body, 
+                                     u64 userdata),
+                                  u64 userdata ){
    u32 len = 0;
    if( body ){
       len = body->cur.co;
@@ -171,6 +175,7 @@ static void network_send_request( netmsg_request *req, vg_msg *body,
             vg_pool_item( &network_client.request_pool, req->id );
          pn->callback = callback;
          pn->sendtime = vg.time_real;
+         pn->userdata = userdata;
       }
       else{
          vg_error( "Unable to send request. Pool is full.\n" );
@@ -186,43 +191,29 @@ static void network_send_request( netmsg_request *req, vg_msg *body,
          k_nSteamNetworkingSend_Reliable, NULL );
 }
 
-static void network_scoreboard_callback( netmsg_request *res, vg_msg *body ){
-   for( u32 i=0; i<13; i++ )
-      sfd_encode( i, "" );
+static void network_scoreboard_callback( netmsg_request *res, vg_msg *body,
+                                         u64 userdata ){
+   world_instance *world = world_current_instance();
 
-   if( res->status != k_request_status_ok ){
-      char buf[32];
-      vg_str s;
-      vg_strnull( &s, buf, 32 );
-      vg_strcat( &s, "Error: " );
-      vg_strcati32( &s, res->status );
-
-      sfd_encode( 4, buf );
-      return;
-   }
+   world_routes_recv_scoreboard( world, body, userdata, res->status );
+   if( userdata == world_sfd.active_route_board )
+      world_sfd_compile_active_scores();
+}
 
-   u32 l = 0;
-   if( vg_msg_seekframe( body, "rows" ) ){
-      while( vg_msg_seekframe( body, NULL ) ){
-         const char *username = vg_msg_getkvstr( body, "username" );
 
-         if( username )
-            sfd_encode( l ++, username );
-         else
-            sfd_encode( l ++, "UNKNOWN USER" );
-
-         vg_msg_skip_frame( body );
-      }
-   }
-}
 
 /* mod_uid: world mod uid,
  * route_uid: run name (just a string)
- * week: 0 for all-time, n for week #
+ * week: 
+ *   0   ALL TIME
+ *   1   CURRENT WEEK
+ *   2   ALL TIME + CURRENT WEEK
+ *   .
+ *   10+ specific week index
  */
 static void network_request_scoreboard( const char *mod_uid, 
                                         const char *route_uid,
-                                        u32 week ){
+                                        u32 week, u64 userdata ){
    if( !network_client.remote )
       return;
 
@@ -235,10 +226,11 @@ static void network_request_scoreboard( const char *mod_uid,
    vg_msg_wkvstr( &data, "mod", mod_uid );
    vg_msg_wkvstr( &data, "route", route_uid );
    vg_msg_wkvu32( &data, "week", week );
-   network_send_request( req, &data, network_scoreboard_callback );
+   network_send_request( req, &data, network_scoreboard_callback, userdata );
 }
 
-static void network_publish_callback( netmsg_request *res, vg_msg *body ){
+static void network_publish_callback( netmsg_request *res, vg_msg *body,
+                                      u64 userdata ){
    if( res->status != k_request_status_ok ){
       vg_error( "Publish laptime, server error #%d\n", (i32)res->status );
    }
@@ -260,7 +252,7 @@ static void network_publish_laptime( const char *mod_uid,
    vg_msg_wkvstr( &data, "mod", mod_uid );
    vg_msg_wkvstr( &data, "route", route_uid );
    vg_msg_wkvi32( &data, "time", time_centiseconds );
-   network_send_request( req, &data, network_publish_callback );
+   network_send_request( req, &data, network_publish_callback, 0 );
 }
 
 static void network_request_rx_300_400( SteamNetworkingMessage_t *msg ){
@@ -288,7 +280,7 @@ static void network_request_rx_300_400( SteamNetworkingMessage_t *msg ){
       if( res->id ){
          struct network_request *pn = 
             vg_pool_item( &network_client.request_pool, res->id );
-         pn->callback( res, body );
+         pn->callback( res, body, pn->userdata );
          vg_pool_unwatch( &network_client.request_pool, res->id );
       }
    }
@@ -448,6 +440,7 @@ static void network_connect(void){
                   hSteamNetworkingSockets, &remoteAddr, 0, NULL );
 }
 
+#if 0
 static void on_inet_scoreboard( SteamNetworkingMessage_t *msg ){
    netmsg_scoreboard *sb = msg->m_pData;
 
@@ -481,6 +474,7 @@ static void on_inet_scoreboard( SteamNetworkingMessage_t *msg ){
 
    network_scores_updated = 1;
 }
+#endif
 
 static void poll_remote_connection(void){
    SteamNetworkingMessage_t *messages[32];
index 2916ad94a824f6f9a5d543daa2e1e319d8ac14ec..fc4829d6d1bb3468fb0db3595aaf867be63ad814 100644 (file)
--- a/network.h
+++ b/network.h
@@ -14,8 +14,6 @@
 
 #define NETWORK_MAX_REQUESTS 8
 
-static int network_scores_updated = 0;
-
 /* 
  * Interface
  */
@@ -56,8 +54,9 @@ struct {
 
    struct network_request {
       vg_pool_node poolnode;
-      void (*callback)( netmsg_request *res, vg_msg *body );
+      void (*callback)( netmsg_request *res, vg_msg *body, u64 userdata );
       f64 sendtime;
+      u64 userdata;
    }
    *request_buffer;
    vg_pool request_pool;
@@ -71,7 +70,7 @@ static int packet_minsize( SteamNetworkingMessage_t *msg, u32 size );
 static void network_send_item( enum netmsg_playeritem_type type );
 static void network_request_scoreboard( const char *mod_uid, 
                                         const char *route_uid,
-                                        u32 week );
+                                        u32 week, u64 userdata );
 static void network_publish_laptime( const char *mod_uid, 
                                      const char *route_uid, f64 lap_time );
 
index ad5fb56337cd3f38e723bf21ba815d5dbff33da6..82274edb4efb31dfb2444ef289b354ebc67294b3 100644 (file)
@@ -8,6 +8,11 @@
 #define NETWORK_MAX_PLAYERS 20
 #define NETWORK_FRAMERATE 0.1
 #define NETWORK_BUFFERFRAMES 6
+#define NETWORK_LEADERBOARD_MAX_SIZE 1024
+
+#define NETWORK_LEADERBOARD_ALLTIME 0
+#define NETWORK_LEADERBOARD_CURRENT_WEEK 1
+#define NETWORK_LEADERBOARD_ALLTIME_AND_CURRENT_WEEK 2
 
 #include "addon_types.h"
 
index 2e62521bb72d6eaa38b8b66c38bf3d631f768507..d06494acfaa99e6574a4052ff1c106d9814445d7 100644 (file)
@@ -28,52 +28,8 @@ struct netmsg_auth
 };
 enum{ k_inetmsg_auth = 1 };
 
-typedef struct netmsg_scores_request netmsg_scores_request;
-struct netmsg_scores_request
-{
-   u16 inetmsg_id;
-};
-enum{ k_inetmsg_scores_request = 2 };
-
-typedef struct netmsg_set_score netmsg_set_score;
-struct netmsg_set_score
-{
-   u16 inetmsg_id;
-
-   u32 record_count;
-   struct netmsg_score_record
-   {
-      u32 trackid;
-      u64 playerid;
-      u16 points, time;
-   }
-   records[];
-};
-enum{ k_inetmsg_set_score = 6 };
-/* 31.05.23: k_inetmsg_set_score id changed from ID 3 to ID 6,
- *                               3 is now INVALID */
-
-typedef struct netmsg_scoreboard netmsg_scoreboard;
-enum{ k_inetmsg_scoreboard = 5 };
-struct netmsg_scoreboard{
-   u16 inetmsg_id;
-   
-   u32 board_count;
-   struct netmsg_board
-   {
-      char data[27*13];
-   }
-   boards[ vg_list_size(track_infos) ];
-}
-static scoreboard_client_data = { 
-   .inetmsg_id = k_inetmsg_scoreboard,
-   .board_count = vg_list_size(track_infos)
-}; 
-/* probably about 10k */
-
 /* server control 100 */
 
-
 /* player updates 200 */
 
 #define NETMSG_BOUNDARY_BIT 0x8000
diff --git a/world.c b/world.c
index af9466c66dfebe37a6b534c5bc9bbd4424e55352..40f3d75423b7fbdf09f4d4cfce6001555500a33d 100644 (file)
--- a/world.c
+++ b/world.c
@@ -58,8 +58,7 @@ static void skaterift_world_get_save_path( enum world_purpose which,
 #include "world_routes.c"
 #include "world_traffic.c"
 
-static void world_update( world_instance *world, v3f pos )
-{
+static void world_update( world_instance *world, v3f pos ){
    world_render.sky_time += world_render.sky_rate * vg.time_delta;
    world_render.sky_rate = vg_lerp( world_render.sky_rate, 
                                     world_render.sky_target_rate, 
diff --git a/world.h b/world.h
index 76d43d6e66d6e58f4c5a841983fb1feaa5aa286a..98b9df90bc7e120bfea347fcad2e088037b444cc 100644 (file)
--- a/world.h
+++ b/world.h
@@ -6,6 +6,7 @@
 #define WORLD_H
 
 #include "render.h"
+#include "network_msg.h"
 
 /* types
  */
@@ -22,6 +23,13 @@ enum world_purpose{
    k_world_max
 };
 
+struct leaderboard_cache {
+   enum request_status status;
+   f64 cache_time;
+   u8 *data;
+   u32 data_len;
+};
+
 typedef struct world_instance world_instance;
 
 static void skaterift_world_get_save_path( enum world_purpose which, 
@@ -194,6 +202,9 @@ struct world_instance {
    u32 cubemap_cooldown, cubemap_side;
 
    rb_object rb_geo;
+
+   /* leaderboards */
+   struct leaderboard_cache *leaderboard_cache;
 };
 
 struct world_static {
index 455d30d7856abb0ae43d9763c745a37a4874e6a5..fd75aa8f8cca887ca34443154fbaf071800936ff 100644 (file)
@@ -97,6 +97,18 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){
    world_gen_compute_light_indices( world );
    mdl_close( meta );
 
+   /* allocate leaderboard buffers */
+   u32 bs = mdl_arrcount(&world->ent_route)*sizeof(struct leaderboard_cache);
+   world->leaderboard_cache = vg_linear_alloc( heap, bs );
+
+   for( u32 i=0; i<mdl_arrcount( &world->ent_route ); i ++ ){
+      struct leaderboard_cache *board = &world->leaderboard_cache[i];
+      board->data = vg_linear_alloc( heap, NETWORK_LEADERBOARD_MAX_SIZE );
+      board->status = k_request_status_client_error;
+      board->cache_time = 0.0;
+      board->data_len = 0;
+   }
+
    vg_async_call( async_world_postprocess, world, 0 );
    vg_async_stall();
 }
index 87b21c8572504917cb21150389426b59f900f819..52c2c2aa76ad4afad3d10211fcca13afb1e99c5b 100644 (file)
@@ -17,6 +17,8 @@
 #include "pointcloud.h"
 #include "gui.h"
 #include "steam.h"
+#include "network_msg.h"
+#include "network_common.h"
 
 #include "shaders/scene_route.h"
 #include "shaders/routeui.h"
@@ -953,14 +955,37 @@ static void world_gen_routes_ent_init( world_instance *world ){
    world_routes_clear( world );
 }
 
+static void world_routes_recv_scoreboard( world_instance *world, 
+                                          vg_msg *body, u32 route_id,
+                                          enum request_status status ){
+   if( route_id >= mdl_arrcount( &world->ent_route ) ){
+      vg_error( "Scoreboard route_id out of range (%u)\n", route_id );
+      return;
+   }
+
+   struct leaderboard_cache *board = &world->leaderboard_cache[ route_id ];
+   board->status = status;
+
+   if( body == NULL )
+      board->data_len = 0;
+
+   if( body->max > NETWORK_LEADERBOARD_MAX_SIZE ){
+      vg_error( "Scoreboard leaderboard too big (%u>%u)\n", body->max,
+                NETWORK_LEADERBOARD_MAX_SIZE );
+      return;
+   }
+
+   memcpy( board->data, body->buf, body->max );
+   board->data_len = body->max;
+}
+
 /* 
  * -----------------------------------------------------------------------------
  *                                    Events
  * -----------------------------------------------------------------------------
  */
 
-static void world_routes_init(void)
-{
+static void world_routes_init(void){
    world_static.current_run_version = 200;
    world_static.time = 300.0;
    world_static.last_use = 0.0;
@@ -969,8 +994,7 @@ static void world_routes_init(void)
    shader_routeui_register();
 }
 
-static void world_routes_update( world_instance *world )
-{
+static void world_routes_update( world_instance *world ){
    world_static.time += vg.time_delta;
 
    for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
index 13541eddd519842fbd43fa58cc442334772f5f62..636793dd87d68fa75d10c10b2344e47858012b1d 100644 (file)
@@ -6,6 +6,7 @@
 #define ROUTES_H
 
 #include "world.h"
+#include "network_msg.h"
 
 static void world_routes_init(void);
 static void world_routes_fracture( world_instance *world, ent_gate *gate,
@@ -21,5 +22,8 @@ static void world_routes_update_timer_texts( world_instance *world );
 static void world_routes_update( world_instance *world );
 static void world_routes_fixedupdate( world_instance *world );
 static void world_routes_clear( world_instance *world );
+static void world_routes_recv_scoreboard( world_instance *world, 
+                                          vg_msg *body, u32 route_id,
+                                          enum request_status status );
 
 #endif /* ROUTES_H */
index 9310aee6a52e21f54040b1f46a8f559e81010570..ca6f774b327fe4cd41ae3002b2a1cf8ea049a8d0 100644 (file)
@@ -6,6 +6,8 @@
 #include "shaders/scene_vertex_blend.h"
 #include "network.h"
 #include "entity.h"
+#include "network_common.h"
+#include "world_routes.h"
 
 static f32 sfd_encode_glyph( char c ){
    int value = 0;
@@ -59,6 +61,77 @@ static void sfd_encode( u32 row, const char *str ){
    }
 }
 
+static void world_sfd_compile_scores( struct leaderboard_cache *board ){
+   for( u32 i=0; i<13; i++ )
+      sfd_encode( i, "" );
+
+   if( !board ){
+      sfd_encode( 4, "Error out of range" );
+      return;
+   }
+
+   if( !network_client.remote ){
+      sfd_encode( 4, "Offline" );
+      return;
+   }
+
+   if( board->status == k_request_status_not_found ){
+      sfd_encode( 4, "No records" );
+      return;
+   }
+
+   if( board->status != k_request_status_ok ){
+      char buf[32];
+      vg_str s;
+      vg_strnull( &s, buf, 32 );
+      vg_strcat( &s, "Error: " );
+      vg_strcati32( &s, board->status );
+      sfd_encode( 4, buf );
+      return;
+   }
+
+   vg_msg body;
+   vg_msg_init( &body, board->data, board->data_len );
+
+   const char *alias = "rows";
+
+   if( world_sfd.view_weekly ){
+      alias = "rows_weekly";
+      sfd_encode( 0, "Weekly" );
+   }
+   else {
+      sfd_encode( 0, "All-Time" );
+   }
+
+   u32 l = 1;
+   if( vg_msg_seekframe( &body, alias ) ){
+      while( vg_msg_seekframe( &body, NULL ) ){
+         const char *username = vg_msg_getkvstr( &body, "username" );
+
+         if( username )
+            sfd_encode( l ++, username );
+         else
+            sfd_encode( l ++, "UNKNOWN USER" );
+
+         vg_msg_skip_frame( &body );
+      }
+   }
+   else {
+      sfd_encode( 4, "No records" );
+   }
+}
+
+static void world_sfd_compile_active_scores(void){
+   world_instance *world = world_current_instance();
+   
+   struct leaderboard_cache *board = NULL;
+
+   if( world_sfd.active_route_board < mdl_arrcount( &world->ent_route ) )
+      board = &world->leaderboard_cache[ world_sfd.active_route_board ];
+         
+   world_sfd_compile_scores( board );
+}
+
 static void world_sfd_update( world_instance *world, v3f pos ){
    if( mdl_arrcount( &world->ent_route ) ){
       u32 closest = 0;
@@ -74,22 +147,33 @@ static void world_sfd_update( world_instance *world, v3f pos ){
          }
       }
 
-      if( (world_sfd.active_route_board != closest) || network_scores_updated ){
-         network_scores_updated = 0;
-         world_sfd.active_route_board = closest;
-         ent_route *route = mdl_arritm( &world->ent_route, closest );
+      struct leaderboard_cache *board = &world->leaderboard_cache[ closest ];
 
-         addon_reg *world_reg = 
-            world_static.instance_addons[ world_static.active_instance ];
+      /* request new board if cache expires */
+      if( network_client.remote ){
+         f64 delta = vg.time_real - board->cache_time;
+         if( (delta > 45.0) || (board->cache_time == 0.0) ){
+            board->cache_time = vg.time_real;
+            ent_route *route = mdl_arritm( &world->ent_route, closest );
+            addon_reg *world_reg = 
+               world_static.instance_addons[ world - world_static.instances ];
 
-         char mod_uid[ ADDON_UID_MAX ];
-         addon_alias_uid( &world_reg->alias, mod_uid );
+            char mod_uid[ ADDON_UID_MAX ];
+            addon_alias_uid( &world_reg->alias, mod_uid );
 
-         network_request_scoreboard( 
-               mod_uid, 
-               mdl_pstr( &world->meta, route->pstr_name ),
-               0 );
+            network_request_scoreboard( 
+                  mod_uid, 
+                  mdl_pstr( &world->meta, route->pstr_name ),
+                  NETWORK_LEADERBOARD_ALLTIME_AND_CURRENT_WEEK, closest );
+         }
       }
+
+      /* compile board text if we changed. */
+      if( world_sfd.active_route_board != closest ){
+         world_sfd_compile_active_scores();
+      }
+
+      world_sfd.active_route_board = closest;
    }
 
    for( int i=0; i<world_sfd.w*world_sfd.h; i++ ){
index c83b0b2469a35d2931f8033faa0e8b457f9047d8..19c867c9a28ecc447b4f5fe901feb025c60b0898 100644 (file)
@@ -6,15 +6,19 @@
 #define SFD_H
 
 #include "world.h"
+#include "world_routes.h"
 
 struct world_sfd{
    GLuint tex_scoretex;
 
    glmesh mesh_base, mesh_display;
    mdl_submesh sm_base;
+
    u32 active_route_board;
    scene_context scene;
 
+   u32 view_weekly;
+
    u32 w, h;
    float *buffer;
 }
@@ -24,5 +28,7 @@ static void world_sfd_init(void);
 static void sfd_encode( u32 row, const char *str );
 static void sfd_render( world_instance *world, camera *cam, 
                            m4x3f transform );
+static void world_sfd_compile_scores( struct leaderboard_cache *leaderboard );
+static void world_sfd_compile_active_scores(void);
 
 #endif /* SFD_H */