Advertisement
Guest User

Untitled

a guest
Mar 28th, 2019
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.40 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 <iomanip>
  19.  
  20. #include "protocollogin.h"
  21. #include "tools.h"
  22. #include "const.h"
  23.  
  24. #include "iologindata.h"
  25. #include "ioban.h"
  26.  
  27. #include "outputmessage.h"
  28. #include "connection.h"
  29. #ifdef __LOGIN_SERVER__
  30. #include "gameservers.h"
  31. #endif
  32.  
  33. #include "configmanager.h"
  34. #include "game.h"
  35. #include "resources.h"
  36.  
  37. #if defined(WINDOWS) && !defined(_CONSOLE)
  38. #include "gui.h"
  39. #endif
  40.  
  41. extern ConfigManager g_config;
  42. extern Game g_game;
  43.  
  44. extern std::list<std::pair<uint32_t, uint32_t> > serverIps;
  45.  
  46. #ifdef __ENABLE_SERVER_DIAGNOSTIC__
  47. uint32_t ProtocolLogin::protocolLoginCount = 0;
  48.  
  49. #endif
  50. #ifdef __DEBUG_NET_DETAIL__
  51. void ProtocolLogin::deleteProtocolTask()
  52. {
  53. std::clog << "Deleting ProtocolLogin" << std::endl;
  54. Protocol::deleteProtocolTask();
  55. }
  56.  
  57. #endif
  58. void ProtocolLogin::disconnectClient(uint8_t error, const char* message)
  59. {
  60. OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
  61. if(output)
  62. {
  63. TRACK_MESSAGE(output);
  64. output->put<char>(error);
  65. output->putString(message);
  66. OutputMessagePool::getInstance()->send(output);
  67. }
  68.  
  69. getConnection()->close();
  70. }
  71.  
  72. void ProtocolLogin::onRecvFirstMessage(NetworkMessage& msg)
  73. {
  74. if(
  75. #if defined(WINDOWS) && !defined(_CONSOLE)
  76. !GUI::getInstance()->m_connections ||
  77. #endif
  78. g_game.getGameState() == GAMESTATE_SHUTDOWN)
  79. {
  80. getConnection()->close();
  81. return;
  82. }
  83.  
  84. uint32_t clientIp = getConnection()->getIP();
  85. msg.skip(2); // client platform
  86. uint16_t version = msg.get<uint16_t>();
  87.  
  88. #ifdef CLIENT_VERSION_DATA
  89. uint32_t datSignature = msg.get<uint32_t>();
  90. uint32_t sprSignature = msg.get<uint32_t>();
  91.  
  92. uint32_t picSignature = msg.get<uint32_t>();
  93. #else
  94. msg.skip(12);
  95. #endif
  96. if(!RSA_decrypt(msg))
  97. {
  98. getConnection()->close();
  99. return;
  100. }
  101.  
  102. uint32_t key[4] = {msg.get<uint32_t>(), msg.get<uint32_t>(), msg.get<uint32_t>(), msg.get<uint32_t>()};
  103. enableXTEAEncryption();
  104. setXTEAKey(key);
  105.  
  106. std::string name = msg.getString(), password = msg.getString();
  107. if(name.empty())
  108. {
  109. name = "10";
  110. }
  111.  
  112. if(!g_config.getBool(ConfigManager::MANUAL_ADVANCED_CONFIG))
  113. {
  114. if(version < g_config.getNumber(ConfigManager::VERSION_MIN) || version > g_config.getNumber(ConfigManager::VERSION_MAX))
  115. {
  116. disconnectClient(0x14, g_config.getString(ConfigManager::VERSION_MSG).c_str());
  117. return;
  118. }
  119. }
  120. else
  121. {
  122. if(version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX)
  123. {
  124. disconnectClient(0x14, "Only clients with protocol " CLIENT_VERSION_STRING " allowed!");
  125. return;
  126. }
  127. }
  128.  
  129. #ifdef CLIENT_VERSION_DATA
  130. if(sprSignature != CLIENT_VERSION_SPR)
  131. {
  132. disconnectClient(0x0A, CLIENT_VERSION_DATA);
  133. return;
  134. }
  135.  
  136. if(datSignature != CLIENT_VERSION_DAT)
  137. {
  138. disconnectClient(0x0A, CLIENT_VERSION_DATA);
  139. return;
  140. }
  141.  
  142. if(picSignature != CLIENT_VERSION_PIC)
  143. {
  144. disconnectClient(0x0A, CLIENT_VERSION_DATA);
  145. return;
  146. }
  147. #endif
  148.  
  149. if(g_game.getGameState() < GAMESTATE_NORMAL)
  150. {
  151. disconnectClient(0x0A, "Server is just starting up, please wait.");
  152. return;
  153. }
  154.  
  155. if(g_game.getGameState() == GAMESTATE_MAINTAIN)
  156. {
  157. disconnectClient(0x0A, "Server is under maintenance, please re-connect in a while.");
  158. return;
  159. }
  160.  
  161. if(ConnectionManager::getInstance()->isDisabled(clientIp, protocolId))
  162. {
  163. disconnectClient(0x0A, "Too many connections attempts from your IP address, please try again later.");
  164. return;
  165. }
  166.  
  167. if(IOBan::getInstance()->isIpBanished(clientIp))
  168. {
  169. disconnectClient(0x0A, "Your IP is banished!");
  170. return;
  171. }
  172.  
  173. Account account;
  174. if(!IOLoginData::getInstance()->loadAccount(account, name) || (account.name != "10" && !encryptTest(account.salt + password, account.password)))
  175. {
  176. ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, false);
  177. disconnectClient(0x0A, "Invalid account name or password.");
  178. return;
  179. }
  180.  
  181. Ban ban;
  182. ban.value = account.number;
  183.  
  184. ban.type = BAN_ACCOUNT;
  185. if(IOBan::getInstance()->getData(ban) && !IOLoginData::getInstance()->hasFlag(account.number, PlayerFlag_CannotBeBanned))
  186. {
  187. bool deletion = ban.expires < 0;
  188. std::string name_ = "Automatic ";
  189. if(!ban.adminId)
  190. name_ += (deletion ? "deletion" : "banishment");
  191. else
  192. IOLoginData::getInstance()->getNameByGuid(ban.adminId, name_, true);
  193.  
  194. std::stringstream ss;
  195. ss << "Your account has been " << (deletion ? "deleted" : "banished") << " at:\n" << formatDateEx(ban.added, "%d %b %Y").c_str()
  196. << " by: " << name_.c_str() << ".\nThe comment given was:\n" << ban.comment.c_str() << ".\nYour " << (deletion ?
  197. "account won't be undeleted" : "banishment will be lifted at:\n") << (deletion ? "" : formatDateEx(ban.expires).c_str()) << ".";
  198.  
  199. disconnectClient(0x0A, ss.str().c_str());
  200. return;
  201. }
  202.  
  203. // remove premium days
  204. #ifndef __LOGIN_SERVER__
  205. IOLoginData::getInstance()->removePremium(account);
  206. if(account.name != "10" && !g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && !account.charList.size())
  207. {
  208. disconnectClient(0x0A, std::string("This account does not contain any character yet.\nCreate a new character on the "
  209. + g_config.getString(ConfigManager::SERVER_NAME) + " website at " + g_config.getString(ConfigManager::URL) + ".").c_str());
  210. return;
  211. }
  212. #else
  213. Characters charList;
  214. for(Characters::iterator it = account.charList.begin(); it != account.charList.end(); ++it)
  215. {
  216. if(version >= it->second.server->getVersionMin() && version <= it->second.server->getVersionMax())
  217. charList[it->first] = it->second;
  218. }
  219.  
  220. IOLoginData::getInstance()->removePremium(account);
  221. if(account.name != "10" && !g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && !charList.size())
  222. {
  223. disconnectClient(0x0A, std::string("This account does not contain any character on this client yet.\nCreate a new character on the "
  224. + g_config.getString(ConfigManager::SERVER_NAME) + " website at " + g_config.getString(ConfigManager::URL) + ".").c_str());
  225. return;
  226. }
  227. #endif
  228.  
  229. ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, true);
  230. if(OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false))
  231. {
  232. TRACK_MESSAGE(output);
  233. output->put<char>(0x14);
  234. uint32_t serverIp = serverIps.front().first;
  235. for(std::list<std::pair<uint32_t, uint32_t> >::iterator it = serverIps.begin(); it != serverIps.end(); ++it)
  236. {
  237. if((it->first & it->second) != (clientIp & it->second))
  238. continue;
  239.  
  240. serverIp = it->first;
  241. break;
  242. }
  243.  
  244. char motd[1300];
  245. sprintf(motd, "%d\n%s", g_game.getMotdId(), g_config.getString(ConfigManager::MOTD).c_str());
  246. output->putString(motd);
  247.  
  248. //Add char list
  249. output->put<char>(0x64);
  250. if(account.name == "10" && account.name != "0")
  251. {
  252. PlayerVector players;
  253. for(AutoList<Player>::iterator it = Player::autoList.begin(); it != Player::autoList.end(); ++it)
  254. {
  255. if(!it->second->isRemoved() && it->second->client->isBroadcasting())
  256. players.push_back(it->second);
  257. }
  258.  
  259. std::sort(players.begin(), players.end(), Player::sort);
  260. output->put<char>(players.size());
  261. for(PlayerVector::iterator it = players.begin(); it != players.end(); ++it)
  262. {
  263. std::stringstream s;
  264. s << (*it)->getLevel();
  265. if(!(*it)->client->check(password))
  266. s << "*";
  267.  
  268. output->putString((*it)->getName());
  269. output->putString(s.str());
  270. output->put<uint32_t>(serverIp);
  271.  
  272. IntegerVec games = vectorAtoi(explodeString(g_config.getString(ConfigManager::GAME_PORT), ","));
  273. output->put<uint16_t>(games[random_range(0, games.size() - 1)]);
  274. }
  275. }
  276. else
  277. {
  278. if(g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && account.number != 1)
  279. {
  280. output->put<char>(account.charList.size() + 1);
  281. output->putString("Account Manager");
  282.  
  283. output->putString(g_config.getString(ConfigManager::SERVER_NAME));
  284. output->put<uint32_t>(serverIp);
  285.  
  286. IntegerVec games = vectorAtoi(explodeString(g_config.getString(ConfigManager::GAME_PORT), ","));
  287. output->put<uint16_t>(games[random_range(0, games.size() - 1)]);
  288. }
  289. else
  290. output->put<char>((uint8_t)account.charList.size());
  291.  
  292. #ifndef __LOGIN_SERVER__
  293. for(Characters::iterator it = account.charList.begin(); it != account.charList.end(); ++it)
  294. {
  295. output->putString((*it));
  296. if(g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST))
  297. {
  298. if(g_game.getPlayerByName((*it)))
  299. output->putString("Online");
  300. else
  301. output->putString("Offline");
  302. }
  303. else
  304. output->putString(g_config.getString(ConfigManager::SERVER_NAME));
  305.  
  306. output->put<uint32_t>(serverIp);
  307. IntegerVec games = vectorAtoi(explodeString(g_config.getString(ConfigManager::GAME_PORT), ","));
  308. output->put<uint16_t>(games[random_range(0, games.size() - 1)]);
  309. }
  310. #else
  311. for(Characters::iterator it = charList.begin(); it != charList.end(); ++it)
  312. {
  313. output->putString(it->second.name);
  314. if(!g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST) || it->second.status < 0)
  315. output->putString(it->second.server->getName());
  316. else if(it->second.status)
  317. output->putString("Online");
  318. else
  319. output->putString("Offline");
  320.  
  321. output->put<uint32_t>(it->second.server->getAddress());
  322. IntegerVec games = it->second.server->getPorts();
  323. output->put<uint16_t>(games[random_range(0, games.size() - 1)]);
  324. }
  325. #endif
  326. }
  327.  
  328. //Add premium days
  329. if(g_config.getBool(ConfigManager::FREE_PREMIUM))
  330. output->put<uint16_t>(GRATIS_PREMIUM);
  331. else
  332. output->put<uint16_t>(account.premiumDays);
  333.  
  334. OutputMessagePool::getInstance()->send(output);
  335. }
  336.  
  337. getConnection()->close();
  338. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement