/* 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;
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.
NULL, 1 );
}
memset( client, 0, sizeof(struct gameserver_client) );
+ gameserver_update_all_knowledge( index, 1 );
}
/*
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;
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;
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 );
[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);