/* core/info.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include "auxiliary/functions.h" #include "core/info.h" #include "sys/sys.h" #include "core/info.h" #include "core/gameinterface.h" #include namespace core { /* ---- class InfoType --------------------------------------------- */ InfoType::InfoType(const char *label) : Label(label) { infotype_registry.push_back(this); } InfoType::~InfoType() { } /* ---- static InfoType registry ----------------------------------- */ InfoType::Registry InfoType::infotype_registry; void InfoType::clear() { for (Registry::iterator it = infotype_registry.begin(); it != infotype_registry.end(); it++) { InfoType *infotype = (*it); delete infotype; } infotype_registry.clear(); } InfoType *InfoType::find(const std::string & label) { if (!label.size()) return 0; for (Registry::iterator it = infotype_registry.begin(); it != infotype_registry.end(); it++) { InfoType *infotype = (*it); if (infotype->label().compare(label) == 0) { return infotype; } } return 0; } void InfoType::list() { if (infotype_registry.size()) { con_print << " "; for (Registry::const_iterator it = infotype_registry.begin(); it != infotype_registry.end(); it++) { InfoType *infotype = (*it); con_print << infotype->label() << " "; } con_print << std::endl; } con_print << "^B " << infotype_registry.size() << " info types" << std::endl; } /* ---- class Info ------------------------------------------------- */ unsigned int info_id_counter = 0; // server-side constructor, assigns an id Info::Info(const InfoType *type, const char *label) : Label(label) { info_id_counter++; info_id = info_id_counter; info_type = type; info_registry.push_back(this); info_timestamp = 0; info_level = 1; info_price = 0; info_volume = 0; } // client-side constructor, id is passed as param Info::Info(const unsigned int id) { info_id = id; info_type = 0; info_registry.push_back(this); info_timestamp = 1; info_level = 1; info_price = 0; info_volume = 0; add_text("Requesting server information..."); } Info::~Info() { info_text.clear(); info_modelname.clear(); info_text.clear(); info_timestamp = 0; info_type = 0; } void Info::set_id(const unsigned int id) { info_id = id; } void Info::set_type(const InfoType *type) { info_type = type; } void Info::set_modelname(const std::string & modelname) { info_modelname.assign(modelname); } void Info::set_modelname(const char *modelname) { info_modelname.assign(modelname); } void Info::set_level(const Level level) { info_level = level; } void Info::set_price(const long price) { info_price = price; } void Info::set_volume(const float volume) { info_volume = volume; } void Info::set_timestamp(const unsigned long timestamp) { info_timestamp = timestamp; } void Info::clear_timestamp() { info_timestamp = 0; } void Info::add_line(const std::string & text) { add_line(text.c_str()); } void Info::add_line(const char *text) { std::string str(text); aux::strip_quotes(str); info_text.push_back(str); } void Info::add_text(const char *text) { std::string str(text); aux::strip_quotes(str); if (!info_text.size()) { info_text.push_back(str); } else if (str.size()) { if ((*info_text.rbegin()).size()) { (*info_text.rbegin()) += ' '; (*info_text.rbegin()).append(str); } else { info_text.push_back(str); } } else { info_text.push_back(str); } } void Info::add_text(const std::string & text) { add_text(text.c_str()); } void Info::clear_text() { info_text.clear(); } void Info::serialize_server_update(std::ostream & os) const { os << '"' << name() << "\" \"" << modelname() << "\" " << price() << " " << volume() << " " << info_text.size() << " "; for (Text::const_iterator it = info_text.begin(); it != info_text.end(); it++) { if (it != info_text.begin()) os << ' '; os << '"' << (*it) << '"'; } } void Info::receive_server_update(std::istream &is) { std::string n; char c; // read name n.clear(); while ((is.get(c)) && (c != '"')); while ((is.get(c)) && (c != '"')) n += c; set_name(n); // read model name n.clear(); while ((is.get(c)) && (c != '"')); while ((is.get(c)) && (c != '"')) n += c; set_modelname(n); is >> info_price; is >> info_volume; // read info text size_t s; if (!(is >> s)) s = 0; clear_text(); for (size_t i = 0; (i < s) && is.good(); i++) { n.clear(); while ((is.get(c)) && (c != '"')); while ((is.get(c)) && (c != '"')) n += c; add_line(n); } // set timestamp to 0 info_timestamp = 0; } void Info::print() const { con_print << " ^Ninfo id ^B" << std::setw(4) << std::setfill(' ') << id() << " ^Ntype ^B" << (type() ? type()->label() : "NULL") << " ^Nlabel ^B" << label() << " ^Nname ^B" << name() << " ^Nmodel ^B" << modelname() << "^N" << std::endl; if (info_text.size()) { for (Text::const_iterator it = info_text.begin(); it != info_text.end(); it++) { con_print << " " << (*it) << std::endl; } } } /* ---- static info registry --------------------------------------- */ Info::Registry Info::info_registry; Info *Info::find(const Info *info) { if (!info) return 0; for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { if (info == (*it)) { return *it; } } return 0; } Info *Info::find(unsigned int id) { if (!id) return 0; for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { Info *info = (*it); if (info->id() == id) { return info; } } return 0; } Info *Info::find(const char *label) { if (!label) return 0; for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { Info *info = (*it); if (info->label().compare(label) == 0) { return info; } } return 0; } Info *Info::find(const std::string & label) { if (!label.size()) return 0; for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { Info *info = (*it); if (info->label().compare(label) == 0) { return info; } } return 0; } Info *Info::search(const std::string & searchstr) { if (!searchstr.size()) return 0; std::string strsearchkey(aux::lowercase(searchstr)); if (strsearchkey.size() < 3) { return 0; } for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { Info *info = *(it); std::string labelstr(info->label()); if (labelstr.size() && (labelstr.find(strsearchkey) != std::string::npos)) { return info; } std::string namestr(aux::lowercase(info->name())); if (namestr.size() && (namestr.find(strsearchkey) != std::string::npos)) { return info; } } return 0; } Info *Info::find(const InfoType *type, const char *label) { if (!label) return 0; for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { Info *info = (*it); if ((info->type() == type) && (info->label().compare(label) == 0)) { return info; } } return 0; } Info *Info::find(const InfoType *type, const std::string & label) { if (!label.size()) return 0; for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { Info *info = (*it); if ((info->type() == type) && (info->label().compare(label) == 0)) { return info; } } return 0; } Info *Info::search(const InfoType *type, const std::string & searchstr) { if (!searchstr.size()) return 0; std::string strsearchkey(aux::lowercase(searchstr)); if (strsearchkey.size() < 3) { return 0; } for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { Info *info = *(it); if (info->type() == type) { std::string labelstr(info->label()); if (labelstr.size() && (labelstr.find(strsearchkey) != std::string::npos)) { return info; } std::string namestr(aux::lowercase(info->name())); if (namestr.size() && (namestr.find(strsearchkey) != std::string::npos)) { return info; } } } return 0; } void Info::clear() { for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { Info *info = (*it); delete info; } info_registry.clear(); info_id_counter = 0; InfoType::clear(); } void Info::list_header() { con_print << " " << " id " << "type " << "label " << "name" << std::endl; } void Info::list(const Info *info) { con_print << " " << "^B" << std::setw(4) << info->id() << " " << "^N" << (info->type() ? aux::pad_right(info->type()->label(), 8) : "NULL ") << " " << "^N" << aux::pad_right(info->label(), 12) << " " << "^N" << info->name() << std::endl; } void Info::list() { InfoType::list(); list_header(); for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { Info *info = (*it); list(info); } con_print << "^B " << info_registry.size() << " info " << aux::plural("record", info_registry.size()) << std::endl; } void Info::list(const InfoType *type) { size_t count = 0; list_header(); for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { core::Info *info = (*it); if (info->type() == type) { count++; list(info); } } con_print << "^B " << count << " " << type->label() << " info " << aux::plural("record", count) << std::endl; } }