From 4293e8854a30443e4d5818fc55df404976dbfd9b Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sat, 14 Nov 2009 14:14:21 +0000 Subject: update the info system, fixes network info exchange --- src/core/commandbuffer.cc | 58 +++++++++++++++++++++++++-- src/core/gameconnection.cc | 19 +++++---- src/core/info.cc | 97 +++++----------------------------------------- src/core/info.h | 64 ++++++------------------------ src/core/inventory.cc | 4 +- src/core/inventory.h | 2 +- src/core/item.cc | 8 ++-- src/core/item.h | 15 ++----- src/core/netconnection.cc | 38 +++++++++++------- src/core/netserver.cc | 43 ++++++++++++-------- 10 files changed, 149 insertions(+), 199 deletions(-) (limited to 'src/core') diff --git a/src/core/commandbuffer.cc b/src/core/commandbuffer.cc index fc98e21..00a3486 100644 --- a/src/core/commandbuffer.cc +++ b/src/core/commandbuffer.cc @@ -44,11 +44,61 @@ void func_print_file(std::string const &args) void func_list_info(std::string const &args) { - Info *info = Info::find(args); - if (info) - info->print(); - else + std::string typestr; + std::string labelstr; + + std::istringstream argstream(args); + if (!(argstream >> typestr)) { + // no argument, list all info records Info::list(); + return; + } + + Info *info = 0; + InfoType *infotype = InfoType::find(typestr); + + if(!(argstream >> labelstr)) { + // a single argument + if (infotype) { + // list all the records of a single type + Info::list(infotype); + return; + } + + info = Info::find(typestr); + if (info) { + // list a single record + info->print(); + return; + } + + info = Info::search(typestr); + if (info) { + // list a single record + info->print(); + return; + } + + con_print << "Unkown info record '" << typestr << "'" << std::endl; + + } else { + // two arguments + info = Info::find(infotype, labelstr); + if (info) { + // list a single record + info->print(); + return; + } + + info = Info::search(infotype, labelstr); + if (info) { + // list a single record + info->print(); + return; + } + + con_print << "Unkown info record '" << typestr << "' for type '" << typestr << "'" << std::endl; + } } void func_list_func(std::string const &args) diff --git a/src/core/gameconnection.cc b/src/core/gameconnection.cc index 064974c..8910bca 100644 --- a/src/core/gameconnection.cc +++ b/src/core/gameconnection.cc @@ -92,18 +92,21 @@ bool GameConnection::interactive() const Info *GameConnection::info(const std::string &type, const std::string &label) { - // find the class + // find the info record type InfoType *infotype = InfoType::find(type); - if (!infotype) - return 0; + if (!infotype) { + // create a new info record type and set the label + infotype = new InfoType(type.c_str()); + } - // check if we already have the info record + // find the info record Info *info = Info::find(infotype, label); - if (info) + if (info) { return info; - - // create a new information record and set the label - info = new Info(0); + } + + // create a new info record and set the label + info = new Info(infotype); info->set_label(label); info->text().push_back("Requesting information..."); diff --git a/src/core/info.cc b/src/core/info.cc index 8f843c4..ca23d79 100644 --- a/src/core/info.cc +++ b/src/core/info.cc @@ -16,33 +16,21 @@ namespace core /* ---- class InfoType --------------------------------------------- */ -// server-side constructor, assigns id InfoType::InfoType(const char *label) { - 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; } /* ---- static InfoType registry ----------------------------------- */ InfoType::Registry InfoType::infotype_registry; -unsigned int InfoType::infotype_id_counter = 0; void InfoType::clear() { @@ -51,8 +39,6 @@ void InfoType::clear() delete infotype; } infotype_registry.clear(); - infotype_id_counter = 0; - } InfoType *InfoType::find(const std::string & label) @@ -69,28 +55,12 @@ InfoType *InfoType::find(const std::string & label) 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; -} - /* ---- class Info ------------------------------------------------- */ // server-side constructor, assigns id -Info::Info() +Info::Info(const InfoType *type) { - info_id_counter++; - info_id = info_id_counter; - info_type = 0; + info_type = type; info_model = 0; info_timestamp = 0; @@ -99,18 +69,6 @@ Info::Info() 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; - - info_registry.push_back(this); -} Info::~Info() { @@ -119,6 +77,7 @@ Info::~Info() info_text.clear(); info_timestamp = 0; info_model = 0; + info_type = 0; } void Info::set_type(const InfoType *type) @@ -175,7 +134,7 @@ void Info::clear_text() void Info::serialize_server_update(std::ostream & os) const { - os << " \"" << label() << "\" \"" << name() << "\" \"" << modelname() << "\" " << info_text.size() << " "; + os << '"' << name() << "\" \"" << modelname() << "\" " << info_text.size() << " "; for (Text::const_iterator it = info_text.begin(); it != info_text.end(); it++) { if (it != info_text.begin()) @@ -190,13 +149,8 @@ void Info::receive_server_update(std::istream &is) std::string n; char c; - // read label - while ((is.get(c)) && (c != '"')); - while ((is.get(c)) && (c != '"')) - n += c; - set_label(n); - // read name + n.clear(); while ((is.get(c)) && (c != '"')); while ((is.get(c)) && (c != '"')) n += c; @@ -207,7 +161,6 @@ void Info::receive_server_update(std::istream &is) while ((is.get(c)) && (c != '"')); while ((is.get(c)) && (c != '"')) n += c; - set_modelname(n); // read info text @@ -226,19 +179,19 @@ void Info::receive_server_update(std::istream &is) void Info::print() const { + con_print << " type: ^B" << type()->label() << " ^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; } } else { - con_print << " label: ^B" << label() << " ^Nname: ^B" << name() << " ^Nmodel: ^B" << modelname() << "^N" << std::endl; + con_print << " type: ^B" << type()->label() << " ^Nlabel: ^B" << label() << " ^Nname: ^B" << name() << " ^Nmodel: ^B" << modelname() << "^N" << std::endl; } } /* ---- static info registry --------------------------------------- */ Info::Registry Info::info_registry; -unsigned int Info::info_id_counter = 0; Info *Info::find(const char *label) { @@ -268,20 +221,6 @@ Info *Info::find(const std::string & label) return 0; } -Info *Info::find(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->id() == id) { - return info; - } - } - return 0; -} - Info *Info::search(const std::string & searchstr) { if (!searchstr.size()) @@ -337,20 +276,6 @@ Info *Info::find(const InfoType *type, const std::string & label) 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()) @@ -387,7 +312,6 @@ void Info::clear() delete info; } info_registry.clear(); - info_id_counter = 0; InfoType::clear(); } @@ -404,20 +328,19 @@ void Info::list() con_print << info_registry.size() << " info " << aux::plural("record", info_registry.size()) << std::endl; } -void Info::list_class(const InfoType *type) +void Info::list(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++; - + count++; con_print << " " << "^B" << aux::pad_right(info->label(), 12) << "^N " << info->name() << "^N" << std::endl; } } - con_print << count << " info " << aux::plural("record", count) << std::endl; + con_print << count << " " << type->label() << " info " << aux::plural("record", count) << std::endl; } } diff --git a/src/core/info.h b/src/core/info.h index 13f38f8..0296ec9 100644 --- a/src/core/info.h +++ b/src/core/info.h @@ -19,62 +19,40 @@ namespace core { /** - * @brief an object class information record - * Describes a class of object + * @brief an information record type + * The InfoType groups information records of the same type */ class InfoType : public Label { public: /** - * @brief create a server side object class information record + * @brief create a new information record type + * The constructor automaticly adds the instance to the registry */ 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; - + virtual ~InfoType(); /* ---- 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 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/ + * This information is exchanged between server and the client, and can be used to build + * HUD widgets. */ class Info : public Label { @@ -83,26 +61,16 @@ public: typedef std::deque Text; /** - * @brief create a new server-side information record - * This is a server-side constructor and assigns an id + * @brief create a new information record + * The constructor automaticly adds the instance to the registry */ - Info(); + Info(const InfoType *type = 0); - /** - * @brief create a new client-side information record - * This is a client-side constructor - */ - Info(const unsigned int id); - /// delete the information record virtual ~Info(); /* ---- inspectors ------------------------------------------------- */ - inline const unsigned int id() const { - return info_id; - } - inline const InfoType* type() const { return info_type; } @@ -173,7 +141,6 @@ public: private: const InfoType* info_type; - unsigned int info_id; long info_price; unsigned long info_timestamp; std::string info_modelname; @@ -199,9 +166,6 @@ public: /// search the info registry for a label static Info *find(const std::string & label); - /// 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); @@ -211,9 +175,6 @@ public: /// 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); @@ -224,11 +185,10 @@ public: static void list(); /// list a single class in the info registry - static void list_class(const InfoType *type); + static void list(const InfoType *type); private: static Registry info_registry; - static unsigned int info_id_counter; }; } diff --git a/src/core/inventory.cc b/src/core/inventory.cc index a58664c..e1a74dc 100644 --- a/src/core/inventory.cc +++ b/src/core/inventory.cc @@ -43,12 +43,12 @@ void Inventory::remove(Item *item) } } -Item *Inventory::find(unsigned int const class_id, unsigned int const info_id) +Item *Inventory::find(const Info *info) { // sarch the inventory for a specified item type for (Items::iterator it = inventory_items.begin(); it != inventory_items.end(); it++) { Item *item = (*it); - if ((item->class_id() == class_id) && (item->info_id() == info_id )) { + if (item->info() == info) { return item; } } diff --git a/src/core/inventory.h b/src/core/inventory.h index 0a1db92..a451dc7 100644 --- a/src/core/inventory.h +++ b/src/core/inventory.h @@ -53,7 +53,7 @@ public: /** * @brief search the inventory for a specific item type */ - Item *find(unsigned int const class_id, unsigned int const info_id); + Item *find(const Info *info); private: Items inventory_items; diff --git a/src/core/item.cc b/src/core/item.cc index a029674..a6cc89f 100644 --- a/src/core/item.cc +++ b/src/core/item.cc @@ -12,17 +12,15 @@ namespace core /* ---- class Item ------------------------------------------------- */ -Item::Item(const unsigned int class_id, const unsigned int info_id) +Item::Item(const Info *info) { - item_class_id = class_id; - item_info_id = info_id; - + item_info = info; item_amount = 0; - item_info = Info::find(info_id); } Item::~Item() { + item_info = 0; item_amount = 0; } diff --git a/src/core/item.h b/src/core/item.h index f88da57..21eae87 100644 --- a/src/core/item.h +++ b/src/core/item.h @@ -19,16 +19,12 @@ namespace core class Item { public: - Item(const unsigned int class_id, const unsigned int info_id); + Item(const Info *info); ~Item(); /* ---- inspectors --------------------------------------------- */ - inline unsigned int class_id() const { return item_class_id; } - - inline unsigned int info_id() const { return item_info_id; } - /** * @brief associated amount */ @@ -37,7 +33,7 @@ public: /** * @brief information record */ - inline Info *info(); + inline const Info *info() const { return item_info; } /* ---- mutators ----------------------------------------------- */ @@ -47,11 +43,8 @@ public: void set_amount(const int amount); private: - unsigned int item_class_id; - unsigned int item_info_id; - int item_amount; - - Info *item_info; + const Info *item_info; + int item_amount; }; } // namespace core diff --git a/src/core/netconnection.cc b/src/core/netconnection.cc index 39a25a3..2975bc5 100644 --- a/src/core/netconnection.cc +++ b/src/core/netconnection.cc @@ -403,6 +403,7 @@ void NetConnection::send_private_message(std::string const &text) } // send a ping reply +// ping timestamp void NetConnection::send_ping_reply(unsigned long timestamp) { std::ostringstream msg; @@ -411,10 +412,11 @@ void NetConnection::send_ping_reply(unsigned long timestamp) } // send an info record request +// inf type.label info.label void NetConnection::send_info_request(Info *info) { std::ostringstream msg; - msg << "inf " << '"' << info->label() << '"' << '\n'; + msg << "inf " << ' ' << info->type()->label() << ' ' << info->label() << '\n'; this->send_raw(msg.str()); info->set_timestamp(application()->timestamp()); @@ -690,20 +692,30 @@ void NetConnection::parse_incoming_message(const std::string & message) } else if (command == "inf") { // incoming info record - unsigned int id; - if (msgstream >> id) { - - Info *info = Info::find(id); - if (!info) { - info = new Info(id); - } + std::string typelabelstr; + std::string infolabelstr; - info->receive_server_update(msgstream); - info->clear_timestamp(); - - } else { - con_warn << "Received empty information record!" << std::endl; + if (!(msgstream >> typelabelstr)) { + con_warn << "Received invalid info record message!" << std::endl; + return; } + InfoType *infotype = InfoType::find(typelabelstr); + if (!infotype) { + infotype = new InfoType(typelabelstr.c_str()); + } + + if (!(msgstream >> infolabelstr)) { + con_warn << "Received invalid info record message for type '" << typelabelstr << "'!" << std::endl; + return; + } + Info *info = Info::find(infotype, infolabelstr); + if (!info) { + info = new Info(infotype); + info->set_label(infolabelstr); + } + + info->receive_server_update(msgstream); + info->clear_timestamp(); } else if (command == "sup") { diff --git a/src/core/netserver.cc b/src/core/netserver.cc index c4eef11..32b2d69 100644 --- a/src/core/netserver.cc +++ b/src/core/netserver.cc @@ -561,8 +561,11 @@ void NetServer::send_player_disconnect_info(NetClient *client, Player *player) // send a "inf" info record void NetServer::send_info_update(NetClient *client, Info *info) { + if (!info || !info->type()) + return; + std::ostringstream msg; - msg << "inf " << info->id() << ' '; + msg << "inf " << info->type()->label() << ' ' << info->label() << ' '; info->serialize_server_update(msg); msg << '\n'; client->send_raw(msg.str()); @@ -672,19 +675,27 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me } if (command == "inf") { - std::string n; - char c; - - while ((msgstream.get(c)) && (c != '"')); - while ((msgstream.get(c)) && (c != '"')) - n += c; - - if (n.size()) { - Info *info = Info::find(n); - if (info) { - send_info_update(client, info); - client->transmit(); - } + std::string typelabelstr; + std::string infolabelstr; + + if (!(msgstream >> typelabelstr)) { + con_warn << "^B" << client->player()->name() << "^W invalid info record request" << std::endl; + return; + } + + InfoType *infotype = InfoType::find(typelabelstr); + if (!infotype) + return; + + if (!(msgstream >> infolabelstr)) { + con_warn << "^B" << client->player()->name() << "^W invalid info record request" << std::endl; + return; + } + + Info *info = Info::find(infotype, infolabelstr); + if (info) { + send_info_update(client, info); + client->transmit(); } } @@ -709,7 +720,7 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me } else { send_message(client, "info", "rcon access denied"); - con_print << "^B" << client->player()->name() << "^W rcon access denied" << std::endl; + con_warn << "^B" << client->player()->name() << "^W rcon access denied" << std::endl; } } return; @@ -734,7 +745,7 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me EntityControlable *entitycontrolable = (EntityControlable *)entity; if (entitycontrolable->owner() != client->player()) { - con_warn << client->host() << ":" << client->port() << " update for not-owned entity " << id << "\n"; + con_warn << client->host() << ":" << client->port() << " update for non-owned entity " << id << "\n"; return; } -- cgit v1.2.3