Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
ex_gui_netclient.c
Go to the documentation of this file.
1
7#define WIDTH 640
8#define HEIGHT 480
9
10#define HAVE_ALLEGRO 1
11
12#include "nilorea/n_common.h"
13#include "nilorea/n_str.h"
14#include "nilorea/n_list.h"
15#include "nilorea/n_hash.h"
16#include "nilorea/n_network.h"
18#include "nilorea/n_allegro5.h"
19
20
22typedef struct PEER_OBJECT
23{
25 double position[ 3 ];
27 int id ;
29 long int life_time ;
31
32
33
34int update_peer( HASH_TABLE *peer_table, int id, double position[ 3 ] )
35{
36 __n_assert( peer_table, return FALSE );
37
38 PEER_OBJECT *peer = NULL ;
39
40 if( ht_get_ptr_ex( peer_table, id, (void *)&peer ) == TRUE )
41 {
42 memcpy( peer -> position, position, 3 * sizeof( double ) );
43 peer -> life_time = 10000000 ; /* 10s in usec */
44 }
45 else
46 {
47
48 Malloc( peer, PEER_OBJECT, 1 );
49 __n_assert( peer, return FALSE );
50
51 memcpy( peer -> position, position, 3 * sizeof( double ) );
52 peer -> id = id ;
53 peer -> life_time = 10000000 ; /* 10s in usec */
54
55 ht_put_ptr_ex( peer_table, id, peer, &free );
56 }
57 return TRUE ;
58}
59
60int manage_peers( HASH_TABLE *peer_table, int delta_t )
61{
62 LIST *to_kill = new_generic_list( -1 );
63 ht_foreach( node, peer_table )
64 {
65 PEER_OBJECT *peer = hash_val( node, PEER_OBJECT );
66 peer -> life_time -= delta_t ;
67 if( peer -> life_time < 0 )
68 list_push( to_kill, peer, NULL );
69 }
70 list_foreach( node, to_kill )
71 {
72 if( node && node -> ptr )
73 {
74 PEER_OBJECT *peer = (PEER_OBJECT *)node -> ptr ;
75 ht_remove_ex( peer_table, peer -> id );
76 }
77 }
78 return TRUE ;
79}
80
81int draw_peers( HASH_TABLE *peer_table, ALLEGRO_FONT *font, ALLEGRO_COLOR color )
82{
83 ht_foreach( node, peer_table )
84 {
85 PEER_OBJECT *peer = hash_val( node, PEER_OBJECT );
86 /* mouse pointers */
87 al_draw_line( peer -> position[ 0 ] - 5, peer -> position[ 1 ], peer -> position[ 0 ] + 5, peer -> position[ 1 ], al_map_rgb( 255, 0, 0 ), 1 );
88 al_draw_line( peer -> position[ 0 ], peer -> position[ 1 ] + 5, peer -> position[ 0 ], peer -> position[ 1 ] - 5, al_map_rgb( 255, 0, 0 ), 1 );
89 N_STR *textout = NULL ;
90 nstrprintf( textout, "id: %d", peer -> id );
91 al_draw_text( font, color, peer -> position[ 0 ] + 10, peer -> position[ 1 ], ALLEGRO_ALIGN_LEFT, _nstr( textout) );
92 free_nstr( &textout );
93 }
94 return TRUE ;
95}
96
97void usage(void)
98{
99 fprintf( stderr, " -v version\n"
100 " -V log level: LOG_INFO, LOG_NOTICE, LOG_ERR, LOG_DEBUG\n"
101 " -h help\n"
102 " -a serveur address name/ip to bind (server mode) (optionnal)\n"
103 " -s serveur address name/ip to connect (client mode)\n"
104 " -p port\n"
105 " -i [v4,v6] ip version (default support both ipv4 and ipv6 )\n" );
106}
107
108void process_args( int argc, char **argv, char **server, char **port, int *ip_version )
109{
110 int getoptret = 0,
111 log_level = LOG_ERR; /* default log level */
112
113 /* Arguments optionnels */
114 /* -v version
115 * -V log level
116 * -h help
117 * -s serveur address name/ip to connect (client mode)
118 * -p port
119 * -i v4 ip version (default support both ipv4 and ipv6 )
120 * -i v6 ip version ( " " " " " " )
121 */
122 if( argc == 1 )
123 {
124 fprintf( stderr, "No arguments given, help:\n" );
125 usage();
126 exit( 1 );
127 }
128 while( ( getoptret = getopt( argc, argv, "hvs:p:i:V:" ) ) != EOF)
129 {
130 switch( getoptret )
131 {
132 case 'i' :
133 if( !strcmp( "v4", optarg ) )
134 {
135 (*ip_version) = NETWORK_IPV4 ;
136 n_log( LOG_NOTICE, "IPV4 selected" );
137 }
138 else if( !strcmp( "v6", optarg ) )
139 {
140 (*ip_version) = NETWORK_IPV6 ;
141 n_log( LOG_NOTICE, "IPV6 selected" );
142 }
143 else
144 {
145 n_log( LOG_NOTICE, "IPV4/6 selected" );
146 }
147 break;
148 case 'v' :
149 fprintf( stderr, "Date de compilation : %s a %s.\n", __DATE__, __TIME__ );
150 exit( 1 );
151 case 'V' :
152 if( !strncmp( "LOG_NULL", optarg, 8 ) )
153 {
155 }
156 else
157 {
158 if( !strncmp( "LOG_NOTICE", optarg, 10 ) )
159 {
161 }
162 else
163 {
164 if( !strncmp( "LOG_INFO", optarg, 8 ) )
165 {
167 }
168 else
169 {
170 if( !strncmp( "LOG_ERR", optarg, 7 ) )
171 {
173 }
174 else
175 {
176 if( !strncmp( "LOG_DEBUG", optarg, 9 ) )
177 {
179 }
180 else
181 {
182 fprintf( stderr, "%s n'est pas un niveau de log valide.\n", optarg );
183 exit( -1 );
184 }
185 }
186 }
187 }
188 }
189 break;
190 case 's' :
191 (*server) = strdup( optarg );
192 break ;
193 case 'p' :
194 (*port) = strdup( optarg );
195 break ;
196 default :
197 case '?' :
198 {
199 if( optopt == 'V' )
200 {
201 fprintf( stderr, "\n Missing log level\n" );
202 }
203 else if( optopt == 'p' )
204 {
205 fprintf( stderr, "\n Missing port\n" );
206 }
207 else if( optopt != 's' )
208 {
209 fprintf( stderr, "\n Unknow missing option %c\n", optopt );
210 }
211 usage();
212 exit( 1 );
213 }
214 break ;
215 case 'h' :
216 {
217 usage();
218 exit( 1 );
219 }
220 break ;
221 }
222 }
224} /* void process_args( ... ) */
225
226
228{
231int key[ 7 ] = {false,false,false,false,false,false,false};
232
233
234/* start */
235int main( int argc, char *argv[] )
236{
237 int DONE = 0, QUIT_ASKED = 0, /* Flag to check if we are always running */
238 getoptret = 0, /* launch parameter check */
239 log_level = LOG_ERR ; /* default LOG_LEVEL */
240
241 ALLEGRO_DISPLAY *display = NULL ;
242 ALLEGRO_BITMAP *scr_buf = NULL ;
243 ALLEGRO_TIMER *fps_timer = NULL ;
244 ALLEGRO_TIMER *logic_timer = NULL ;
245 ALLEGRO_TIMER *network_heartbeat_timer = NULL ;
246
247 char *server = NULL ;
248 char *port = NULL ;
249 LIST *chatbuf = NULL;
250 HASH_TABLE *peer_table = NULL ;
251 ALLEGRO_USTR *chat_line = NULL;
252
253 N_STR *name = NULL,
254 *password = NULL ;
255
256 NETWORK *netw = NULL ;
258 unsigned long ping_time = 0 ;
259
260 int mx = 0, my = 0, mouse_b1 = 0, mouse_b2 = 0 ;
261 int do_draw = 0, do_logic = 0, do_network_update = 0;
262 N_STR *netw_exchange = NULL ;
263 int it = -1, ident = -1 ;
264
265 static pthread_t netw_thr ;
266
267 ALLEGRO_COLOR white_color = al_map_rgba_f(1, 1, 1, 1);
268 ALLEGRO_FONT *font = NULL ;
269
270
272
273 /* processing args and set log_level */
274 process_args( argc, argv, &server, &port, &ip_version );
275 if( !server )
276 {
277 n_log( LOG_ERR, "No server given. Exiting." );
278 exit( -1 );
279 }
280 if( !port )
281 {
282 n_log( LOG_ERR, "No port given. Exiting." );
283 exit( -1 );
284 }
285
286#ifdef __linux__
287 struct sigaction sa;
288 sa.sa_handler = netw_sigchld_handler; // reap all dead processes
289 sigemptyset(&sa.sa_mask);
290 sa.sa_flags = SA_RESTART;
291 if (sigaction(SIGCHLD, &sa, NULL) == -1)
292 {
293 perror("sigaction");
294 exit(1);
295 }
296#endif
297
298 n_log( LOG_NOTICE, "%s is starting ...", argv[ 0 ] );
299
300 /* allegro 5 + addons loading */
301 if (!al_init())
302 {
303 n_abort("Could not init Allegro.\n");
304 }
305 if (!al_install_audio())
306 {
307 n_abort("Unable to initialize audio addon\n");
308 }
309 if (!al_init_acodec_addon())
310 {
311 n_abort("Unable to initialize acoded addon\n");
312 }
313 if (!al_init_image_addon())
314 {
315 n_abort("Unable to initialize image addon\n");
316 }
317 if (!al_init_primitives_addon() )
318 {
319 n_abort("Unable to initialize primitives addon\n");
320 }
321 if( !al_init_font_addon() )
322 {
323 n_abort("Unable to initialize font addon\n");
324 }
325 if( !al_init_ttf_addon() )
326 {
327 n_abort("Unable to initialize ttf_font addon\n");
328 }
329 if( !al_install_keyboard() )
330 {
331 n_abort("Unable to initialize keyboard handler\n");
332 }
333 if( !al_install_mouse())
334 {
335 n_abort("Unable to initialize mouse handler\n");
336 }
337 ALLEGRO_EVENT_QUEUE *event_queue = NULL;
338
339 event_queue = al_create_event_queue();
340 if(!event_queue)
341 {
342 fprintf(stderr, "failed to create event_queue!\n");
343 al_destroy_display(display);
344 return -1;
345 }
346
347 fps_timer = al_create_timer( 1.0/60.0 );
348 logic_timer = al_create_timer( 1.0/60.0 );
349 network_heartbeat_timer = al_create_timer( 1.0/10.0 );
350
351 al_set_new_display_flags( ALLEGRO_OPENGL|ALLEGRO_WINDOWED );
352 display = al_create_display( WIDTH, HEIGHT );
353 if( !display )
354 {
355 n_abort("Unable to create display\n");
356 }
357 al_set_window_title( display, argv[ 0 ] );
358
359 al_set_new_bitmap_flags( ALLEGRO_VIDEO_BITMAP );
360
361 peer_table = new_ht( 1024 );
362 chatbuf = new_generic_list( 1000 );
363 chat_line = al_ustr_new( "" );
364 font = al_load_font( "2Dumb.ttf", 18, 0 );
365 if (! font )
366 {
367 n_log( LOG_ERR, "Unable to load 2Dumb.ttf" );
368 exit( 1 );
369 }
370 al_register_event_source(event_queue, al_get_display_event_source(display));
371
372 al_start_timer( fps_timer );
373 al_start_timer( logic_timer );
374 al_start_timer( network_heartbeat_timer );
375
376 al_register_event_source(event_queue, al_get_timer_event_source(fps_timer));
377 al_register_event_source(event_queue, al_get_timer_event_source(logic_timer));
378 al_register_event_source(event_queue, al_get_timer_event_source(network_heartbeat_timer));
379
380 al_register_event_source(event_queue, al_get_keyboard_event_source());
381 al_register_event_source(event_queue, al_get_mouse_event_source());
382
383 ALLEGRO_BITMAP *scrbuf = al_create_bitmap( WIDTH, HEIGHT );
384
385 al_hide_mouse_cursor(display);
386
387 if( netw_connect( &netw, server, port, ip_version ) != TRUE )
388 {
389 n_log( LOG_ERR, "Could not connect to %s:%s", _str( server ), _str( port ) );
390 }
392
393 name = char_to_nstr( "ClientName" );
394 password = char_to_nstr( "ClientPassword" );
395
396 if( netw_send_ident( netw, NETMSG_IDENT_REQUEST, 0, name, password ) == FALSE )
397 {
398 n_log( LOG_ERR, "Sending ident request failed" );
399 goto exit_client;
400 }
401 n_log( LOG_INFO,"Ident request sended");
402
403 unsigned long int ident_timeout = 10000000 ;
404 do
405 {
406 netw_exchange = netw_get_msg( netw );
407 if( netw_exchange )
408 {
409 int type = netw_msg_get_type( netw_exchange );
410 if( type == NETMSG_IDENT_REPLY_OK )
411 {
412 break ;
413 }
414 if( type == NETMSG_IDENT_REPLY_NOK )
415 {
416 n_log( LOG_ERR, "Login refused !!!" );
417 goto exit_client ;
418 }
419 }
420 ident_timeout -= 1000 ;
421 usleep( 1000 );
422 }
423 while( ident_timeout > 0 );
424 free_nstr( &name );
425 free_nstr( &password );
426 netw_get_ident( netw_exchange, &it, &ident, &name, &password );
427 n_log( LOG_INFO,"Id Message received, pointer:%p size %d id %d", netw_exchange -> data, netw_exchange -> length, ident );
428
429 if( ident == -1 )
430 {
431 n_log( LOG_ERR,"No ident received");
432 goto exit_client;
433 }
434 /* We got our id ! */
435 n_log( LOG_NOTICE, "Id is:%d", ident );
436 DONE = 0 ;
437 QUIT_ASKED = 0 ;
438
439 al_clear_keyboard_state( NULL );
440 al_flush_event_queue( event_queue );
441 do
442 {
443 do
444 {
445 ALLEGRO_EVENT ev ;
446
447 al_wait_for_event(event_queue, &ev);
448
449 if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
450 {
451 switch(ev.keyboard.keycode)
452 {
453 case ALLEGRO_KEY_UP:
454 key[KEY_UP] = 1;
455 break;
456 case ALLEGRO_KEY_DOWN:
457 key[KEY_DOWN] = 1;
458 break;
459 case ALLEGRO_KEY_LEFT:
460 key[KEY_LEFT] = 1;
461 break;
462 case ALLEGRO_KEY_RIGHT:
463 key[KEY_RIGHT] = 1;
464 break;
465 case ALLEGRO_KEY_ESCAPE:
466 key[KEY_ESC] = 1 ;
467 break;
468 case ALLEGRO_KEY_SPACE:
469 key[KEY_SPACE] = 1 ;
470 break;
471 case ALLEGRO_KEY_LCTRL:
472 case ALLEGRO_KEY_RCTRL:
473 key[KEY_CTRL] = 1 ;
474 default:
475 break;
476 }
477 }
478 else if(ev.type == ALLEGRO_EVENT_KEY_UP)
479 {
480 switch(ev.keyboard.keycode)
481 {
482 case ALLEGRO_KEY_UP:
483 key[KEY_UP] = 0;
484 break;
485 case ALLEGRO_KEY_DOWN:
486 key[KEY_DOWN] = 0;
487 break;
488 case ALLEGRO_KEY_LEFT:
489 key[KEY_LEFT] = 0;
490 break;
491 case ALLEGRO_KEY_RIGHT:
492 key[KEY_RIGHT] =0;
493 break;
494 case ALLEGRO_KEY_ESCAPE:
495 key[KEY_ESC] = 0 ;
496 break;
497 case ALLEGRO_KEY_SPACE:
498 key[KEY_SPACE] = 0 ;
499 break;
500 case ALLEGRO_KEY_LCTRL:
501 case ALLEGRO_KEY_RCTRL:
502 key[KEY_CTRL] = 0 ;
503 default:
504 break;
505 }
506 }
507 else if( ev.keyboard.keycode == ALLEGRO_KEY_ENTER )
508 {
509 N_STR *txtmsg = new_nstr( 1024 );
510 al_ustr_trim_ws( chat_line ) ;
511 al_ustr_to_buffer( chat_line, txtmsg -> data, txtmsg -> length );
512
513 N_STR *netmsg = netmsg_make_string_msg( netw -> link . sock, -1, name, txtmsg, txtmsg, 1 );
514 netw_add_msg( netw, netmsg );
515 free_nstr( &txtmsg );
516
517 }
518 else if( ev.type == ALLEGRO_EVENT_TIMER )
519 {
520 if( al_get_timer_event_source( fps_timer ) == ev.any.source )
521 {
522 do_draw = 1 ;
523 }
524 else if( al_get_timer_event_source( logic_timer ) == ev.any.source )
525 {
526 do_logic = 1;
527 }
528 else if( al_get_timer_event_source( network_heartbeat_timer ) == ev.any.source )
529 {
530 do_network_update = 1;
531 }
532 }
533 else if( ev.type == ALLEGRO_EVENT_MOUSE_AXES )
534 {
535 mx = ev.mouse.x;
536 my = ev.mouse.y;
537 }
538 else if( ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN )
539 {
540 if( ev.mouse.button == 1 )
541 mouse_b1 = 1 ;
542 if( ev.mouse.button == 2 )
543 mouse_b2 = 1 ;
544 }
545 else if( ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP )
546 {
547 if( ev.mouse.button == 1 )
548 mouse_b1 = 0 ;
549 if( ev.mouse.button == 2 )
550 mouse_b2 = 0 ;
551 }
552 else if( ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE )
553 {
554 DONE = 1 ;
555 }
556 else if( ev.type == ALLEGRO_EVENT_DISPLAY_SWITCH_IN || ev.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT )
557 {
558 al_clear_keyboard_state( display );
559 al_flush_event_queue( event_queue );
560 }
561 else
562 {
563 /* Processing inputs */
564 get_keyboard( chat_line, ev );
565 }
566 }
567 while( !al_is_event_queue_empty( event_queue) );
568
569
570 if( do_logic == 1 )
571 {
572 N_STR *netmsg = NULL ;
573 netmsg = netw_get_msg( netw );
574 if( netmsg )
575 {
576 int type = -1 ;
577 type = netw_msg_get_type( netmsg );
578 switch( type )
579 {
580 case( NETMSG_GET_BOX ):
581 /* ask for world box */
582 break ;
583 case( NETMSG_BOX ):
584 /* a world object at position X,Y,Z with associated datas, add/update local world cache */
585 break ;
586 case( NETMSG_POSITION ):
587 {
588
589 /* add/update object with id at position */
590 double pos[ 3 ];
591 double spe[ 3 ];
592 int id = -1, timestamp = -1 ;
593 netw_get_position( netmsg, &id, &pos[ 0 ],&pos[ 1 ],&pos[ 2 ], &spe[ 0 ], &spe[ 1 ], &spe[ 2 ], &timestamp );
594 // too much log n_log( LOG_INFO, "Received position from %d: %g %g", id, pos[ 0 ], pos[ 1 ] );
595 update_peer( peer_table, id, pos );
596 }
597 break;
598 case( NETMSG_STRING ):
599 {
600 /* add text to chat */
601 int id = -1, color = -1 ;
602 N_STR *name = NULL, *txt = NULL, *chan = NULL ;
603 netw_get_string( netmsg, &id, &name, &chan, &txt, &color );
604 n_log( LOG_INFO, "Received chat from %s:%s:%s (id: %d , color:%d)", name, chan, txt, id, color );
605 }
606 break;
607 case( NETMSG_PING_REQUEST ):
608 /* compare to sent pings and add string to chat with times */
609 break;
610 case( NETMSG_PING_REPLY ):
611 /* compare to sent pings and add string to chat with times */
612 break;
613 case( NETMSG_QUIT ):
614 n_log( LOG_INFO, "Quit received !" );
615 DONE = 1 ;
616 break ;
617 default:
618 n_log( LOG_ERR, "Unknow message type %d", type );
619 DONE = 1 ;
620 break ;
621 }
622 }
623 ping_time += 1.0 / 60.0 ;
624
625 if( key[KEY_ESC] )
626 {
627 if( QUIT_ASKED != 1 )
628 {
629 QUIT_ASKED = 1 ;
630 n_log( LOG_INFO, "Asking server to quit..." );
632 }
633 }
634 manage_peers( peer_table, 1000000 / 60.0 );
635 do_logic = 0 ;
636 }
637
638 if( do_draw == 1 )
639 {
640 al_acknowledge_resize( display );
641 int w = al_get_display_width( display );
642 int h = al_get_display_height( display );
643
644 al_set_target_bitmap( scrbuf );
645 al_clear_to_color( al_map_rgba( 0, 0, 0, 255 ) );
646
647 al_set_target_bitmap( al_get_backbuffer( display ) );
648
649 al_clear_to_color( al_map_rgba( 0, 0, 0, 255 ) );
650 al_draw_bitmap( scrbuf, 0, 0, 0 );
651
652 /* mouse pointer */
653 /*al_draw_line( mx - 5, my, mx + 5, my, al_map_rgb( 255, 0, 0 ), 1 );
654 al_draw_line( mx, my + 5, mx, my - 5, al_map_rgb( 255, 0, 0 ), 1 );*/
655
656 draw_peers( peer_table, font, white_color );
657
658 al_draw_ustr( font, white_color, 0, HEIGHT - 20, ALLEGRO_ALIGN_LEFT, chat_line );
659
660 al_flip_display();
661 do_draw = 0 ;
662 }
663
664 if( do_network_update == 1 )
665 {
666 /* send position here */
667 netw_send_position( netw, ident, mx, my, 0, 0, 0, 0, 0 );
668 do_network_update = 0 ;
669 }
670
671 }
672 while( !DONE );
673
674exit_client:
676
677 return 0;
678
679}
void usage(void)
Definition: ex_common.c:20
void process_args(int argc, char **argv)
Definition: ex_common.c:27
int main(void)
Definition: ex_exceptions.c:71
#define WIDTH
ALLEGRO_TIMER * fps_timer
int getoptret
int DONE
int log_level
ALLEGRO_BITMAP * scr_buf
#define HEIGHT
ALLEGRO_TIMER * logic_timer
ALLEGRO_DISPLAY * display
long int life_time
current life time, updated when receiving a position from a peer.
int id
remote object id
int draw_peers(HASH_TABLE *peer_table, ALLEGRO_FONT *font, ALLEGRO_COLOR color)
double position[3]
last received object position
int key[7]
APP_KEYS
@ KEY_SPACE
@ KEY_CTRL
@ KEY_UP
@ KEY_LEFT
@ KEY_RIGHT
@ KEY_DOWN
@ KEY_ESC
int update_peer(HASH_TABLE *peer_table, int id, double position[3])
int manage_peers(HASH_TABLE *peer_table, int delta_t)
a simple structure to hold objects positions / timeouts
NETWORK * server
Definition: ex_network.c:17
static pthread_t netw_thr
Definition: ex_network.c:22
int ip_version
Definition: ex_network.c:20
NETWORK * netw
Network for server mode, accepting incomming.
Definition: ex_network.c:18
int get_keyboard(ALLEGRO_USTR *str, ALLEGRO_EVENT event)
update a keyboard buffer from an event
Definition: n_allegro5.c:19
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
Definition: n_common.h:183
#define __n_assert(__ptr, __ret)
macro to assert things
Definition: n_common.h:276
#define _str(__PTR)
define true
Definition: n_common.h:172
void n_abort(char const *format,...)
abort program with a text
Definition: n_common.c:38
#define _nstr(__PTR)
N_STR or "NULL" string for logging purposes.
Definition: n_common.h:178
int ht_put_ptr_ex(HASH_TABLE *table, unsigned long int hash_value, void *val, void(*destructor)(void *ptr))
put a pointer value with given key in the targeted hash table (HASH_CLASSIC only)
Definition: n_hash.c:2526
#define ht_foreach(__ITEM_, __HASH_)
ForEach macro helper (classic / old)
Definition: n_hash.h:163
int ht_remove_ex(HASH_TABLE *table, unsigned long int hash_value)
Remove a key from a hash table (HASH_CLASSIC only)
Definition: n_hash.c:2582
HASH_TABLE * new_ht(unsigned long int size)
Create a hash table with the given size.
Definition: n_hash.c:2169
int ht_get_ptr_ex(HASH_TABLE *table, unsigned long int hash_value, void **val)
Retrieve a pointer value in the hash table, at the given key.
Definition: n_hash.c:2496
#define hash_val(node, type)
Cast a HASH_NODE element.
Definition: n_hash.h:159
structure of a hash table
Definition: n_hash.h:109
int list_push(LIST *list, void *ptr, void(*destructor)(void *ptr))
Add a pointer to the end of the list.
Definition: n_list.c:244
#define list_foreach(__ITEM_, __LIST_)
ForEach macro helper.
Definition: n_list.h:70
LIST * new_generic_list(int max_items)
Initialiaze a generic list container to max_items pointers.
Definition: n_list.c:20
Structure of a generic LIST container.
Definition: n_list.h:45
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition: n_log.h:74
#define LOG_DEBUG
debug-level messages
Definition: n_log.h:66
#define LOG_ERR
error conditions
Definition: n_log.h:58
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
Definition: n_log.c:97
#define LOG_NOTICE
normal but significant condition
Definition: n_log.h:62
#define LOG_NULL
no log output
Definition: n_log.h:27
#define LOG_INFO
informational
Definition: n_log.h:64
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
Definition: n_str.h:222
#define nstrprintf(__nstr_var,...)
Macro to quickly allocate and sprintf to N_STR *.
Definition: n_str.h:97
N_STR * char_to_nstr(const char *src)
Convert a char into a N_STR, short version.
Definition: n_str.c:274
N_STR * new_nstr(NSTRBYTE size)
create a new N_STR string
Definition: n_str.c:215
A box including a string and his lenght.
Definition: n_str.h:173
#define NETMSG_IDENT_REQUEST
Network Message is identification request: (int)type , (int)id , (N_STR *)name , (N_STR *)password.
Definition: n_network_msg.h:27
int netw_get_position(N_STR *msg, int *id, double *X, double *Y, double *vx, double *vy, double *acc_x, double *acc_y, int *time_stamp)
Retrieves position from netwmsg.
#define NETMSG_PING_REQUEST
Network Message is ping request: (int)type , (int)id_from , (int)id_to.
Definition: n_network_msg.h:37
#define NETMSG_IDENT_REPLY_NOK
Network Message is identification reply NON OK: (int)type , (int)id , (N_STR *)name ,...
Definition: n_network_msg.h:31
#define NETMSG_STRING
Network Message is string: (int)type , (int)id , (N_STR *)name , (N_STR *)chan , (N_STR *)text ,...
Definition: n_network_msg.h:33
#define NETMSG_PING_REPLY
Network Message is ping reply: (int)type , (int)id_from , (int)id_to.
Definition: n_network_msg.h:39
#define NETMSG_QUIT
Network asking for exit.
Definition: n_network_msg.h:45
#define NETMSG_POSITION
Network Message position: (int)type , (int)id , (int)X , (int)Y , (int)x_shift , (int)y_shift ,...
Definition: n_network_msg.h:35
int netw_msg_get_type(N_STR *msg)
Get the type of message without killing the first number. Use with netw_get_XXX.
#define NETMSG_BOX
Network Message is box retrieving reply: (int x , int y , int z , N_STR *data )
Definition: n_network_msg.h:43
#define NETMSG_GET_BOX
Network Message is box retrieve: int x , int y , int z.
Definition: n_network_msg.h:41
#define NETMSG_IDENT_REPLY_OK
Network Message is identification reply OK : (int)type , (int)id , (N_STR *)name ,...
Definition: n_network_msg.h:29
int netw_get_string(N_STR *msg, int *id, N_STR **name, N_STR **chan, N_STR **txt, int *color)
Retrieves string from netwmsg.
int netw_get_ident(N_STR *msg, int *type, int *ident, N_STR **name, N_STR **passwd)
Retrieves identification from netwmsg.
N_STR * netmsg_make_string_msg(int id_from, int id_to, N_STR *name, N_STR *chan, N_STR *txt, int color)
make a network NETMSG_STRING message with given parameters
N_STR * netw_get_msg(NETWORK *netw)
Get a message from aimed NETWORK.
Definition: n_network.c:2067
int netw_add_msg(NETWORK *netw, N_STR *msg)
Add a message to send in aimed NETWORK.
Definition: n_network.c:1988
#define NETWORK_IPV6
Flag to force IPV6
Definition: n_network.h:31
int netw_start_thr_engine(NETWORK *netw)
Start the NETWORK netw Threaded Engine.
Definition: n_network.c:2151
#define NETWORK_IPV4
Flag to force IPV4
Definition: n_network.h:29
int netw_wait_close(NETWORK **netw)
Wait for peer closing a specified Network, destroy queues, free the structure.
Definition: n_network.c:1597
#define NETWORK_IPALL
Flag for auto detection by OS of ip version to use.
Definition: n_network.h:27
int netw_send_quit(NETWORK *netw)
Add a formatted NETMSG_QUIT message to the specified network.
Definition: n_network.c:3215
int netw_connect(NETWORK **netw, char *host, char *port, int ip_version)
Use this to connect a NETWORK to any listening one, unrestricted send/recv lists.
Definition: n_network.c:1384
int netw_send_ident(NETWORK *netw, int type, int id, N_STR *name, N_STR *passwd)
Add a formatted NETWMSG_IDENT message to the specified network.
Definition: n_network.c:3121
int netw_send_position(NETWORK *netw, int id, double X, double Y, double vx, double vy, double acc_x, double acc_y, int time_stamp)
Add a formatted NETWMSG_IDENT message to the specified network.
Definition: n_network.c:3148
Structure of a NETWORK.
Definition: n_network.h:254
Allegro5 helpers.
Common headers and low-level hugly functions & define.
Hash functions and table.
List structures and definitions.
Network Engine.
Network messages , serialization tools.
N_STR and string function declaration.