#include "ResourceManager.hpp"\r
#include "../common/unicode.hpp"\r
#include "../common/network/Command.hpp"\r
+#include "../common/network/Utils.hpp"\r
#include "../common/database/AccountProperty.hpp"\r
#include "Profiler.hpp"\r
#include "GenerateJSON.hpp"\r
return Undefined();\r
}\r
\r
+Handle<Value> Card::Function_Account_channel(const Arguments& args)\r
+{\r
+ auto self = static_cast<Card*>(args.Holder()->GetPointerFromInternalField(0));\r
+\r
+ int id = 0;\r
+ if (auto command_manager = self->manager_accessor_->command_manager().lock()) {\r
+ id = command_manager->user_id();\r
+ }\r
+ if (auto player_manager = self->manager_accessor_->player_manager().lock()) {\r
+ if (auto player = player_manager->GetFromId(id)) {\r
+ return Integer::New(player->channel());\r
+ }\r
+ }\r
+\r
+ return Undefined();\r
+}\r
+\r
+Handle<Value> Card::Function_Account_updateChannel(const Arguments& args)\r
+{\r
+ auto self = static_cast<Card*>(args.Holder()->GetPointerFromInternalField(0));\r
+\r
+ if (args.Length() >= 1 && args[0]->IsNumber()) {\r
+\r
+ int channel = args[0]->ToInteger()->Int32Value();\r
+\r
+ if (channel >= 0 && channel <= UCHAR_MAX) {\r
+ if (auto command_manager = self->manager_accessor_->command_manager().lock()) {\r
+ auto channel_str = network::Utils::Serialize((unsigned char)channel);\r
+ command_manager->Write(network::ServerUpdateAccountProperty(CHANNEL, channel_str));\r
+ }\r
+ }\r
+ }\r
+\r
+ return Undefined();\r
+}\r
+\r
\r
Handle<Value> Card::Function_Screen_width(const Arguments& args)\r
{\r
script_.SetFunction("Account.updateTrip", Function_Account_updateTrip);\r
\r
/**\r
+ * 現在のチャンネルを返します\r
+ *\r
+ * @method channel\r
+ * @return {Integer} チャンネル\r
+ *\r
+ * @static\r
+ */\r
+ script_.SetFunction("Account.channel", Function_Account_channel);\r
+\r
+ /**\r
+ * 現在のチャンネルを設定します\r
+ *\r
+ * @method updateChannel\r
+ * @param {Integer} channel チャンネル\r
+ *\r
+ * @static\r
+ */\r
+ script_.SetFunction("Account.updateChannel", Function_Account_updateChannel);\r
+\r
+ /**\r
* カード\r
*\r
* @class Card\r
name_(""),\r
model_name_(""),\r
login_(false),\r
+channel_(0),\r
revision_(0)\r
{\r
name_tip_image_handle_ = ResourceManager::LoadCachedDivGraph<4>(\r
return Boolean::New(self->login_);\r
}\r
\r
+Handle<Value> Player::Function_Player_channel(const Arguments& args)\r
+{\r
+ assert(args.This()->InternalFieldCount() > 0);\r
+ auto self = *static_cast<PlayerPtr*>(args.This()->GetPointerFromInternalField(0));\r
+ assert(self);\r
+ return Integer::New(self->channel_);\r
+}\r
+\r
Handle<Value> Player::Function_Player_setBalloonContent(const Arguments& args)\r
{\r
\r
*/\r
object->Set(String::New("login"), FunctionTemplate::New(Function_Player_login));\r
\r
+ /**\r
+ * プレイヤーチャンネルを返します\r
+ *\r
+ * @method channel\r
+ * @return {Integer} ログインしている時trueを返します\r
+ */\r
+ object->Set(String::New("channel"), FunctionTemplate::New(Function_Player_channel));\r
\r
/**\r
* プレイヤーの頭上の吹き出しに表示する内容を設定します\r
model_name_ = trip;\r
}\r
\r
+std::string Player::current_model_name() const\r
+{\r
+ return current_model_name_;\r
+}\r
+\r
+void Player::set_current_model_name(const std::string& model_name)\r
+{\r
+ current_model_name_ = model_name;\r
+}\r
+\r
bool Player::login() const\r
{\r
return login_;\r
login_ = login;\r
}\r
\r
+unsigned char Player::channel() const\r
+{\r
+ return channel_;\r
+}\r
+\r
+void Player::set_channel(unsigned char channel)\r
+{\r
+ channel_ = channel;\r
+}\r
+\r
uint32_t Player::revision() const\r
{\r
return revision_;\r
static Handle<Value> Function_Player_name(const Arguments& args);
static Handle<Value> Function_Player_trip(const Arguments& args);
static Handle<Value> Function_Player_login(const Arguments& args);
+ static Handle<Value> Function_Player_channel(const Arguments& args);
static Handle<Value> Function_Player_setBalloonContent(const Arguments& args);
static Handle<Value> Function_Player_position(const Arguments& args);
void set_trip(const std::string& trip);
std::string model_name() const;
void set_model_name(const std::string& model_name);
+
bool login() const;
void set_login(bool login);
+ unsigned char channel() const;
+ void set_channel(unsigned char channel);
+
uint32_t revision() const;
void set_revision(uint32_t revision);
const PlayerPosition& position() const;
void set_position(const PlayerPosition& pos);
+
+ std::string current_model_name() const;
+ void set_current_model_name(const std::string& model_name);
std::string ip_address() const;
void set_ip_address(const std::string& ip_address);
unsigned int id_;
std::string name_;
std::string trip_;
- std::string model_name_;
+ std::string model_name_, current_model_name_;
bool login_;
+ unsigned char channel_;
unsigned int revision_;
PlayerPosition pos_;
if (args.This() != child) {
UIBasePtr child_ptr = *static_cast<UIBasePtr*>(child->GetPointerFromInternalField(0));
child_ptr->set_parent(args.This());
- self->items_.push_back(Persistent<Object>::New(child));
+ self->items_.push_back(child_ptr);
}
}
return args.This();
assert(self);
if (args.Length() > 0 && args[0]->IsObject()) {
- auto child = args[0]->ToObject();
- auto it = std::find(self->items_.begin(), self->items_.end(), child);
+ auto it = std::find(self->items_.begin(), self->items_.end(), self);
if (it != self->items_.end()) {
- UIBasePtr chid_ptr = *static_cast<UIBasePtr*>((*it)->GetPointerFromInternalField(0));
+ UIBasePtr chid_ptr = *it;
chid_ptr->set_parent(Handle<Object>());
self->items_.erase(it);
}
assert(self);
BOOST_FOREACH(auto it, self->items_) {
- UIBasePtr chid_ptr = *static_cast<UIBasePtr*>(it->GetPointerFromInternalField(0));
+ UIBasePtr chid_ptr = it;
chid_ptr->set_parent(Handle<Object>());
}
self->items_.clear();
void UIList::ProcessInput(InputManager* input)
{
- for (auto it = items_.begin(); it != items_.end(); ++it) {
- auto item = *it;
- UIBasePtr item_ptr = *static_cast<UIBasePtr*>(item->GetPointerFromInternalField(0));
+ BOOST_FOREACH (UIBasePtr& item_ptr, items_) {
if (input->GetMousePos().second > absolute_y() &&
input->GetMousePos().second < absolute_y() + absolute_height()) {
item_ptr->ProcessInput(input);
int content_height = 0;
int index = 0;
- for (auto it = items_.begin(); it != items_.end(); ++it) {
- auto item = *it;
- UIBasePtr item_ptr = *static_cast<UIBasePtr*>(item->GetPointerFromInternalField(0));
+ BOOST_FOREACH (UIBasePtr& item_ptr, items_) {
item_ptr->set_offset_y(offset_y - BASE_BLOCK_SIZE);
// item_ptr->set_offset_width(-18);
item_ptr->Update();
SetDrawArea(absolute_x(), absolute_y(),
absolute_x() + absolute_width(), absolute_y() + absolute_height());
if (item_start_ >= 0) {
- for (int i = item_start_; i <= item_end_; i++) {
- UIBasePtr item_ptr = *static_cast<UIBasePtr*>(items_[i]->GetPointerFromInternalField(0));
+ BOOST_FOREACH (UIBasePtr& item_ptr, items_) {
item_ptr->Draw();
}
}
private:
std::array<ImageHandlePtr,4> scrollbar_base_image_handle_;
- std::vector<Persistent<Object>> items_;
+ std::vector<UIBasePtr> items_;
int scroll_y_, max_scroll_y_, scroll_y_target_;
int scrollbar_height_, scrollbar_y_;
REVISION = 0x0,
PUBLIC_KEY = 0x1,
LOGIN = 0x2,
+ CHANNEL = 0x3,
NAME = 0xA3,
TRIP = 0xA4,
MODEL_NAME = 0xA5,
}
ServerUpdateAccountProperty::ServerUpdateAccountProperty(AccountProperty property, const std::string& value) :
-Command(header::ServerUpdateAccountProperty, Utils::Serialize(property, value))
+Command(header::ServerUpdateAccountProperty, Utils::Serialize(property) + value)
{
}
serialized_byte_sum_(0),\r
compressed_byte_sum_(0),\r
write_average_limit_(999999),\r
- id_(0)\r
+ id_(0),\r
+ channel_(0)\r
{\r
\r
}\r
id_ = id;\r
}\r
\r
+ unsigned char Session::channel() const\r
+ {\r
+ return channel_;\r
+ }\r
+\r
+ void Session::set_channel(unsigned char channel)\r
+ {\r
+ channel_ = channel;\r
+ }\r
+\r
bool Session::online() const\r
{\r
return online_;\r
void set_id(UserID id);\r
bool online() const;\r
\r
+ unsigned char channel() const;\r
+ void set_channel(unsigned char channel);\r
+\r
std::string global_ip() const;\r
uint16_t udp_port() const;\r
void set_global_ip(const std::string& global_ip);\r
int write_average_limit_;\r
\r
UserID id_;\r
+ unsigned char channel_;\r
};\r
\r
}\r
\r
PropertyMap& property_map = usermap_it->second;\r
\r
- for (auto it = property_map.begin(); it != property_map.end(); ++it) {\r
- if (it->second.revision > revision) {\r
- patch += network::Utils::Serialize((uint16_t)it->first) + it->second.value;\r
+ BOOST_FOREACH (auto& property, property_map) {\r
+ if (property.second.revision > revision) {\r
+ patch += network::Utils::Serialize((uint16_t)property.first) + property.second.value;\r
}\r
}\r
}\r
return revision;\r
}\r
\r
+void Account::SetUserChannel(UserID user_id, unsigned char channel)\r
+{\r
+ Set(user_id, CHANNEL, channel);\r
+}\r
+\r
+unsigned char Account::GetUserChannel(UserID user_id) const\r
+{\r
+ unsigned char channel = 0;\r
+ Get(user_id, CHANNEL, &channel);\r
+ return channel;\r
+}\r
+\r
void Account::SetUserPosition(UserID user_id, const PlayerPosition& pos)\r
{\r
auto it = position_map_.find(user_id);\r
uint16_t GetUserUDPPort(UserID) const;\r
void SetUserUDPPort(UserID, uint16_t);\r
uint32_t GetUserRevision(UserID) const;\r
+ \r
+ void SetUserChannel(UserID, unsigned char);\r
+ unsigned char GetUserChannel(UserID) const;\r
\r
void SetUserPosition(UserID, const PlayerPosition&);\r
PlayerPosition GetUserPosition(UserID) const;\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
+ session->Send(command);\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() != 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
void Start(CallbackFuncPtr callback);\r
void Stop();\r
void Stop(int interrupt_type);\r
- void SendAll(const Command&);\r
- void SendAllLimited(const Command& command);\r
+\r
+ void SendAll(const Command&, int channel = -1, bool limited = false);\r
+ void SendOthers(const Command&, uint32_t self_id, int channel = -1, bool limited = false);\r
void SendTo(const Command&, uint32_t);\r
- void SendOthers(const Command&, SessionWeakPtr);\r
- void SendOthersLimited(const Command&, SessionWeakPtr);\r
\r
bool Empty() const;\r
std::string GetStatusJSON() const;\r
server.SendTo(send_command, user_id);\r
}\r
} else {\r
- server.SendAll(send_command);\r
+ server.SendAll(send_command, session->channel());\r
}\r
\r
Logger::Info("Receive JSON: %s", message_json.str());\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.SendOthersLimited(network::ClientUpdatePlayerPosition(session->id(),\r
- pos.x,pos.y,pos.z,pos.theta, pos.vy), c.session());\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
}\r
break;\r
\r
server.SendOthers(\r
network::ClientReceiveAccountRevisionUpdateNotify(session->id(),\r
- account.GetUserRevision(session->id())), c.session());\r
+ account.GetUserRevision(session->id())), session->id());\r
\r
Logger::Info(msg);\r
}\r
{\r
if (auto session = c.session().lock()) {\r
AccountProperty property;\r
- std::string value;\r
- network::Utils::Deserialize(c.body(), &property, &value);\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
\r
\r
case NAME:\r
{\r
- account.SetUserName(session->id(), value);\r
+ account.SetUserName(session->id(), buffer);\r
}\r
break;\r
case TRIP:\r
{\r
- account.SetUserTrip(session->id(), value);\r
+ account.SetUserTrip(session->id(), buffer);\r
}\r
break;\r
case MODEL_NAME:\r
{\r
- account.SetUserModelName(session->id(), value);\r
+ account.SetUserModelName(session->id(), buffer);\r
+ }\r
+ break;\r
+ case CHANNEL:\r
+ {\r
+ unsigned char value;\r
+ network::Utils::Deserialize(buffer, &value);\r
+ account.SetUserChannel(session->id(), value);\r
}\r
break;\r
default:\r
#define MMO_VERSION_TOSTRING(val) MMO_VERSION_TOSTRING_(val)\r
\r
#define MMO_VERSION_MAJOR 0\r
-#define MMO_VERSION_MINOR 1\r
-#define MMO_VERSION_REVISION 9\r
+#define MMO_VERSION_MINOR 2\r
+#define MMO_VERSION_REVISION 0\r
\r
-#define MMO_PROTOCOL_VERSION 2\r
+#define MMO_PROTOCOL_VERSION 3\r
\r
#ifdef MMO_VERSION_BUILD\r
#define MMO_VERSION_BUILD_TEXT " Build " MMO_VERSION_TOSTRING(MMO_VERSION_BUILD)\r