medfall

A super great game engine
Log | Files | Refs

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 }