Advertisement
Guest User

Untitled

a guest
May 1st, 2017
400
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.12 KB | None | 0 0
  1. ////////////////////////////////////////////////////////////////////////
  2. // OpenTibia - an opensource roleplaying game
  3. ////////////////////////////////////////////////////////////////////////
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16. ////////////////////////////////////////////////////////////////////////
  17. #include "otpch.h"
  18. #include <libxml/xmlmemory.h>
  19. #include <libxml/parser.h>
  20.  
  21. #include "status.h"
  22. #include "tools.h"
  23.  
  24. #include "connection.h"
  25. #include "networkmessage.h"
  26. #include "outputmessage.h"
  27.  
  28. #include "configmanager.h"
  29. #include "game.h"
  30.  
  31. extern ConfigManager g_config;
  32. extern Game g_game;
  33.  
  34. #ifdef __ENABLE_SERVER_DIAGNOSTIC__
  35. uint32_t ProtocolStatus::protocolStatusCount = 0;
  36. #endif
  37. IpConnectMap ProtocolStatus::ipConnectMap;
  38.  
  39. void ProtocolStatus::onRecvFirstMessage(NetworkMessage& msg)
  40. {
  41.     IpConnectMap::const_iterator it = ipConnectMap.find(getIP());
  42.     if(it != ipConnectMap.end() && OTSYS_TIME() < it->second + g_config.getNumber(ConfigManager::STATUSQUERY_TIMEOUT))
  43.     {
  44.         getConnection()->close();
  45.         return;
  46.     }
  47.  
  48.     ipConnectMap[getIP()] = OTSYS_TIME();
  49.     uint8_t type = msg.get<char>();
  50.     switch(type)
  51.     {
  52.         case 0xFF:
  53.         {
  54.             if(msg.getString(false, 4) == "info")
  55.             {
  56.                 if(OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false))
  57.                 {
  58.                     TRACK_MESSAGE(output);
  59.                     if(Status* status = Status::getInstance())
  60.                     {
  61.                         bool sendPlayers = false;
  62.                         if(msg.size() > msg.position())
  63.                             sendPlayers = msg.get<char>() == 0x01;
  64.  
  65.                         output->putString(status->getStatusString(sendPlayers), false);
  66.                     }
  67.  
  68.                     setRawMessages(true); // we dont want the size header, nor encryption
  69.                     OutputMessagePool::getInstance()->send(output);
  70.                 }
  71.             }
  72.  
  73.             break;
  74.         }
  75.  
  76.         case 0x01:
  77.         {
  78.             uint32_t requestedInfo = msg.get<uint16_t>(); //Only a Byte is necessary, though we could add new infos here
  79.             if(OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false))
  80.             {
  81.                 TRACK_MESSAGE(output);
  82.                 if(Status* status = Status::getInstance())
  83.                     status->getInfo(requestedInfo, output, msg);
  84.  
  85.                 OutputMessagePool::getInstance()->send(output);
  86.             }
  87.  
  88.             break;
  89.         }
  90.  
  91.         default:
  92.             break;
  93.     }
  94.  
  95.     getConnection()->close();
  96. }
  97.  
  98. void ProtocolStatus::deleteProtocolTask()
  99. {
  100. #ifdef __DEBUG_NET_DETAIL__
  101.     std::clog << "Deleting ProtocolStatus" << std::endl;
  102. #endif
  103.     Protocol::deleteProtocolTask();
  104. }
  105.  
  106. std::string Status::getStatusString(bool sendPlayers) const
  107. {
  108.     char buffer[90];
  109.     xmlDocPtr doc;
  110.     xmlNodePtr p, root;
  111.  
  112.     doc = xmlNewDoc((const xmlChar*)"1.0");
  113.     doc->children = xmlNewDocNode(doc, NULL, (const xmlChar*)"tsqp", NULL);
  114.     root = doc->children;
  115.  
  116.     xmlSetProp(root, (const xmlChar*)"version", (const xmlChar*)"1.0");
  117.  
  118.     p = xmlNewNode(NULL,(const xmlChar*)"serverinfo");
  119.     sprintf(buffer, "%u", (uint32_t)getUptime());
  120.     xmlSetProp(p, (const xmlChar*)"uptime", (const xmlChar*)buffer);
  121.     xmlSetProp(p, (const xmlChar*)"ip", (const xmlChar*)g_config.getString(ConfigManager::IP).c_str());
  122.     xmlSetProp(p, (const xmlChar*)"servername", (const xmlChar*)g_config.getString(ConfigManager::SERVER_NAME).c_str());
  123.     sprintf(buffer, "%d", g_config.getNumber(ConfigManager::LOGIN_PORT));
  124.     xmlSetProp(p, (const xmlChar*)"port", (const xmlChar*)buffer);
  125.     xmlSetProp(p, (const xmlChar*)"location", (const xmlChar*)g_config.getString(ConfigManager::LOCATION).c_str());
  126.     xmlSetProp(p, (const xmlChar*)"url", (const xmlChar*)g_config.getString(ConfigManager::URL).c_str());
  127.     xmlSetProp(p, (const xmlChar*)"server", (const xmlChar*)SOFTWARE_NAME);
  128.     xmlSetProp(p, (const xmlChar*)"version", (const xmlChar*)SOFTWARE_VERSION);
  129.     xmlSetProp(p, (const xmlChar*)"client", (const xmlChar*)SOFTWARE_PROTOCOL);
  130.     xmlAddChild(root, p);
  131.  
  132.     p = xmlNewNode(NULL,(const xmlChar*)"owner");
  133.     xmlSetProp(p, (const xmlChar*)"name", (const xmlChar*)g_config.getString(ConfigManager::OWNER_NAME).c_str());
  134.     xmlSetProp(p, (const xmlChar*)"email", (const xmlChar*)g_config.getString(ConfigManager::OWNER_EMAIL).c_str());
  135.     xmlAddChild(root, p);
  136.  
  137.     p = xmlNewNode(NULL,(const xmlChar*)"players");
  138.     uint32_t real = 0;
  139.     std::map<uint32_t, uint32_t> listIP;
  140.     for(AutoList<Player>::iterator it = Player::autoList.begin(); it != Player::autoList.end(); ++it) {
  141.         if (it->second->getIP() != 0) {
  142.             uint32_t ip = listIP.find(it->second->getIP());
  143.             if (ip != listIP.end()) {
  144.                 listIP[it->second->getIP()]++;
  145.                 if (listIP[it->second->getIP()] < 5) {
  146.                     real++;
  147.                 }
  148.             } else {
  149.                 listIP[it->second->getIP()] = 1;
  150.                 real++;
  151.             }
  152.         }
  153.     }
  154.     sprintf(buffer, "%d", real);
  155.     xmlSetProp(p, (const xmlChar*)"online", (const xmlChar*)buffer);
  156.     sprintf(buffer, "%d", g_config.getNumber(ConfigManager::MAX_PLAYERS));
  157.     xmlSetProp(p, (const xmlChar*)"max", (const xmlChar*)buffer);
  158.     sprintf(buffer, "%d", g_game.getPlayersRecord());
  159.     xmlSetProp(p, (const xmlChar*)"peak", (const xmlChar*)buffer);
  160.     if(sendPlayers)
  161.     {
  162.         std::stringstream ss;
  163.         for(AutoList<Player>::iterator it = Player::autoList.begin(); it != Player::autoList.end(); ++it)
  164.         {
  165.             if(it->second->isRemoved() || it->second->isGhost())
  166.                 continue;
  167.  
  168.             if(!ss.str().empty())
  169.                 ss << ";";
  170.  
  171.             ss << it->second->getName() << "," << it->second->getVocationId() << "," << it->second->getLevel();
  172.         }
  173.  
  174.         xmlNodeSetContent(p, (const xmlChar*)ss.str().c_str());
  175.     }
  176.  
  177.     xmlAddChild(root, p);
  178.  
  179.     p = xmlNewNode(NULL,(const xmlChar*)"monsters");
  180.     sprintf(buffer, "%d", g_game.getMonstersOnline());
  181.     xmlSetProp(p, (const xmlChar*)"total", (const xmlChar*)buffer);
  182.     xmlAddChild(root, p);
  183.  
  184.     p = xmlNewNode(NULL,(const xmlChar*)"npcs");
  185.     sprintf(buffer, "%d", g_game.getNpcsOnline());
  186.     xmlSetProp(p, (const xmlChar*)"total", (const xmlChar*)buffer);
  187.     xmlAddChild(root, p);
  188.  
  189.     p = xmlNewNode(NULL,(const xmlChar*)"map");
  190.     xmlSetProp(p, (const xmlChar*)"name", (const xmlChar*)g_config.getString(ConfigManager::MAP_NAME).c_str());
  191.     xmlSetProp(p, (const xmlChar*)"author", (const xmlChar*)g_config.getString(ConfigManager::MAP_AUTHOR).c_str());
  192.  
  193.     uint32_t mapWidth, mapHeight;
  194.     g_game.getMapDimensions(mapWidth, mapHeight);
  195.     sprintf(buffer, "%u", mapWidth);
  196.     xmlSetProp(p, (const xmlChar*)"width", (const xmlChar*)buffer);
  197.     sprintf(buffer, "%u", mapHeight);
  198.  
  199.     xmlSetProp(p, (const xmlChar*)"height", (const xmlChar*)buffer);
  200.     xmlAddChild(root, p);
  201.  
  202.     xmlNewTextChild(root, NULL, (const xmlChar*)"motd", (const xmlChar*)g_config.getString(ConfigManager::MOTD).c_str());
  203.  
  204.     xmlChar* s = NULL;
  205.     int32_t len = 0;
  206.     xmlDocDumpMemory(doc, (xmlChar**)&s, &len);
  207.  
  208.     std::string xml;
  209.     if(s)
  210.         xml = std::string((char*)s, len);
  211.  
  212.     xmlFree(s);
  213.     xmlFreeDoc(doc);
  214.     return xml;
  215. }
  216.  
  217. void Status::getInfo(uint32_t requestedInfo, OutputMessage_ptr output, NetworkMessage& msg) const
  218. {
  219.     if(requestedInfo & REQUEST_BASIC_SERVER_INFO)
  220.     {
  221.         output->put<char>(0x10);
  222.         output->putString(g_config.getString(ConfigManager::SERVER_NAME).c_str());
  223.         output->putString(g_config.getString(ConfigManager::IP).c_str());
  224.  
  225.         char buffer[10];
  226.         sprintf(buffer, "%d", g_config.getNumber(ConfigManager::LOGIN_PORT));
  227.         output->putString(buffer);
  228.     }
  229.  
  230.     if(requestedInfo & REQUEST_SERVER_OWNER_INFO)
  231.     {
  232.         output->put<char>(0x11);
  233.         output->putString(g_config.getString(ConfigManager::OWNER_NAME).c_str());
  234.         output->putString(g_config.getString(ConfigManager::OWNER_EMAIL).c_str());
  235.     }
  236.  
  237.     if(requestedInfo & REQUEST_MISC_SERVER_INFO)
  238.     {
  239.         output->put<char>(0x12);
  240.         output->putString(g_config.getString(ConfigManager::MOTD).c_str());
  241.         output->putString(g_config.getString(ConfigManager::LOCATION).c_str());
  242.         output->putString(g_config.getString(ConfigManager::URL).c_str());
  243.  
  244.         uint64_t uptime = getUptime();
  245.         output->put<uint32_t>((uint32_t)(uptime >> 32));
  246.         output->put<uint32_t>((uint32_t)(uptime));
  247.     }
  248.  
  249.     if(requestedInfo & REQUEST_PLAYERS_INFO)
  250.     {
  251.         output->put<char>(0x20);
  252.         output->put<uint32_t>(g_game.getPlayersOnline());
  253.         output->put<uint32_t>(g_config.getNumber(ConfigManager::MAX_PLAYERS));
  254.         output->put<uint32_t>(g_game.getPlayersRecord());
  255.     }
  256.  
  257.     if(requestedInfo & REQUEST_SERVER_MAP_INFO)
  258.     {
  259.         output->put<char>(0x30);
  260.         output->putString(g_config.getString(ConfigManager::MAP_NAME).c_str());
  261.         output->putString(g_config.getString(ConfigManager::MAP_AUTHOR).c_str());
  262.  
  263.         uint32_t mapWidth, mapHeight;
  264.         g_game.getMapDimensions(mapWidth, mapHeight);
  265.         output->put<uint16_t>(mapWidth);
  266.         output->put<uint16_t>(mapHeight);
  267.     }
  268.  
  269.     if(requestedInfo & REQUEST_EXT_PLAYERS_INFO)
  270.     {
  271.         output->put<char>(0x21);
  272.         std::list<std::pair<std::string, uint32_t> > players;
  273.         for(AutoList<Player>::iterator it = Player::autoList.begin(); it != Player::autoList.end(); ++it)
  274.         {
  275.             if(!it->second->isRemoved() && !it->second->isGhost())
  276.                 players.push_back(std::make_pair(it->second->getName(), it->second->getLevel()));
  277.         }
  278.  
  279.         output->put<uint32_t>(players.size());
  280.         for(std::list<std::pair<std::string, uint32_t> >::iterator it = players.begin(); it != players.end(); ++it)
  281.         {
  282.             output->putString(it->first);
  283.             output->put<uint32_t>(it->second);
  284.         }
  285.     }
  286.  
  287.     if(requestedInfo & REQUEST_PLAYER_STATUS_INFO)
  288.     {
  289.         output->put<char>(0x22);
  290.         const std::string name = msg.getString();
  291.  
  292.         Player* p = NULL;
  293.         if(g_game.getPlayerByNameWildcard(name, p) == RET_NOERROR && !p->isGhost())
  294.             output->put<char>(0x01);
  295.         else
  296.             output->put<char>(0x00);
  297.     }
  298.  
  299.     if(requestedInfo & REQUEST_SERVER_SOFTWARE_INFO)
  300.     {
  301.         output->put<char>(0x23);
  302.         output->putString(SOFTWARE_NAME);
  303.         output->putString(SOFTWARE_VERSION);
  304.         output->putString(SOFTWARE_PROTOCOL);
  305.     }
  306. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement