-//\r
+//\r
// Server.cpp\r
//\r
\r
#include <algorithm>\r
#include <boost/make_shared.hpp>\r
#include <boost/foreach.hpp>\r
+#include <boost/archive/text_oarchive.hpp>\r
+#include <boost/property_tree/ptree_serialization.hpp>\r
#include "../common/Logger.hpp"\r
#include "../common/network/Command.hpp"\r
#include "../common/network/Utils.hpp"\r
\r
namespace network {\r
\r
- Server::Server(const Config& config) :\r
- config_(config),\r
- endpoint_(tcp::v4(), config.port()),\r
+ Server::Server() :\r
+ endpoint_(tcp::v4(), config_.port()),\r
acceptor_(io_service_, endpoint_),\r
- socket_udp_(io_service_, udp::endpoint(udp::v4(), config.port())),\r
- udp_packet_count_(0)\r
+ socket_udp_(io_service_, udp::endpoint(udp::v4(), config_.port())),\r
+ udp_packet_count_(0),\r
+ recent_chat_log_(10)\r
{\r
}\r
\r
[&](network::Command c){\r
\r
// ログアウト\r
- if (c.header() == network::header::FatalConnectionError) {\r
+ if (c.header() == network::header::FatalConnectionError || \r
+ c.header() == network::header::UserFatalConnectionError) {\r
if (callback) {\r
(*callback)(c);\r
}\r
} else if (auto session = c.session().lock()) {\r
auto read_average = session->GetReadByteAverage();\r
if (read_average > config_.receive_limit_2()) {\r
- Logger::Info(_T("Banished session: %d"), session->id());\r
+ Logger::Info(_T("Banished a session: %d %dbyte/s"), session->id(), read_average);\r
session->Close();\r
} else if(read_average > config_.receive_limit_1()) {\r
Logger::Info(_T("Receive limit exceeded: %d: %d byte/s"), session->id(), read_average);\r
\r
});\r
\r
+ BOOST_FOREACH(const auto& host, config().lobby_servers()) {\r
+ udp::resolver resolver(io_service_);\r
+ udp::resolver::query query(udp::v4(), host.c_str(), "39380");\r
+ lobby_hosts_.push_back(resolver.resolve(query));\r
+ }\r
+\r
{\r
auto new_session = boost::make_shared<ServerSession>(io_service_);\r
acceptor_.async_accept(new_session->tcp_socket(),\r
int Server::GetUserCount() const\r
{\r
auto count = std::count_if(sessions_.begin(), sessions_.end(),\r
- [](const SessionWeakPtr& s){ return !s.expired() && s.lock()->online(); });\r
+ [](const SessionWeakPtr& s){ \r
+ return !s.expired() && s.lock()->online() && s.lock()->id() > 0; \r
+ });\r
\r
return count;\r
}\r
return msg;\r
}\r
\r
+ std::string Server::GetFullStatus() const\r
+ {\r
+ using namespace boost::property_tree;\r
+ ptree xml_ptree;\r
+\r
+ xml_ptree.put_child("config", config_.pt());\r
+ xml_ptree.put("version", (boost::format("%d.%d.%d") \r
+ % MMO_VERSION_MAJOR % MMO_VERSION_MINOR % MMO_VERSION_REVISION).str());\r
+ xml_ptree.put("protocol_version", MMO_PROTOCOL_VERSION);\r
+\r
+ {\r
+ ptree player_array;\r
+ auto id_list = account_.GetIDList();\r
+ BOOST_FOREACH(const auto& s, sessions_) {\r
+ if (!s.expired() && s.lock()->online() && s.lock()->id() > 0) {\r
+ auto id = s.lock()->id();\r
+ ptree player;\r
+ player.put("name", account_.GetUserName(id));\r
+ player.put("model_name", account_.GetUserModelName(id));\r
+ player_array.push_back(std::make_pair("", player));\r
+ }\r
+ }\r
+ xml_ptree.put_child("players", player_array);\r
+ }\r
+\r
+ //{\r
+ // ptree log_array;\r
+ // BOOST_FOREACH(const std::string& msg, recent_chat_log_) {\r
+ // log_array.push_back(std::make_pair("", msg));\r
+ // }\r
+ // xml_ptree.put_child("recent_chat_log", log_array);\r
+ //}\r
+\r
+ xml_ptree.put_child("channels", channel_.pt());\r
+ std::stringstream stream;\r
+ boost::archive::text_oarchive oa(stream);\r
+ oa << xml_ptree;\r
+\r
+ return stream.str();\r
+ }\r
+\r
+ const Config& Server::config() const\r
+ {\r
+ return config_;\r
+ }\r
+\r
+ Account& Server::account()\r
+ {\r
+ return account_;\r
+ }\r
+ \r
+ void Server::AddChatLog(const std::string& msg)\r
+ {\r
+ recent_chat_log_.push_back(msg);\r
+ }\r
+\r
bool Server::Empty() const\r
{\r
return GetUserCount() == 0;\r
\r
void Server::ReceiveSession(const SessionPtr& session, const boost::system::error_code& error)\r
{\r
+ \r
+ config_.Reload();\r
+\r
const auto address = session->tcp_socket().remote_endpoint().address();\r
+\r
+ // 拒否IPでないか判定\r
if(IsBlockedAddress(address)) {\r
Logger::Info("Blocked IP Address: %s", address);\r
session->Close();\r
\r
- } else if (GetUserCount() >= config_.capacity()) {\r
- Logger::Info("Refused Session");\r
- session->SyncSend(ClientReceiveServerCrowdedError());\r
- session->Close();\r
-\r
- } else {\r
+ } else {\r
session->set_on_receive(callback_);\r
session->Start();\r
sessions_.push_back(SessionWeakPtr(session));\r
}\r
\r
auto new_session = boost::make_shared<ServerSession>(io_service_);\r
- acceptor_.async_accept(new_session->tcp_socket(),\r
- boost::bind(&Server::ReceiveSession, this, new_session, boost::asio::placeholders::error));\r
+ acceptor_.async_accept(new_session->tcp_socket(),\r
+ boost::bind(&Server::ReceiveSession, this, new_session, boost::asio::placeholders::error));\r
\r
RefreshSession();\r
}\r
Logger::Info("Active connection: %d", GetUserCount());\r
}\r
\r
- void Server::SendAll(const Command& command)\r
+ void Server::SendAll(const Command& command, int channel, bool limited)\r
{\r
BOOST_FOREACH(SessionWeakPtr& ptr, sessions_) {\r
if (auto session = ptr.lock()) {\r
- session->Send(command);\r
+ if (channel < 0 || (channel >= 0 && session->channel() == channel)) {\r
+ if (!limited || session->write_average_limit() > session->GetWriteByteAverage()) {\r
+ if (session->id() > 0) {\r
+ session->Send(command);\r
+ }\r
+ }\r
+ }\r
}\r
}\r
}\r
\r
- void Server::SendAllLimited(const Command& command)\r
+ void Server::SendOthers(const Command& command, uint32_t self_id, int channel, bool limited)\r
{\r
BOOST_FOREACH(SessionWeakPtr& ptr, sessions_) {\r
if (auto session = ptr.lock()) {\r
- if (session->write_average_limit() > session->GetWriteByteAverage()) {\r
- session->Send(command);\r
+ if (channel < 0 || (channel >= 0 && session->channel() == channel)) {\r
+ if (!limited || session->write_average_limit() > session->GetWriteByteAverage()) {\r
+ if (session->id() > 0 && session->id() != self_id) {\r
+ session->Send(command);\r
+ }\r
+ }\r
}\r
}\r
}\r
}\r
}\r
\r
- void Server::SendOthers(const Command& command, SessionWeakPtr self_ptr)\r
- {\r
- BOOST_FOREACH(SessionWeakPtr& ptr, sessions_) {\r
- if (auto session = ptr.lock()) {\r
- if (auto self = self_ptr.lock()) {\r
- if (*session != *self) {\r
- session->Send(command);\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- void Server::SendOthersLimited(const Command& command, SessionWeakPtr self_ptr)\r
- {\r
- BOOST_FOREACH(SessionWeakPtr& ptr, sessions_) {\r
- if (auto session = ptr.lock()) {\r
- if (auto self = self_ptr.lock()) {\r
- if (*session != *self) {\r
- if (session->write_average_limit() > session->GetWriteByteAverage()) {\r
- session->Send(command);\r
- }\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
void Server::SendUDPTestPacket(const std::string& ip_address, uint16_t port)\r
{\r
using boost::asio::ip::udp;\r
}\r
}\r
\r
+ void Server::SendPublicPing()\r
+ {\r
+ static char request[] = "P";\r
+ BOOST_FOREACH(const auto& iterator, lobby_hosts_) {\r
+ io_service_.post(boost::bind(&Server::DoWriteUDP, this, request, *iterator));\r
+ }\r
+ }\r
+\r
void Server::SendUDP(const std::string& message, const boost::asio::ip::udp::endpoint endpoint)\r
{\r
io_service_.post(boost::bind(&Server::DoWriteUDP, this, message, endpoint));\r