diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/Makefile.am | 2 | ||||
-rw-r--r-- | src/core/gameconnection.cc | 12 | ||||
-rw-r--r-- | src/core/gameconnection.h | 2 | ||||
-rw-r--r-- | src/core/gameinterface.h | 2 | ||||
-rw-r--r-- | src/core/gameserver.cc | 9 | ||||
-rw-r--r-- | src/core/gameserver.h | 2 | ||||
-rw-r--r-- | src/core/info.cc | 285 | ||||
-rw-r--r-- | src/core/info.h | 148 | ||||
-rw-r--r-- | src/core/label.h | 78 |
9 files changed, 431 insertions, 109 deletions
diff --git a/src/core/Makefile.am b/src/core/Makefile.am index fce79a6..421dd59 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -14,4 +14,4 @@ noinst_LTLIBRARIES = libcore.la noinst_HEADERS = application.h commandbuffer.h core.h cvar.h entity.h func.h \ gameconnection.h gameinterface.h gameserver.h message.h module.h net.h netclient.h \ netconnection.h netserver.h player.h range.h stats.h timer.h parser.h descriptions.h \ - extension.h loader.h info.h item.h inventory.h + extension.h loader.h info.h item.h inventory.h label.h diff --git a/src/core/gameconnection.cc b/src/core/gameconnection.cc index c0a769c..064974c 100644 --- a/src/core/gameconnection.cc +++ b/src/core/gameconnection.cc @@ -90,15 +90,21 @@ bool GameConnection::interactive() const return true; } -Info *GameConnection::info(const std::string &label) +Info *GameConnection::info(const std::string &type, const std::string &label) { + // find the class + InfoType *infotype = InfoType::find(type); + if (!infotype) + return 0; + // check if we already have the info record - Info *info = Info::find(label); + Info *info = Info::find(infotype, label); if (info) return info; // create a new information record and set the label - info = new Info(label); + info = new Info(0); + info->set_label(label); info->text().push_back("Requesting information..."); // send an information request to the server diff --git a/src/core/gameconnection.h b/src/core/gameconnection.h index 52885f4..9c0b5a9 100644 --- a/src/core/gameconnection.h +++ b/src/core/gameconnection.h @@ -59,7 +59,7 @@ public: void private_message(std::string const &args); /// returns an info record - Info *info(const std::string &label); + virtual Info *info(const std::string &type, const std::string &label); /*----- static ---------------------------------------------------- */ diff --git a/src/core/gameinterface.h b/src/core/gameinterface.h index 44b4230..ef479b1 100644 --- a/src/core/gameinterface.h +++ b/src/core/gameinterface.h @@ -63,7 +63,7 @@ public: virtual unsigned long timestamp() const = 0; /// returns an info record - virtual Info *info(const std::string &label) = 0; + virtual Info *info(const std::string &type, const std::string &label) = 0; /*----- mutators ------------------------------------------------- */ diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index e170a4d..c0d7382 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -237,9 +237,14 @@ float GameServer::time() const return ((float)(server_timestamp) / 1000.0f); } -Info *GameServer::info(const std::string &label) +Info *GameServer::info(const std::string &type, const std::string &label) { - return Info::find(label); + // find the class + InfoType *infotype = InfoType::find(type); + if (!infotype) + return 0; + + return Info::find(infotype, label); } void GameServer::abort() diff --git a/src/core/gameserver.h b/src/core/gameserver.h index 57feac1..2c82870 100644 --- a/src/core/gameserver.h +++ b/src/core/gameserver.h @@ -89,7 +89,7 @@ public: } /// returns an info record - Info *info(const std::string &label); + virtual Info *info(const std::string &type, const std::string &label); /*----- static ---------------------------------------------------- */ diff --git a/src/core/info.cc b/src/core/info.cc index 4e5399a..8f843c4 100644 --- a/src/core/info.cc +++ b/src/core/info.cc @@ -9,78 +9,121 @@ #include "sys/sys.h" #include "core/info.h" +#include <iomanip> + namespace core { -/* ---- class Info ------------------------------------------------- */ +/* ---- class InfoType --------------------------------------------- */ -// default constructor -Info::Info() +// server-side constructor, assigns id +InfoType::InfoType(const char *label) { - static_info_id_counter++; - info_id = static_info_id_counter; - - info_model = 0; - info_timestamp = 0; + infotype_id_counter++; + infotype_id = infotype_id_counter; + if (label) + set_label(label); + + infotype_registry.push_back(this); +} + +// client-side constructor, receives id +InfoType::InfoType(const unsigned int id) +{ + infotype_id = id; + infotype_registry.push_back(this); +} + +InfoType::~InfoType() +{ + infotype_id = 0; +} - add(this); +/* ---- static InfoType registry ----------------------------------- */ + +InfoType::Registry InfoType::infotype_registry; +unsigned int InfoType::infotype_id_counter = 0; + +void InfoType::clear() +{ + for (Registry::iterator it = infotype_registry.begin(); it != infotype_registry.end(); it++) { + InfoType *infotype = (*it); + delete infotype; + } + infotype_registry.clear(); + infotype_id_counter = 0; + +} + +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; +} + +InfoType *InfoType::find(const unsigned int id) +{ + if (!id) + return 0; + + for (Registry::iterator it = infotype_registry.begin(); it != infotype_registry.end(); it++) { + InfoType *infotype = (*it); + if (infotype->id() == id) { + return infotype; + } + } + return 0; } -Info::Info(const std::string & label) +/* ---- class Info ------------------------------------------------- */ + +// server-side constructor, assigns id +Info::Info() { - static_info_id_counter++; - info_id = static_info_id_counter; + info_id_counter++; + info_id = info_id_counter; + info_type = 0; - info_timestamp = 0; info_model = 0; - - info_label.assign(label); - aux::to_lowercase(info_label); - aux::strip_quotes(info_label); - - add(this); + info_timestamp = 0; + info_price = 0; + + info_registry.push_back(this); } +// client-side constructor, receives id Info::Info(const unsigned int id) { info_id = id; + info_type = 0; info_timestamp = 0; info_model = 0; + info_price = 0; - add(this); + info_registry.push_back(this); } Info::~Info() { info_text.clear(); - info_label.clear(); info_modelname.clear(); info_text.clear(); info_timestamp = 0; info_model = 0; } -void Info::set_label(const std::string & label) +void Info::set_type(const InfoType *type) { - info_label.assign(label); - aux::to_label(info_label); -} - -void Info::set_label(const char *label) -{ - info_label.assign(label); - aux::to_label(info_label); -} - -void Info::set_name(const std::string & name) -{ - info_name.assign(name); -} - -void Info::set_name(const char *name) -{ - info_name.assign(name); + info_type = type; } void Info::set_modelname(const std::string & modelname) @@ -98,6 +141,11 @@ void Info::set_model(const model::Model *model) info_model = model; } +void Info::set_price(const long price) +{ + info_price = price; +} + void Info::set_timestamp(const unsigned long timestamp) { info_timestamp = timestamp; @@ -127,7 +175,7 @@ void Info::clear_text() void Info::serialize_server_update(std::ostream & os) const { - os << '"' << label() << "\" \"" << name() << "\" \"" << modelname() << "\" " << info_text.size() << " "; + os << " \"" << label() << "\" \"" << name() << "\" \"" << modelname() << "\" " << info_text.size() << " "; for (Text::const_iterator it = info_text.begin(); it != info_text.end(); it++) { if (it != info_text.begin()) @@ -146,13 +194,13 @@ void Info::receive_server_update(std::istream &is) while ((is.get(c)) && (c != '"')); while ((is.get(c)) && (c != '"')) n += c; - info_label.assign(n); + set_label(n); // read name while ((is.get(c)) && (c != '"')); while ((is.get(c)) && (c != '"')) n += c; - info_name.assign(n); + set_name(n); // read model name n.clear(); @@ -160,11 +208,11 @@ void Info::receive_server_update(std::istream &is) while ((is.get(c)) && (c != '"')) n += c; - info_modelname.assign(n); + set_modelname(n); // read info text - size_t s; - info_text.clear(); + clear_text(); + size_t s; is >> s; for (size_t i = 0; (i < s) && is.good(); i++) { n.clear(); @@ -172,29 +220,25 @@ void Info::receive_server_update(std::istream &is) while ((is.get(c)) && (c != '"')) n += c; - info_text.push_back(n); + add_text(n); } } void Info::print() const { - con_print << "label: ^B" << label() << " ^Nname: ^B" << name() << " ^Nmodel: ^B" << modelname() << "^N" << std::endl; - - for (Text::const_iterator it = info_text.begin(); it != info_text.end(); it++) { - con_print << " " << (*it) << std::endl; + if (info_text.size()) { + for (Text::const_iterator it = info_text.begin(); it != info_text.end(); it++) { + con_print << " " << (*it) << std::endl; + } + } else { + con_print << " label: ^B" << label() << " ^Nname: ^B" << name() << " ^Nmodel: ^B" << modelname() << "^N" << std::endl; } } - /* ---- static info registry --------------------------------------- */ Info::Registry Info::info_registry; -unsigned int Info::static_info_id_counter = 0; - -void Info::add(Info *info) -{ - info_registry.push_back(info); -} +unsigned int Info::info_id_counter = 0; Info *Info::find(const char *label) { @@ -238,6 +282,104 @@ Info *Info::find(const unsigned int id) 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::find(const InfoType *type, const unsigned int id) +{ + if (!id) + return 0; + + for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { + Info *info = (*it); + if ((info->type() == type) && (info->id() == id)) { + 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++) { @@ -245,16 +387,37 @@ void Info::clear() delete info; } info_registry.clear(); - static_info_id_counter = 0; + info_id_counter = 0; + + InfoType::clear(); } void Info::list() { for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { Info *info = (*it); - con_print << info->label() << std::endl; + con_print << " " + << "^B" << aux::pad_right(info->type()->label(), 8) << "^N " + << "^B" << aux::pad_right(info->label(), 12) << "^N " + << info->name() << "^N" << std::endl; + } + con_print << info_registry.size() << " info " << aux::plural("record", info_registry.size()) << std::endl; +} + +void Info::list_class(const InfoType *type) +{ + size_t count = 0; + for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { + core::Info *info = (*it); + if (info->type() == type) { + count++; + + con_print << " " + << "^B" << aux::pad_right(info->label(), 12) << "^N " + << info->name() << "^N" << std::endl; + } } - con_print << info_registry.size() << " registered info " << aux::plural("record", info_registry.size()) << std::endl; + con_print << count << " info " << aux::plural("record", count) << std::endl; } } diff --git a/src/core/info.h b/src/core/info.h index 9f1fab8..13f38f8 100644 --- a/src/core/info.h +++ b/src/core/info.h @@ -12,48 +12,101 @@ #include <vector> #include <deque> +#include "core/label.h" #include "model/model.h" namespace core { /** + * @brief an object class information record + * Describes a class of object + */ +class InfoType : public Label +{ +public: + /** + * @brief create a server side object class information record + */ + InfoType(const char* label); + + /** + * @brief create a client side object class information record + */ + InfoType(const unsigned int id); + + virtual ~InfoType(); + + /* ---- inspectors ------------------------------------------------- */ + + inline const unsigned int id() const { + return infotype_id; + } + +private: + + unsigned int infotype_id; + + + /* ---- static infoclass registry ---------------------------------- */ + +public: + /// clear infotype registry + static void clear(); + + /// search the infotype registry for a label + static InfoType *find(const std::string & label); + + /// search the infotype registry for an id + static InfoType *find(const unsigned int id); + + +private: + /// info registry type definition + typedef std::vector<InfoType*> Registry; + + static Registry infotype_registry; + static unsigned int infotype_id_counter; + +}; // class InfoType + +/** * @brief an information record * An information record holds extended information about a specific entity or item class. * This information isexchanged between server and the client, and can be used to build * HUD widgets/ */ -class Info +class Info : public Label { public: /// type definition for the text description typedef std::deque<std::string> Text; - /// create a new labeled information record + /** + * @brief create a new server-side information record + * This is a server-side constructor and assigns an id + */ Info(); - /// create a new labeled information record - Info(const std::string & label); - + /** + * @brief create a new client-side information record + * This is a client-side constructor + */ Info(const unsigned int id); /// delete the information record - ~Info(); + virtual ~Info(); /* ---- inspectors ------------------------------------------------- */ inline const unsigned int id() const { return info_id; } - - inline const std::string & label() const { - return info_label; - } - inline const std::string & name() const { - return info_name; + inline const InfoType* type() const { + return info_type; } - + inline const std::string & modelname() const { return info_modelname; } @@ -62,6 +115,10 @@ public: return info_model; } + inline const long price() const { + return info_price; + } + inline const unsigned long ×tamp() const { return info_timestamp; } @@ -73,38 +130,38 @@ public: /* ---- mutators --------------------------------------------------- */ - void set_label(const std::string & name); - - void set_label(const char *name); - - void set_name(const std::string & name); - - void set_name(const char *name); - void set_modelname(const std::string & modelname); void set_modelname(const char *modelname); void set_model(const model::Model *model); + void set_price(const long price); + /// set the timestamp void set_timestamp(const unsigned long timestamp); /// add a line of info text void add_text(const std::string & text); + /// add a line of info text + void add_text(const char *text); + /// clear the info text void clear_text(); - /// print info to sys::con_out - void print() const; + /// print info to the system console + virtual void print() const; /// clear the timestamp void clear_timestamp(); - /// add a line of info text - void add_text(const char *text); +protected: + + /// set the info class id + void set_type(const InfoType *type); +public: /* ---- serializers ------------------------------------------------ */ /// serialize a server-to-client update on a stream @@ -114,17 +171,14 @@ public: void receive_server_update(std::istream &is); private: - - unsigned int info_id; + const InfoType* info_type; - std::string info_label; - std::string info_name; + unsigned int info_id; + long info_price; + unsigned long info_timestamp; std::string info_modelname; - + const model::Model* info_model; - - long info_credits; - unsigned long info_timestamp; Text info_text; @@ -133,12 +187,13 @@ private: public: /// info registry type definition typedef std::vector<Info*> Registry; - + /// the info registry static inline Registry & registry() { return info_registry; } - /// search the info registry for a labeled item + + /// search the info registry for a labeled item static Info *find(const char * label); /// search the info registry for a label @@ -147,18 +202,33 @@ public: /// search the info registry for an id static Info *find(const unsigned int id); + /// search the info registry for a record with a matching label or name + static Info *search(const std::string & searchstr); + + /// search the info registry for a labeled item, belonging to a specific class + static Info *find(const InfoType *type, const char * label); + + /// search the info registry for a label, belonging to a specific class + static Info *find(const InfoType *type, const std::string & label); + + /// search the info registry for an id, belonging to a specific class + static Info *find(const InfoType *type, const unsigned int id); + + /// search the info registry for a record with a matching label or name and belonging to a specific class + static Info *search(const InfoType *type, const std::string & searchstr); + /// clear the info registry static void clear(); /// list the info registry static void list(); -private: - /// add a record to the info registry - static void add(Info *info); + /// list a single class in the info registry + static void list_class(const InfoType *type); +private: static Registry info_registry; - static unsigned int static_info_id_counter; + static unsigned int info_id_counter; }; } diff --git a/src/core/label.h b/src/core/label.h new file mode 100644 index 0000000..e772277 --- /dev/null +++ b/src/core/label.h @@ -0,0 +1,78 @@ +/* + core/label.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_CORE_LABEL_H__ +#define __INCLUDED_CORE_LABEL_H__ + +#include <string> + +#include "auxiliary/functions.h" + +namespace core { + +/** + * @brief baseclass for objects with a name and a label + */ +class Label { +public: + inline Label() { + } + + inline ~Label() { + labelstr.clear(); + namestr.clear(); + } + + /* --- inspectors ------------------------------------------------- */ + + inline const std::string & label() const { + return labelstr; + } + + inline const std::string & name() const { + return namestr; + } + + /* --- mutators --------------------------------------------------- */ + + inline void set_label(const std::string & label) + { + labelstr.assign(label); + aux::to_label(labelstr); + } + + inline void set_label(const char *label) + { + if (label) { + labelstr.assign(label); + aux::to_label(labelstr); + } else { + labelstr.clear(); + } + } + + inline void set_name(const std::string & name) + { + namestr.assign(name); + } + + inline void set_name(const char *name) + { + if (name) + namestr.assign(name); + else + namestr.clear(); + } + +private: + std::string labelstr; + std::string namestr; + +}; // class Label + +} // namespace core + +#endif // __INCLUDED_CORE_LABEL_H__ |