Advertisement
Guest User

Untitled

a guest
Feb 1st, 2025
28
0
141 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 37.50 KB | None | 0 0
  1. //#include "preheaders.h"
  2.  
  3. #include <string>
  4. #include <iostream>
  5. #include <iomanip>
  6. #include <fstream>
  7. #include <sstream>
  8. #include <ctime>
  9.  
  10. #include "networkmessage.h"
  11. #include "protocol76.h"
  12. #include "game.h"
  13. #include "ioaccountsql.h"
  14. #include "ioplayersql.h"
  15. #ifdef TR_SUMMONS
  16. #include "summons.h"
  17. #endif //TR_SUMMONS
  18. #ifdef __MIZIAK_TASKS__
  19. #include "task.h"
  20. #endif //__MIZIAK_TASKS__
  21. #include "status.h"
  22. #include "spells.h"
  23. #include "monsters.h"
  24. #include "actions.h"
  25. #include "commands.h"
  26. #include "town.h"
  27. #include "luascript.h"
  28. #include "account.h"
  29. #include "tools.h"
  30. #include "pvparena.h"
  31. #ifdef __OTSERV_ALLOCATOR__
  32. #include "allocator.h"
  33. #endif
  34. #include "databasemanager.h"
  35. #ifdef WIN32
  36. #define ERROR_EINTR WSAEINTR
  37. #else
  38. /* Comment below line if you want to execute otserv with root user (NOT RECOMMENDED) */
  39. #define _NO_ROOT_PERMISSION_
  40.  
  41. extern int32_t errno;
  42. #endif
  43.  
  44. #ifdef __DEBUG_CRITICALSECTION__
  45. OTSYS_THREAD_LOCK_CLASS::LogList OTSYS_THREAD_LOCK_CLASS::loglist;
  46. #endif
  47.  
  48. std::vector< std::pair<uint32_t, uint32_t> > serverIPs;
  49. std::vector< std::pair<uint32_t, uint32_t> > bannedIPs;
  50. std::vector< std::pair<uint32_t[3], uint32_t> > IPs;
  51.  
  52. LuaScript g_config;
  53.  
  54. Items Item::items;
  55. ReverseItemMap Items::revItems;
  56. Game g_game;
  57. Spells spells(&g_game);
  58. Actions actions(&g_game);
  59. Commands commands(&g_game);
  60. Monsters g_monsters;
  61.  
  62. struct AccSuspensaUCB
  63. {
  64.     uint32_t conta;
  65.     uint32_t tentativas;
  66.     std::time_t tempo;
  67.     bool bloqueado;
  68. };
  69.  
  70. struct IpSuspensoUCB
  71. {
  72.     uint32_t ip;
  73.     uint32_t tentativas;
  74.     std::time_t tempo;
  75.     bool bloqueado;
  76. };
  77.  
  78. std::vector< struct AccSuspensaUCB > ListaAccSuspensas;
  79. std::vector< struct IpSuspensoUCB  > ListaIpsSuspensos;
  80. std::time_t tempo_reciclagem = std::time(NULL) + 3600;
  81.  
  82. #include "networkmessage.h"
  83.  
  84. enum passwordType_t
  85. {
  86.     PASSWORD_TYPE_PLAIN,
  87.     PASSWORD_TYPE_MD5,
  88. };
  89.  
  90. passwordType_t passwordType;
  91.  
  92. bool passwordTest(std::string &plain, std::string &hash)
  93. {
  94.     if(passwordType != PASSWORD_TYPE_MD5)
  95.         if(plain == hash)
  96.             return true;
  97.         else
  98.             return false;
  99.  
  100.     return false; //VISUAL
  101. }
  102.  
  103. /*int32_t polaczenia(SOCKET s)
  104. {
  105.     time_t czas;
  106.     time(&czas);
  107.     struct tm * timeinfo = localtime(&czas);
  108.     int32_t minuta = timeinfo->tm_sec+timeinfo->tm_min*60;
  109.     sockaddr_in sain;
  110.     socklen_t salen = sizeof(sockaddr_in);
  111.  
  112.     if (getpeername(s, (sockaddr*)&sain, &salen) == 0)
  113.     {
  114.         uint32_t clientip = *(uint32_t*)&sain.sin_addr;
  115.         for (size_t i = 0; i < IPs.size(); ++i) {
  116.             if ((IPs[i].first[0]) == (clientip)){
  117.                int32_t cos = IPs[i].first[2] - minuta;
  118.                 if(abs(cos) >= 30){
  119.                     IPs[i].first[1] = 0;
  120.                     IPs[i].first[2] = minuta;
  121.                 }
  122.                 else if(IPs[i].first[1]>=5)
  123.                     return -2;//banned
  124.                 else{
  125.                     IPs[i].first[1]++;
  126.                     return IPs[i].first[1];
  127.                 }
  128.             }
  129.         }
  130.         std::pair<uint32_t[3], uint32_t> IpNetMask;
  131.         IpNetMask.first[0] = clientip;
  132.         IpNetMask.first[1] = 0;
  133.         IpNetMask.first[2] = minuta;
  134.         IpNetMask.second = 0xFFFFFFFF;
  135.         IPs.push_back(IpNetMask);
  136.         return 0;
  137.     }
  138.     return -1;
  139. }*/
  140.  
  141. bool isclientBanished(SOCKET s)
  142. {
  143.     sockaddr_in sain;
  144.     socklen_t salen = sizeof(sockaddr_in);
  145.  
  146.     if (getpeername(s, (sockaddr*)&sain, &salen) == 0)
  147.     {
  148.         uint32_t clientip = *(uint32_t*)&sain.sin_addr;
  149.  
  150.         for (size_t i = 0; i < bannedIPs.size(); ++i)
  151.         {
  152.             if ((bannedIPs[i].first & bannedIPs[i].second) == (clientip & bannedIPs[i].second))
  153.                 return true;
  154.         }
  155.     }
  156.  
  157.     return false;
  158. }
  159.  
  160. // Ulisses (Proglin) - IP/ACC Suspend System
  161. // April / 2006 for turion.no-ip.info
  162. bool isAccIPSuspend(int32_t acc, SOCKET s)
  163. {
  164.     bool suspensa = false;
  165.     bool achouip = false;
  166.     bool achouacc = false;
  167.  
  168.     sockaddr_in sain;
  169.     socklen_t salen = sizeof(sockaddr_in);
  170.  
  171.     std::time_t now = std::time(NULL);
  172.  
  173.     /* Recycling Lists (to save memory ;) ) */
  174.     if( now > tempo_reciclagem )
  175.     {
  176.         OTSYS_THREAD_LOCK(g_game.gameLock, "UCB_IP_Seach");
  177.         OTSYS_THREAD_LOCK(g_game.gameLock, "UCB_ACC_Seach");
  178.         tempo_reciclagem = now + 3600;
  179.         bool achou = true;
  180.  
  181.         std::cout << "Ips  suspend before recycling: " << ListaIpsSuspensos.size() << std::endl;
  182.         std::cout << "Accs suspend before recycling: " << ListaAccSuspensas.size() << std::endl;
  183.  
  184.         /* Ips list */
  185.         std::vector< struct IpSuspensoUCB >::iterator i = ListaIpsSuspensos.begin();
  186.         while( achou )
  187.         {
  188.             achou = false;
  189.             while(i != ListaIpsSuspensos.end())
  190.             {
  191.                 if((*i).tempo < now)
  192.                 {
  193.                     ListaIpsSuspensos.erase(i);
  194.                     achou = true;
  195.                     break;
  196.                 }
  197.                 ++i;
  198.             }
  199.         }
  200.  
  201.         /* Acc list */
  202.         achou = true;
  203.         std::vector< struct AccSuspensaUCB >::iterator ii = ListaAccSuspensas.begin();
  204.         while( achou )
  205.         {
  206.             achou = false;
  207.             while(ii != ListaAccSuspensas.end())
  208.             {
  209.                 if((*ii).tempo < now)
  210.                 {
  211.                     ListaAccSuspensas.erase(ii);
  212.                     achou = true;
  213.                     break;
  214.                 }
  215.                 ++ii;
  216.             }
  217.         }
  218.         OTSYS_THREAD_UNLOCK(g_game.gameLock, "UCB_ACC_Seach");
  219.         OTSYS_THREAD_UNLOCK(g_game.gameLock, "UCB_IP_Seach");
  220.         std::cout << "Ips  suspend  after recycling: " << ListaIpsSuspensos.size() << std::endl;
  221.         std::cout << "Accs suspend  after recycling: " << ListaAccSuspensas.size() << std::endl;
  222.     }
  223.  
  224.     /* Search for IP */
  225.     OTSYS_THREAD_LOCK(g_game.gameLock, "UCB_IP_Seach");
  226.     if (getpeername(s, (sockaddr*)&sain, &salen) == 0 )
  227.     {
  228.         uint32_t clientip = *(uint32_t*)&sain.sin_addr;
  229.         for (size_t i = 0; i < ListaIpsSuspensos.size(); ++i)
  230.         {
  231.             if( ListaIpsSuspensos[i].ip == clientip )
  232.             {
  233.                 achouip = true;
  234.                 if( ListaIpsSuspensos[i].tempo < now )
  235.                 {
  236.                     ListaIpsSuspensos[i].tentativas = 0;
  237.                     ListaIpsSuspensos[i].bloqueado = false;
  238.                     ListaIpsSuspensos[i].tempo = now + 60*g_config.SUSPEND_TIME_MAX;
  239.                 }
  240.                 if( !ListaIpsSuspensos[i].bloqueado )
  241.                 {
  242.                     if( ListaIpsSuspensos[i].tentativas == g_config.SUSPEND_IP_TRIES - 1 )  //VISUAL
  243.                     {
  244.                         ListaIpsSuspensos[i].bloqueado = true;
  245.                         ListaIpsSuspensos[i].tempo = now + 60*g_config.SUSPEND_TIME_MAX;
  246.                     }
  247.                 }
  248.                 ListaIpsSuspensos[i].tentativas++;
  249.                 suspensa = ListaIpsSuspensos[i].bloqueado;
  250.             }
  251.         }
  252.         if( !achouip )
  253.         {
  254.             struct IpSuspensoUCB candidatoip;
  255.             candidatoip.ip = clientip;
  256.             candidatoip.tentativas = 1;
  257.             candidatoip.tempo = now + 60*g_config.SUSPEND_TIME_MAX;
  258.             candidatoip.bloqueado = false;
  259.             ListaIpsSuspensos.push_back(candidatoip);
  260.         }
  261.     }
  262.     OTSYS_THREAD_UNLOCK(g_game.gameLock, "UCB_IP_Seach");
  263.  
  264.     /* Search for Account */
  265.     OTSYS_THREAD_LOCK(g_game.gameLock, "UCB_ACC_Seach");
  266.     for (size_t i = 0; i < ListaAccSuspensas.size(); ++i)
  267.     {
  268.         if( ListaAccSuspensas[i].conta == acc )
  269.         {
  270.             achouacc = true;
  271.             if( ListaAccSuspensas[i].tempo < now )
  272.             {
  273.                 ListaAccSuspensas[i].tentativas = 0;
  274.                 ListaAccSuspensas[i].bloqueado = false;
  275.                 ListaAccSuspensas[i].tempo = now + 60*g_config.SUSPEND_TIME_MAX;
  276.             }
  277.             if( !ListaAccSuspensas[i].bloqueado )
  278.             {
  279.                 if( ListaAccSuspensas[i].tentativas == g_config.SUSPEND_IP_TRIES - 1 )  //VISUAL
  280.                 {
  281.                     ListaAccSuspensas[i].bloqueado = true;
  282.                     ListaAccSuspensas[i].tempo = now + 60*g_config.SUSPEND_TIME_MAX;
  283.                 }
  284.             }
  285.             ListaAccSuspensas[i].tentativas++;
  286.             if( !suspensa )
  287.                 suspensa = ListaAccSuspensas[i].bloqueado;
  288.         }
  289.     }
  290.     if( !achouacc )
  291.     {
  292.         struct AccSuspensaUCB candidatoacc;
  293.         candidatoacc.conta = acc;
  294.         candidatoacc.tentativas = 1;
  295.         candidatoacc.tempo = now + 60*g_config.SUSPEND_TIME_MAX;
  296.         candidatoacc.bloqueado = false;
  297.         ListaAccSuspensas.push_back(candidatoacc);
  298.     }
  299.     OTSYS_THREAD_UNLOCK(g_game.gameLock, "UCB_ACC_Seach");
  300.  
  301.     return suspensa;
  302. }
  303.  
  304. #ifdef YUR_LOGIN_QUEUE
  305. std::string MakeRejectMessage(int32_t place)
  306. {
  307.     if (place < 0)
  308.         return std::string("Zla pozycja temple! Skontaktuj sie z administratorem!");
  309.     else
  310.     {
  311.         std::ostringstream msg;
  312.         msg << "Za duzo graczy online.\n";
  313.  
  314.         if (!g_config.QUEUE_PREMMY)
  315.             msg << "Tylko gracze z Premium moga teraz wejsc.\n";
  316.  
  317.         msg << "\nJestes na " << place << " pozycji na liscie oczekujacych.";
  318.         return msg.str();
  319.     }
  320. }
  321. #endif //YUR_LOGIN_QUEUE
  322.  
  323.  
  324. OTSYS_THREAD_RETURN ConnectionHandler(void *dat)
  325. {
  326.  
  327.     srand((unsigned)time(NULL));
  328.  
  329.     SOCKET s = *(SOCKET*)dat;
  330.  
  331.     NetworkMessage msg;
  332.     if (msg.ReadFromSocket(s))
  333.     {
  334. //      if(polaczenia(s) == -2)
  335. //            std::cout << "Proba ataku!";
  336.  
  337.         //if(polaczenia(s) != -2){
  338.  
  339.         uint16_t protId = msg.GetU16();
  340.  
  341.         // login server connection
  342.         if (protId == 0x0201)
  343.         {
  344.             msg.SkipBytes(15);
  345.             uint32_t accnumber = msg.GetU32();
  346.             std::string  password  = msg.GetString();
  347.  
  348.             int32_t serverip = serverIPs[0].first;
  349.  
  350.             sockaddr_in sain;
  351.             socklen_t salen = sizeof(sockaddr_in);
  352.             if (getpeername(s, (sockaddr*)&sain, &salen) == 0)
  353.             {
  354.                 uint32_t clientip = *(uint32_t*)&sain.sin_addr;
  355.                 for (uint32_t i = 0; i < serverIPs.size(); i++)
  356.                     if ((serverIPs[i].first & serverIPs[i].second) == (clientip & serverIPs[i].second))
  357.                     {
  358.                         serverip = serverIPs[i].first;
  359.                         break;
  360.                     }
  361.             }
  362.  
  363.             msg.Reset();
  364.  
  365.             bool recebeuban = false;
  366.             if(isclientBanished(s))
  367.             {
  368.                 recebeuban = true;
  369.                 msg.AddByte(0x0A);
  370.                 msg.AddString("Twoje IP zostalo zbanowane!");
  371.             }
  372.             if( isAccIPSuspend(accnumber, s) || recebeuban )
  373.             {
  374.                 if( !recebeuban )
  375.                 {
  376.                     msg.AddByte(0x0A);
  377.                     msg.AddString(g_config.SUSPEND_MSG);
  378.                 }
  379.             }
  380.             else
  381.             {
  382.                 //char accstring[16];
  383.                 //sprintf(accstring, "%i", accnumber);
  384.  
  385.                 Account account = IOAccountSQL::getInstance()->loadAccount(accnumber);
  386.                 if (account.accnumber == accnumber && passwordTest(password,account.password) && account.accnumber != 0 && accnumber != 0) // seems to be a successful load
  387.                 {
  388.                     msg.AddByte(0x14);
  389.                     msg.AddString(g_config.MOTD);
  390.  
  391.                     msg.AddByte(0x64);
  392.                     msg.AddByte((uint8_t)account.charList.size());
  393.  
  394.                     std::list<std::string>::iterator it;
  395.                     for (it = account.charList.begin(); it != account.charList.end(); ++it)
  396.                     {
  397.                         msg.AddString((*it));
  398.                         msg.AddString(g_config.WORLD_NAME);
  399.                         msg.AddU32(serverip);
  400.                         msg.AddU16(g_config.PORT);
  401.                     }
  402.  
  403.                     msg.AddU16(account.premDays);
  404.                 }
  405.                 else
  406.                 {
  407.                     msg.AddByte(0x0A);
  408.                     msg.AddString("Zly numer konta lub haslo!");
  409.                 }
  410.             }
  411.  
  412.             msg.WriteToSocket(s);
  413.         }
  414.         // gameworld connection tibia 7.6
  415.         else if (protId == 0x020A)
  416.         {
  417.             unsigned char  clientos = msg.GetByte();
  418.             uint16_t version  = msg.GetU16();
  419.             unsigned char  unknown = msg.GetByte();
  420.             uint32_t accnumber = msg.GetU32();
  421.             std::string name     = msg.GetString();
  422.             std::string password = msg.GetString();
  423.  
  424.             if(version != 760)
  425.             {
  426.                 msg.Reset();
  427.                 msg.AddByte(0x14);
  428.                 msg.AddString("Protokol 7.6 obowiazuje!");
  429.                 msg.WriteToSocket(s);
  430.             }
  431.             else if(isclientBanished(s))
  432.             {
  433.                 msg.Reset();
  434.                 msg.AddByte(0x14);
  435.                 msg.AddString("Twoje IP zostalo zbanowane!");
  436.                 msg.WriteToSocket(s);
  437.             }
  438.             else
  439.             {
  440.                 OTSYS_SLEEP(1000);
  441.                 std::string acc_pass;
  442.                 if(IOAccountSQL::getInstance()->getPassword(accnumber, name, acc_pass) && passwordTest(password,acc_pass))
  443.                 {
  444.                     bool isLocked = true;
  445.                     OTSYS_THREAD_LOCK(g_game.gameLock, "ConnectionHandler()")
  446.                     Player* player = g_game.getPlayerByName(name);
  447.                     bool playerexist = (player != NULL);
  448.                     if(player)
  449.                     {
  450.                         //reattach player?
  451.                         if(player->client->s == 0 && player->isRemoved == false)
  452.                         {
  453.                             player->lastlogin = std::time(NULL);
  454.                             player->client->reinitializeProtocol(s);
  455.                             player->client->s = s;
  456.                             player->client->sendThingAppear(player);
  457.                             player->lastip = player->getIP();
  458.                             s = 0;
  459.                         }
  460.  
  461.                         //guess not...
  462.                         player = NULL;
  463.                     }
  464.                     //OTSYS_THREAD_UNLOCK(g_game.gameLock, "ConnectionHandler()")
  465.  
  466.                     if(s)  //tak mi sie wydaje
  467.                     {
  468.                         int64_t timeNow = std::time(NULL); // VISUAL
  469.                         Protocol76* protocol;
  470.                         protocol = new Protocol76(s);
  471.                         player = new Player(name, protocol);
  472.                         player->useThing();
  473.                         player->setID();
  474.                         IOPlayerSQL::getInstance()->loadPlayer(player, name);
  475. #ifdef YUR_LOGIN_QUEUE
  476.                         int32_t placeInQueue = -1;
  477. #endif //YUR_LOGIN_QUEUE
  478.                         static const int32_t ACCESS_ENTER = g_config.ACCESS_ENTER;
  479.                         if(playerexist)
  480.                         {
  481.                             std::cout << "Odrzucenie gracza: " << player->getName() << " aktulanie zalogowany." << std::endl;
  482.                             msg.Reset();
  483.                             msg.AddByte(0x14);
  484.                             msg.AddString("Aktualnie jestes zalogowany.");
  485.                             msg.WriteToSocket(s);
  486.                         }
  487. #ifdef HUCZU_BAN_SYSTEM
  488.                         else if (player->banned && timeNow < player->banend)
  489.                         {
  490.                             msg.Reset();
  491.                             msg.AddByte(0x14);
  492.                             time_t endBan = player->banend;
  493.                             std::stringstream txt;
  494.                             if(player->deleted == 0) // checks if not deleted
  495.                                 txt << "Twoja postac zostala zablokowana! Powod: " << player->reason << ".\nTwoj ban zostanie zdjety " << ctime(&endBan) << "Sprobuj zalogowac sie po tej dacie.";
  496.                             if(player->namelock != 0) // gdy namelock
  497.                                 txt << "Dostales rowniez namelocka. Zmien swoj nick na stronie.";
  498.                             if(player->deleted != 0)// deleted == 1
  499.                                 txt << "Twoja postac zostala usunieta z serwera!\nNigdy nie zostanie juz odbanowana!";
  500.                             msg.AddString(txt.str().c_str());
  501.                             msg.WriteToSocket(s);
  502.                         }
  503.                         else if(player->banned && timeNow > player->banend && player->deleted == 0)
  504.                         {
  505.                             player->banned = 0;
  506.                             player->comment = "";
  507.                             player->reason = "";
  508.                             player->action = "";
  509.                             player->banrealtime = "";
  510.                             IOPlayerSQL::getInstance()->savePlayer(player);
  511.                             msg.Reset();
  512.                             msg.AddByte(0x14);
  513.                             msg.AddString("Zostales odbanowany. Mozesz sie teraz zalogowac.");
  514.                             msg.WriteToSocket(s);
  515.                         }
  516.                         else if(player->namelock != 0)
  517.                         {
  518.                             msg.Reset();
  519.                             msg.AddByte(0x14);
  520.                             msg.AddString("Posiadasz namelocka. Zmien swoj nick na stronie.");
  521.                             msg.WriteToSocket(s);
  522.                         }
  523. #endif //HUCZU_BAN_SYSTEM
  524.                         else if(player->vocation > 4 || player->vocation < 0 || player->healthmax <=0 || player->manamax < 0 || player->level <= 0 || player->experience < 0 || player->maglevel < 0)
  525.                         {
  526.                             msg.Reset();
  527.                             msg.AddByte(0x14);
  528.                             msg.AddString("Your character is bugged!");
  529.                             msg.WriteToSocket(s);
  530.                         }
  531.                         /*else if(g_game.getGameState() == GAME_STATE_SHUTDOWN){
  532.                             //nothing to do
  533.                         }*/
  534.                         else if(g_game.getGameState() == GAME_STATE_CLOSED && player->access < ACCESS_ENTER)
  535.                         {
  536.                             msg.Reset();
  537.                             msg.AddByte(0x14);
  538.                             msg.AddString("Serwer jest tymczasowo zamkniety. Prosze sprobowac za chwile.");
  539.                             msg.WriteToSocket(s);
  540.                         }
  541.  
  542. #ifdef YUR_LOGIN_QUEUE
  543.                         else if (!protocol->ConnectPlayer(&placeInQueue))
  544.                         {
  545.                             Status* stat = Status::instance();
  546.                             stat->playerswaiting = (int32_t)g_game.loginQueue.size();
  547.                             if (placeInQueue < 0)
  548.                                 std::cout << "Odrzucenie gracza: " << player->getName() << " ,bledna pozycja temple."<< std::endl;
  549.                             else
  550.                                 std::cout << "Odrzucenie gracza: " << player->getName() << ". Ustawiony w kolejce: " << placeInQueue << std::endl;
  551.                             msg.Reset();
  552.                             msg.AddByte(0x16);
  553.                             msg.AddString(MakeRejectMessage(placeInQueue));
  554.                             msg.AddByte(30);
  555.                             msg.WriteToSocket(s);
  556.                         }
  557. #else
  558.                         else if(!protocol->ConnectPlayer())
  559.                         {
  560.                             std::cout << "Odrzucenie gracza: " << player->getName() << " brak miejsca." << std::endl;
  561.                             msg.Reset();
  562.                             msg.AddByte(0x16);
  563.                             msg.AddString("Za duzo graczy online.");
  564.                             msg.AddByte(45);
  565.                             msg.WriteToSocket(s);
  566.                         }
  567. #endif //YUR_LOGIN_QUEUE
  568.                         else
  569.                         {
  570.                             Status* stat = Status::instance();
  571.                             stat->addPlayer();
  572.                             player->lastlogin = std::time(NULL);
  573.                             player->lastip = player->getIP();
  574.                             s = 0;            // protocol/player will close socket
  575.  
  576.                             OTSYS_THREAD_UNLOCK(g_game.gameLock, "ConnectionHandler()")
  577.                             isLocked = false;
  578.  
  579.                             protocol->ReceiveLoop();
  580. /*#ifdef HUCZU_NOLOGOUT_TILE
  581.                             //stat->removePlayer();
  582. #else*/
  583.                             stat->removePlayer();
  584. //#endif
  585.                         }
  586.                         g_game.FreeThing(player);
  587.                     }
  588.  
  589.                     if(isLocked)
  590.                     {
  591.                         OTSYS_THREAD_UNLOCK(g_game.gameLock, "ConnectionHandler()")
  592.                     }
  593.                 }
  594.             }
  595.         }
  596.         // Since Cip made 02xx as Tibia protocol,
  597.         // Lets make FFxx as "our great info protocol" ;P
  598.         else if (protId == 0xFFFF)
  599.         {
  600.             if (msg.GetRaw() == "info")
  601.             {
  602.                 Status* status = Status::instance();
  603.                 /*uint64_t running = (OTSYS_TIME() - status->start)/1000;
  604.                 #ifdef __DEBUG__
  605.                 std::cout << ":: Uptime: " << running << std::endl;
  606.                 #endif*///fix na blokade
  607.                 std::string str = status->getStatusString();
  608.                 send(s, str.c_str(), (int32_t)str.size(), 0);
  609.             }
  610.         }
  611.         // Another ServerInfo protocol
  612.         // Starting from 01, so the above could be 00 ;)
  613.         else if (protId == 0xFF02)  //tez fix
  614.         {
  615.             // This one doesn't need to read nothing, so we could save time and bandwidth
  616.             // Can be called thgough a program that understand the NetMsg protocol
  617.             Status* status = Status::instance();
  618.             status->getInfo(msg);
  619.             msg.WriteToSocket(s);
  620.         }
  621.         //}
  622.     }
  623.     if(s)
  624.         closesocket(s);
  625.  
  626. #if defined WIN32 || defined WINDOWS
  627. #else
  628.     return 0;
  629. #endif
  630. }
  631.  
  632.  
  633.  
  634. void ErrorMessage(const char* message)
  635. {
  636.     std::cout << std::endl << std::endl << "Error: " << message;
  637.  
  638.     std::string s;
  639.     std::cin >> s;
  640. }
  641.  
  642. int32_t main(int32_t argc, char *argv[])
  643. {
  644. #ifdef __OTSERV_ALLOCATOR_STATS__
  645.     OTSYS_CREATE_THREAD(allocatorStatsThread, NULL);
  646. #endif
  647. #ifdef __WIN_LOW_FRAG_HEAP__
  648.     ULONG  HeapFragValue = 2;
  649.  
  650.     if(HeapSetInformation(GetProcessHeap(),HeapCompatibilityInformation,&HeapFragValue,sizeof(HeapFragValue)))
  651.     {
  652.         std::cout << "Heap Success" << std::endl;
  653.     }
  654.     else
  655.     {
  656.         std::cout << "Heap Error" << std::endl;
  657.     }
  658. #endif
  659. //    system("color 80"); //kolorek dla szpaniku :D
  660. //    system("title Kentana OTS Engine"); // tytul ladny
  661.     std::cout << ":: Kentana OTS 3.0" << std::endl;
  662.     std::cout << ":: ~~By Sid/Huczu~~" << std::endl;
  663.     std::cout << ":: Skompilowany przy pomocy " << BOOST_COMPILER << " o " << __DATE__ << ", " << __TIME__ << std::endl;
  664.     std::cout << "::" << std::endl;
  665.  
  666. #ifdef _NO_ROOT_PERMISSION_
  667.     if( getuid() == 0 || geteuid() == 0 )
  668.     {
  669.         std::cout << std::endl << "Silnik zostal uruchomiony z konta administatratora. Odpal ze zwyklego konta." << std::endl;
  670.         return 1;
  671.     }
  672. #endif
  673.  
  674.     // ignore sigpipe...
  675. #if defined __WINDOWS__ || defined WIN32
  676.     //nothing yet
  677. #else
  678.     struct sigaction sigh;
  679.     sigh.sa_handler = SIG_IGN;
  680.     sigaction(SIGPIPE, &sigh, NULL);
  681. #endif
  682.  
  683. //  LOG_MESSAGE("main", EVENT, 1, "Starting server");
  684.  
  685.  
  686.     // random numbers generator
  687.     std::cout << ":: Generator liczb...            ";
  688.     srand ( (uint32_t)time(NULL) );
  689.     std::cout << "[Gotowe]" << std::endl;
  690.  
  691.     // read global config
  692.     std::cout << ":: Ladowanie config.lua...            ";
  693.     if (!g_config.OpenFile("config.lua"))
  694.     {
  695.         ErrorMessage("Blad! Nie mozna zaladowac config.lua!");
  696.         return -1;
  697.     }
  698.     std::cout << "[Gotowe]" << std::endl;
  699. #if defined __WINDOWS__ || defined WIN32
  700.     std::string Priorytet = g_config.PRIORYTET;
  701.     if(Priorytet == "rzeczywisty")
  702.         SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
  703.     if(Priorytet == "wysoki")
  704.         SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
  705.     if(Priorytet == "najwyzszy")
  706.         SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);
  707. #endif
  708.     Database* db = Database::getInstance();
  709.     if(db && db->isConnected())
  710.     {
  711.         std::cout << ":: Running Database Manager" << std::endl;
  712.         if(!DatabaseManager::getInstance()->isDatabaseSetup())
  713.             ErrorMessage("The database you specified in config.lua is empty, please import schemas/<dbengine>.sql to the database (if you are using MySQL, please read doc/MYSQL_HELP for more information).");
  714.  
  715.         DatabaseManager::getInstance()->checkTriggers();
  716.         if(g_config.OPTIMIZE_DB_AT_STARTUP && !DatabaseManager::getInstance()->optimizeTables())
  717.             std::cout << "> No tables were optimized." << std::endl;
  718. #ifdef HUCZU_RECORD
  719.         DBQuery query;
  720.         query << "SELECT `record` FROM `server` LIMIT 1";
  721.         DBResult* result;
  722.         if((result = db->storeQuery(query.str())))
  723.         {
  724.             g_game.record = result->getDataInt("record");
  725.             result->free();
  726.         }
  727. #endif
  728.     }
  729.     else
  730.     {
  731.         ErrorMessage("Couldn't estabilish connection to SQL database!");
  732.         return -1;
  733.     }
  734.  
  735.     //load commands data
  736.     std::cout << ":: Ladowanie komend...          ";
  737.     if(!commands.loadFromDB()/*loadXml(g_config.DATA_DIR)*/)
  738.     {
  739.         ErrorMessage("Blad! Nie mozna zaladowac komend!");
  740.         return -1;
  741.     }
  742.     std::cout << "[Gotowe]" << std::endl;
  743.  
  744.     //load spells data
  745.     std::cout << ":: Ladowanie spells.xml...            ";
  746.     if(!spells.loadFromXml(g_config.DATA_DIR))
  747.     {
  748.         ErrorMessage("Blad! Nie mozna zaladowac spells.xml!");
  749.         return -1;
  750.     }
  751.     std::cout << "[Gotowe]" << std::endl;
  752.  
  753.     //load actions data
  754.     std::cout << ":: Ladowanie actions.xml...           ";
  755.     if(!actions.loadFromXml(g_config.DATA_DIR))
  756.     {
  757.         ErrorMessage("Blad! Nie mozna zaladowac actions.xml!");
  758.         return -1;
  759.     }
  760.     std::cout << "[Gotowe]" << std::endl;
  761.  
  762.     // load item data
  763.     std::cout << ":: Ladowanie items.otb...             ";
  764.     if (Item::items.loadFromOtb(g_config.DATA_DIR + "items/items.otb"))
  765.     {
  766.         ErrorMessage("Blad! Nie mozna zaladowac items.otb!");
  767.         return -1;
  768.     }
  769.     std::cout << "[Gotowe]" << std::endl;
  770.  
  771.     std::cout << ":: Ladowanie items.xml...             ";
  772.     if (!Item::items.loadXMLInfos(g_config.DATA_DIR + "items/items.xml"))
  773.     {
  774.         ErrorMessage("Blad! Nie mozna zaladowac /items/items.xml ...!");
  775.         return -1;
  776.     }
  777.     std::cout << "[Gotowe]" << std::endl;
  778.  
  779. #ifdef YUR_LOGIN_QUEUE
  780.     std::cout << ":: Ladowanie queue.xml...             ";
  781.     if (!g_game.loginQueue.load())
  782.     {
  783.         ErrorMessage("Blad! Nie mozna zaladowac queue.xml!");
  784.         return -1;
  785.     }
  786.     std::cout << "[Gotowe]" << std::endl;
  787. #endif //YUR_LOGIN_QUEUE
  788. #ifdef TR_SUMMONS
  789.     std::cout << ":: Ladowanie summons.xml...             ";
  790.     if (!Summons::Load())
  791.     {
  792.         ErrorMessage("Blad! Nie mozna zaladowac summons.xml!");
  793.         return -1;
  794.     }
  795.     std::cout << "[Gotowe]" << std::endl;
  796. #endif //TR_SUMMONS
  797. #ifdef __MIZIAK_TASKS__
  798.     std::cout << ":: Ladowanie tasks.xml...                ";
  799.     if (!Tasks::Load())
  800.     {
  801.         ErrorMessage("Blad! Nie mozna zaladowac tasks.xml!");
  802.         return -1;
  803.     }
  804.     std::cout << "[Gotowe]" << std::endl;
  805. #endif //__MIZIAK_TASKS__
  806.     // load monster data
  807.     std::cout << ":: Ladowanie monsters.xml...              ";
  808.     if(!g_monsters.loadFromXml(g_config.DATA_DIR))
  809.     {
  810.         ErrorMessage("Blad! Nie mozna zaladowac monsters/monsters.xml!");
  811.         return -1;
  812.     }
  813.     std::cout << "[Gotowe]" << std::endl;
  814.  
  815. #ifdef HUCZU_STAGE_EXP
  816.     if(g_config.STAGE_EXP)
  817.     {
  818.         std::cout << ":: Ladowanie stages.xml...                ";
  819.         if(!g_game.loadStageExp())
  820.         {
  821.             ErrorMessage("Blad! Nie mozna zaladowac stages.xml!");
  822.             return -1;
  823.         }
  824.         std::cout << "[Gotowe]" << std::endl;
  825.     }
  826. #endif
  827.  
  828.     std::string worldtype = g_config.WORLD_TYPE;
  829.     std::transform(worldtype.begin(), worldtype.end(), worldtype.begin(), upchar);
  830.     if(worldtype == "PVP")
  831.         g_game.setWorldType(WORLD_TYPE_PVP);
  832.     else if(worldtype == "NO-PVP")
  833.         g_game.setWorldType(WORLD_TYPE_NO_PVP);
  834.     else if(worldtype == "PVP-ENFORCED")
  835.         g_game.setWorldType(WORLD_TYPE_PVP_ENFORCED);
  836.     else
  837.     {
  838.         ErrorMessage("Nieznany World Type!");
  839.         return -1;
  840.     }
  841.     std::cout << ":: World Type: " << worldtype << std::endl;
  842.  
  843. #ifdef YUR_CVS_MODS
  844.     timer();
  845. #endif
  846.  
  847.     // loads the map and, if needed, an extra-file spawns
  848.     switch(g_game.loadMap(g_config.MAP_PATH, "OTBM"))
  849.     {
  850.     case MAP_LOADER_ERROR:
  851.         std::cout << "FATAL: couldnt determine the map format! exiting" << std::endl;
  852.         exit(1);
  853.         break;
  854.     case SPAWN_XML:
  855.         SpawnManager::initialize(&g_game);
  856.         SpawnManager::instance()->loadSpawnsXML(g_game.getSpawnFile());
  857.         SpawnManager::instance()->startup();
  858.         break;
  859.     }
  860.  
  861. #ifdef YUR_CVS_MODS
  862.     double t = timer();
  863.     std::cout << ":: Mapa zaladowana w " << t << " sekund." << std::endl;
  864. #endif
  865.  
  866.     if(g_config.LOAD_NPC != "spawn")
  867.     {
  868.         std::cout << ":: Ladowanie npc.xml...          ";
  869.         if (!g_game.loadNpcs())
  870.         {
  871.             ErrorMessage("Nie mozna zaladowac npc.xml!");
  872.             return -1;
  873.         }
  874.         std::cout << "[Gotowe]" << std::endl;
  875.     }
  876.  
  877. #ifdef TLM_HOUSE_SYSTEM
  878.     std::cout << ":: Ladowanie houses.xml...            ";
  879.     if (!Houses::Load(&g_game))
  880.     {
  881.         ErrorMessage("Blad! Nie mozna zaladowac houses.xml!");
  882.         return -1;
  883.     }
  884.     std::cout << "[Gotowe]" << std::endl;
  885. #endif //TLM_HOUSE_SYSTEM
  886.  
  887. #ifdef YUR_PVP_ARENA
  888.     std::cout << ":: Ladowanie pvparenas.xml...         ";
  889.     if (!PvpArena::Load(&g_game))
  890.     {
  891.         ErrorMessage("Blad! Nie mozna zaladowac pvparenas.xml!");
  892.         return -1;
  893.     }
  894.     std::cout << "[Gotowe]" << std::endl;
  895. #endif //YUR_PVP_ARENA
  896.  
  897.     std::cout << ":: Ladowanie readables.xml...         ";
  898.     if (!g_game.loadReadables())
  899.     {
  900.         ErrorMessage("Blad! Nie mozna zaladowac readables.xml!");
  901.         return -1;
  902.     }
  903.     std::cout << "[Gotowe]" << std::endl;
  904.  
  905.     std::cout << ":: Ladowanie towns.xml...          ";
  906.     if (!Town::loadTowns())
  907.     {
  908.         ErrorMessage("Blad! Nie mozna zaladowac towns.xml!");
  909.         return -1;
  910.     }
  911.     std::cout << "[Gotowe]" << std::endl;
  912.  
  913.     std::cout << ":: Ladowanie napisy.xml...          ";
  914.     if (!g_game.loadNapisy())
  915.     {
  916.         ErrorMessage("Blad! Nie mozna zaladowac napisy.xml!");
  917.         return -1;
  918.     }
  919.     std::cout << "[Gotowe]" << std::endl;
  920.  
  921.     if (g_config.AUTO_SAVE > 0)
  922.         g_game.addEvent(makeTask(g_config.AUTO_SAVE, std::mem_fun(&Game::autoServerSave)));
  923.     else
  924.         std::cout << ":: Automatyczny zapis serwera wylaczony!" << std::endl;
  925.  
  926.     if (g_config.AUTO_CLEAN > 0)
  927.         g_game.addEvent(makeTask(g_config.AUTO_CLEAN, std::mem_fun(&Game::beforeClean)));
  928.     else
  929.         std::cout << ":: Automatyczny clean wylaczony!" << std::endl;
  930.  
  931.     if (g_config.AUTO_RESTART > 0)
  932.         g_game.addEvent(makeTask(g_config.AUTO_RESTART, std::mem_fun(&Game::beforeRestart)));
  933.     else
  934.         std::cout << ":: Automatyczny restart wylaczony!" << std::endl;
  935.  
  936.     g_game.addEvent(makeTask(1000, std::mem_fun(&Game::checkOwner)));
  937.  
  938.     // Call to WSA Startup on Windows Systems...
  939. #ifdef WIN32
  940.     WORD wVersionRequested;
  941.     WSADATA wsaData;
  942.     wVersionRequested = MAKEWORD( 1, 1 );
  943.  
  944.     if (WSAStartup(wVersionRequested, &wsaData) != 0)
  945.     {
  946.         ErrorMessage("Winsock startup failed!!");
  947.         return -1;
  948.     }
  949.  
  950.     if ((LOBYTE(wsaData.wVersion) != 1) || (HIBYTE(wsaData.wVersion) != 1))
  951.     {
  952.         WSACleanup( );
  953.         ErrorMessage("No Winsock 1.1 found!");
  954.         return -1;
  955.     }
  956. #endif
  957.  
  958. #ifdef YUR_CVS_MODS
  959.     std::string localip = "127.0.0.1";
  960. #endif
  961.  
  962.     std::pair<uint32_t, uint32_t> IpNetMask;
  963.     IpNetMask.first  = inet_addr("127.0.0.1");
  964.     IpNetMask.second = 0xFFFFFFFF;
  965.     serverIPs.push_back(IpNetMask);
  966.  
  967.     char szHostName[128];
  968.     if (gethostname(szHostName, 128) == 0)
  969.     {
  970.         std::cout << "::" << std::endl << ":: Odpalony na hoscie " << szHostName << std::endl;
  971.  
  972.         hostent *he = gethostbyname(szHostName);
  973.  
  974.         if (he)
  975.         {
  976.             std::cout << ":: Lokalny adres IP :     ";
  977.             unsigned char** addr = (unsigned char**)he->h_addr_list;
  978.  
  979.             while (addr[0] != NULL)
  980.             {
  981.                 std::cout << (uint32_t)(addr[0][0]) << "."
  982.                           << (uint32_t)(addr[0][1]) << "."
  983.                           << (uint32_t)(addr[0][2]) << "."
  984.                           << (uint32_t)(addr[0][3]) << "  ";
  985.  
  986.                 IpNetMask.first  = *(uint32_t*)(*addr);
  987.                 IpNetMask.second = 0x0000FFFF;
  988.                 serverIPs.push_back(IpNetMask);
  989.  
  990.                 addr++;
  991.             }
  992.  
  993.             std::cout << std::endl;
  994.         }
  995.     }
  996.  
  997.     std::cout << ":: Globaly adres IP :     ";
  998.     std::string ip;
  999.  
  1000.     if(argc > 1)
  1001.         ip = argv[1];
  1002.     else
  1003.         ip = g_config.IP;
  1004.  
  1005.     std::cout << ip << std::endl << "::" << std::endl;
  1006.  
  1007. #ifdef YUR_CVS_MODS
  1008.     if (ip == "127.0.0.1")
  1009.         std::cout << "UWAGA! Zmien IP w config.lua!\n" << std::endl;
  1010. #endif //YUR_CVS_MODS
  1011.  
  1012.     IpNetMask.first  = inet_addr(ip.c_str());
  1013.     IpNetMask.second = 0;
  1014.     serverIPs.push_back(IpNetMask);
  1015.     std::cout << ":: Startowanie serwera... ";
  1016.  
  1017.     Status* status = Status::instance();
  1018.     status->playersmax = g_config.MAX_PLAYERS;
  1019.  
  1020.     // start the server listen...
  1021.     int32_t listen_errors;
  1022.     int32_t accept_errors;
  1023.     listen_errors = 0;
  1024.     g_game.setGameState(GAME_STATE_NORMAL);
  1025.     while(g_game.getGameState() != GAME_STATE_SHUTDOWN && listen_errors < 100)
  1026.     {
  1027.         sockaddr_in local_adress;
  1028.         memset(&local_adress, 0, sizeof(sockaddr_in)); // zero the struct
  1029.  
  1030.         local_adress.sin_family      = AF_INET;
  1031.         local_adress.sin_port        = htons(g_config.PORT);
  1032.         local_adress.sin_addr.s_addr = htonl(INADDR_ANY);
  1033.  
  1034.         // first we create a new socket
  1035.         SOCKET listen_socket = socket(AF_INET, SOCK_STREAM, 0);
  1036.  
  1037.         if(listen_socket <= 0)
  1038.         {
  1039. #ifdef WIN32
  1040.             WSACleanup();
  1041. #endif
  1042.             ErrorMessage("Unable to create server socket (1)!");
  1043.             return -1;
  1044.         } // if (listen_socket <= 0)
  1045.  
  1046. #ifndef WIN32
  1047.         int32_t yes = 1;
  1048.         // lose the pesky "Address already in use" error message
  1049.         if(setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof (int32_t)) == -1)
  1050.         {
  1051.             ErrorMessage("Unable to set socket options!");
  1052.             return -1;
  1053.         }
  1054. #endif
  1055.  
  1056.         // bind socket on port
  1057.         if(::bind(listen_socket, (struct sockaddr*)&local_adress, sizeof(struct sockaddr_in)) < 0)
  1058.         {
  1059. #ifdef WIN32
  1060.             WSACleanup();
  1061. #endif
  1062.             ErrorMessage("Unable to create server socket (2)!");
  1063.             return -1;
  1064.         } // if (bind(...))
  1065.  
  1066.         // now we start listen on the new socket
  1067.         if(listen(listen_socket, 10) == SOCKET_ERROR)
  1068.         {
  1069. #ifdef WIN32
  1070.             WSACleanup();
  1071. #endif
  1072.             ErrorMessage("Listen on server socket not possible!");
  1073.             return -1;
  1074.         } // if (listen(*listen_socket, 10) == -1)
  1075.  
  1076.  
  1077.         std::cout << "[Gotowe]" << std::endl << ":: " << g_config.SERVER_NAME << " uruchomiony..." << std::endl;
  1078.         accept_errors = 0;
  1079.         while(g_game.getGameState() != GAME_STATE_SHUTDOWN && accept_errors < 100)
  1080.         {
  1081.  
  1082.             fd_set listen_set;
  1083.             timeval tv;
  1084.             FD_ZERO(&listen_set);
  1085.             FD_SET(listen_socket, &listen_set);
  1086.             tv.tv_sec = 2;
  1087.             tv.tv_usec = 0;
  1088.  
  1089.             int32_t reads = (int32_t)select(listen_socket + 1, &listen_set, NULL, NULL, &tv); //VISUAL
  1090.             if(reads == SOCKET_ERROR)
  1091.             {
  1092.                 int32_t errnum;
  1093. #ifdef WIN32
  1094.                 errnum = WSAGetLastError();
  1095. #else
  1096.                 errnum = errno;
  1097. #endif
  1098.  
  1099.                 if(errnum == ERROR_EINTR)
  1100.                 {
  1101.                     continue;
  1102.                 }
  1103.                 else
  1104.                 {
  1105.                     SOCKET_PERROR("select");
  1106.                     break;
  1107.                 }
  1108.             }
  1109.             else if(reads == 0)
  1110.             {
  1111.                 continue;
  1112.             }
  1113.  
  1114.             SOCKET s = accept(listen_socket, NULL, NULL); // accept a new connection
  1115.             OTSYS_SLEEP(100);
  1116.             if(s > 0)
  1117.             {
  1118.                 OTSYS_CREATE_THREAD(ConnectionHandler, (void*)&s);
  1119.             }
  1120.             else
  1121.             {
  1122.                 accept_errors++;
  1123.                 SOCKET_PERROR("accept");
  1124.             }
  1125.         }
  1126.         closesocket(listen_socket);
  1127.         listen_errors++;
  1128.     }
  1129.     if(listen_errors >= 100)
  1130.     {
  1131.         std::cout << "ERROR: Server shutted down because there where 100 listen errors." << std::endl;
  1132.     }
  1133.  
  1134. #ifdef WIN32
  1135.     WSACleanup();
  1136. #endif
  1137.     return 0;
  1138. }
  1139.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement