/* core/player.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2. */ #include #include #include "auxiliary/functions.h" #include "sys/sys.h" #include "core/player.h" #include "core/cvar.h" #include "core/application.h" #include "core/gameserver.h" namespace core { Player::Player(NetClient *client) { player_client = client; clear(); } Player::~Player() { clear(); } void Player::clear() { player_id = 0; player_zone = 0; player_name.clear(); player_dirty = false; player_zonechange = false; player_mute = false; player_mission_target = 0; player_autopilot_target = 0; player_view = 0; clear_assets(); player_control = 0; player_ping = 0; player_level = 1; player_warningtime = 0; player_admin_level = 0; player_reputation.clear(); player_npckills = 0; player_pvpkills = 0; player_time_wasted = 0; player_time_joined = 0; } void Player::print() const { con_print << "id: ^B" << id() << "^N name: ^B" << name() << "^N" << std::endl; if (zone()) { con_print << " zone ^B" << zone()->name() << std::endl; } con_print << " color ^B" << color() << std::endl; con_print << " ping ^B" << ping() << std::endl; con_print << " credits ^B" << credits() << std::endl; con_print << " level ^B" << level() << std::endl; con_print << " npc kills ^B" << npckills() << std::endl; con_print << " pvp kills ^B" << pvpkills() << std::endl; con_print << " time wasted ^B"; long time_wasted = (player_time_wasted + server()->timestamp() - player_time_joined) / 1000; const long time_wasted_seconds = time_wasted % 60; time_wasted = (time_wasted - time_wasted_seconds) / 60; const long time_wasted_minutes = time_wasted % 60; time_wasted = (time_wasted - time_wasted_minutes) / 60; const long time_wasted_hours = time_wasted % 24; const long time_wasted_days = (time_wasted - time_wasted_hours) / 24; if (time_wasted_days > 0) { con_print << time_wasted_days << aux::plural("day", time_wasted_days) << " "; } con_print << std::setfill('0') << std::setw(2) << time_wasted_hours << ":" << std::setfill('0') << std::setw(2) << time_wasted_minutes << ":" << std::setfill('0') << std::setw(2) << time_wasted_seconds << std::endl; } void Player::messagebox(const char *text, const char *label1, const char *command1, const char *label2, const char *command2) { std::string str_text(text ? text : "" ); std::string str_label1(label1 ? label1 : "" ); std::string str_command1(command1 ? command1 : "" ); std::string str_label2(label2 ? label2 : "" ); std::string str_command2(command2 ? command2 : "" ); server()->messagebox(this, str_text, str_label1, str_command1, str_label2, str_command2); } void Player::message(Message::Channel channel, const std::string text) { server()->message(this, channel, text); } void Player::send(const std::string text) { server()->message(this, core::Message::Info, text); } void Player::sound(const std::string name) { server()->message(this, core::Message::Sound, name); } void Player::set_control(EntityControlable *entitycontrolable) { player_control = entitycontrolable; if (entitycontrolable) { set_zone(entitycontrolable->zone()); player_view = 0; } player_dirty = true; } void Player::set_zone(Zone *zone) { if (zone != player_zone) { player_zone = zone; player_zonechange = true; } } void Player::set_view(Entity *view) { player_view = view; player_dirty = true; if (player_view) { set_zone(player_view->zone()); } } void Player::set_mission_target(Entity *new_mission_target) { if (new_mission_target != player_mission_target) { player_mission_target = new_mission_target; player_dirty = true; } } void Player::set_autopilot_target(Entity *new_autopilot_target) { if (new_autopilot_target != player_autopilot_target) { player_autopilot_target = new_autopilot_target; player_dirty = true; } } void Player::set_credits(const long amount) { player_credits = amount; } void Player::add_credits(const long amount) { player_credits += amount; } void Player::set_ping(const long ping) { player_ping = ping; } void Player::set_level(const Level level) { player_level = level; } void Player::set_admin_level(const Level admin_level) { player_admin_level = admin_level; } void Player::set_npckills(const long kills) { player_npckills = kills; } void Player::set_pvpkills(const long kills) { player_pvpkills = kills; } void Player::set_time_wasted(const long time_wasted) { player_time_wasted = time_wasted; } void Player::set_time_joined() { player_time_joined = server()->timestamp(); } void Player::update_info() { Cvar *cl_name = Cvar::find("cl_name"); if (cl_name) { if (cl_name->str().size()) { player_name = cl_name->str(); aux::strip_quotes(player_name); (*cl_name) = player_name; } } Cvar *cl_color = Cvar::find("cl_color"); math::Color color(1.0, 1.0, 1.0, 1.0); if (cl_color) { std::istringstream is(cl_color->str()); if (is >> color) player_color.assign(color); } Cvar *cl_color_second = Cvar::find("cl_colorsecond"); math::Color color_second(1.0, 1.0, 1.0, 1.0); if (cl_color_second) { std::istringstream is(cl_color_second->str()); if (is >> color_second) player_color_second.assign(color_second); } Cvar *passwd = Cvar::find("rconpassword"); if (passwd) { player_rconpassword.assign(passwd->str()); } else { player_rconpassword.clear(); } } void Player::serialize_client_update(std::ostream & os) { os << player_color << " " << player_color_second << " " << "\"" << player_name << "\" " << "\"" << player_rconpassword << "\" "; } void Player::receive_client_update(std::istream &is) { is >> player_color; is >> player_color_second; std::string n; char c; while ((is.get(c)) && (c != '"')); while ((is.get(c)) && (c != '"')) n += c; if (n.size()) player_name.assign(n); n.clear(); while ((is.get(c)) && (c != '"')); while ((is.get(c)) && (c != '"')) n += c; if (n.size()) player_rconpassword.assign(n); } void Player::serialize_server_update(std::ostream & os) const { const unsigned int zone_id = (zone() ? zone()->id() : 0); const unsigned int view_id = (player_view ? player_view->id() : 0); const unsigned int control_id = (player_control ? player_control->id() : 0); const unsigned int mission_id = (player_mission_target ? player_mission_target->id() : 0); const unsigned int autopilot_id = (player_autopilot_target ? player_autopilot_target->id() : 0); os << player_id << " " << zone_id << " " << view_id << " " << control_id << " " << mission_id << " " << autopilot_id << " " << player_credits << " " << player_level << " " << player_npckills << " " << player_pvpkills << " " << player_time_wasted << " " << player_time_joined << " " << player_ping; } void Player::receive_server_update(std::istream &is) { int id = 0; is >> id; if (!player_id) { player_id = id; } else if (player_id != id) { con_warn << "received inconsistent update for player " << id << "\n"; return; } unsigned int zone_id = 0; is >> zone_id; set_zone(Zone::find(zone_id)); unsigned int view_id = 0; is >> view_id; set_view(Entity::find(view_id)); unsigned int control_id = 0; is >> control_id; if (control_id) { Entity *e = Entity::find(control_id); if (e && e->type() == Entity::Controlable) { player_control = static_cast(e); } else { player_control = 0; con_warn << "control set to unknown entity " << control_id << "\n"; // FIMXE request entity } } else { player_control = 0; } unsigned int mission_id = 0; is >> mission_id; if (mission_id) { player_mission_target = Entity::find(mission_id); if (!player_mission_target) { con_warn << "mission target set to unknown entity " << mission_id << "\n"; // FIMXE request entity } } else { player_mission_target = 0; } unsigned int autopilot_id = 0; is >> autopilot_id; if (autopilot_id) { player_autopilot_target = Entity::find(autopilot_id); if (!player_autopilot_target) { con_warn << "autopilot target set to unknown entity " << autopilot_id << "\n"; // FIMXE request entity } } else { player_autopilot_target = 0; } is >> player_credits; is >> player_level; is >> player_npckills; is >> player_pvpkills; is >> player_time_wasted; is >> player_time_joined; is >> player_ping; /* std::string n; char c; while ( (is.get(c)) && (c != '"')); while ( (is.get(c)) && (c != '"')) n += c; if (n.size()) player_name = n; */ } void Player::serialize_short_server_update(std::ostream & os) const { unsigned int zone_id = (zone() ? zone()->id() : 0); os << player_id << " " << "\"" << player_name << "\" " << zone_id << " " << player_color << " " << player_color_second << " " << player_level << " " << player_ping; } void Player::receive_short_server_update(std::istream &is) { // read player id int id = 0; is >> id; if (!player_id) { player_id = id; } else if (player_id != id) { con_warn << "received inconsistent short update for player " << id << "\n"; return; } // read player name std::string n; char c; while ((is.get(c)) && (c != '"')); while ((is.get(c)) && (c != '"')) n += c; if (n.size()) player_name = n; // read zone id unsigned int zone_id = 0; is >> zone_id; set_zone(Zone::find(zone_id)); // read attributes is >> player_color; is >> player_color_second; is >> player_level; is >> player_ping; } void Player::add_asset(EntityControlable *entity) { entity->entity_owner = this; assets.push_back(entity); //con_debug << " adding asset " << entity->id() << " to player " << id() << std::endl; } void Player::remove_asset(EntityControlable *entity) { if (!entity) return; for (std::list::iterator asset = assets.begin(); asset != assets.end(); asset++) { if (((*asset) == entity) && (entity->owner() == this)) { //con_debug << " removing asset " << (*asset)->id() << " from player " << id() << std::endl; if ((*asset) == player_control) player_control = 0; (*asset)->entity_owner = 0; (*asset)->die(); assets.erase(asset); player_dirty = true; return; } } con_warn << "Could not remove asset " << entity->id() << " from player " << this->id() << "\n"; } void Player::remove_asset(unsigned int id) { if (!id) return; for (std::list::iterator asset = assets.begin(); asset != assets.end(); asset++) { if (((*asset)->id() == id) && ((*asset)->owner() == this)) { //con_debug << " removing asset " << (*asset)->id() << " from player " << this->id() << std::endl; if ((*asset) == player_control) player_control = 0; (*asset)->entity_owner = 0; (*asset)->die(); assets.erase(asset); player_dirty = true; return; } } con_warn << "Could not remove asset " << id << " from player " << this->id() << "\n"; } void Player::clear_assets() { // clear assets for (std::list::iterator asset = assets.begin(); asset != assets.end(); asset++) { //con_debug << " removing asset " << (*asset)->id() << " from player " << id() << std::endl; (*asset)->entity_owner = 0; (*asset)->die(); } assets.clear(); player_control = 0; } }