diff --git a/src/server/server.cpp b/src/server/server.cpp index 9177fafdab12..6b22c07b30ca 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -1772,290 +1772,6 @@ void server::send_server_message_to_all(const std::string& message, socket_ptr e } } -/* - int graceful_counter = 0; - - for (int loop = 0;; ++loop) { - // Try to run with 50 FPS all the time - // Server will respond a bit faster under heavy load - fps_limit_.limit(); - try { - // We are going to waith 10 seconds before shutting down so users can get out of game. - if (graceful_restart && games_.empty() && ++graceful_counter > 500 ) - { - // TODO: We should implement client side autoreconnect. - // Idea: - // server should send [reconnect]host=host,port=number[/reconnect] - // Then client would reconnect to new server automatically. - // This would also allow server to move to new port or address if there is need - - process_command("msg All games ended. Shutting down now. Reconnect to the new server instance.", "system"); - throw network::error("shut down"); - } - - if (config_reload == 1) { - cfg_ = read_config(); - load_config(); - config_reload = 0; - } - - // Process commands from the server socket/fifo - std::string admin_cmd; - if (input_ && input_->read_line(admin_cmd)) { - LOG_SERVER << "Admin Command: type: " << admin_cmd << "\n"; - const std::string res = process_command(admin_cmd, "*socket*"); - // Only mark the response if we fake the issuer (i.e. command comes from IRC or so) - if (admin_cmd.at(0) == '+') { - LOG_SERVER << "[admin_command_response]\n" << res << "\n" << "[/admin_command_response]\n"; - } else { - LOG_SERVER << res << "\n"; - } - } - - time_t now = time(nullptr); - if (last_ping_ + network::ping_interval <= now) { - if (lan_server_ && players_.empty() && last_user_seen_time_ + lan_server_ < now) - { - LOG_SERVER << "Lan server has been empty for " << (now - last_user_seen_time_) << " seconds. Shutting down!\n"; - // We have to shutdown - graceful_restart = true; - } - // and check if bans have expired - ban_manager_.check_ban_times(now); - // Make sure we log stats every 5 minutes - if (last_stats_ + 5 * 60 <= now) { - dump_stats(now); - if (rooms_.dirty()) rooms_.write_rooms(); - } - - // Cleaning the user_handler once a day should be more than enough - if (last_uh_clean_ + 60 * 60 * 24 <= now) { - clean_user_handler(now); - } - - // Send network stats every hour - static int prev_hour = localtime(&now)->tm_hour; - if (prev_hour != localtime(&now)->tm_hour) - { - prev_hour = localtime(&now)->tm_hour; - LOG_SERVER << network::get_bandwidth_stats(); - - } - - // send a 'ping' to all players to detect ghosts - DBG_SERVER << "Pinging inactive players.\n" ; - std::ostringstream strstr ; - strstr << "ping=\"" << now << "\"" ; - simple_wml::document ping( strstr.str().c_str(), - simple_wml::INIT_COMPRESSED ); - simple_wml::string_span s = ping.output_compressed(); - BOOST_FOREACH(network::connection sock, ghost_players_) { - if (!lg::debug.dont_log(log_server)) { - wesnothd::player_map::const_iterator i = players_.find(sock); - if (i != players_.end()) { - DBG_SERVER << "Pinging " << i->second.name() << "(" << i->first << ").\n"; - } else { - ERR_SERVER << "Player " << sock << " is in ghost_players_ but not in players_." << std::endl; - } - } - network::send_raw_data(s.begin(), s.size(), sock, "ping") ; - } - - // Copy new player list on top of ghost_players_ list. - // Only a single thread should be accessing this - // Erase before we copy - speeds inserts - ghost_players_.clear(); - BOOST_FOREACH(const wesnothd::player_map::value_type v, players_) { - ghost_players_.insert(v.first); - } - last_ping_ = now; - } - - network::process_send_queue(); - - network::connection sock = network::accept_connection(); - if (sock) { - const std::string ip = network::ip_address(sock); - const std::string reason = is_ip_banned(ip); - if (!reason.empty()) { - LOG_SERVER << ip << "\trejected banned user. Reason: " << reason << "\n"; - send_error(sock, "You are banned. Reason: " + reason); - network::queue_disconnect(sock); - } else if (ip_exceeds_connection_limit(ip)) { - LOG_SERVER << ip << "\trejected ip due to excessive connections\n"; - send_error(sock, "Too many connections from your IP."); - network::queue_disconnect(sock); - } else { - DBG_SERVER << ip << "\tnew connection accepted. (socket: " - << sock << ")\n"; - send_doc(version_query_response_, sock); - } - not_logged_in_.insert(sock); - } - - static int sample_counter = 0; - - std::vector buf; - network::bandwidth_in_ptr bandwidth_type; - while ((sock = network::receive_data(buf, &bandwidth_type)) != network::null_connection) { - metrics_.service_request(); - - if(buf.empty()) { - WRN_SERVER << "received empty packet" << std::endl; - continue; - } - - const bool sample = request_sample_frequency >= 1 && (sample_counter++ % request_sample_frequency) == 0; - - const clock_t before_parsing = get_cpu_time(sample); - - char* buf_ptr = new char [buf.size()]; - memcpy(buf_ptr, &buf[0], buf.size()); - simple_wml::string_span compressed_buf(buf_ptr, buf.size()); - const std::unique_ptr data_ptr; - try { - data_ptr.reset(new simple_wml::document(compressed_buf)); // might throw a simple_wml::error - data_ptr->take_ownership_of_buffer(buf_ptr); - - } catch (simple_wml::error& e) { - WRN_CONFIG << "simple_wml error in received data: " << e.message << std::endl; - send_error(sock, "Invalid WML received: " + e.message); - delete [] buf_ptr; - continue; - } catch(...) { - delete [] buf_ptr; - throw; - } - - simple_wml::document& data = *data_ptr; - std::vector().swap(buf); - - const clock_t after_parsing = get_cpu_time(sample); - - process_data(sock, data); - - bandwidth_type->set_type(data.root().first_child().to_string()); - if(sample) { - const clock_t after_processing = get_cpu_time(sample); - metrics_.record_sample(data.root().first_child(), - after_parsing - before_parsing, - after_processing - after_parsing); - } - - } - - metrics_.no_requests(); - - } catch(simple_wml::error& e) { - WRN_CONFIG << "Warning: error in received data: " << e.message << std::endl; - } catch(network::error& e) { - if (e.message == "shut down") { - LOG_SERVER << "Try to disconnect all users...\n"; - for (wesnothd::player_map::const_iterator pl = players_.begin(); - pl != players_.end(); ++pl) - { - network::disconnect(pl->first); - } - LOG_SERVER << "Shutting server down.\n"; - break; - } - if (!e.socket) { - ERR_SERVER << "network error: " << e.message << std::endl; - continue; - } - DBG_SERVER << "socket closed: " << e.message << "\n"; - const std::string ip = network::ip_address(e.socket); - if (proxy::is_proxy(e.socket)) { - LOG_SERVER << ip << "\tProxy user disconnected.\n"; - proxy::disconnect(e.socket); - e.disconnect(); - DBG_SERVER << "done closing socket...\n"; - continue; - } - // Was the user already logged in? - const wesnothd::player_map::iterator pl_it = players_.find(e.socket); - if (pl_it == players_.end()) { - std::set::iterator i = not_logged_in_.find(e.socket); - if (i != not_logged_in_.end()) { - DBG_SERVER << ip << "\tNot logged in user disconnected.\n"; - not_logged_in_.erase(i); - } else { - WRN_SERVER << ip << "\tWarning: User disconnected right after the connection was accepted." << std::endl; - } - e.disconnect(); - DBG_SERVER << "done closing socket...\n"; - continue; - } - const simple_wml::node::child_list& users = games_and_users_list_.root().children("user"); - const size_t index = std::find(users.begin(), users.end(), pl_it->second.config_address()) - users.begin(); - if (index < users.size()) { - simple_wml::document diff; - if(make_delete_diff(games_and_users_list_.root(), nullptr, "user", - pl_it->second.config_address(), diff)) { - for (t_games::const_iterator g = games_.begin(); g != games_.end(); ++g) { - // Note: This string is parsed by the client to identify lobby leave messages! - g->send_server_message_to_all(pl_it->second.name() + " has disconnected"); - } - rooms_.lobby().send_data(diff, e.socket); - } - - games_and_users_list_.root().remove_child("user", index); - } else { - ERR_SERVER << ip << "ERROR: Could not find user to remove: " - << pl_it->second.name() << " in games_and_users_list_.\n"; - } - // Was the player in the lobby or a game? - if (rooms_.in_lobby(e.socket)) { - rooms_.remove_player(e.socket); - LOG_SERVER << ip << "\t" << pl_it->second.name() - << "\thas logged off. (socket: " << e.socket << ")\n"; - - } else { - for (t_games::iterator g = games_.begin(); - g != games_.end(); ++g) - { - if (!g->is_member(e.socket)) { - continue; - } - // Did the last player leave? - if (g->remove_player(e.socket, true)) { - delete_game(g); - break; - } else { - g->describe_slots(); - - update_game_in_lobby(*g, e.socket); - } - break; - } - } - - // Find the matching nick-ip pair in the log and update the sign off time - connection_log ip_name = connection_log(pl_it->second.name(), ip, 0); - std::deque::iterator i = std::find(ip_log_.begin(), ip_log_.end(), ip_name); - if(i != ip_log_.end()) { - i->log_off = time(nullptr); - } - - players_.erase(pl_it); - ghost_players_.erase(e.socket); - if (lan_server_) - { - last_user_seen_time_ = time(0); - } - e.disconnect(); - DBG_SERVER << "done closing socket...\n"; - - // Catch user_handler exceptions here, to prevent the - // server from going down completely. Once we are sure - // all user_handler exceptions are caught correctly - // this can removed. - } catch (user_handler::error& e) { - ERR_SERVER << "Uncaught user_handler exception: " << e.message << std::endl; - } - } - */ - void server::start_new_server() { if (restart_command.empty()) return;