/* ==================================================================== Close chatroom and return to LBreakout's menu. ==================================================================== */ void client_quit( GuiWidget *widget, GuiEvent *event ) { if ( event->type == GUI_CLICKED ) gui_widget_hide( dlg_chatroom ); /* disconnect is handled in client_run to cover * stk_quit_requests as well */ }
/* ==================================================================== Close statistics ==================================================================== */ void client_close_stats( GuiWidget *widget, GuiEvent *event ) { if ( event->type != GUI_CLICKED ) return; gui_widget_hide( dlg_stats ); client_state = CLIENT_NONE; gui_label_set_text( label_stats, _("Awaiting stats...") ); gui_label_set_text( label_winner, "..." ); }
void close_pause_chat( void ) { gui_widget_hide( dlg_pauseroom ); set_state( CS_PLAY ); /* enable event filter */ SDL_SetEventFilter( event_filter ); gui_widget_enable_event( dlg_chatroom, GUI_TIME_PASSED ); }
void client_cancel( GuiWidget *widget, GuiEvent *event ) { #ifdef NETWORK_ENABLED if ( event->type != GUI_CLICKED ) return; gui_widget_hide( dlg_confirm ); msg_begin_writing( msgbuf, &msglen, MAX_MSG_SIZE ); switch ( client_state ) { case CLIENT_ANSWER: msg_write_int8( MSG_REJECT_CHALLENGE ); break; } client_transmit( CODE_BLUE, msglen, msgbuf ); client_state = CLIENT_NONE; #endif }
/* ==================================================================== Close the info window and clear state. ==================================================================== */ void client_close_info( GuiWidget *widget, GuiEvent *event ) { #ifdef NETWORK_ENABLED if ( event->type == GUI_CLICKED ) { gui_widget_hide( dlg_info ); msg_begin_writing( msgbuf, &msglen, 128 ); switch ( client_state ) { case CLIENT_AWAIT_ANSWER: msg_write_int8( MSG_CANCEL_GAME ); break; } client_transmit( CODE_BLUE, msglen, msgbuf ); client_state = CLIENT_NONE; } #endif }
/* ==================================================================== Close channel selector or enter new channel. ==================================================================== */ void client_enter_channel( GuiWidget *widget, GuiEvent *event ) { #ifdef NETWORK_ENABLED char buf[16]; if ( event->type != GUI_CLICKED ) return; gui_widget_hide( dlg_channels ); client_state = CLIENT_NONE; /* retreive name of channel we want to enter */ buf[0] = 0; gui_edit_get_text( edit_channel, buf, 16, 0,-1 ); /* send it */ msg_begin_writing( msgbuf, &msglen, MAX_MSG_SIZE ); msg_write_int8( MSG_ENTER_CHANNEL ); msg_write_string( buf ); client_transmit( CODE_BLUE, msglen, msgbuf ); #endif }
/* ==================================================================== Handle confirmation/cancelling of confirmation dialogue. ==================================================================== */ void client_confirm( GuiWidget *widget, GuiEvent *event ) { #ifdef NETWORK_ENABLED if ( event->type != GUI_CLICKED ) return; gui_widget_hide( dlg_confirm ); msg_begin_writing( msgbuf, &msglen, MAX_MSG_SIZE ); switch ( client_state ) { case CLIENT_ANSWER: msg_write_int8( MSG_ACCEPT_CHALLENGE ); client_transmit( CODE_BLUE, msglen, msgbuf ); /* play */ gui_disable_event_filter(); if ( client_game_init_network( mp_peer_name, mp_diff ) ) client_game_run(); client_game_finalize(); gui_enable_event_filter(); gui_widget_draw( dlg_chatroom ); stk_display_fade( STK_FADE_IN, STK_FADE_DEFAULT_TIME ); break; } #endif }
/* ==================================================================== Close help dialogue. ==================================================================== */ void client_close_help( GuiWidget *widget, GuiEvent *event ) { if ( event->type != GUI_CLICKED ) return; gui_widget_hide( dlg_help ); }
void client_cancel_channel( GuiWidget *widget, GuiEvent *event ) { if ( event->type != GUI_CLICKED ) return; gui_widget_hide( dlg_channels ); client_state = CLIENT_NONE; }
void client_close_connect_window( GuiWidget *widget, GuiEvent *event ) { if ( event->type == GUI_CLICKED ) gui_widget_hide( dlg_connect ); }
/* ==================================================================== Try to connect to a game server. Retry twice every second or quit then. ==================================================================== */ void client_connect( GuiWidget *widget, GuiEvent *event ) { #ifdef NETWORK_ENABLED NetAddr newaddr; int attempt = 0; int type; char server[128]; if ( event->type != GUI_CLICKED ) return; /* close the connect window */ gui_widget_hide( dlg_connect ); /* disconnect from current server */ client_disconnect(); /* extract ip and port and build a new socket out of it */ gui_edit_get_text( edit_server, server, 128, 0, -1 ); snprintf( config.server, 64, "%s", server ); if ( !net_build_addr( &newaddr, server, 0 ) ) { client_printf_chatter( 1, _("ERROR: address %s does not resolve"), config.server ); return; } socket_init( &client, &newaddr ); /* get username */ gui_edit_get_text( edit_username, config.username, 16, 0,-1 ); /* build connect message */ msg_begin_writing( msgbuf, &msglen, 64 ); msg_write_int8( MSG_CONNECT ); msg_write_int8( PROTOCOL ); msg_write_string( config.username ); msg_write_string( _("unused") ); /* passwd */ while ( attempt < 3 ) { client_printf_chatter( 1, "%s: %s...", config.server, attempt==0?_("connecting"):_("retry") ); stk_display_update( STK_UPDATE_ALL ); net_transmit_connectionless( &newaddr, msglen, msgbuf ); SDL_Delay( 1000 ); while ( net_recv_packet() ) { if ( msg_is_connectionless() ) msg_begin_connectionless_reading(); else if ( !socket_process_header( &client ) ) continue; type = msg_read_int8(); switch ( type ) { case MSG_LOGIN_OKAY: client_id = msg_read_int32(); strcpy( client_name, msg_read_string() ); client_printf_chatter( 1, _("%s: connected!"), config.server ); client_is_connected = 1; return; case MSG_ERROR: client_printf_chatter( 1, _("ERROR: connection refused: %s"), msg_read_string() ); return; } } attempt++; } client_add_chatter( _("ERROR: server does not respond"), 1 ); #endif }
static void client_parse_packet() { int i, num; char name[16]; unsigned char type; int handled; while ( 1 ) { type = (unsigned)msg_read_int8(); handled = 0; if ( msg_read_failed() ) break; /* no more messages */ switch ( type ) { case MSG_PREPARE_FULL_UPDATE: /* do only clear users as channels and * levelsets are fixed */ list_clear( client_users ); client_user = 0; handled = 1; break; case MSG_ERROR: client_printf_chatter( 1, _("ERROR: %s"), msg_read_string() ); handled = 1; break; case MSG_BUSY: if ( client_state == CLIENT_AWAIT_ANSWER || client_state == CLIENT_AWAIT_TRANSFER_CONFIRMATION ) client_popup_info( _("%s is busy at the moment."), mp_peer_name ); handled = 1; break; case MSG_DISCONNECT: client_disconnect(); handled = 1; break; case MSG_SET_COMM_DELAY: client_comm_delay = msg_read_int16(); printf( _("comm_delay set to %i\n"), client_comm_delay ); handled = 1; break; /* chatter */ case MSG_SERVER_INFO: client_add_chatter( msg_read_string(), 1 ); handled = 1; break; case MSG_CHATTER: client_add_chatter( msg_read_string(), 0 ); handled = 1; break; /* users */ case MSG_ADD_USER: num = msg_read_int32(); snprintf( name, 16, "%s", msg_read_string() ); name[15] = 0; if ( msg_read_failed() ) break; client_add_user( num, name ); gui_list_update( list_users, client_users->count ); /* re-select current entry */ if ( client_user ) { num = list_check( client_users, client_user ); if ( num != -1 ) gui_list_select( list_users, 0, num, 1 ); } handled = 1; break; case MSG_REMOVE_USER: num = msg_read_int32(); if ( msg_read_failed() ) break; client_remove_user( num ); gui_list_update( list_users, client_users->count ); /* re-select current entry */ if ( client_user ) { num = list_check( client_users, client_user ); if ( num != -1 ) gui_list_select( list_users, 0, num, 1 ); } handled = 1; break; case MSG_CHANNEL_LIST: list_clear( client_channels ); num = msg_read_int8(); for ( i = 0; i < num; i++ ) list_add( client_channels, strdup(msg_read_string()) ); handled = 1; break; case MSG_LEVELSET_LIST: list_clear( client_levelsets ); num = msg_read_int8(); for ( i = 0; i < num; i++ ) list_add( client_levelsets, strdup(msg_read_string()) ); gui_list_update( list_levels, client_levelsets->count ); handled = 1; break; case MSG_ADD_LEVELSET: list_add( client_levelsets, strdup(msg_read_string()) ); gui_list_update( list_levels, client_levelsets->count ); handled = 1; break; case MSG_SET_CHANNEL: /* we only need to update the name */ gui_label_set_text( label_channel, msg_read_string() ); handled = 1; break; /* challenge */ case MSG_CHALLENGE: /* the user may only be challenged if client state is NONE because otherwise he is doing something that shouldn't be interrupted */ if ( client_state != CLIENT_NONE ) { msg_begin_writing( msgbuf, &msglen, 128 ); msg_write_int8( MSG_BUSY ); msg_write_int32( msg_read_int32() ); client_transmit( CODE_BLUE, msglen, msgbuf ); break; } snprintf( mp_peer_name, 15, "%s", msg_read_string() ); snprintf( mp_levelset, 16, "%s", msg_read_string() ); mp_diff = msg_read_int8(); mp_rounds = msg_read_int8(); mp_frags = msg_read_int8(); mp_balls = msg_read_int8(); if ( msg_read_failed() ) break; client_popup_confirm( _(" You have been challenged!##"\ " Challenger: %13s#"\ " Levelset: %13s#"\ " Difficulty: %13s#"\ " Rounds: %13i#"\ " Frag Limit: %13i#"\ " Balls: %13i"), mp_peer_name, mp_levelset, mp_diff_names[mp_diff], mp_rounds, mp_frags, mp_balls ); client_state = CLIENT_ANSWER; handled = 1; break; case MSG_REJECT_CHALLENGE: handled = 1; if ( client_state != CLIENT_AWAIT_ANSWER ) break; client_popup_info( _("%s is too scared to accept your challenge."), mp_peer_name ); break; case MSG_CANCEL_GAME: handled = 1; if ( client_state != CLIENT_ANSWER ) break; gui_widget_hide( dlg_confirm ); client_popup_info( _("%s got cold feet."), mp_peer_name ); break; case MSG_ACCEPT_CHALLENGE: handled = 1; if ( client_state != CLIENT_AWAIT_ANSWER ) break; gui_widget_hide( dlg_info ); /* play */ gui_disable_event_filter(); if ( client_game_init_network( mp_peer_name, mp_diff ) ) client_game_run(); client_game_finalize(); gui_enable_event_filter(); gui_widget_draw( dlg_chatroom ); stk_display_fade( STK_FADE_IN, STK_FADE_DEFAULT_TIME ); break; /* dummy parse game packets that may arrive after the QUIT_GAME * message was sent because ADD_USER commands may be in the * package and these we should get. */ case MSG_PADDLE_STATE: comm_unpack_paddle_dummy( net_buffer, &msg_read_pos ); handled = 1; break; case MSG_SHOT_POSITIONS: comm_unpack_shots_dummy( net_buffer, &msg_read_pos ); handled = 1; break; case MSG_BALL_POSITIONS: comm_unpack_balls_dummy( net_buffer, &msg_read_pos ); handled = 1; break; case MSG_SCORES: comm_unpack_scores_dummy( net_buffer, &msg_read_pos ); handled = 1; break; case MSG_BRICK_HITS: comm_unpack_brick_hits_dummy( net_buffer, &msg_read_pos ); handled = 1; break; case MSG_NEW_EXTRAS: comm_unpack_collected_extras_dummy( net_buffer, &msg_read_pos ); handled = 1; break; case MSG_ROUND_OVER: i = msg_read_int8(); handled = 1; break; case MSG_LAST_ROUND_OVER: i = msg_read_int8(); handled = 1; break; } if ( !handled ) { printf( _("chat: state %i: invalid message %x: skipping %i bytes\n"), client_state, type, net_buffer_cur_size - msg_read_pos ); msg_read_pos = net_buffer_cur_size; } } }