main.cc (2490B)
1 #include <stdio.h> 2 #include <errno.h> 3 #include <err.h> 4 5 #include "intrinsics.h" 6 #include "log.h" 7 #include "stream.h" 8 #include "pool.h" 9 #include "hashtable.h" 10 #include "linear_algebra.h" 11 #include "int_conversions.h" 12 #include "rng/pcg.h" 13 #include "platform_io.h" 14 #include "platform_network.h" 15 #include "platform_time.h" 16 17 #define PORT 13337 18 #define MAX_PLAYERS 128 19 20 #define DISCONNECT_TIMEOUT 5.0 21 22 struct PlayerState { 23 u64 sid; 24 v3 pos; 25 NetAddress addr; 26 double last_message_time; 27 u16 next_free; 28 }; 29 30 static Pool< PlayerState, MAX_PLAYERS > states; 31 static HashTable< PlayerState *, MAX_PLAYERS * 2 > sids_to_states; 32 33 int main() { 34 UDPSocket sock = net_new_udp( NET_NONBLOCKING, PORT ); 35 36 PCG rng = new_pcg(); 37 38 for( ;; ) { 39 printf( "frame\n" ); 40 const double now = get_time(); 41 42 NetAddress addr; 43 u8 read_buf[ 1400 ]; 44 size_t len; 45 46 while( net_tryrecv( sock, read_buf, sizeof( read_buf ), &addr, &len ) ) { 47 ReadStream r( read_buf, len ); 48 49 // u16 command = read_u16( &r ); 50 u64 sid = read_u64( &r ); 51 if( !r.ok ) continue; 52 53 if( sid == ~u64( 0 ) ) { 54 v3 pos; 55 read( &r, &pos ); 56 if( !r.ok ) continue; 57 58 u64 new_sid = rng_next_u64( &rng ); 59 ggprint( "new connection {08x}\n", new_sid ); 60 PlayerState * state = states.acquire(); 61 ASSERT( state ); 62 63 state->sid = new_sid; 64 state->pos = pos; 65 state->addr = addr; 66 state->last_message_time = now; 67 68 sids_to_states.add( new_sid, state ); 69 70 char write_buf[ 1400 ]; 71 WriteStream w( write_buf, sizeof( write_buf ) ); 72 write( &w, new_sid ); 73 74 if( w.ok ) { 75 net_send( sock, w.start, w.len(), state->addr ); 76 } 77 } 78 else { 79 PlayerState * state = NULL; 80 if( sids_to_states.get( sid, &state ) ) { 81 v3 pos; 82 read( &r, &pos ); 83 if( !r.ok ) continue; 84 85 state->pos = pos; 86 state->last_message_time = now; 87 } 88 } 89 } 90 91 char write_buf[ 1400 ]; 92 WriteStream w( write_buf ); 93 write_u16( &w, states.elems.n ); 94 95 for( size_t i = 0; i < states.elems.n; i++ ) { 96 PlayerState * state = &states.elems[ i ]; 97 write( &w, state->sid ); 98 if( state->last_message_time + DISCONNECT_TIMEOUT <= now ) { 99 ggprint( "{08x} disconnected\n", state->sid ); 100 write_u8( &w, 1 ); 101 states.release( state ); 102 i--; 103 } 104 else { 105 write_u8( &w, 0 ); 106 write( &w, state->pos ); 107 } 108 } 109 110 if( w.ok ) { 111 for( const PlayerState & state : states.elems ) { 112 net_send( sock, w.start, w.len(), state.addr ); 113 } 114 } 115 116 usleep( 50 * 1000 ); 117 } 118 119 return 0; 120 }