void Client::sevt_login(ServerEvent& evt) { ScopeMutex lock(mtx); const Resources::LoadedPaks& paks = resources.get_loaded_paks(); GPakHash gph; for (Resources::LoadedPaks::const_iterator it = paks.begin(); it != paks.end(); it++) { const Resources::LoadedPak& pak = *it; memset(&gph, 0, GPakHashLen); strncpy(gph.pak_name, pak.pak_short_name.c_str(), NameLength - 1); strncpy(gph.pak_hash, pak.pak_hash.c_str(), 64); gph.to_net(); stacked_send_data(evt.c, 0, GPSPakSyncHash, NetFlagsReliable, GPakHashLen, &gph); } stacked_send_data(evt.c, 0, GPSPakSyncHashFinished, NetFlagsReliable, 0, 0); flush_stacked_send_data(evt.c, 0); }
void Client::idle() throw (Exception) { /* process net io */ bool queue_empty = true; do { ServerEvent evt; { Scope<Mutex> lock(mtx); if (server_events.empty()) { break; } evt = server_events.front(); server_events.pop(); queue_empty = server_events.empty(); } switch (evt.event) { case EventTypeStatus: { std::string msg(evt.data, evt.sz); subsystem << msg << std::endl; break; } case EventTypeAccessDenied: { stop_thread(); exception_msg.assign(evt.data, evt.sz); throw_exception = true; break; } case EventTypeLogin: { sevt_login(evt); break; } case EventTypeLogout: { stop_thread(); logged_in = false; conn = 0; exception_msg.assign(evt.data, evt.sz); throw_exception = true; break; } case EventTypeData: sevt_data(evt); break; } if (evt.data) { delete[] evt.data; } } while (!queue_empty && !throw_exception); /* have to throw an exception? */ if (throw_exception) { throw ClientException(exception_msg); } /* interpolate movements */ get_now(now); ns_t diff = diff_ns(last, now); last = now; if (tournament) { tournament->update_states(diff); if (conn) { tournament->set_ping_time(conn->ping_time); Tournament::StateResponses& responses = tournament->get_state_responses(); size_t sz = responses.size(); { Scope<Mutex> lock(mtx); for (size_t i = 0; i < sz; i++) { StateResponse *resp = responses[i]; if (resp->action == GPCTextMessage) { std::string msg(reinterpret_cast<const char *>(resp->data), resp->len); add_text_msg(msg); } else { stacked_send_data(conn, factory.get_tournament_id(), resp->action, 0, resp->len, resp->data); } } flush_stacked_send_data(conn, 0); } } tournament->delete_responses(); /* send player position (unreliable) */ updatecnt += diff; bool player_force = false; if (me && me->force_broadcast) { player_force = true; me->force_broadcast = false; me->state.client_server_state.flags |= PlayerClientServerFlagForceBroadcast; } if (updatecnt >= UpdatePeriod || force_send || player_force) { updatecnt = 0; if (conn && me && tournament->is_ready()) { GPlayerClientServerState state; state = me->state.client_server_state; state.to_net(); { Scope<Mutex> lock(mtx); send_data(conn, factory.get_tournament_id(), GPSUpdatePlayerClientServerState, 0, GPlayerClientServerStateLen, &state); } me->state.client_server_state.flags &= ~PlayerClientServerFlagForceBroadcast; } } } /* interpolate messages */ for (TextMessages::iterator it = text_messages.begin(); it != text_messages.end(); it++) { TextMessage *cmsg = *it; cmsg->duration += (diff / 1000000.0f); if (cmsg->duration > text_message_duration) { cmsg->delete_me = true; } } text_messages.erase(std::remove_if(text_messages.begin(), text_messages.end(), erase_element<TextMessage>), text_messages.end()); /* player in options or in chatbox? */ if (me) { if (get_stack_count()) { me->state.client_server_state.flags |= PlayerClientServerFlagWriting; } else { me->state.client_server_state.flags &= ~PlayerClientServerFlagWriting; } } /* draw map */ if (tournament) { tournament->draw(); } /* draw messages */ Font *font = resources.get_font("normal"); int view_height = subsystem.get_view_height(); int font_height = font->get_font_height(); int y = view_height - font_height - 5; for (TextMessages::reverse_iterator it = text_messages.rbegin(); it != text_messages.rend(); it++) { TextMessage *cmsg = *it; float alpha = 1.0f; if (cmsg->duration > text_message_fade_out_at) { alpha = static_cast<float>((text_message_duration - cmsg->duration) / (text_message_duration - text_message_fade_out_at)); } subsystem.set_color(0.75f, 0.75f, 1.0f, alpha); subsystem.draw_text(font, 5, y, cmsg->text); alpha *= 0.9f; y -= font_height; } subsystem.reset_color(); /* draw file transfer status */ if (fhnd) { Font *big = resources.get_font("big"); int percent = 100 - static_cast<int>(100.0f / static_cast<float>(total_xfer_sz) * remaining_xfer_sz); sprintf(buffer, "transferring %s (%d%%)", xfer_filename.c_str(), percent); int tw = big->get_text_width(buffer); subsystem.draw_text(big, subsystem.get_view_width() / 2 - tw / 2, view_height - 30, buffer); } }