Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
ex_gui_netserver.c
Go to the documentation of this file.
1
7#define WIDTH 640
8#define HEIGHT 480
9
10#include "nilorea/n_common.h"
11#include "nilorea/n_str.h"
12#include "nilorea/n_list.h"
13#include "nilorea/n_hash.h"
14#include "nilorea/n_network.h"
16#include "nilorea/n_user.h"
17
18#include <allegro5/allegro.h>
19#include <allegro5/allegro_audio.h>
20#include <allegro5/allegro_acodec.h>
21#include <allegro5/allegro_font.h>
22#include <allegro5/allegro_image.h>
23#include <allegro5/allegro_primitives.h>
24#include <allegro5/allegro_ttf.h>
25
26void usage(void)
27{
28 fprintf( stderr, " -v version\n"
29 " -V log level: LOG_INFO, LOG_NOTICE, LOG_ERR, LOG_DEBUG\n"
30 " -h help\n"
31 " -a serveur address name/ip to bind (server mode)\n"
32 " -p port\n"
33 " -i [v4,v6] ip version (default support both ipv4 and ipv6 )\n" );
34} /* usage() */
35
36
37
38void process_args( int argc, char **argv, char **bind_addr, char **port, int *ip_version )
39{
40 int getoptret = 0,
41 log_level = LOG_ERR; /* default log level */
42
43 /* Arguments optionnels */
44 /* -v version
45 * -V log level
46 * -h help
47 * -a serveur address name/ip to bind (server mode, optionnal)
48 * -p port
49 * -i v4 ip version (default support both ipv4 and ipv6 )
50 * -i v6 ip version ( " " " " " " )
51 */
52 if( argc == 1 )
53 {
54 fprintf( stderr, "No arguments given, help:\n" );
55 usage();
56 exit( 1 );
57 }
58 while( ( getoptret = getopt( argc, argv, "hva:p:i:V:" ) ) != EOF)
59 {
60 switch( getoptret )
61 {
62 case 'i' :
63 if( !strcmp( "v4", optarg ) )
64 {
65 (*ip_version) = NETWORK_IPV4 ;
66 n_log( LOG_NOTICE, "IPV4 selected" );
67 }
68 else if( !strcmp( "v6", optarg ) )
69 {
70 (*ip_version) = NETWORK_IPV6 ;
71 n_log( LOG_NOTICE, "IPV6 selected" );
72 }
73 else
74 {
75 n_log( LOG_NOTICE, "IPV4/6 selected" );
76 }
77 break;
78 case 'v' :
79 fprintf( stderr, "Date de compilation : %s a %s.\n", __DATE__, __TIME__ );
80 exit( 1 );
81 case 'V' :
82 if( !strncmp( "LOG_NULL", optarg, 8 ) )
83 {
85 }
86 else
87 {
88 if( !strncmp( "LOG_NOTICE", optarg, 10 ) )
89 {
91 }
92 else
93 {
94 if( !strncmp( "LOG_INFO", optarg, 8 ) )
95 {
97 }
98 else
99 {
100 if( !strncmp( "LOG_ERR", optarg, 7 ) )
101 {
103 }
104 else
105 {
106 if( !strncmp( "LOG_DEBUG", optarg, 9 ) )
107 {
109 }
110 else
111 {
112 fprintf( stderr, "%s n'est pas un niveau de log valide.\n", optarg );
113 exit( -1 );
114 }
115 }
116 }
117 }
118 }
119 break;
120 case 'a' :
121 (*bind_addr) = strdup( optarg );
122 break ;
123 case 'p' :
124 (*port) = strdup( optarg );
125 break ;
126 default :
127 case '?' :
128 if( optopt == 'V' )
129 {
130 fprintf( stderr, "\n Missing log level\n" );
131 }
132 else if( optopt == 'p' )
133 {
134 fprintf( stderr, "\n Missing port\n" );
135 }
136 else if( optopt != 's' )
137 {
138 fprintf( stderr, "\n Unknow missing option %c\n", optopt );
139 }
140 usage();
141 exit( 1 );
142 break ;
143 case 'h' :
144 usage();
145 exit( 1 );
146 break ;
147 }
148 }
150} /* void process_args( ... ) */
151
152
153
154int process_clients( NETWORK_POOL *netw_pool, N_USERLIST *userlist )
155{
156 __n_assert( netw_pool, return FALSE );
157
158 LIST *netw_to_close = NULL ;
159
160 netw_to_close = new_generic_list( -1 );
161
162 /* write lock the pool */
163 read_lock( netw_pool -> rwlock );
164 HT_FOREACH( node, netw_pool -> pool,
165 {
166 N_STR *netw_exchange = NULL ;
167 NETWORK *netw = HASH_VAL( node, NETWORK );
168 int state = -1 ;
169 int thr_engine_status = -1 ;
170 netw_get_state( netw, &state, &thr_engine_status );
171 if( state != NETW_RUN || thr_engine_status != NETW_THR_ENGINE_STARTED )
172 list_push( netw_to_close, netw, NULL );
173
174 /* process all data sent by the client */
175 while( ( netw_exchange = netw_get_msg( netw ) ) )
176 {
177 int type = netw_msg_get_type( netw_exchange ) ;
178 switch( type )
179 {
180 case( NETMSG_POSITION ):
181 // add/update object with id at position
182 userlist_add_msg_to_all( userlist, netw_exchange );
183 break;
184 case( NETMSG_STRING ):
185 // directly add text to chat
186 netw_pool_broadcast( netw_pool, NULL, netw_exchange );
187 break;
188 case( NETMSG_PING_REQUEST ):
189 {
190 // directly send back reply
191 int id_from = -1, id_to = -1, time = -1, type = -1 ;
192 netw_get_ping( netw_exchange, &id_from, &id_to, &time, &type );
193 if( id_to == -1 )
194 {
195 netw_send_ping( netw, NETMSG_PING_REPLY, id_to, id_from, time );
196 }
197 else
198 {
199 N_STR *pingmsg = netmsg_make_ping( NETMSG_PING_REQUEST, id_from, id_to, time );
200 userlist_add_msg_to( userlist, pingmsg, id_to );
201 }
202 }
203 //netw_get_ping( )
204 break ;
205 case( NETMSG_GET_BOX ):
206 // a world object at position X,Y,Z with associated datas, add/update local world cache
207 break;
208 case( NETMSG_IDENT_REQUEST ):
209 {
210 N_STR *name = NULL, *passwd = NULL ;
211 int d_it = 0, ident = 0 ;
212 netw_get_ident( netw_exchange, &d_it, &ident, &name, &passwd );
213 n_log( LOG_NOTICE, "Ident %d received", netw -> link . sock );
214 netw_send_ident( netw, NETMSG_IDENT_REPLY_OK, netw -> link . sock, name, passwd );
215 n_log( LOG_NOTICE, "Answer sent", netw -> link . sock );
216 }
217 break ;
218 case( NETMSG_QUIT ):
219 n_log( LOG_INFO, "Client is asking us to quit" );
221 list_push( netw_to_close, netw, NULL );
222 break ;
223 default:
224 n_log( LOG_ERR, "Unknow message type %d", type );
225 break ;
226 }
227 free_nstr( &netw_exchange );
228 }
229 });
230 unlock( netw_pool -> rwlock );
231
232 NETWORK *netw = NULL ;
233 LIST_NODE *node = netw_to_close -> start ;
234 while( node && node -> ptr )
235 {
236 NETWORK *netw = (NETWORK *)node -> ptr ;
237 if( netw )
238 {
239 n_log( LOG_DEBUG, "Closing %d", netw -> link . sock );
240 userlist_del_user( userlist, netw -> user_id );
241 netw_close( &netw );
242 }
243 else
244 {
245 n_log( LOG_DEBUG, "Already closed: duplicated quit message" );
246 }
247 node = node -> next ;
248 };
249 list_destroy( &netw_to_close );
250
251 return TRUE ;
252} /* process clients datas */
253
254
255
256int main( int argc, char *argv[] )
257{
258 ALLEGRO_DISPLAY *display = NULL ;
259
260 int DONE = 0, /* Flag to check if we are always running */
261 getoptret = 0, /* launch parameter check */
262 log_level = LOG_ERR, /* default log level */
264
265 ALLEGRO_BITMAP *scr_buf = NULL ;
266
267 ALLEGRO_TIMER *fps_timer = NULL ;
268 ALLEGRO_TIMER *logic_timer = NULL ;
269 ALLEGRO_TIMER *network_heartbeat_timer = NULL ;
270
271 NETWORK *server = NULL ;
272 NETWORK_POOL *netw_pool = NULL ;
273 N_USERLIST *userlist = NULL ;
274 char *bind_addr = NULL,
275 *port = NULL ;
276
278
279 /* processing args and set log_level */
280 process_args( argc, argv, &bind_addr, &port, &ip_version );
281 if( !port )
282 {
283 n_log( LOG_ERR, "No port given. Exiting." );
284 exit( -1 );
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 netw_pool = netw_new_pool( 1024 );
299 __n_assert( netw_pool, goto exit_server );
300
301 userlist = userlist_new( 256 );
302 __n_assert( userlist, goto exit_server );
303
304 n_log( LOG_INFO, "Creating listening network for %s:%s %d", _str( bind_addr ), _str( port ), ip_version );
305 /* create listening network */
306 if( netw_make_listening( &server, bind_addr, port, 128, ip_version ) == FALSE )
307 {
308 n_log( LOG_ERR, "Fatal error with network initialization" );
309 goto exit_server ;
310 }
311
312 n_log( LOG_NOTICE, "%s is starting ...", argv[ 0 ] );
313 /* allegro 5 + addons loading */
314 if (!al_init())
315 {
316 n_abort("Could not init Allegro.\n");
317 }
318 if (!al_install_audio())
319 {
320 n_abort("Unable to initialize audio addon\n");
321 }
322 if (!al_init_acodec_addon())
323 {
324 n_abort("Unable to initialize acoded addon\n");
325 }
326 if (!al_init_image_addon())
327 {
328 n_abort("Unable to initialize image addon\n");
329 }
330 if (!al_init_primitives_addon() )
331 {
332 n_abort("Unable to initialize primitives addon\n");
333 }
334 if( !al_init_font_addon() )
335 {
336 n_abort("Unable to initialize font addon\n");
337 }
338 if( !al_init_ttf_addon() )
339 {
340 n_abort("Unable to initialize ttf_font addon\n");
341 }
342 if( !al_install_keyboard() )
343 {
344 n_abort("Unable to initialize keyboard handler\n");
345 }
346 if( !al_install_mouse())
347 {
348 n_abort("Unable to initialize mouse handler\n");
349 }
350 ALLEGRO_EVENT_QUEUE *event_queue = NULL;
351
352 event_queue = al_create_event_queue();
353 if(!event_queue)
354 {
355 fprintf(stderr, "failed to create event_queue!\n");
356 al_destroy_display(display);
357 return -1;
358 }
359
360 fps_timer = al_create_timer( 1.0/30.0 ); /* low fps on the server */
361 logic_timer = al_create_timer( 1.0/100.0 ); /* 100 hz == higher logic processing */
362 network_heartbeat_timer = al_create_timer( 1.0/10.0 ); /* frequency of the clients answers */
363
364 al_set_new_display_flags( ALLEGRO_OPENGL|ALLEGRO_WINDOWED );
365 display = al_create_display( WIDTH, HEIGHT );
366 if( !display )
367 {
368 n_abort("Unable to create display\n");
369 }
370 al_set_window_title( display, argv[ 0 ] );
371
372 al_set_new_bitmap_flags( ALLEGRO_VIDEO_BITMAP );
373
374 DONE = 0 ;
375
377
378 enum APP_KEYS
379 {
381 };
382 int key[ 7 ] = {false,false,false,false,false,false,false};
383
384 al_register_event_source(event_queue, al_get_display_event_source(display));
385 al_register_event_source(event_queue, al_get_keyboard_event_source());
386 al_register_event_source(event_queue, al_get_mouse_event_source());
387
388 al_start_timer( fps_timer );
389 al_start_timer( logic_timer );
390 al_start_timer( logic_timer );
391 al_register_event_source(event_queue, al_get_timer_event_source(fps_timer));
392 al_register_event_source(event_queue, al_get_timer_event_source(logic_timer));
393 al_register_event_source(event_queue, al_get_timer_event_source(logic_timer));
394
395 ALLEGRO_BITMAP *scrbuf = al_create_bitmap( WIDTH, HEIGHT );
396 ALLEGRO_COLOR white_color = al_map_rgba_f(1, 1, 1, 1);
397 ALLEGRO_FONT *font = NULL ;
398 font = al_load_font( "2Dumb.ttf", 18, 0 );
399 if (! font )
400 {
401 n_log( LOG_ERR, "Unable to load 2Dumb.ttf" );
402 exit( 1 );
403 }
404
405 al_hide_mouse_cursor(display);
406
407 int mx = 0, my = 0, mouse_b1 = 0, mouse_b2 = 0 ;
408 int do_draw = 0, do_logic = 0, do_network = 0 ;
409
410 al_clear_keyboard_state( NULL );
411 al_flush_event_queue( event_queue );
412 do
413 {
414
415 do
416 {
417 ALLEGRO_EVENT ev ;
418
419 al_wait_for_event(event_queue, &ev);
420
421 if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
422 {
423 switch(ev.keyboard.keycode)
424 {
425 case ALLEGRO_KEY_UP:
426 key[KEY_UP] = 1;
427 break;
428 case ALLEGRO_KEY_DOWN:
429 key[KEY_DOWN] = 1;
430 break;
431 case ALLEGRO_KEY_LEFT:
432 key[KEY_LEFT] = 1;
433 break;
434 case ALLEGRO_KEY_RIGHT:
435 key[KEY_RIGHT] = 1;
436 break;
437 case ALLEGRO_KEY_ESCAPE:
438 key[KEY_ESC] = 1 ;
439 break;
440 case ALLEGRO_KEY_SPACE:
441 key[KEY_SPACE] = 1 ;
442 break;
443 case ALLEGRO_KEY_LCTRL:
444 case ALLEGRO_KEY_RCTRL:
445 key[KEY_CTRL] = 1 ;
446 default:
447 break;
448 }
449 }
450 else if(ev.type == ALLEGRO_EVENT_KEY_UP)
451 {
452 switch(ev.keyboard.keycode)
453 {
454 case ALLEGRO_KEY_UP:
455 key[KEY_UP] = 0;
456 break;
457 case ALLEGRO_KEY_DOWN:
458 key[KEY_DOWN] = 0;
459 break;
460 case ALLEGRO_KEY_LEFT:
461 key[KEY_LEFT] = 0;
462 break;
463 case ALLEGRO_KEY_RIGHT:
464 key[KEY_RIGHT] =0;
465 break;
466 case ALLEGRO_KEY_ESCAPE:
467 key[KEY_ESC] = 0 ;
468 break;
469 case ALLEGRO_KEY_SPACE:
470 key[KEY_SPACE] = 0 ;
471 break;
472 case ALLEGRO_KEY_LCTRL:
473 case ALLEGRO_KEY_RCTRL:
474 key[KEY_CTRL] = 0 ;
475 default:
476 break;
477 }
478 }
479 else if( ev.type == ALLEGRO_EVENT_TIMER )
480 {
481 if( al_get_timer_event_source( fps_timer ) == ev.any.source )
482 {
483 do_draw = 1 ;
484 }
485 else if( al_get_timer_event_source( logic_timer ) == ev.any.source )
486 {
487 do_logic = 1;
488 }
489 else if( al_get_timer_event_source( network_heartbeat_timer ) == ev.any.source )
490 {
491 do_network = 1;
492 }
493 }
494 else if( ev.type == ALLEGRO_EVENT_MOUSE_AXES )
495 {
496 mx = ev.mouse.x;
497 my = ev.mouse.y;
498 }
499 else if( ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN )
500 {
501 if( ev.mouse.button == 1 )
502 mouse_b1 = 1 ;
503 if( ev.mouse.button == 2 )
504 mouse_b2 = 1 ;
505 }
506 else if( ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP )
507 {
508 if( ev.mouse.button == 1 )
509 mouse_b1 = 0 ;
510 if( ev.mouse.button == 2 )
511 mouse_b2 = 0 ;
512 }
513 else if( ev.type == ALLEGRO_EVENT_DISPLAY_SWITCH_IN || ev.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT )
514 {
515 al_clear_keyboard_state( display );
516 al_flush_event_queue( event_queue );
517 }
518 else
519 {
520 /* Processing inputs */
521 // get_keyboard( chat_line , ev );
522 }
523 }
524 while( !al_is_event_queue_empty( event_queue) );
525
526
527
528 if( do_logic == 1 )
529 {
530 if( key[ KEY_UP ] )
531 {
532 }
533 else
534 {
535 }
536 if( key[ KEY_DOWN ] )
537 {
538 }
539 else
540 {
541 }
542 if( key[ KEY_LEFT ] )
543 {
544 }
545 else
546 {
547 }
548 if( key[ KEY_RIGHT ] )
549 {
550 }
551 else
552 {
553 }
554 /* accept new connections */
555 NETWORK *netw = NULL ;
556 int error = 0 ;
557 if ( ( netw = netw_accept_from_ex( server, 0, 0, -1, &error ) ) )
558 {
559 int id = userlist_add_user( userlist, netw );
560 if( id >= 0 )
561 {
562 netw_set_user_id( netw, id );
563 }
565 netw_pool_add( netw_pool, netw );
566 }
567 process_clients( netw_pool, userlist );
568 do_logic = 0 ;
569 }
570 if( do_network == 1 )
571 {
572 /* process queues and send datas back to clients */
573 userlist_send_waiting_msgs( userlist );
574 do_network == 0 ;
575 }
576
577 if( do_draw == 1 )
578 {
579 al_acknowledge_resize( display );
580 int w = al_get_display_width( display );
581 int h = al_get_display_height( display );
582
583 al_set_target_bitmap( scrbuf );
584 al_clear_to_color( al_map_rgba( 0, 0, 0, 255 ) );
585
586 al_set_target_bitmap( al_get_backbuffer( display ) );
587
588 al_clear_to_color( al_map_rgba( 0, 0, 0, 255 ) );
589 al_draw_bitmap( scrbuf, 0, 0, 0 );
590
591 /* mouse pointer */
592 al_draw_line( mx - 5, my, mx + 5, my, al_map_rgb( 255, 0, 0 ), 1 );
593 al_draw_line( mx, my + 5, mx, my - 5, al_map_rgb( 255, 0, 0 ), 1 );
594
595 /* informations */
596 N_STR *textout = NULL ;
597 nstrprintf( textout, "Nb client: %d", netw_pool_nbclients( netw_pool) );
598 al_draw_text( font, white_color, 5, 5, ALLEGRO_ALIGN_LEFT, _nstr( textout ) );
599 free_nstr( &textout );
600
601 al_flip_display();
602 do_draw = 0 ;
603 }
604
605 }
606 while( !key[KEY_ESC] && !DONE );
607
608exit_server:
610
611 return 0;
612
613}
614
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
int key[7]
APP_KEYS
@ KEY_SPACE
@ KEY_CTRL
@ KEY_UP
@ KEY_LEFT
@ KEY_RIGHT
@ KEY_DOWN
@ KEY_ESC
int process_clients(NETWORK_POOL *netw_pool, N_USERLIST *userlist)
LIST * active_object
NETWORK * server
Definition: ex_network.c:17
int ip_version
Definition: ex_network.c:20
NETWORK * netw
Network for server mode, accepting incomming.
Definition: ex_network.c:18
#define __n_assert(__ptr, __ret)
macro to assert things
Definition: n_common.h:276
#define _str(__PTR)
define true
Definition: n_common.h:172
#define unlock(__rwlock_mutex)
Macro for releasing read/write lock a rwlock mutex.
Definition: n_common.h:409
void n_abort(char const *format,...)
abort program with a text
Definition: n_common.c:38
#define read_lock(__rwlock_mutex)
Macro for acquiring a read lock on a rwlock mutex.
Definition: n_common.h:377
#define _nstr(__PTR)
N_STR or "NULL" string for logging purposes.
Definition: n_common.h:178
#define HASH_VAL(node, type)
Cast a HASH_NODE element.
Definition: n_hash.h:191
#define HT_FOREACH(__ITEM_, __HASH_,...)
ForEach macro helper.
Definition: n_hash.h:195
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
int list_destroy(LIST **list)
Empty and Free a list container.
Definition: n_list.c:603
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
Structure of a generic list node.
Definition: n_list.h:27
#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
A box including a string and his lenght.
Definition: n_str.h:173
int userlist_del_user(N_USERLIST *ulist, int id)
delete an user from the list
Definition: n_user.c:134
int userlist_add_msg_to(N_USERLIST *ulist, N_STR *msg, int id)
add a N_STR *message to user list (USERLIST_ONE)
Definition: n_user.c:240
N_USERLIST * userlist_new(int max)
create a new N_USERLIST user list with 'max' users
Definition: n_user.c:16
int userlist_add_msg_to_all(N_USERLIST *ulist, N_STR *msg)
add a N_STR *message to user list (USERLIST_ALL)
Definition: n_user.c:252
int userlist_send_waiting_msgs(N_USERLIST *ulist)
send all waiting messages ofr each user of the lsit
Definition: n_user.c:362
int userlist_add_user(N_USERLIST *ulist, NETWORK *netw)
add an user to the list
Definition: n_user.c:101
USER list.
Definition: n_user.h:67
#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
#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_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
int netw_get_ping(N_STR *msg, int *type, int *from, int *to, int *time)
Retrieves a ping travel elapsed time.
#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_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
N_STR * netmsg_make_ping(int type, int id_from, int id_to, int time)
Make a ping message to send to a network.
int netw_get_ident(N_STR *msg, int *type, int *ident, N_STR **name, N_STR **passwd)
Retrieves identification from netwmsg.
int netw_pool_broadcast(NETWORK_POOL *netw_pool, NETWORK *from, N_STR *net_msg)
add net_msg to all network in netork pool
Definition: n_network.c:3030
N_STR * netw_get_msg(NETWORK *netw)
Get a message from aimed NETWORK.
Definition: n_network.c:2067
int netw_pool_nbclients(NETWORK_POOL *netw_pool)
return the number of networks in netw_pool
Definition: n_network.c:3061
#define NETWORK_IPV6
Flag to force IPV6
Definition: n_network.h:31
int netw_set_user_id(NETWORK *netw, int id)
associate an id and a network
Definition: n_network.c:3081
int netw_make_listening(NETWORK **netw, char *addr, char *port, int nbpending, int ip_version)
Make a NETWORK be a Listening network.
Definition: n_network.c:1690
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
NETWORK * netw_accept_from_ex(NETWORK *from, int send_list_limit, int recv_list_limit, int non_blocking, int *retval)
make a normal 'accept' .
Definition: n_network.c:1816
#define NETWORK_IPALL
Flag for auto detection by OS of ip version to use.
Definition: n_network.h:27
int netw_close(NETWORK **netw)
Closing a specified Network, destroy queues, free the structure.
Definition: n_network.c:1503
int netw_send_quit(NETWORK *netw)
Add a formatted NETMSG_QUIT message to the specified network.
Definition: n_network.c:3215
int netw_send_ping(NETWORK *netw, int type, int id_from, int id_to, int time)
Add a ping reply to the network.
Definition: n_network.c:3099
NETWORK_POOL * netw_new_pool(int nb_min_element)
return a new network pool of nb_min_element
Definition: n_network.c:2876
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_pool_add(NETWORK_POOL *netw_pool, NETWORK *netw)
add a NETWORK *netw to a NETWORK_POOL *pool
Definition: n_network.c:2936
int netw_get_state(NETWORK *netw, int *state, int *thr_engine_status)
Get the state of a network.
Definition: n_network.c:1399
@ NETW_THR_ENGINE_STARTED
Definition: n_network.h:226
@ NETW_RUN
Definition: n_network.h:226
Structure of a NETWORK.
Definition: n_network.h:254
structure of a network pool
Definition: n_network.h:342
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.
USERS handling for tiny game apps.