new lobby: rooms logic, crude room window support...

...(faked with one textbox and a 'next window' button)
This commit is contained in:
Tomasz Śniatowski 2009-07-10 00:11:57 +01:00
parent 1baefd38e3
commit 91b27c3cbc
7 changed files with 651 additions and 34 deletions

View file

@ -269,6 +269,12 @@
{GAMELISTBOX}
{VERTICAL_SEP}
{VERTICAL_BEGIN}
[label]
id = "chat_log_header"
definition = "title"
label = "Lobby"
[/label]
{VERTICAL_SEP}
[label]
id = "chat_log"
definition = "default"
@ -288,6 +294,12 @@
definition = "default"
label = _ "Send"
[/button]
{HORIZONTAL_SEP}
[button]
id = "next_window"
definition = "default"
label = _ "Next room"
[/button]
{HORIZONTAL_END}
{VERTICAL_END}
{VERTICAL_END}

View file

@ -35,9 +35,27 @@ protected:
virtual void add_chat_message(const time_t& time,
const std::string& speaker, int side, const std::string& message,
MESSAGE_TYPE type=MESSAGE_PRIVATE)=0;
virtual void send_chat_message(const std::string& message, bool allies_only=false)=0;
virtual void send_whisper(const std::string& receiver, const std::string& message);
virtual void add_whisper_sent(const std::string& receiver, const std::string& message);
virtual void add_whisper_received(const std::string& sender, const std::string& message);
virtual void send_chat_room_message(const std::string& room, const std::string& message);
virtual void add_chat_room_message_sent(const std::string& room, const std::string& message);
virtual void add_chat_room_message_received(const std::string& room,
const std::string& speaker, const std::string& message);
void send_command(const std::string& cmd, const std::string& args="");
void change_logging(const std::string& data);
friend class chat_command_handler;
};

View file

@ -33,6 +33,7 @@
#include <boost/bind.hpp>
static lg::log_domain log_network("network");
#define DBG_NW LOG_STREAM(info, log_network)
#define LOG_NW LOG_STREAM(info, log_network)
#define ERR_NW LOG_STREAM(err, log_network)
@ -46,6 +47,17 @@ static lg::log_domain log_config("config");
namespace gui2 {
namespace {
//TODO move this and other MP prefs to a MP_prefs header and possibly cpp
const char* prefkey_whisper_friends_only = "lobby_whisper_friends_only";
const char* prefkey_auto_open_whisper_windows = "lobby_auto_open_whisper_windows";
bool whisper_friends_only() {
return utils::string_bool(preferences::get(prefkey_whisper_friends_only));
}
bool auto_open_whisper_windows() {
return utils::string_bool(preferences::get(prefkey_auto_open_whisper_windows), true);
}
}
void tlobby_main::send_chat_message(const std::string& message, bool /*allies_only*/)
{
@ -54,30 +66,128 @@ void tlobby_main::send_chat_message(const std::string& message, bool /*allies_on
msg["sender"] = preferences::login();
data.add_child("message", msg);
add_chat_message(time(NULL), preferences::login(), 0, message); //local echo
add_chat_message(time(NULL), preferences::login(), 0, message); //local echo
network::send_data(data, 0, true);
}
void tlobby_main::add_chat_message(const time_t& /*time*/, const std::string& speaker,
int /*side*/, const std::string& message, events::chat_handler::MESSAGE_TYPE /*type*/)
{
//chat_.add_message(time, speaker, message);
//chat_.update_textbox(chat_textbox_);
std::stringstream ss;
ss << "<" << speaker << "> ";
ss << message;
LOG_NW << "Message: " << ss.str() << std::endl;
chat_log_->set_label(chat_log_->label() + "\n" + ss.str());
append_to_chatbox(ss.str());
}
void tlobby_main::add_whisper_sent(const std::string& receiver, const std::string& message)
{
if (whisper_window_active(receiver)) {
add_active_window_message(preferences::login(), message);
} else if (tlobby_chat_window* t = whisper_window_open(receiver, utils::string_bool(prefkey_auto_open_whisper_windows))) {
switch_to_window(t);
add_active_window_message(preferences::login(), message);
} else {
add_active_window_whisper("whisper to " + receiver, message);
}
lobby_info_.get_whisper_log(receiver).add_message(preferences::login(), message);
}
void tlobby_main::add_whisper_received(const std::string& sender, const std::string& message)
{
bool can_go_to_active = !whisper_friends_only() || preferences::is_friend(sender);
bool can_open_new = utils::string_bool(preferences::get(prefkey_auto_open_whisper_windows)) && can_go_to_active;
lobby_info_.get_whisper_log(sender).add_message(sender, message);
if (whisper_window_open(sender, can_open_new)) {
if (whisper_window_active(sender)) {
add_active_window_message(sender, message);
do_notify(NOTIFY_WHISPER);
} else {
add_whisper_window_whisper(sender, message);
increment_waiting_whsipers(sender);
do_notify(NOTIFY_WHISPER_OTHER_WINDOW);
}
} else if (can_go_to_active) {
add_active_window_whisper(sender, message);
do_notify(NOTIFY_WHISPER);
} else {
DBG_NW << "Ignoring whisper from " << sender << "\n";
}
}
/** inherited form chat_handler */
void tlobby_main::add_chat_room_message_sent(const std::string& room,
const std::string& message)
{
//do not open room window here, player should be in the room before sending
//messages yo it should be allowed to happen
if (tlobby_chat_window* t = room_window_open(room, false)) {
room_info* ri = lobby_info_.get_room(room);
assert(ri);
if (!room_window_active(room)) {
switch_to_window(t);
}
ri->log().add_message(preferences::login(), message);
add_active_window_message(preferences::login(), message);
} else {
DBG_NW << "Cannot add sent message to ui for room " << room
<< ", player not in the room\n";
}
}
void tlobby_main::add_chat_room_message_received(const std::string& room,
const std::string& speaker, const std::string& message)
{
if (room_info* ri = lobby_info_.get_room(room)) {
t_notify_mode notify_mode = NOTIFY_NONE;
ri->log().add_message(speaker, message);
if (room_window_active(room)) {
add_active_window_message(speaker, message);
notify_mode = NOTIFY_MESSAGE;
} else {
add_room_window_message(room, speaker, message);
increment_waiting_messages(room);
notify_mode = NOTIFY_MESSAGE_OTHER_WINDOW;
}
if (speaker == "server") {
notify_mode = NOTIFY_SERVER_MESSAGE;
} else if (utils::word_match(message, preferences::login())) {
notify_mode = NOTIFY_OWN_NICK;
} else if (preferences::is_friend(speaker)) {
notify_mode = NOTIFY_FRIEND_MESSAGE;
}
do_notify(notify_mode);
} else {
LOG_NW << "Discarding message to room " << room
<< " from " << speaker << " (room not open)\n";
}
}
void tlobby_main::append_to_chatbox(const std::string& text)
{
chat_log_->set_label(chat_log_->label() + "\n" + text);
window_->invalidate_layout();
}
void tlobby_main::do_notify(t_notify_mode mode)
{
switch (mode) {
case NOTIFY_MESSAGE:
break;
default:
break;
}
}
tlobby_main::tlobby_main(const config& game_config, lobby_info& info)
: legacy_result_(QUIT)
, game_config_(game_config)
, gamelistbox_(NULL), chat_log_(NULL)
, chat_input_(NULL), window_(NULL)
, lobby_info_(info), preferences_callback_(NULL)
, open_windows_(), active_window_(0)
{
room_window_open("lobby", true);
}
void tlobby_main::set_preferences_callback(boost::function<void ()> cb)
@ -215,6 +325,7 @@ void tlobby_main::pre_show(CVideo& /*video*/, twindow& window)
GUI2_EASY_BUTTON_CALLBACK(show_preferences, tlobby_main);
GUI2_EASY_BUTTON_CALLBACK(join_global, tlobby_main);
GUI2_EASY_BUTTON_CALLBACK(observe_global, tlobby_main);
GUI2_EASY_BUTTON_CALLBACK(next_window, tlobby_main);
}
void tlobby_main::post_show(twindow& /*window*/)
@ -222,6 +333,142 @@ void tlobby_main::post_show(twindow& /*window*/)
window_ = NULL;
}
tlobby_chat_window* tlobby_main::room_window_open(const std::string& room, bool open_new)
{
return search_create_window(room, false, open_new);
}
tlobby_chat_window* tlobby_main::whisper_window_open(const std::string& name, bool open_new)
{
return search_create_window(name, true, open_new);
}
tlobby_chat_window* tlobby_main::search_create_window(const std::string& name, bool whisper, bool open_new)
{
foreach (tlobby_chat_window& t, open_windows_) {
if (t.name == name && t.whisper == whisper) return &t;
}
if (open_new) {
open_windows_.push_back(tlobby_chat_window(name, whisper));
if (!whisper) {
lobby_info_.open_room(name);
}
return &open_windows_.back();
}
return NULL;
}
bool tlobby_main::whisper_window_active(const std::string& name)
{
const tlobby_chat_window& t = open_windows_[active_window_];
return t.name == name && t.whisper == true;
}
bool tlobby_main::room_window_active(const std::string& room)
{
const tlobby_chat_window& t = open_windows_[active_window_];
return t.name == room && t.whisper == false;
}
void tlobby_main::increment_waiting_whsipers(const std::string& name)
{
if (tlobby_chat_window* t = whisper_window_open(name, false)) {
t->pending_messages++;
}
}
void tlobby_main::increment_waiting_messages(const std::string& room)
{
if (tlobby_chat_window* t = room_window_open(room, false)) {
t->pending_messages++;
}
}
void tlobby_main::add_whisper_window_whisper(const std::string& /*sender*/, const std::string& /*message*/)
{
}
void tlobby_main::add_active_window_whisper(const std::string& sender, const std::string& message)
{
std::stringstream ss;
ss << "<" << "whisper: " << sender << ">" << message;
append_to_chatbox(ss.str());
}
void tlobby_main::add_room_window_message(const std::string& /*room*/,
const std::string& /*sender*/, const std::string& /*message*/)
{
}
void tlobby_main::add_active_window_message(const std::string& sender, const std::string& message)
{
std::stringstream ss;
ss << "<" << sender << ">" << message;
append_to_chatbox(ss.str());
}
void tlobby_main::next_active_window()
{
if (open_windows_.size() < 2) return;
if (active_window_ == open_windows_.size() - 1) {
active_window_ = 0;
} else {
active_window_++;
}
active_window_changed();
}
void tlobby_main::switch_to_window(tlobby_chat_window* t)
{
active_window_ = t - &open_windows_[0];
assert(active_window_ < open_windows_.size());
active_window_changed();
}
void tlobby_main::active_window_changed()
{
tlabel* header = dynamic_cast<tlabel*>(window_->find_widget("chat_log_header", false));
const tlobby_chat_window& t = open_windows_[active_window_];
if (t.whisper) {
header->set_label("<" + t.name + ">");
chat_log_->set_label(lobby_info_.get_whisper_log(t.name).assemble_text());
} else {
header->set_label(t.name);
assert(lobby_info_.get_room(t.name));
chat_log_->set_label(lobby_info_.get_room(t.name)->log().assemble_text());
}
window_->invalidate_layout();
}
void tlobby_main::close_active_window()
{
return close_window(active_window_);
}
void tlobby_main::close_window(size_t idx)
{
const tlobby_chat_window& t = open_windows_[idx];
bool active_changed = idx == active_window_;
if (t.name == "lobby" && t.whisper == false) return;
if (open_windows_.size() == 1) return;
if (active_window_ == open_windows_.size() - 1) {
active_window_--;
}
if (t.whisper) {
lobby_info_.get_whisper_log(t.name).clear();
} else {
lobby_info_.close_room(t.name);
}
open_windows_.erase(open_windows_.begin() + idx);
if (active_changed) active_window_changed();
}
void tlobby_main::network_handler()
{
config data;
@ -257,15 +504,21 @@ void tlobby_main::process_network_data(const config &data)
}
}
void tlobby_main::process_message(const config &data, bool /*whisper / *= false*/)
void tlobby_main::process_message(const config &data, bool whisper /*= false*/)
{
std::string sender = data["sender"];
if (preferences::is_ignored(sender)) return;
const std::string& message = data["message"];
const std::string& room = data["room"];
if (!room.empty()) {
sender = room + ": " + sender;
if (whisper) {
add_whisper_received(sender, message);
} else {
std::string room = data["room"];
if (room.empty()) {
LOG_NW << "Message without a room from " << sender << ", assuming lobby\n";
room = "lobby";
}
add_chat_room_message_received(room, sender, message);
}
add_chat_message(time(0), sender, 0, message);
}
void tlobby_main::process_gamelist(const config &data)
@ -281,12 +534,41 @@ void tlobby_main::process_gamelist_diff(const config &data)
}
}
void tlobby_main::process_room_join(const config &/*data*/)
void tlobby_main::process_room_join(const config &data)
{
const std::string& room = data["room"];
const std::string& player = data["player"];
room_info* r = lobby_info_.get_room(room);
if (r) {
if (player == preferences::login()) {
//parse full userlist
} else {
r->add_member(player);
//update userlists
//check the show-lobby-joins param
}
} else {
if (player == preferences::login()) {
tlobby_chat_window* t = room_window_open(room, true);
switch_to_window(t);
lobby_info_.open_room(room);
} else {
LOG_NW << "Discarding join info for a room the player is not in\n";
}
}
}
void tlobby_main::process_room_part(const config &/*data*/)
void tlobby_main::process_room_part(const config &data)
{
//todo close room window when the part message is sent
const std::string& room = data["room"];
const std::string& player = data["player"];
room_info* r = lobby_info_.get_room(room);
if (r) {
r->remove_member(player);
} else {
LOG_NW << "Discarding part info for a room the player is not in\n";
}
}
void tlobby_main::process_room_query_response(const config &/*data*/)
@ -359,10 +641,35 @@ void tlobby_main::send_message_button_callback(gui2::twindow &/*window*/)
{
const std::string& input = chat_input_->get_value();
if (input.empty()) return;
chat_handler::do_speak(input);
if (input[0] == '/') {
//TODO: refactor do_speak so it uses context information about
// opened window, so e.g. /ignore in a whisper session ignores
// the other party without having to specify it's nick.
chat_handler::do_speak(input);
} else {
config msg;
send_message_to_active_window(input);
}
chat_input_->set_value("");
}
void tlobby_main::send_message_to_active_window(const std::string& input)
{
tlobby_chat_window& t = open_windows_[active_window_];
if (t.whisper) {
send_whisper(t.name, input);
add_whisper_sent(t.name, input);
} else {
send_chat_room_message(t.name, input);
add_chat_room_message_sent(t.name, input);
}
}
void tlobby_main::next_window_button_callback(twindow& /*window*/)
{
next_active_window();
}
void tlobby_main::create_button_callback(gui2::twindow& window)
{
legacy_result_ = CREATE;

View file

@ -31,6 +31,17 @@ class tlistbox;
class ttext_box;
class twindow;
struct tlobby_chat_window
{
tlobby_chat_window(std::string name, bool whisper)
: name(name), whisper(whisper), pending_messages(0)
{
}
std::string name;
bool whisper;
int pending_messages;
};
class tlobby_main : public tdialog, private events::chat_handler
{
public:
@ -48,14 +59,115 @@ public:
enum legacy_result { QUIT, JOIN, OBSERVE, CREATE, PREFERENCES };
legacy_result get_legacy_result() const { return legacy_result_; }
enum t_notify_mode {
NOTIFY_NONE,
NOTIFY_MESSAGE,
NOTIFY_MESSAGE_OTHER_WINDOW,
NOTIFY_SERVER_MESSAGE,
NOTIFY_OWN_NICK,
NOTIFY_FRIEND_MESSAGE,
NOTIFY_WHISPER,
NOTIFY_WHISPER_OTHER_WINDOW,
NOTIFY_COUNT
};
void do_notify(t_notify_mode mode);
protected:
void send_chat_message(const std::string& message, bool /*allies_only*/);
void add_chat_message(const time_t& time, const std::string& speaker,
/** inherited form chat_handler */
virtual void send_chat_message(const std::string& message, bool /*allies_only*/);
/** inherited form chat_handler */
virtual void add_chat_message(const time_t& time, const std::string& speaker,
int side, const std::string& message,
events::chat_handler::MESSAGE_TYPE type = events::chat_handler::MESSAGE_PRIVATE);
/** inherited form chat_handler */
virtual void add_whisper_sent(const std::string& receiver, const std::string& message);
/** inherited form chat_handler */
virtual void add_whisper_received(const std::string& sender, const std::string& message);
/** inherited form chat_handler */
virtual void add_chat_room_message_sent(const std::string& room, const std::string& message);
/** inherited form chat_handler */
virtual void add_chat_room_message_received(const std::string& room,
const std::string& speaker, const std::string& message);
private:
void append_to_chatbox(const std::string& text);
legacy_result legacy_result_;
/**
* Check if a room window for "room" is open, if open_new is true
* then it will be created if not found.
* @return valid ptr if the window was found or added, null otherwise
*/
tlobby_chat_window* room_window_open(const std::string& room, bool open_new);
/**
* Check if a whisper window for user "name" is open, if open_new is true
* then it will be created if not found.
* @return valid ptr if the window was found or added, null otherwise
*/
tlobby_chat_window* whisper_window_open(const std::string& name, bool open_new);
tlobby_chat_window* search_create_window(const std::string& name, bool whisper, bool open_new);
/**
* @return true if the whisper window for "name" is the active window
*/
bool whisper_window_active(const std::string& name);
/**
* @return true if the room window for "room" is the active window
*/
bool room_window_active(const std::string& room);
/**
* Mark the whisper window for "name" as having one more pending message
*/
void increment_waiting_whsipers(const std::string& name);
/**
* Mark the room window for "room" as having one more pending message
*/
void increment_waiting_messages(const std::string& room);
/**
* Add a whisper message to the whisper window
*/
void add_whisper_window_whisper(const std::string& sender, const std::string& message);
/**
* Add a whisper message to the current window which is not the whisper window
* for "name".
*/
void add_active_window_whisper(const std::string& sender, const std::string& message);
/**
* Add a message to the window for room "room"
*/
void add_room_window_message(const std::string& room, const std::string& sender, const std::string& message);
/**
* Add a message to the window for room "room"
*/
void add_active_window_message(const std::string& sender, const std::string& message);
void next_active_window();
void switch_to_window(tlobby_chat_window* t);
void active_window_changed();
void close_active_window();
void close_window(size_t idx);
/**
* Network polling callback
*/
@ -93,6 +205,10 @@ private:
void send_message_button_callback(twindow& window);
void send_message_to_active_window(const std::string& input);
void next_window_button_callback(twindow& window);
void create_button_callback(twindow& window);
void show_preferences_button_callback(twindow& window);
@ -127,6 +243,10 @@ private:
lobby_info& lobby_info_;
boost::function<void ()> preferences_callback_;
std::vector<tlobby_chat_window> open_windows_;
size_t active_window_;
};
} // namespace gui2

View file

@ -29,6 +29,45 @@
static lg::log_domain log_config("config");
#define ERR_CF LOG_STREAM(err, log_config)
chat_message::chat_message(const time_t& timestamp, const std::string& user, const std::string& message)
: timestamp(timestamp), user(user), message(message)
{
}
chat_message::chat_message(const std::string& user, const std::string& message)
: timestamp(time(0)), user(user), message(message)
{
}
chat_log::chat_log()
: history_()
{
}
void chat_log::add_message(const time_t& timestamp, const std::string& user, const std::string& message)
{
history_.push_back(chat_message(timestamp, user, message));
}
void chat_log::add_message(const std::string& user, const std::string& message) {
add_message(time(NULL), user, message);
}
std::string chat_log::assemble_text()
{
std::stringstream ss;
foreach (const chat_message& ch, history_) {
ss << "<" << ch.user << ">" << ch.message << "\n";
}
return ss.str();
}
void chat_log::clear()
{
history_.clear();
}
room_info::room_info(const std::string& name)
: name_(name), members_()
{
@ -336,3 +375,42 @@ void lobby_info::parse_gamelist()
games_.push_back(game_info(c, game_config_));
}
}
room_info* lobby_info::get_room(const std::string &name)
{
foreach (room_info& r, rooms_) {
if (r.name() == name) return &r;
}
return NULL;
}
const room_info* lobby_info::get_room(const std::string &name) const
{
foreach (const room_info& r, rooms_) {
if (r.name() == name) return &r;
}
return NULL;
}
bool lobby_info::has_room(const std::string &name) const
{
return get_room(name) != NULL;
}
chat_log& lobby_info::get_whisper_log(const std::string &name)
{
return whispers_[name];
}
void lobby_info::open_room(const std::string &name)
{
rooms_.push_back(room_info(name));
}
void lobby_info::close_room(const std::string &name)
{
room_info* r = get_room(name);
if (r) {
rooms_.erase(rooms_.begin() + (r - &rooms_[0]));
}
}

View file

@ -17,8 +17,43 @@
#include "config.hpp"
#include "sdl_utils.hpp"
#include <set>
#include <map>
#include <deque>
/** This class represenst a single stored chat message */
struct chat_message
{
/** Create a chat message */
chat_message(const time_t& timestamp, const std::string& user, const std::string& message);
/** Create a chat message, assume the time is "now" */
chat_message(const std::string& user, const std::string& message);
time_t timestamp;
std::string user;
std::string message;
};
/** this class memorizes a chat session. */
class chat_log
{
public:
chat_log();
void add_message(const time_t& timestamp, const std::string& user, const std::string& message);
void add_message(const std::string& user, const std::string& message);
const std::deque<chat_message>& history() const { return history_; }
std::string assemble_text();
void clear();
private:
std::deque<chat_message> history_;
};
/**
* This class represents the information a client has about a room
@ -32,9 +67,15 @@ public:
bool is_member(const std::string& user) const;
void add_member(const std::string& user);
void remove_member(const std::string& user);
void process_room_members(const config &data);
const chat_log& log() const { return log_; }
chat_log& log() { return log_; }
private:
const std::string& name_;
std::string name_;
std::set<std::string> members_;
chat_log log_;
};
@ -112,6 +153,17 @@ public:
bool process_gamelist_diff(const config &data);
const config& gamelist() const { return gamelist_; }
void open_room(const std::string& name);
void close_room(const std::string& name);
bool has_room(const std::string& name) const;
room_info* get_room(const std::string& name);
const room_info* get_room(const std::string& name) const;
user_info& get_user(const std::string& name);
chat_log& get_whisper_log(const std::string& name);
const std::vector<room_info>& rooms() const { return rooms_; }
const std::vector<game_info>& games() const { return games_; }
const std::vector<user_info>& users() const { return users_; }
@ -124,6 +176,7 @@ private:
std::vector<room_info> rooms_;
std::vector<game_info> games_;
std::vector<user_info> users_;
std::map<std::string, chat_log> whispers_;
};
#endif

View file

@ -2458,6 +2458,49 @@ private:
cch.dispatch(cmd);
}
void chat_handler::send_whisper(const std::string& receiver, const std::string& message)
{
config cwhisper, data;
cwhisper["receiver"] = receiver;
cwhisper["message"] = message;
cwhisper["sender"] = preferences::login();
data.add_child("whisper", cwhisper);
network::send_data(data, 0, true);
}
void chat_handler::add_whisper_sent(const std::string& receiver, const std::string& message)
{
add_chat_message(time(NULL), "whisper to " + receiver, 0, message);
}
void chat_handler::add_whisper_received(const std::string& sender, const std::string& message)
{
add_chat_message(time(NULL), "whisper: " + sender, 0, message);
}
void chat_handler::send_chat_room_message(const std::string& room,
const std::string& message)
{
config cmsg, data;
cmsg["room"] = room;
cmsg["message"] = message;
cmsg["sender"] = preferences::login();
data.add_child("message", cmsg);
network::send_data(data, 0, true);
}
void chat_handler::add_chat_room_message_sent(const std::string &room, const std::string &message)
{
add_chat_room_message_received(room, preferences::login(), message);
}
void chat_handler::add_chat_room_message_received(const std::string &room,
const std::string &speaker, const std::string &message)
{
add_chat_message(time(NULL), room + ": " + speaker, 0, message, events::chat_handler::MESSAGE_PRIVATE);
}
void chat_command_handler::do_emote()
{
chat_handler_.send_chat_message("/me " + get_data(), allies_only_);
@ -2496,30 +2539,16 @@ private:
{
if (get_data(1).empty()) return command_failed_need_arg(1);
if (get_data(2).empty()) return command_failed_need_arg(2);
config cwhisper, data;
cwhisper["receiver"] = get_arg(1);
cwhisper["message"] = get_data(2);
cwhisper["sender"] = preferences::login();
data.add_child("whisper", cwhisper);
chat_handler_.add_chat_message(time(NULL),
"whisper to " + cwhisper["receiver"], 0,
cwhisper["message"], events::chat_handler::MESSAGE_PRIVATE);
network::send_data(data, 0, true);
chat_handler_.send_whisper(get_arg(1), get_data(2));
chat_handler_.add_whisper_sent(get_arg(1), get_data(2));
}
void chat_command_handler::do_chanmsg()
{
if (get_data(1).empty()) return command_failed_need_arg(1);
if (get_data(2).empty()) return command_failed_need_arg(2);
config cwhisper, data;
cwhisper["room"] = get_arg(1);
cwhisper["message"] = get_data(2);
cwhisper["sender"] = preferences::login();
data.add_child("message", cwhisper);
chat_handler_.add_chat_message(time(NULL),
cwhisper["room"] + ": " + preferences::login(), 0,
cwhisper["message"], events::chat_handler::MESSAGE_PRIVATE);
network::send_data(data, 0, true);
chat_handler_.send_chat_room_message(get_arg(1), get_data(2));
chat_handler_.add_chat_room_message_sent(get_arg(1), get_data(2));
}
void chat_command_handler::do_log()