Guest User

Untitled

a guest
Feb 23rd, 2015
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.35 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.  
  36. extern ConfigManager g_config;
  37. extern Game g_game;
  38.  
  39. extern std::list<std::pair<uint32_t, uint32_t> > serverIps;
  40.  
  41. #ifdef __ENABLE_SERVER_DIAGNOSTIC__
  42. uint32_t ProtocolLogin::protocolLoginCount = 0;
  43.  
  44. #endif
  45. #ifdef __DEBUG_NET_DETAIL__
  46. void ProtocolLogin::deleteProtocolTask()
  47. {
  48. std::clog << "Deleting ProtocolLogin" << std::endl;
  49. Protocol::deleteProtocolTask();
  50. }
  51.  
  52. #endif
  53. void ProtocolLogin::disconnectClient(uint8_t error, const char* message)
  54. {
  55. OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
  56. if(output)
  57. {
  58. TRACK_MESSAGE(output);
  59. output->put<char>(error);
  60. output->putString(message);
  61. OutputMessagePool::getInstance()->send(output);
  62. }
  63.  
  64. getConnection()->close();
  65. }
  66.  
  67. void ProtocolLogin::onRecvFirstMessage(NetworkMessage& msg)
  68. {
  69. if(g_game.getGameState() == GAMESTATE_SHUTDOWN)
  70. {
  71. getConnection()->close();
  72. return;
  73. }
  74.  
  75. uint32_t clientIp = getConnection()->getIP();
  76. msg.skip(2); // client platform
  77. uint16_t version = msg.get<uint16_t>();
  78.  
  79. if(version >= 971)
  80. msg.skip(17);
  81. else
  82. msg.skip(12);
  83.  
  84. #ifdef CLIENT_VERSION_DATA
  85. uint32_t datSignature = msg.get<uint32_t>();
  86. uint32_t sprSignature = msg.get<uint32_t>();
  87.  
  88. uint32_t picSignature = msg.get<uint32_t>();
  89. #endif
  90. if(!RSA_decrypt(msg))
  91. {
  92. getConnection()->close();
  93. return;
  94. }
  95.  
  96. uint32_t key[4] = {msg.get<uint32_t>(), msg.get<uint32_t>(), msg.get<uint32_t>(), msg.get<uint32_t>()};
  97. enableXTEAEncryption();
  98. setXTEAKey(key);
  99.  
  100. std::string name = msg.getString(), password = msg.getString();
  101. if(name.empty())
  102. {
  103. if(!g_config.getBool(ConfigManager::ACCOUNT_MANAGER))
  104. {
  105. disconnectClient(0x0A, "Invalid account name.");
  106. return;
  107. }
  108.  
  109. name = "1";
  110. password = "1";
  111. }
  112.  
  113. if(version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX)
  114. {
  115. disconnectClient(0x0A, "Only clients with protocol " CLIENT_VERSION_STRING " allowed!");
  116. return;
  117. }
  118. #ifdef CLIENT_VERSION_DATA
  119.  
  120. if(sprSignature != CLIENT_VERSION_SPR)
  121. {
  122. disconnectClient(0x0A, CLIENT_VERSION_DATA);
  123. return;
  124. }
  125.  
  126. if(datSignature != CLIENT_VERSION_DAT)
  127. {
  128. disconnectClient(0x0A, CLIENT_VERSION_DATA);
  129. return;
  130. }
  131.  
  132. if(picSignature != CLIENT_VERSION_PIC)
  133. {
  134. disconnectClient(0x0A, CLIENT_VERSION_DATA);
  135. return;
  136. }
  137. #endif
  138.  
  139. if(g_game.getGameState() < GAMESTATE_NORMAL)
  140. {
  141. disconnectClient(0x0A, "Server is just starting up, please wait.");
  142. return;
  143. }
  144.  
  145. if(g_game.getGameState() == GAMESTATE_MAINTAIN)
  146. {
  147. disconnectClient(0x0A, "Server is under maintenance, please re-connect in a while.");
  148. return;
  149. }
  150.  
  151. if(ConnectionManager::getInstance()->isDisabled(clientIp, protocolId))
  152. {
  153. disconnectClient(0x0A, "Too many connections attempts from your IP address, please try again later.");
  154. return;
  155. }
  156.  
  157. if(IOBan::getInstance()->isIpBanished(clientIp))
  158. {
  159. disconnectClient(0x0A, "Your IP is banished!");
  160. return;
  161. }
  162.  
  163. Account account;
  164. if(!IOLoginData::getInstance()->loadAccount(account, name) || !encryptTest(account.salt + password, account.password))
  165. {
  166. ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, false);
  167. disconnectClient(0x0A, "Invalid account name or password.");
  168. return;
  169. }
  170.  
  171. Ban ban;
  172. ban.value = account.number;
  173.  
  174. ban.type = BAN_ACCOUNT;
  175. if(IOBan::getInstance()->getData(ban) && !IOLoginData::getInstance()->hasFlag(account.number, PlayerFlag_CannotBeBanned))
  176. {
  177. bool deletion = ban.expires < 0;
  178. std::string name_ = "Automatic ";
  179. if(!ban.adminId)
  180. name_ += (deletion ? "deletion" : "banishment");
  181. else
  182. IOLoginData::getInstance()->getNameByGuid(ban.adminId, name_, true);
  183.  
  184. std::stringstream ss;
  185. ss << "Your account has been " << (deletion ? "deleted" : "banished") << " at:\n" << formatDateEx(ban.added, "%d %b %Y").c_str()
  186. << " by: " << name_.c_str() << ".\nThe comment given was:\n" << ban.comment.c_str() << ".\nYour " << (deletion ?
  187. "account won't be undeleted" : "banishment will be lifted at:\n") << (deletion ? "" : formatDateEx(ban.expires).c_str()) << ".";
  188.  
  189. disconnectClient(0x0A, ss.str().c_str());
  190. return;
  191. }
  192.  
  193. // remove premium days
  194. #ifndef __LOGIN_SERVER__
  195. IOLoginData::getInstance()->removePremium(account);
  196. if(!g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && !account.charList.size())
  197. {
  198. disconnectClient(0x0A, std::string("This account does not contain any character yet.\nCreate a new character on the "
  199. + g_config.getString(ConfigManager::SERVER_NAME) + " website at " + g_config.getString(ConfigManager::URL) + ".").c_str());
  200. return;
  201. }
  202. #else
  203. Characters charList;
  204. for(Characters::iterator it = account.charList.begin(); it != account.charList.end(); ++it)
  205. {
  206. if(version >= it->second.server->getVersionMin() && version <= it->second.server->getVersionMax())
  207. charList[it->first] = it->second;
  208. }
  209.  
  210. IOLoginData::getInstance()->removePremium(account);
  211. if(!g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && !charList.size())
  212. {
  213. disconnectClient(0x0A, std::string("This account does not contain any character on this client yet.\nCreate a new character on the "
  214. + g_config.getString(ConfigManager::SERVER_NAME) + " website at " + g_config.getString(ConfigManager::URL) + ".").c_str());
  215. return;
  216. }
  217. #endif
  218.  
  219. ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, true);
  220. if(OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false))
  221. {
  222. TRACK_MESSAGE(output);
  223. output->put<char>(0x14);
  224. uint32_t serverIp = serverIps.front().first;
  225. for(std::list<std::pair<uint32_t, uint32_t> >::iterator it = serverIps.begin(); it != serverIps.end(); ++it)
  226. {
  227. if((it->first & it->second) != (clientIp & it->second))
  228. continue;
  229.  
  230. serverIp = it->first;
  231. break;
  232. }
  233.  
  234. char motd[1300];
  235. sprintf(motd, "%d\n%s", g_game.getMotdId(), g_config.getString(ConfigManager::MOTD).c_str());
  236. output->putString(motd);
  237.  
  238. //Add char list
  239. output->put<char>(0x64);
  240. output->put<char>(0x01); // number of worlds
  241. output->put<char>(0x00); // world id
  242. output->putString(g_config.getString(ConfigManager::SERVER_NAME));
  243. output->putString(g_config.getString(ConfigManager::IP));
  244. IntegerVec games = vectorAtoi(explodeString(g_config.getString(ConfigManager::GAME_PORT), ","));
  245. output->put<uint16_t>(games[random_range(0, games.size() - 1)]);
  246. if(!g_config.getBool(ConfigManager::SERVER_NAME))
  247. output->put<char>(0x00);
  248. else
  249. output->put<char>(0x01);
  250.  
  251. output->put<char>((uint8_t)account.charList.size());
  252. #ifndef __LOGIN_SERVER__
  253. for(Characters::iterator it = account.charList.begin(); it != account.charList.end(); ++it)
  254. {
  255. output->put<char>(0x00);
  256. output->putString((*it));
  257. }
  258. #else
  259. for(Characters::iterator it = charList.begin(); it != charList.end(); ++it)
  260. {
  261. output->put<char>(0x00);
  262. output->putString((*it));
  263. }
  264. #endif
  265.  
  266. //Add premium days
  267. if(g_config.getBool(ConfigManager::FREE_PREMIUM))
  268. output->put<uint16_t>(GRATIS_PREMIUM);
  269. else
  270. output->put<uint16_t>(account.premiumDays);
  271.  
  272. OutputMessagePool::getInstance()->send(output);
  273. }
  274.  
  275. getConnection()->close();
  276. }
Advertisement
Add Comment
Please, Sign In to add comment