#include "vg_platform.h"
#include "vg_mem.h"
#include "vg_mem_pool.h"
-#include <stddef.h>
-/* implementation
- * -------------------------------------------------------------------------- */
-
-vg_pool_node *vg_pool_nodeptr( vg_pool *pool, u16 id )
+void vg_pool_switch( vg_pool *pool, vg_pool_chain *source, vg_pool_chain *dest, u16 which )
{
- if( !id )
- return NULL;
- else
- return pool->buffer + (pool->stride*(id-1)) + pool->offset;
-}
+ VG_ASSERT( which );
-/* is thread safe */
-void *vg_pool_item( vg_pool *pool, u16 id )
-{
- if( (id == 0) || (id > pool->count) )
- return NULL;
+ vg_pool_node *pnode = &pool->nodes[ which -1 ];
+ if( source )
+ {
+ /* unlink from source list pointers */
+ if( source->tail == which )
+ source->tail = pnode->l;
+ if( source->head == which )
+ source->head = pnode->r;
+
+ VG_ASSERT( source->count );
+ source->count --;
+ }
- return pool->buffer + pool->stride*(size_t)(id-1);
-}
+ /* unlink self from chain */
+ if( pnode->l )
+ pool->nodes[ pnode->l -1 ].r = pnode->r;
+ if( pnode->r )
+ pool->nodes[ pnode->r -1 ].l = pnode->l;
+ pnode->r = 0;
+ pnode->l = 0;
-void vg_pool_init( vg_pool *pool )
-{
- pool->head = 1;
- pool->tail = pool->count;
- for( u16 ib=1; ib <= pool->count; ib++ )
+ /* update destination list head/tail pointers */
+ if( dest )
{
- vg_pool_node *nb = vg_pool_nodeptr( pool, ib );
- u16 ia = ib-1, ic = ib+1;
- nb->l = ia;
- nb->r = ic<=pool->count? ic: 0;
- nb->ref_count = 0;
+ pnode->r = dest->head;
+ if( dest->head )
+ pool->nodes[ dest->head -1 ].l = which;
+ dest->head = which;
+ if( dest->tail == 0 )
+ dest->tail = which;
+
+ dest->count ++;
+ VG_ASSERT( dest->count ); // Overflow? in some mad scenario...
}
}
-u16 vg_pool_id( vg_pool *pool, void *item )
-{
- return ((item - pool->buffer) / pool->stride) + 1;
-}
-
-static void vg_pool_unlink( vg_pool *pool, u16 id )
+u16 vg_pool_reference( vg_pool *pool, u16 pool_id, bool increment )
{
- vg_pool_node *node = vg_pool_nodeptr( pool, id );
- vg_pool_node *l = vg_pool_nodeptr( pool, node->l ),
- *r = vg_pool_nodeptr( pool, node->r );
+ VG_ASSERT( pool_id );
+ VG_ASSERT( pool );
- if( pool->head == id ) pool->head = node->r;
- if( pool->tail == id ) pool->tail = node->l;
-
- if( l ) l->r = node->r;
- if( r ) r->l = node->l;
-
- node->r = 0;
- node->l = 0;
-}
+ vg_pool_node *pnode = &pool->nodes[ pool_id -1 ];
+ if( increment )
+ {
+ VG_ASSERT( pnode->refcount < 100 ); // 100 is one of the largest numbers known to man
+ pnode->refcount ++;
+ }
+ else
+ {
+ VG_ASSERT( pnode->refcount > 0 );
+ pnode->refcount --;
+ }
-u16 vg_pool_lru( vg_pool *pool )
-{
- u16 head = pool->head;
- if( !head )
- return 0;
- vg_pool_unlink( pool, head );
- return head;
+ return pnode->refcount;
}
-void vg_pool_watch( vg_pool *pool, u16 id )
+void vg_pool_init( vg_pool *pool, vg_pool_chain *start_chain, u16 count, vg_stack_allocator *stack )
{
- vg_pool_node *node = vg_pool_nodeptr( pool, id );
-
- if( !node->ref_count )
- vg_pool_unlink( pool, id );
+ u32 size = sizeof(vg_pool_node) * count;
+ pool->nodes = stack? vg_stack_allocate( stack, size, 8, "Pool Nodes" ): vg_malloc( size );
+ pool->count = count;
- if( node->ref_count == 0xffff )
- vg_fatal_error( "Pool watch missmatch (limit is 128)\n" );
+ for( u16 i=0; i<count; i ++ )
+ {
+ u16 id = i+1;
+ pool->nodes[ i ].l = id-1;
+ pool->nodes[ i ].r = id==count? 0: id+1;
+ pool->nodes[ i ].refcount = 0;
+ pool->nodes[ i ].unused0 = 0;
+ }
- node->ref_count ++;
+ start_chain->head = 1;
+ start_chain->tail = count;
+ start_chain->count = count;
+ start_chain->unused0 = 0;
}
-/* if after this no more watches, places back into the volatile list */
-bool vg_pool_unwatch( vg_pool *pool, u16 id )
+u32 vg_pool_index( vg_pool *pool, u16 id )
{
- vg_pool_node *node = vg_pool_nodeptr( pool, id );
-
- if( node->ref_count == 0 )
- vg_fatal_error( "pool unwatch missmatch (no watchers)\n" );
+ VG_ASSERT( id );
+ VG_ASSERT( id <= pool->count );
+ return id-1;
+}
- node->ref_count --;
- if( !node->ref_count )
- {
- vg_pool_node *head = vg_pool_nodeptr( pool, pool->head ),
- *tail = vg_pool_nodeptr( pool, pool->tail );
- if( tail )
- tail->r = id;
- node->l = pool->tail;
- pool->tail = id;
- if( !head )
- pool->head = id;
- return 1;
- }
- else return 0;
+u16 vg_pool_next( vg_pool *pool, u16 pool_id, bool right )
+{
+ VG_ASSERT( pool_id );
+ if( right ) return pool->nodes[ pool_id -1 ].r;
+ else return pool->nodes[ pool_id -1 ].l;
}
#pragma once
#include "vg_platform.h"
+#include "vg_mem.h"
+
+/*
+ * This is most straightforwardly a way to maintain stable ID's for various other things, it does not directly manage
+ * the memory here.
+ */
+
+#define VG_POOL_INCREMENT 1
+#define VG_POOL_DECREMENT 0
typedef struct vg_pool vg_pool;
typedef struct vg_pool_node vg_pool_node;
+typedef struct vg_pool_chain vg_pool_chain;
-/* this goes in your structures */
-struct vg_pool_node
+struct vg_pool_node
{
- u16 l, r, ref_count;
+ u16 l, r, refcount, unused0;
};
struct vg_pool
{
- void *buffer; /* array which holds the real data */
- u16 count, head, tail;
- size_t stride, offset;
+ vg_pool_node *nodes;
+ u32 count;
+};
+
+struct vg_pool_chain
+{
+ u16 head, tail, count, unused0;
};
-vg_pool_node *vg_pool_nodeptr ( vg_pool *pool, u16 id );
-void *vg_pool_item ( vg_pool *pool, u16 id );
-void vg_pool_init ( vg_pool *pool );
-u16 vg_pool_id ( vg_pool *pool, void *item );
-u16 vg_pool_lru ( vg_pool *pool );
-void vg_pool_watch ( vg_pool *pool, u16 id );
-bool vg_pool_unwatch ( vg_pool *pool, u16 id );
+u32 vg_pool_index( vg_pool *pool, u16 pool_id );
+u16 vg_pool_reference( vg_pool *pool, u16 pool_id, bool increment );
+void vg_pool_init( vg_pool *pool, vg_pool_chain *chain, u16 count, vg_stack_allocator *stack );
+u16 vg_pool_next( vg_pool *pool, u16 pool_id, bool right );
+void vg_pool_switch( vg_pool *pool, vg_pool_chain *source, vg_pool_chain *dest, u16 which );
*/
u64 vg_msg_cast_to_u64( const void *src, u8 src_base, u8 src_size )
{
- if( src_base == k_vg_msg_float ){
- if( src_size == 4 ) return (u64)(*((f32*)src));
- else if( src_size == 8 ) return (u64)(*((f64*)src));
- else return 0;
+ if( src_base == k_vg_msg_float )
+ {
+ retrun (u64)vg_msg_cast_to_f64( src, src_base, src_size );
}
- else {
+ else
+ {
u64 a = 0;
memcpy( &a, src, src_size );
return a;
*/
i64 vg_msg_cast_to_i64( const void *src, u8 src_base, u8 src_size )
{
- if( src_base == k_vg_msg_float ){
- if( src_size == 4 ) return (i64)(*((f32*)src));
- else if( src_size == 8 ) return (i64)(*((f64*)src));
- else return 0;
+ if( src_base == k_vg_msg_float )
+ {
+ retrun (i64)vg_msg_cast_to_f64( src, src_base, src_size );
}
- else {
+ else
+ {
u64 a = 0;
memcpy( &a, src, src_size );
*/
f64 vg_msg_cast_to_f64( const void *src, u8 src_base, u8 src_size )
{
- if( src_base == k_vg_msg_float ){
- if( src_size == 4 ) return (f64)(*((f32*)src));
- else if( src_size == 8 ) return *((f64*)src);
- else return 0.0;
+ if( src_base == k_vg_msg_float )
+ {
+ if( src_size == 4 )
+ {
+ f32 a = 0;
+ memcpy( &a, src, sizeof(a) );
+ return (f64);
+ }
+ else if( src_size == 8 )
+ {
+ f64 a = 0;
+ memcpy( &a, src, sizeof(a) );
+ return a;
+ }
+ else return 0.0;
}
else
return (f64)vg_msg_cast_to_i64( src, src_base, src_size );
#include "vg_steam2.h"
#include "vg_log.h"
#include "vg_string.h"
+#include "vg_mem.h"
+#include "vg_io.h"
#include <stdio.h>
#include <string.h>
}
#endif
+#if defined( VG_SERVER )
+static u8 vg_char_base16( c8 c )
+{
+ if( c >= '0' && c <= '9' )
+ return c-'0';
+ if( c >= 'a' && c <= 'f' )
+ return (c-'a') + 10;
+ return 0;
+}
+#endif
+
#if defined( VG_SERVER )
bool vg_steam_init( u32 unIP, u16 usGamePort, u16 usQueryPort, EServerMode eServerMode, const c8 *pchVersionString,
const c8 *appid_str )
fputs( appid_str, txt );
fclose( txt );
+ // FIXME: Add no-auth launch option (hoist from skaterift, as we have it there, to vg steam module?)
+ vg_stack_allocator stack;
+ vg_stack_init( &stack, NULL, VG_KB(256), NULL );
+ u32 size;
+ char *src = vg_file_read( &stack, "application_key", &size, 0 );
+ if( src )
+ {
+ if( size < k_nSteamEncryptedAppTicketSymmetricKeyLen )
+ {
+ vg_error( "Application key was invalid size\n" );
+ return 0;
+ }
+
+ for( int i=0; i<k_nSteamEncryptedAppTicketSymmetricKeyLen; i++ )
+ _steam_api.server_symmetric_key[i] = (vg_char_base16( src[i*2+0] ) << 4) | vg_char_base16( src[i*2+1] );
+ }
+ else
+ {
+ vg_error( "No application_key file\n" );
+ return 0;
+ }
+
const char *pszInternalCheckInterfaceVersions =
STEAMUTILS_INTERFACE_VERSION "\0"
STEAMNETWORKINGUTILS_INTERFACE_VERSION "\0"
api_calls[ 32 ];
u32 api_call_count;
+#if defined( VG_SERVER )
+ u8 server_symmetric_key[ k_nSteamEncryptedAppTicketSymmetricKeyLen ];
+#else
u8 app_symmetric_key[ 1024 ];
u32 app_key_length;
+#endif
}
extern _steam_api;