/* 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 "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_view = 0; clear_assets(); player_control = 0; player_ping = 0; player_level = 1; player_warningtime = 0; player_admin_level = 0; } void Player::print() const { con_print << "id: ^B" << id() << "^N name: ^B" << name() << "^N" << 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; if (zone()) { con_print << " zone ^B" << zone()->name() << std::endl; } } 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_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 int level) { player_level = level; } void Player::set_admin_level(const int admin_level) { player_admin_level = admin_level; } 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 { unsigned int zone_id = (zone() ? zone()->id() : 0); unsigned int view_id = (player_view ? player_view->id() : 0); unsigned int control_id = (player_control ? player_control->id() : 0); unsigned int mission_id = (player_mission_target ? player_mission_target->id() : 0); os << player_id << " " << zone_id << " " << view_id << " " << control_id << " " << mission_id << " " << player_credits << " " << player_level << " " << 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"; } } 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"; } } else { player_mission_target = 0; } is >> player_credits; is >> player_level; 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; } }