static void process_data_from_server() { /* enough data present for the length field ? */ if (3 <= in_data_used) { Uint8 *pData = in_data; Uint16 size; do { /* while (3 <= in_data_used) (enough data present for the length field) */ static const int foo = 1; /* used for run-time byteorder check */ /* make a copy of the length field...watch alignment/byteorder */ if (*(char *)&foo) { /* little-endian ? */ ((Uint8 *)&size)[0] = pData[1]; ((Uint8 *)&size)[1] = pData[2]; } else { /* big-endian */ ((Uint8 *)&size)[0] = pData[2]; ((Uint8 *)&size)[1] = pData[1]; } if (sizeof (in_data) - 3 >= size) { /* buffer big enough ? */ size += 2; /* add length field size */ if (size <= in_data_used) { /* do we have a complete message ? */ process_message_from_server(pData, size); if (log_conn_data) log_conn(pData, size); /* advance to next message */ pData += size; in_data_used -= size; } else break; } else { /* sizeof (in_data) - 3 < size */ log_to_console(c_red2, packet_overrun); log_to_console(c_red2, disconnected_from_server); log_to_console(c_red2, alt_x_quit); in_data_used = 0; disconnected = 1; // clear buddy list clear_buddy(); } } while (3 <= in_data_used); /* move the remaining data to the start of the buffer...(not tested...never happened to me) */ if (in_data_used && pData != in_data) memmove(in_data, pData, in_data_used); } }
int start_rendering() { static int done = 0; static void * network_thread_data[2] = { NULL, NULL }; static Uint32 last_frame_and_command_update = 0; SDL_Thread *network_thread; queue_t *message_queue; #ifndef WINDOWS SDL_EventState(SDL_SYSWMEVENT,SDL_ENABLE); #endif queue_initialise(&message_queue); network_thread_data[0] = message_queue; network_thread_data[1] = &done; network_thread = SDL_CreateThread(get_message_from_server, network_thread_data); /* Loop until done. */ while( !done ) { SDL_Event event; // handle SDL events in_main_event_loop = 1; while( SDL_PollEvent( &event ) ) { done = HandleEvent(&event); } in_main_event_loop = 0; //advance the clock cur_time = SDL_GetTicks(); //check for network data if(!queue_isempty(message_queue)) { message_t *message; while((message = queue_pop(message_queue)) != NULL) { process_message_from_server(message->data, message->length); free(message->data); free(message); } } #ifdef OLC olc_process(); #endif //OLC my_tcp_flush(my_socket); // make sure the tcp output buffer is set if (have_a_map && cur_time > last_frame_and_command_update + 60) { LOCK_ACTORS_LISTS(); next_command(); UNLOCK_ACTORS_LISTS(); move_to_next_frame(); last_frame_and_command_update = cur_time; } while (cur_time > next_second_time && real_game_second < 59) { real_game_second += 1; new_second(); next_second_time += 1000; } #ifdef NEW_SOUND weather_sound_control(); #endif //NEW_SOUND if(!limit_fps || (cur_time-last_time && 1000/(cur_time-last_time) <= limit_fps)) { weather_update(); animate_actors(); //draw everything draw_scene(); last_time=cur_time; } else { SDL_Delay(1);//give up timeslice for anyone else } #ifdef TIMER_CHECK //Check the timers to make sure that they are all still alive... check_timers(); #endif //cache handling if(cache_system)cache_system_maint(); //see if we need to exit if(exit_now) { done = 1; break; } } if(!done) { done = 1; } LOG_INFO("Client closed"); SDL_WaitThread(network_thread,&done); queue_destroy(message_queue); if(pm_log.ppl)free_pm_log(); //save all local data save_local_data(NULL, 0); #ifdef PAWN cleanup_pawn (); #endif #ifdef NEW_SOUND destroy_sound(); // Cleans up physical elements of the sound system and the streams thread clear_sound_data(); // Cleans up the config data #endif // NEW_SOUND ec_destroy_all_effects(); if (have_a_map) { destroy_map(); free_buffers(); } unload_questlog(); save_item_lists(); free_emotes(); free_actor_defs(); free_books(); free_vars(); cleanup_rules(); save_exploration_map(); cleanup_counters(); cleanup_chan_names(); cleanup_hud(); SDL_RemoveTimer(draw_scene_timer); SDL_RemoveTimer(misc_timer); end_particles (); free_bbox_tree(main_bbox_tree); main_bbox_tree = NULL; free_astro_buffer(); free_translations(); free_skybox(); /* Destroy our GL context, etc. */ SDL_QuitSubSystem(SDL_INIT_AUDIO); SDL_QuitSubSystem(SDL_INIT_TIMER); /*#ifdef WINDOWS // attempt to restart if requested if(restart_required > 0){ LOG_INFO("Restarting %s", win_command_line); SDL_CreateThread(system, win_command_line); } #endif //WINDOWS */ #ifdef NEW_SOUND final_sound_exit(); #endif #ifdef CUSTOM_UPDATE stopp_custom_update(); #endif /* CUSTOM_UPDATE */ clear_zip_archives(); destroy_tcp_out_mutex(); if (use_frame_buffer) free_reflection_framebuffer(); printf("doing SDL_Quit\n"); fflush(stderr); SDL_Quit( ); printf("done SDL_Quit\n"); fflush(stderr); cleanup_mem(); xmlCleanupParser(); FreeXML(); exit_logging(); return(0); }
void handle_extended_protocol_message(const Uint8 *in_data, int data_length) { char info[1024]; int i; switch (in_data[0]) { case OL_GENERIC_DATA: { Uint8 action; Uint16 group, subgroup, start, data_type, a_length, a_width; action = in_data[3]; group = SDL_SwapLE16(*(Uint16 *)(in_data+4)); subgroup = SDL_SwapLE16(*(Uint16 *)(in_data+6)); start = SDL_SwapLE16(*(Uint16 *)(in_data+8)); data_type = SDL_SwapLE16(*(Uint16 *)(in_data+10)); a_length = SDL_SwapLE16(*(Uint16 *)(in_data+12)); a_width = SDL_SwapLE16(*(Uint16 *)(in_data+14)); #if 0 safe_snprintf(info, sizeof(info), "Got OL_GENERIC_DATA message. LENGTH: %u/%i, Action: %u, GROUP: %u, SUBGROUP: %u, Start Entry: %u, Data type: %u, ARRAY Length: %u, ARRAY Width: %u",SDL_SwapLE16(*(Uint16 *)(in_data+1)), data_length, action, group, subgroup, start, data_type, a_length, a_width); LOG_TO_CONSOLE(c_green1, info); for(i=0; i<SDL_SwapLE16(*(Uint16 *)(in_data+12)); i++) { safe_snprintf(info, sizeof(info), "%u", SDL_SwapLE32(*(Uint32 *)(in_data+16+i*4))); LOG_TO_CONSOLE(c_green1, info); } #endif if(action == 1 && group == 0 && subgroup == 16) { if(a_length*a_width > data_length-16) { LOG_WARNING("CAUTION: Possibly forged x-attrib packet received.\n"); break; } if (a_length > 1) get_xattribs(a_length, (Uint16 *)(in_data+16)); else get_partial_xattribs(start, (Uint16 *)(in_data+16)); } } break; case OL_EXTENDED_PACKET: #if 0 safe_snprintf(info, sizeof(info), "Got OL_EXTENDED_PACKET message. LENGTH: %u/%i, Ext Type: %u",SDL_SwapLE16(*(Uint16 *)(in_data+1)), data_length, SDL_SwapLE16(*(Uint16 *)(in_data+3))); LOG_TO_CONSOLE(c_green1, info); #endif break; case OL_COMPRESSED_PACKET: #if 0 safe_snprintf(info, sizeof(info), "Got OL_COMPRESSED_PACKET message. LENGTH: %u/%i, FLAGS: %u",SDL_SwapLE16(*(Uint16 *)(in_data+1)), data_length, in_data[3]); LOG_TO_CONSOLE(c_green1, info); #endif break; case OL_OLD_EL_PACKET: { Uint8 *new_data; #if 0 safe_snprintf(info, sizeof(info), "Got OL_OLD_EL_PACKET message. LENGTH: %u/%i, EL Packet Type: %u",SDL_SwapLE16(*(Uint16 *)(in_data+1)), data_length, in_data[3]); LOG_TO_CONSOLE(c_green1, info); #endif new_data = malloc(data_length-1); new_data[0] = in_data[3]; if(SDL_BYTEORDER == SDL_LIL_ENDIAN) *((Uint16 *)(new_data+1)) = data_length-3; else *((Uint16 *)(new_data+1)) = SDL_Swap16(data_length-3); if(data_length > 4) memcpy(&new_data[3], &in_data[4], data_length-3); #if 0 safe_snprintf(info, sizeof(info), "Generated EL message. LENGTH: %u/%i, EL Packet Type: %u",SDL_SwapLE16(*(Uint16 *)(new_data+1)), data_length-1, new_data[0]); LOG_TO_CONSOLE(c_green1, info); #endif process_message_from_server(new_data, data_length-1); free(new_data); } break; default: process_message_from_server(in_data, data_length); } }