gameserver optimisations
authorhgn <hgodden00@gmail.com>
Thu, 23 Nov 2023 12:32:34 +0000 (12:32 +0000)
committerhgn <hgodden00@gmail.com>
Thu, 23 Nov 2023 13:32:19 +0000 (13:32 +0000)
gameserver.c
gameserver.h
network_common.h
player.c
player.h
player_basic_info.c [new file with mode: 0644]
player_basic_info.h [new file with mode: 0644]
player_remote.c
player_remote.h
shaders/scene_override.h

index cd1678a2d3612f73c38f8052f56f400ff9aec1c7..e641256c2ddc7f292afd0ef9f0c970b0ee07c48b 100644 (file)
@@ -116,7 +116,7 @@ static void gameserver_player_join( int index ){
 
       /* items */
       for( int j=0; j<k_netmsg_playeritem_max; j++ ){
-         chs = vg_strncpy( client->items[j], item->uid, ADDON_UID_MAX, 
+         chs = vg_strncpy( client->items[j].uid, item->uid, ADDON_UID_MAX, 
                            k_strncpy_always_add_null );
          item->type_index = j;
          item->client = i;
@@ -145,6 +145,8 @@ static void gameserver_player_leave( int index ){
                            k_nSteamNetworkingSend_Reliable );
 }
 
+static void gameserver_update_all_knowledge( int client, int clear );
+
 /*
  * Deletes client at index and disconnects the connection handle if it was 
  * set.
@@ -160,6 +162,7 @@ static void remove_client( int index ){
             NULL, 1 );
    }
    memset( client, 0, sizeof(struct gameserver_client) );
+   gameserver_update_all_knowledge( index, 1 );
 }
 
 /*
@@ -432,6 +435,103 @@ static void gameserver_update_db_username( db_request *db_req ){
    db_updateuser( inf->steamid, inf->username, admin );
 }
 
+static int gameserver_item_eq( struct gameserver_item *ia, 
+                               struct gameserver_item *ib ){
+   if( ia->hash == ib->hash )
+      if( !strcmp(ia->uid,ib->uid) )
+         return 1;
+
+   return 0;
+}
+
+/*
+ * Match addons between two player IDs. if clear is set, then the flags between
+ * those two IDs will all be set to 0.
+ */
+static void gameserver_update_knowledge_table( int client0, int client1, 
+                                               int clear ){
+   u32 idx = network_pair_index( client0, client1 );
+
+   struct gameserver_client *c0 = &gameserver.clients[client0],
+                            *c1 = &gameserver.clients[client1];
+
+   u8 flags = 0x00;
+
+   if( !clear ){
+      if( gameserver_item_eq(&c0->items[k_netmsg_playeritem_world0],
+                             &c1->items[k_netmsg_playeritem_world0]))
+         flags |= CLIENT_KNOWLEDGE_SAME_WORLD0;
+
+      if( gameserver_item_eq(&c0->items[k_netmsg_playeritem_world1],
+                             &c1->items[k_netmsg_playeritem_world1]))
+         flags |= CLIENT_KNOWLEDGE_SAME_WORLD1;
+   }
+
+   gameserver.client_knowledge_mask[idx] = flags;
+}
+
+/*
+ * If a change has been made on this client, then it will adjust the entire
+ * table of other players. if clear is set, all references to client will be set
+ * to 0.
+ */
+static void gameserver_update_all_knowledge( int client, int clear ){
+   for( int i=0; i<NETWORK_MAX_PLAYERS; i ++ ){
+      if( i == client )
+         continue;
+
+      struct gameserver_client *ci = &gameserver.clients[i];
+
+      if( ci->steamid )
+         gameserver_update_knowledge_table( client, i, clear );
+   }
+}
+
+static void gameserver_propogate_player_frame( int client_id, 
+                                               netmsg_playerframe *frame, 
+                                               u32 size ){
+   u32 basic_size = sizeof(netmsg_playerframe) + ((24*3)/8);
+   netmsg_playerframe *full = alloca(size),
+                      *basic= alloca(basic_size);
+
+   memcpy( full, frame, size );
+   memcpy( basic, frame, basic_size );
+
+   full->client = client_id;
+   basic->client = client_id;
+   basic->subsystem = 4; /* (.._basic_info: 24f*3 animator ) */
+   basic->sound_effects = 0;
+
+   struct gameserver_client *c0 = &gameserver.clients[client_id];
+   c0->instance = frame->instance_id;
+
+   for( int i=0; i<vg_list_size(gameserver.clients); i++ ){
+      if( i == client_id )
+         continue;
+
+      struct gameserver_client *ci = &gameserver.clients[i];
+
+      int send_full = 0;
+
+      if( c0->instance == ci->instance ){
+         u32 k_index = network_pair_index( client_id, i );
+         u8 k_mask = gameserver.client_knowledge_mask[ k_index ];
+         
+         if( (k_mask & (CLIENT_KNOWLEDGE_SAME_WORLD0<<c0->instance)) )
+            send_full = 1;
+      }
+
+      if( send_full ){
+         gameserver_send_to_client( i, full, size, 
+                                    k_nSteamNetworkingSend_Unreliable );
+      }
+      else {
+         gameserver_send_to_client( i, basic, basic_size, 
+                                    k_nSteamNetworkingSend_Unreliable );
+      }
+   }
+}
+
 static void gameserver_rx_200_300( SteamNetworkingMessage_t *msg ){
    netmsg_blank *tmp = msg->m_pData;
 
@@ -477,12 +577,8 @@ static void gameserver_rx_200_300( SteamNetworkingMessage_t *msg ){
       db_send_request( call );
    }
    else if( tmp->inetmsg_id == k_inetmsg_playerframe ){
-      /* propogate */
-      netmsg_playerframe *frame = alloca(msg->m_cbSize);
-      memcpy( frame, msg->m_pData, msg->m_cbSize );
-      frame->client = client_id;
-      gameserver_send_to_all( client_id, frame, msg->m_cbSize, 
-                              k_nSteamNetworkingSend_Unreliable );
+      gameserver_propogate_player_frame( client_id, 
+                                         msg->m_pData, msg->m_cbSize );
    }
    else if( tmp->inetmsg_id == k_inetmsg_playeritem ){
       netmsg_playeritem *item = msg->m_pData;
@@ -495,7 +591,7 @@ static void gameserver_rx_200_300( SteamNetworkingMessage_t *msg ){
          return;
       }
       
-      char *dest = client->items[ item->type_index ];
+      char *dest = client->items[ item->type_index ].uid;
 
       network_msgstring( item->uid, msg->m_cbSize, sizeof(netmsg_playeritem),
                          dest, ADDON_UID_MAX );
@@ -507,6 +603,8 @@ static void gameserver_rx_200_300( SteamNetworkingMessage_t *msg ){
                                 [k_netmsg_playeritem_world0]="world0",
                                 [k_netmsg_playeritem_world1]="world1"
                }[item->type_index], item->uid );
+
+      gameserver_update_all_knowledge( client_id, 0 );
                            
       /* propogate */
       netmsg_playeritem *prop = alloca(msg->m_cbSize);
index fa856cee1785aed63b10e9112a84d411cd58dec2..ac1c4914201c5b8cca64e8ed825c36e9ba0f2164 100644 (file)
 #include "highscores.h"
 #include <sys/socket.h>
 
+#define CLIENT_KNOWLEDGE_SAME_WORLD0 0x1
+#define CLIENT_KNOWLEDGE_SAME_WORLD1 0x2
+#define CLIENT_KNOWLEDGE_FRIENDS     0x4 /* TODO? */
+
 struct {
    HSteamNetPollGroup client_group;
    EServerMode auth_mode;
@@ -23,13 +27,23 @@ struct {
       int authenticated;
       HSteamNetConnection connection;
       char username[ NETWORK_USERNAME_MAX ];
-      char items[k_netmsg_playeritem_max][ADDON_UID_MAX];
+
+      u8 instance;
+
+      struct gameserver_item {
+         char uid[ADDON_UID_MAX];
+         u32  hash;
+      }
+      items[k_netmsg_playeritem_max];
+
       u64  steamid;
    }
    clients[ NETWORK_MAX_PLAYERS ];
 
+   u8 client_knowledge_mask[ (NETWORK_MAX_PLAYERS*(NETWORK_MAX_PLAYERS-1))/2 ];
    u8 app_symmetric_key[ k_nSteamEncryptedAppTicketSymmetricKeyLen ];
 
+   /* TODO: Consider removing this */
    int monitor_fd;
    int monitor_clients[ 4 ];
 }
index b3abade7705e2573e04b7d48313b5a5866218482..7b6f81d22b8cffb2b9c7b82df493b929eaa5282a 100644 (file)
@@ -29,4 +29,14 @@ static u32 network_msgstring( const char *src,
    return vg_strncpy( src, buf, string_len, k_strncpy_always_add_null );
 }
 
+static u32 network_pair_index( u32 _a, u32 _b ){
+   const u32 N = NETWORK_MAX_PLAYERS;
+   assert( (_a != _b) && (_a<N) && (_b<N) );
+
+   u32 a = VG_MIN( _a, _b ),
+       b = VG_MAX( _a, _b );
+
+   return ((N-a)*((N-a)-1))/2 - b + a;
+}
+
 #endif /* NETWORK_COMMON_H */
index bf1a5801da4415454e141c7d542326fd2414720e..93cfb10d169fa3c9aef8f9224f32ee6bf3548678 100644 (file)
--- a/player.c
+++ b/player.c
@@ -343,10 +343,13 @@ static void player__clear_sfx_buffer(void){
 
 /* implementation */
 #include "player_common.c"
+
 #include "player_walk.c"
 #include "player_skate.c"
 #include "player_dead.c"
 #include "player_drive.c"
+#include "player_basic_info.c"
+
 #include "player_render.c"
 #include "player_ragdoll.c"
 #include "player_replay.c"
index 939033a5296cca74b86692ac701279453f7b7a07..ef78e31645475117a4573609d16ed7a33dd1757b 100644 (file)
--- a/player.h
+++ b/player.h
@@ -10,6 +10,7 @@ enum player_subsystem{
    k_player_subsystem_skate = 1,
    k_player_subsystem_dead = 2,
    k_player_subsystem_drive = 3,
+   k_player_subsystem_basic_info = 4,
    k_player_subsystem_max,
    k_player_subsystem_invalid = 255
 };
@@ -55,10 +56,14 @@ struct player_subsystem_interface{
 #include "player_ragdoll.h"
 #include "player_render.h"
 #include "player_model.h"
+
+/* subsystem headers */
 #include "player_walk.h"
 #include "player_skate.h"
 #include "player_dead.h"
 #include "player_drive.h"
+#include "player_basic_info.h"
+
 #include "player_replay.h"
 
 #define PLAYER_REWIND_FRAMES 60*4
@@ -73,12 +78,6 @@ struct {
    rigidbody rb;
    v3f angles;
 
-#if 0
-   v4f   qbasis;
-   m3x3f basis, invbasis, basis_gate;
-   world_instance *viewable_world;
-#endif
-
    /*
     * Camera management
     * ---------------------------
@@ -170,7 +169,8 @@ struct player_subsystem_interface static *player_subsystems[] = {
    [k_player_subsystem_walk]  = &player_subsystem_walk,
    [k_player_subsystem_dead]  = &player_subsystem_dead,
    [k_player_subsystem_drive] = &player_subsystem_drive,
-   [k_player_subsystem_skate] = &player_subsystem_skate
+   [k_player_subsystem_skate] = &player_subsystem_skate,
+   [k_player_subsystem_basic_info]=&player_subsystem_basic_info
 };
 
 /*
diff --git a/player_basic_info.c b/player_basic_info.c
new file mode 100644 (file)
index 0000000..3d6c85a
--- /dev/null
@@ -0,0 +1,22 @@
+#include "player_basic_info.h"
+#include "network_compression.h"
+
+static void player__basic_info_animator_exchange(bitpack_ctx *ctx, void *data){
+   struct player_basic_info_animator *animator = data;
+   /* TODO: This range needs to be standardized in a common header */
+   bitpack_qv3f( ctx, 24, -1024.0f, 1024.0f, animator->root_co );
+}
+
+static void player__basic_info_pose( void *_animator, player_pose *pose ){
+   struct player_basic_info_animator *animator = _animator;
+   v3_copy( animator->root_co, pose->root_co );
+   q_identity( pose->root_q );
+   pose->type = k_player_pose_type_fk_2;
+   pose->board.lean = 0.0f;
+
+   for( int i=0; i<localplayer.skeleton.bone_count; i ++ ){
+      v3_zero(pose->keyframes[i].co);
+      q_identity(pose->keyframes[i].q);
+      v3_fill(pose->keyframes[i].s,1.0f);
+   }
+}
diff --git a/player_basic_info.h b/player_basic_info.h
new file mode 100644 (file)
index 0000000..12f46c9
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef PLAYER_BASIC_INFO_H
+#define PLAYER_BASIC_INFO_H
+
+#include "player.h"
+#include "player_api.h"
+
+struct player_basic_info {
+   struct player_basic_info_animator {
+      v3f root_co;
+   }
+   animator;
+}
+static player_basic_info;
+static void player__basic_info_animator_exchange(bitpack_ctx *ctx, void *data);
+static void player__basic_info_pose( void *_animator, player_pose *pose );
+
+struct player_subsystem_interface static player_subsystem_basic_info = {
+   .pose = player__basic_info_pose,
+   .network_animator_exchange = player__basic_info_animator_exchange,
+   .animator_data = &player_basic_info.animator,
+   .animator_size = sizeof(player_basic_info.animator),
+   .name = "Basic Info"
+};
+
+#endif /* PLAYER_BASIC_INFO_H */
index d9f0065ee9f172d7d2ae0f16fc65323f661c2ac9..82bc3da24ab24d29ed82d754fac781211ff6c188 100644 (file)
@@ -5,6 +5,7 @@
 #include "addon.h"
 #include "font.h"
 #include "gui.h"
+#include "ent_miniworld.h"
 
 static i32 k_show_own_name = 0;
 
@@ -175,7 +176,24 @@ static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg ){
          .buffer_len = datasize,
          .bytes = 0,
       };
-         
+      
+      /* animation 
+       * -------------------------------------------------------------*/
+
+      dest->timestamp = frame->timestamp;
+      dest->boundary_hash = frame->boundary_hash;
+
+      struct network_player *player = &netplayers.list[ frame->client ];
+      struct player_subsystem_interface *sys = 
+         player_subsystems[ frame->subsystem ];
+
+      if( sys->network_animator_exchange ){
+         memset( &dest->data, 0, sys->animator_size );
+         sys->network_animator_exchange( &ctx, &dest->data );
+      }
+      else {
+         bitpack_bytes( &ctx, sys->animator_size, sys->animator_data );
+      }
 
       /* sfx
        * -------------------------------------------------------------*/
@@ -209,24 +227,6 @@ static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg ){
             dst->subframe = remaining;
          }
       }
-      
-      /* animation 
-       * -------------------------------------------------------------*/
-
-      dest->timestamp = frame->timestamp;
-      dest->boundary_hash = frame->boundary_hash;
-
-      struct network_player *player = &netplayers.list[ frame->client ];
-      struct player_subsystem_interface *sys = 
-         player_subsystems[ frame->subsystem ];
-
-      if( sys->network_animator_exchange ){
-         memset( &dest->data, 0, sys->animator_size );
-         sys->network_animator_exchange( &ctx, &dest->data );
-      }
-      else {
-         bitpack_bytes( &ctx, sys->animator_size, sys->animator_data );
-      }
 
       player->subsystem = frame->subsystem;
       player->down_bytes += msg->m_cbSize;
@@ -314,13 +314,6 @@ static void remote_player_send_playerframe(void){
          .bytes = 0
       };
 
-      /* sfx
-       * ---------------------------------------------*/
-
-      frame->sound_effects = localplayer.sfx_buffer_count;
-      for( u32 i=0; i<localplayer.sfx_buffer_count; i ++ )
-         net_sfx_exchange( &ctx, &localplayer.sfx_buffer[i] );
-
       /* animation 
        * -----------------------------------------------*/
 
@@ -331,6 +324,13 @@ static void remote_player_send_playerframe(void){
       else
          bitpack_bytes( &ctx, sys->animator_size, sys->animator_data );
 
+      /* sfx
+       * ---------------------------------------------*/
+
+      frame->sound_effects = localplayer.sfx_buffer_count;
+      for( u32 i=0; i<localplayer.sfx_buffer_count; i ++ )
+         net_sfx_exchange( &ctx, &localplayer.sfx_buffer[i] );
+
       u32 wire_size = base_size + ctx.bytes;
       netplayers.up_bytes += wire_size;
 
@@ -849,8 +849,13 @@ static void remote_players_imgui_world( world_instance *world, m4x4f pv,
          v3f co;
          remote_player_position( i, co );
 
-         if( player->active_world != world ){
+         if( !player->active_world )
             continue;
+
+         /* their in our active subworld */
+         if( player->active_world != world ){
+            m4x3_mulv( global_miniworld.mmdl, co, co );
+            co[1] -= 2.0f; /* HACK lol */
          }
 
          f32 d2 = v3_dist2( co, localplayer.rb.co );
@@ -878,9 +883,7 @@ static void remote_players_imgui_world( world_instance *world, m4x4f pv,
          player->opacity = vg_lerpf( player->opacity, opacity,
                                      vg.time_frame_delta * 2.0f );
          
-         remote_player_world_gui( 
-               pv, netplayers.final_mtx[localplayer.skeleton.bone_count*i][3], 
-               player );
+         remote_player_world_gui( pv, co, player );
 
          vg_ui.colour[3] = player->opacity;
          ui_flush( k_ui_shader_colour );
index d29ffa387d44e6550215e70a99f88d7d5560de96..5ba0105277bacf456073da567a08c6b6b32be2f1 100644 (file)
@@ -45,9 +45,12 @@ struct {
          u16 boundary_hash;
 
          union interp_animdata {
-            struct player_skate_animator _skate;
-            struct player_walk_animator _walk;
-            struct player_dead_animator _dead;
+            /* these aren't accessed directly, just used to take the 
+             * max(sizeof) all systems */
+            struct player_skate_animator __skate;
+            struct player_walk_animator __walk;
+            struct player_dead_animator __dead;
+            struct player_basic_info_animator __basic;
          } 
          data;
       }
index 602cda4d88053c4127c72b19910acff6cac1b9f4..0d7515b8c7616b864160cdbdb3bde784925962e5 100644 (file)
@@ -479,7 +479,11 @@ static struct vg_shader _shader_scene_override = {
 "   float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
 "\n"
 "   float dcam = (-8.0+distance( aCo, uCamera ))/4.0;\n"
-"   if( min(aCo.y*0.5 + dither, dcam + dither) < 0.51 ) discard;\n"
+"   float dy0 = aCo.y - uMapInfo.x;\n"
+"   float dy1 = uMapInfo.y - aCo.y;\n"
+"\n"
+"   if( min(min(dy0,dy1)*0.5, dcam) + dither < 0.51 ) \n"
+"      discard;\n"
 "\n"
 "   compute_motion_vectors();\n"
 "\n"