Advertisement
Guest User

Untitled

a guest
May 6th, 2017
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.61 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.     sprintf(buffer, "%d", g_game.getPlayersOnline());
  139.     xmlSetProp(p, (const xmlChar*)"online", (const xmlChar*)buffer);
  140.     sprintf(buffer, "%d", g_config.getNumber(ConfigManager::MAX_PLAYERS));
  141.     xmlSetProp(p, (const xmlChar*)"max", (const xmlChar*)buffer);
  142.     sprintf(buffer, "%d", g_game.getPlayersRecord());
  143.     xmlSetProp(p, (const xmlChar*)"peak", (const xmlChar*)buffer);
  144.     if(sendPlayers)
  145.     {
  146.         std::stringstream ss;
  147.         for(AutoList<Player>::iterator it = Player::autoList.begin(); it != Player::autoList.end(); ++it)
  148.         {
  149.             if(it->second->isRemoved() || it->second->isGhost())
  150.                 continue;
  151.  
  152.             if(!ss.str().empty())
  153.                 ss << ";";
  154.  
  155.             ss << it->second->getName() << "," << it->second->getVocationId() << "," << it->second->getLevel();
  156.         }
  157.  
  158.         xmlNodeSetContent(p, (const xmlChar*)ss.str().c_str());
  159.     }
  160.  
  161.     xmlAddChild(root, p);
  162.  
  163.     p = xmlNewNode(NULL,(const xmlChar*)"monsters");
  164.     sprintf(buffer, "%d", g_game.getMonstersOnline());
  165.     xmlSetProp(p, (const xmlChar*)"total", (const xmlChar*)buffer);
  166.     xmlAddChild(root, p);
  167.  
  168.     p = xmlNewNode(NULL,(const xmlChar*)"npcs");
  169.     sprintf(buffer, "%d", g_game.getNpcsOnline());
  170.     xmlSetProp(p, (const xmlChar*)"total", (const xmlChar*)buffer);
  171.     xmlAddChild(root, p);
  172.  
  173.     p = xmlNewNode(NULL,(const xmlChar*)"map");
  174.     xmlSetProp(p, (const xmlChar*)"name", (const xmlChar*)g_config.getString(ConfigManager::MAP_NAME).c_str());
  175.     xmlSetProp(p, (const xmlChar*)"author", (const xmlChar*)g_config.getString(ConfigManager::MAP_AUTHOR).c_str());
  176.  
  177.     uint32_t mapWidth, mapHeight;
  178.     g_game.getMapDimensions(mapWidth, mapHeight);
  179.     sprintf(buffer, "%u", mapWidth);
  180.     xmlSetProp(p, (const xmlChar*)"width", (const xmlChar*)buffer);
  181.     sprintf(buffer, "%u", mapHeight);
  182.  
  183.     xmlSetProp(p, (const xmlChar*)"height", (const xmlChar*)buffer);
  184.     xmlAddChild(root, p);
  185.  
  186.     xmlNewTextChild(root, NULL, (const xmlChar*)"motd", (const xmlChar*)g_config.getString(ConfigManager::MOTD).c_str());
  187.  
  188.     xmlChar* s = NULL;
  189.     int32_t len = 0;
  190.     xmlDocDumpMemory(doc, (xmlChar**)&s, &len);
  191.  
  192.     std::string xml;
  193.     if(s)
  194.         xml = std::string((char*)s, len);
  195.  
  196.     xmlFree(s);
  197.     xmlFreeDoc(doc);
  198.     return xml;
  199. }
  200.  
  201. void Status::getInfo(uint32_t requestedInfo, OutputMessage_ptr output, NetworkMessage& msg) const
  202. {
  203.     if(requestedInfo & REQUEST_BASIC_SERVER_INFO)
  204.     {
  205.         output->put<char>(0x10);
  206.         output->putString(g_config.getString(ConfigManager::SERVER_NAME).c_str());
  207.         output->putString(g_config.getString(ConfigManager::IP).c_str());
  208.  
  209.         char buffer[10];
  210.         sprintf(buffer, "%d", g_config.getNumber(ConfigManager::LOGIN_PORT));
  211.         output->putString(buffer);
  212.     }
  213.  
  214.     if(requestedInfo & REQUEST_SERVER_OWNER_INFO)
  215.     {
  216.         output->put<char>(0x11);
  217.         output->putString(g_config.getString(ConfigManager::OWNER_NAME).c_str());
  218.         output->putString(g_config.getString(ConfigManager::OWNER_EMAIL).c_str());
  219.     }
  220.  
  221.     if(requestedInfo & REQUEST_MISC_SERVER_INFO)
  222.     {
  223.         output->put<char>(0x12);
  224.         output->putString(g_config.getString(ConfigManager::MOTD).c_str());
  225.         output->putString(g_config.getString(ConfigManager::LOCATION).c_str());
  226.         output->putString(g_config.getString(ConfigManager::URL).c_str());
  227.  
  228.         uint64_t uptime = getUptime();
  229.         output->put<uint32_t>((uint32_t)(uptime >> 32));
  230.         output->put<uint32_t>((uint32_t)(uptime));
  231.     }
  232.  
  233.     if(requestedInfo & REQUEST_PLAYERS_INFO)
  234.     {
  235.         output->put<char>(0x20);
  236.         output->put<uint32_t>(g_game.getPlayersOnline());
  237.         output->put<uint32_t>(g_config.getNumber(ConfigManager::MAX_PLAYERS));
  238.         output->put<uint32_t>(g_game.getPlayersRecord());
  239.     }
  240.  
  241.     if(requestedInfo & REQUEST_SERVER_MAP_INFO)
  242.     {
  243.         output->put<char>(0x30);
  244.         output->putString(g_config.getString(ConfigManager::MAP_NAME).c_str());
  245.         output->putString(g_config.getString(ConfigManager::MAP_AUTHOR).c_str());
  246.  
  247.         uint32_t mapWidth, mapHeight;
  248.         g_game.getMapDimensions(mapWidth, mapHeight);
  249.         output->put<uint16_t>(mapWidth);
  250.         output->put<uint16_t>(mapHeight);
  251.     }
  252.  
  253.     if(requestedInfo & REQUEST_EXT_PLAYERS_INFO)
  254.     {
  255.         output->put<char>(0x21);
  256.         std::list<std::pair<std::string, uint32_t> > players;
  257.         for(AutoList<Player>::iterator it = Player::autoList.begin(); it != Player::autoList.end(); ++it)
  258.         {
  259.             if(!it->second->isRemoved() && !it->second->isGhost())
  260.                 players.push_back(std::make_pair(it->second->getName(), it->second->getLevel()));
  261.         }
  262.  
  263.         output->put<uint32_t>(players.size());
  264.         for(std::list<std::pair<std::string, uint32_t> >::iterator it = players.begin(); it != players.end(); ++it)
  265.         {
  266.             output->putString(it->first);
  267.             output->put<uint32_t>(it->second);
  268.         }
  269.     }
  270.  
  271.     if(requestedInfo & REQUEST_PLAYER_STATUS_INFO)
  272.     {
  273.         output->put<char>(0x22);
  274.         const std::string name = msg.getString();
  275.  
  276.         Player* p = NULL;
  277.         if(g_game.getPlayerByNameWildcard(name, p) == RET_NOERROR && !p->isGhost())
  278.             output->put<char>(0x01);
  279.         else
  280.             output->put<char>(0x00);
  281.     }
  282.  
  283.     if(requestedInfo & REQUEST_SERVER_SOFTWARE_INFO)
  284.     {
  285.         output->put<char>(0x23);
  286.         output->putString(SOFTWARE_NAME);
  287.         output->putString(SOFTWARE_VERSION);
  288.         output->putString(SOFTWARE_PROTOCOL);
  289.     }
  290. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement