{
"port": 39390,
+
"server_name": "MMO Server",
+ "server_note": "MikuMikuOnlineのサーバーです",
+
+ "public": true,
+ "lobby_servers":
+ [
+ "m2op.net"
+ ],
+
"stage": "stage:ケロリン町",
"capacity": 20,
return udp_endpoint_;
}
+bool Command::plain() const
+{
+ return plain_;
+}
+
FatalConnectionError::FatalConnectionError() :
Command(header::FatalConnectionError, "")
{
}
+ClientReceivePlainFullServerInfo::ClientReceivePlainFullServerInfo(const std::string& xml) :
+ Command(header::ClientReceivePlainFullServerInfo, Utils::Serialize(xml))
+{
+ plain_ = true;
+}
+
}
class Command {
public:
- Command(header::CommandHeader header, const std::string body) :
- header_(header), body_(body) {}
+ Command(header::CommandHeader header,
+ const std::string body) :
+ header_(header), body_(body), plain_(false) {}
- Command(header::CommandHeader header, const std::string body, const SessionWeakPtr& session) :
- header_(header), body_(body), session_(session) {}
+ Command(header::CommandHeader header,
+ const std::string body,
+ const SessionWeakPtr& session) :
+ header_(header), body_(body), session_(session), plain_(false) {}
- Command(header::CommandHeader header, const std::string body,
+ Command(header::CommandHeader header,
+ const std::string body,
const boost::asio::ip::udp::endpoint& udp_endpoint) :
- header_(header), body_(body), udp_endpoint_(udp_endpoint) {}
+ header_(header), body_(body), udp_endpoint_(udp_endpoint), plain_(false) {}
header::CommandHeader header() const;
const std::string& body() const;
SessionWeakPtr session();
boost::asio::ip::udp::endpoint udp_endpoint() const;
+ bool plain() const;
private:
header::CommandHeader header_;
std::string body_;
SessionWeakPtr session_;
boost::asio::ip::udp::endpoint udp_endpoint_;
+ bool plain_;
};
template<header::CommandHeader Header>
typedef CommandTemplate<header::ClientRequestedClientInfo> ClientRequestedClientInfo;
typedef CommandTemplate<header::ClientReceiveServerCrowdedError> ClientReceiveServerCrowdedError;
typedef CommandTemplate<header::ServerRequestedFullServerInfo> ServerRequestedFullServerInfo;
+ typedef CommandTemplate<header::ServerRequestedPlainFullServerInfo> ServerRequestedPlainFullServerInfo;
// コネクションの切断
class FatalConnectionError : public Command {
ClientReceiveFullServerInfo(const std::string& xml);
};
+ class ClientReceivePlainFullServerInfo : public Command {
+ public:
+ ClientReceivePlainFullServerInfo(const std::string& xml);
+ };
}
ClientReceiveFullServerInfo = 0x17,
ServerReceiveWriteLimit = 0x20,
+
+ ServerRequestedPlainFullServerInfo = 0x40,
+ ClientReceivePlainFullServerInfo = 0x41,
+
ServerRequstedStatus = 0xE0,
LZ4_COMPRESS_HEADER = 0xF0,
\r
void Session::Send(const Command& command)\r
{\r
- auto msg = Serialize(command);\r
+ auto msg = Serialize(command, command.plain());\r
write_byte_sum_ += msg.size();\r
UpdateWriteByteAverage();\r
\r
\r
void Session::SyncSend(const Command& command)\r
{\r
- auto msg = Serialize(command);\r
+ auto msg = Serialize(command, command.plain());\r
write_byte_sum_ += msg.size();\r
UpdateWriteByteAverage();\r
\r
write_average_limit_ = limit;\r
}\r
\r
- std::string Session::Serialize(const Command& command)\r
+ std::string Session::Serialize(const Command& command, bool plain)\r
{\r
assert(command.header() < 0xFF);\r
auto header = static_cast<uint8_t>(command.header());\r
\r
std::string msg = Utils::Serialize(header) + body;\r
\r
- // 圧縮\r
- if (body.size() >= COMPRESS_MIN_LENGTH) {\r
- auto compressed = Utils::LZ4Compress(msg);\r
- if (msg.size() > compressed.size() + sizeof(uint8_t)) {\r
- assert(msg.size() < 65535);\r
- msg = Utils::Serialize(static_cast<uint8_t>(header::LZ4_COMPRESS_HEADER),\r
- static_cast<uint16_t>(msg.size()))\r
- + compressed;\r
- }\r
- }\r
-\r
- // 暗号化\r
- if (encryption_) {\r
- msg = Utils::Serialize(static_cast<uint8_t>(header::ENCRYPT_HEADER))\r
- + encrypter_.Encrypt(msg);\r
- }\r
+ if (plain) {\r
+ auto length = Utils::Serialize(static_cast<unsigned int>(msg.size()));\r
+ return length + msg;\r
+ } else {\r
+ // 圧縮\r
+ if (body.size() >= COMPRESS_MIN_LENGTH) {\r
+ auto compressed = Utils::LZ4Compress(msg);\r
+ if (msg.size() > compressed.size() + sizeof(uint8_t)) {\r
+ assert(msg.size() < 65535);\r
+ msg = Utils::Serialize(static_cast<uint8_t>(header::LZ4_COMPRESS_HEADER),\r
+ static_cast<uint16_t>(msg.size()))\r
+ + compressed;\r
+ }\r
+ }\r
+\r
+ // 暗号化\r
+ if (encryption_) {\r
+ msg = Utils::Serialize(static_cast<uint8_t>(header::ENCRYPT_HEADER))\r
+ + encrypter_.Encrypt(msg);\r
+ }\r
+ return Utils::Encode(msg);\r
+ }\r
\r
- return Utils::Encode(msg);\r
}\r
\r
Command Session::Deserialize(const std::string& msg)\r
\r
std::string body = decoded_msg.substr(sizeof(header));\r
\r
- return Command(static_cast<header::CommandHeader>(header), body, shared_from_this());\r
+ return Command(static_cast<header::CommandHeader>(header), body, shared_from_this());\r
}\r
\r
void Session::ReceiveTCP(const boost::system::error_code& error)\r
void UpdateReadByteAverage();\r
void UpdateWriteByteAverage();\r
\r
- std::string Serialize(const Command& command);\r
+ std::string Serialize(const Command& command, bool plain);\r
Command Deserialize(const std::string& msg);\r
\r
void ReceiveTCP(const boost::system::error_code& error);\r
#include <boost/date_time/posix_time/posix_time.hpp>\r
#include <assert.h>\r
\r
-Account::Account(const std::string& logfile) :\r
+Account::Account() :\r
revision_(0),\r
max_user_id_(0)\r
{\r
#include <boost/thread.hpp>\r
\r
typedef uint32_t UserID;\r
+#undef GetUserName\r
\r
class Account {\r
public:\r
- Account(const std::string&);\r
+ Account();\r
~Account();\r
\r
void LoadInitializeData(UserID user_id, std::string data);\r
--- /dev/null
+//
+// Channel.hpp
+//
+
+#include "Channel.hpp"
+#include <boost/filesystem.hpp>
+
+using namespace boost::filesystem;
+
+Channel::Channel()
+{
+ Load();
+}
+
+void Channel::Load()
+{
+ pt_.clear();
+ path p("./channels");
+
+ if (exists(p) && is_directory(p)) {
+ for (auto it_dir = directory_iterator(p); it_dir != directory_iterator(); ++it_dir) {
+ if (is_directory(*it_dir)) {
+ path json_path = it_dir->path() / "config.json";
+ if (exists(json_path)) {
+ auto channel_str = it_dir->path().leaf().string();
+ try {
+ boost::property_tree::ptree config_pt;
+ read_json(json_path.string(), config_pt);
+ pt_.put_child(channel_str, config_pt);
+
+ } catch (const std::exception& e) {
+ Logger::Error("%d", e.what());
+ }
+ }
+ }
+ }
+ }
+}
+
+const boost::property_tree::ptree& Channel::pt() const
+{
+ return pt_;
+}
\ No newline at end of file
--- /dev/null
+//
+// Channel.cpp
+//
+
+#pragma once
+#include <boost/property_tree/json_parser.hpp>
+
+class Channel {
+ public:
+ Channel();
+
+ const boost::property_tree::ptree& pt() const;
+
+ private:
+ void Load();
+
+ private:
+ boost::property_tree::ptree pt_;
+};
\ No newline at end of file
void Config::Load()
{
+
try {
- read_json(std::ifstream(CONFIG_JSON), pt_);
+ std::ifstream ifs;
+ ifs.open(CONFIG_JSON);
+ read_json(ifs, pt_);
} catch(std::exception& e) {
Logger::Error(unicode::ToTString(e.what()));
}
port_ = pt_.get<uint16_t>("port", 39390);\r
- server_name_ = pt_.get<std::string>("server_name", "MMO Server");
- stage_ = pt_.get<std::string>("stage", unicode::sjis2utf8("stage:ケロリン町"));
+ server_name_ = pt_.get<std::string>("server_name", "MMO Server");\r
+ server_note_ = pt_.get<std::string>("server_note", "");
+ stage_ = pt_.get<std::string>("stage", unicode::ToString(_T("stage:ケロリン町")));
capacity_ = pt_.get<int>("capacity", 20);
public_ = pt_.get<bool>("public", false);
BOOST_FOREACH(const auto& item, patterns) {
blocking_address_patterns_.push_back(item.second.get_value<std::string>());
}
+
+ auto lobby_servers = pt_.get_child("lobby_servers", ptree());
+ BOOST_FOREACH(const auto& item, lobby_servers) {
+ lobby_servers_.push_back(item.second.get_value<std::string>());
+ }
if (exists(CONFIG_JSON)) {
timestamp_ = last_write_time(CONFIG_JSON);
return server_name_;
}
+const std::string& Config::server_note() const
+{
+ return server_note_;
+}
+
+bool Config::is_public() const
+{
+ return public_;
+}
+
const std::string& Config::stage() const
{
return stage_;
{
return blocking_address_patterns_;
}
+\r
+const std::list<std::string>& Config::lobby_servers() const
+{
+ return lobby_servers_;
+}
const boost::property_tree::ptree& Config::pt() const
{
\r
uint16_t port_;\r
std::string server_name_;\r
+ std::string server_note_;\r
std::string stage_;\r
int capacity_;\r
\r
int receive_limit_2_;\r
\r
std::list<std::string> blocking_address_patterns_;\r
+ std::list<std::string> lobby_servers_;\r
\r
boost::property_tree::ptree pt_;\r
\r
public:\r
uint16_t port() const;\r
const std::string& server_name() const;\r
+ const std::string& server_note() const;\r
+\r
+ bool is_public() const;\r
+\r
const std::string& stage() const;\r
int capacity() const;\r
\r
int receive_limit_2() const;\r
\r
const std::list<std::string>& blocking_address_patterns() const;\r
+ const std::list<std::string>& lobby_servers() const;\r
\r
const boost::property_tree::ptree& pt() const;\r
\r
all: stdafx.h.gch $(OBJS)
$(LD) $(CXXFLAGS) -o $(TARGET) $(OBJS) $(LIBS) $(LIBDIRS)
+ cp ../client/bin/server/config.json .
clean:
@rm -f $(OBJS) $(TARGET) stdafx.h.gch
\r
namespace network {\r
\r
- Server::Server(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
\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
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(unsigned int id, id_list) {\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
+ 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
+ \r
std::stringstream stream;\r
write_xml(stream, xml_ptree);\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
if (auto session = ptr.lock()) {\r
if (channel < 0 || (channel >= 0 && session->channel() == channel)) {\r
if (!limited || session->write_average_limit() > session->GetWriteByteAverage()) {\r
- session->Send(command);\r
+ if (session->id() > 0) {\r
+ session->Send(command);\r
+ }\r
}\r
}\r
}\r
if (auto session = ptr.lock()) {\r
if (channel < 0 || (channel >= 0 && session->channel() == channel)) {\r
if (!limited || session->write_average_limit() > session->GetWriteByteAverage()) {\r
- if (session->id() != self_id) {\r
+ if (session->id() > 0 && session->id() != self_id) {\r
session->Send(command);\r
}\r
}\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
#include <string>\r
#include <list>\r
#include <functional>\r
+#include <boost/circular_buffer.hpp>\r
#include "../common/network/Session.hpp"\r
#include "Config.hpp"\r
+#include "Account.hpp"\r
+#include "Channel.hpp"\r
\r
#define UDP_MAX_RECEIVE_LENGTH (2048)\r
#define UDP_TEST_PACKET_TIME (5)\r
};\r
\r
public:\r
- Server(Config& config);\r
+ Server();\r
void Start(CallbackFuncPtr callback);\r
void Stop();\r
void Stop(int interrupt_type);\r
std::string GetStatusJSON() const;\r
std::string GetFullStatus() const;\r
\r
+ const Config& config() const;\r
+ Account& account();\r
+\r
+ void AddChatLog(const std::string& msg);\r
+\r
int GetSessionReadAverageLimit();\r
int GetUserCount() const;\r
void RefreshSession();\r
\r
void SendUDPTestPacket(const std::string& ip_address, uint16_t port);\r
void SendUDP(const std::string& message, const boost::asio::ip::udp::endpoint endpoint);\r
+ void SendPublicPing();\r
\r
bool IsBlockedAddress(const boost::asio::ip::address& address);\r
\r
void FetchUDP(const std::string& buffer, const boost::asio::ip::udp::endpoint endpoint);\r
\r
private:\r
- Config& config_;\r
+ Config config_;\r
+ Account account_;\r
+ Channel channel_;\r
\r
boost::asio::io_service io_service_;\r
tcp::endpoint endpoint_;\r
boost::mutex mutex_;\r
std::list<SessionWeakPtr> sessions_;\r
\r
+ boost::circular_buffer<std::string> recent_chat_log_;\r
+ std::list<udp::resolver::iterator> lobby_hosts_;\r
+\r
};\r
\r
}\r
#include "../common/database/AccountProperty.hpp"\r
#include "../common/Logger.hpp"\r
#include "Config.hpp"\r
-#include "Account.hpp"\r
#include "version.hpp"\r
\r
#ifdef __linux__\r
using namespace boost::posix_time;\r
\r
void client_sync(network::Server& server);\r
+void public_ping(network::Server& server);\r
void server();\r
\r
int main(int argc, char* argv[])\r
void server()\r
{\r
\r
- // 設定を読み込み\r
- Config config;\r
-\r
// 署名\r
network::Signature sign("server_key");\r
\r
// アカウント\r
- Account account("account.db");\r
- network::Server server(config);\r
+ network::Server server;\r
\r
auto callback = std::make_shared<std::function<void(network::Command)>>(\r
- [&server, &account, &sign, &config](network::Command c){\r
+ [&server, &sign](network::Command c){\r
\r
// ログを出力\r
auto msg = (boost::format("Receive: 0x%08x %dbyte") % c.header() % c.body().size()).str();\r
// if (auto session = c.session().lock()) {\r
// std::cout << "Write Average: " << session->GetReadByteAverage() << "bytes" << std::endl;\r
// }\r
-\r
+ auto header = c.header();\r
switch (c.header()) {\r
\r
- // フルステータス要求\r
case network::header::ServerRequestedFullServerInfo:\r
{\r
if (auto session = c.session().lock()) {\r
}\r
break;\r
\r
+ case network::header::ServerRequestedPlainFullServerInfo:\r
+ {\r
+ if (auto session = c.session().lock()) {\r
+ session->Send(network::ClientReceivePlainFullServerInfo(server.GetFullStatus()));\r
+ }\r
+ }\r
+ break;\r
+\r
// ステータス要求\r
case network::header::ServerRequstedStatus:\r
{\r
server.SendTo(send_command, user_id);\r
}\r
} else {\r
+ auto name = server.account().GetUserName(id);\r
+ auto body = message_tree.get<std::string>("body", std::string());\r
+ server.AddChatLog((boost::format("[%s] %s") % name % body).str());\r
+\r
server.SendAll(send_command, session->channel());\r
}\r
\r
if (auto session = c.session().lock()) {\r
PlayerPosition pos;\r
network::Utils::Deserialize(c.body(), &pos.x, &pos.y, &pos.z, &pos.theta, &pos.vy);\r
- account.SetUserPosition(session->id(), pos);\r
+ server.account().SetUserPosition(session->id(), pos);\r
server.SendOthers(network::ClientUpdatePlayerPosition(session->id(),\r
pos.x,pos.y,pos.z,pos.theta, pos.vy), session->id(), session->channel(), true);\r
}\r
if (auto session = c.session().lock()) {\r
\r
// 最大接続数を超えていないか判定\r
- if (server.GetUserCount() >= config.capacity()) {\r
+ if (server.GetUserCount() >= server.config().capacity()) {\r
Logger::Info("Refused Session");\r
session->SyncSend(network::ClientReceiveServerCrowdedError());\r
session->Close();\r
// テスト送信\r
server.SendUDPTestPacket(session->global_ip(), session->udp_port());\r
\r
- uint32_t id = account.GetUserIdFromFingerPrint(finger_print);\r
+ uint32_t id = server.account().GetUserIdFromFingerPrint(finger_print);\r
if (id == 0) {\r
// 未登録の場合、公開鍵を要求\r
session->Send(network::ClientRequestedPublicKey());\r
uint32_t user_id = static_cast<uint32_t>(id);\r
// ログイン\r
session->set_id(user_id);\r
- account.LogIn(user_id);\r
- session->encrypter().SetPublicKey(account.GetPublicKey(user_id));\r
+ server.account().LogIn(user_id);\r
+ session->encrypter().SetPublicKey(server.account().GetPublicKey(user_id));\r
\r
- account.SetUserIPAddress(session->id(), session->global_ip());\r
- account.SetUserUDPPort(session->id(), session->udp_port());\r
+ server.account().SetUserIPAddress(session->id(), session->global_ip());\r
+ server.account().SetUserUDPPort(session->id(), session->udp_port());\r
\r
// 共通鍵を送り返す\r
auto key = session->encrypter().GetCryptedCommonKey();\r
case network::header::ServerReceivePublicKey:\r
{\r
if (auto session = c.session().lock()) {\r
- uint32_t user_id = account.RegisterPublicKey(c.body());\r
+ uint32_t user_id = server.account().RegisterPublicKey(c.body());\r
assert(user_id > 0);\r
\r
session->ResetReadByteAverage();\r
\r
// ログイン\r
session->set_id(user_id);\r
- account.LogIn(user_id);\r
- session->encrypter().SetPublicKey(account.GetPublicKey(user_id));\r
+ server.account().LogIn(user_id);\r
+ session->encrypter().SetPublicKey(server.account().GetPublicKey(user_id));\r
\r
- account.SetUserIPAddress(session->id(), session->global_ip());\r
- account.SetUserUDPPort(session->id(), session->udp_port());\r
+ server.account().SetUserIPAddress(session->id(), session->global_ip());\r
+ server.account().SetUserUDPPort(session->id(), session->udp_port());\r
\r
// 共通鍵を送り返す\r
auto key = session->encrypter().GetCryptedCommonKey();\r
{\r
if (auto session = c.session().lock()) {\r
\r
- session->Send(network::ClientReceiveServerInfo(config.stage()));\r
+ session->Send(network::ClientReceiveServerInfo(server.config().stage()));\r
\r
session->Send(network::ClientStartEncryptedSession());\r
session->EnableEncryption();\r
case network::header::ServerReceiveAccountInitializeData:\r
{\r
if (auto session = c.session().lock()) {\r
- account.LoadInitializeData(session->id(), c.body());\r
+ server.account().LoadInitializeData(session->id(), c.body());\r
\r
- const auto& list = account.GetIDList();\r
+ const auto& list = server.account().GetIDList();\r
BOOST_FOREACH(UserID user_id, list) {\r
session->Send(network::ClientReceiveAccountRevisionUpdateNotify(user_id,\r
- account.GetUserRevision(user_id)));\r
+ server.account().GetUserRevision(user_id)));\r
}\r
\r
server.SendOthers(\r
network::ClientReceiveAccountRevisionUpdateNotify(session->id(),\r
- account.GetUserRevision(session->id())), session->id());\r
+ server.account().GetUserRevision(session->id())), session->id());\r
\r
Logger::Info(msg);\r
}\r
uint32_t client_revision;\r
network::Utils::Deserialize(c.body(), &user_id, &client_revision);\r
\r
- if (client_revision < account.GetUserRevision(user_id)) {\r
+ if (client_revision < server.account().GetUserRevision(user_id)) {\r
session->Send(network::ClientReceiveAccountRevisionPatch(\r
- account.GetUserRevisionPatch(user_id, client_revision)));\r
+ server.account().GetUserRevisionPatch(user_id, client_revision)));\r
}\r
Logger::Info(msg);\r
}\r
std::string buffer = c.body().substr(sizeof(AccountProperty));\r
network::Utils::Deserialize(c.body(), &property);\r
\r
- auto old_revision = account.GetUserRevision(session->id());\r
+ auto old_revision = server.account().GetUserRevision(session->id());\r
\r
switch (property) {\r
\r
{\r
std::string value;\r
network::Utils::Deserialize(buffer, &value);\r
- account.SetUserName(session->id(), value);\r
+ server.account().SetUserName(session->id(), value);\r
}\r
break;\r
case TRIP:\r
{\r
std::string value;\r
network::Utils::Deserialize(buffer, &value);\r
- account.SetUserTrip(session->id(), value);\r
+ server.account().SetUserTrip(session->id(), value);\r
}\r
break;\r
case MODEL_NAME:\r
{\r
std::string value;\r
network::Utils::Deserialize(buffer, &value);\r
- account.SetUserModelName(session->id(), value);\r
+ server.account().SetUserModelName(session->id(), value);\r
+ }\r
+ break;\r
+ case CHANNEL:\r
+ {\r
+ std::string value;\r
+ network::Utils::Deserialize(buffer, &value);\r
+ auto channel = *reinterpret_cast<const unsigned int*>(value.data());\r
+ server.account().SetUserChannel(session->id(), channel);\r
+ session->set_channel(channel);\r
}\r
break;\r
- // case CHANNEL:\r
- // {\r
- //unsigned char value;\r
- //network::Utils::Deserialize(buffer, &value);\r
- // account.SetUserChannel(session->id(), value);\r
- //session->set_channel(value);\r
- // }\r
- // break;\r
default:\r
;\r
}\r
\r
- auto new_revison = account.GetUserRevision(session->id());\r
+ auto new_revison = server.account().GetUserRevision(session->id());\r
if (new_revison > old_revision) {\r
server.SendAll(\r
network::ClientReceiveAccountRevisionUpdateNotify(\r
if (c.body().size() > 0) {\r
int user_id;\r
network::Utils::Deserialize(c.body(), &user_id);\r
- account.LogOut(user_id);\r
+ server.account().LogOut(user_id);\r
\r
server.SendAll(\r
network::ClientReceiveAccountRevisionUpdateNotify(user_id,\r
- account.GetUserRevision(user_id)));\r
+ server.account().GetUserRevision(user_id)));\r
\r
Logger::Info("Logout User: %d", user_id);\r
- account.Remove(user_id);\r
+ server.account().Remove(user_id);\r
}\r
}\r
Logger::Info(msg);\r
});\r
\r
client_sync(server);\r
+\r
+ if (server.config().is_public()) {\r
+ public_ping(server);\r
+ }\r
+\r
server.Start(callback);\r
}\r
\r
+void public_ping(network::Server& server)\r
+{\r
+ boost::thread([&server](){\r
+ while (1) {\r
+ boost::this_thread::sleep(boost::posix_time::seconds(10));\r
+ server.SendPublicPing();\r
+ }\r
+ });\r
+}\r
+\r
void client_sync(network::Server& server)\r
{\r
bool execute_with_client;\r
if (execute_with_client) {\r
boost::thread([&server](){\r
while (1) {\r
- boost::this_thread::sleep(boost::posix_time::milliseconds(4000));\r
+ boost::this_thread::sleep(boost::posix_time::seconds(4));\r
try {\r
using namespace boost::interprocess;\r
windows_shared_memory shm(open_only, "MMO_SERVER_WITH_CLIENT", read_only);\r
#include <boost/format.hpp>
#include <boost/thread.hpp>
#include <boost/foreach.hpp>
+#include <boost/circular_buffer.hpp>
+#include <boost/lexical_cast.hpp>
#include "../common/Logger.hpp"
\ No newline at end of file