| 82 | | // normal work |
| 83 | | if(m_loops != Master::m_masterLoopCounter) |
| 84 | | { |
| 85 | | m_lastchange = curtime; |
| 86 | | m_loops = Master::m_masterLoopCounter; |
| 87 | | } |
| 88 | | // possible freeze |
| 89 | | else if(getMSTimeDiff(m_lastchange,curtime) > _delaytime) |
| 90 | | { |
| 91 | | sLog.outError("Main/Sockets Thread hangs, kicking out server!"); |
| 92 | | *((uint32 volatile*)NULL) = 0; // bang crash |
| 93 | | } |
| | 84 | // There is no Master anymore |
| | 85 | // TODO: clear the rest of the code |
| | 86 | // // normal work |
| | 87 | // if(m_loops != Master::m_masterLoopCounter) |
| | 88 | // { |
| | 89 | // m_lastchange = curtime; |
| | 90 | // m_loops = Master::m_masterLoopCounter; |
| | 91 | // } |
| | 92 | // // possible freeze |
| | 93 | // else if(getMSTimeDiff(m_lastchange,curtime) > _delaytime) |
| | 94 | // { |
| | 95 | // sLog.outError("Main/Sockets Thread hangs, kicking out server!"); |
| | 96 | // *((uint32 volatile*)NULL) = 0; // bang crash |
| | 97 | // } |
| | 116 | class RARunnable : public ZThread::Runnable |
| | 117 | { |
| | 118 | public: |
| | 119 | uint32 numLoops, loopCounter; |
| | 120 | |
| | 121 | RARunnable () |
| | 122 | { |
| | 123 | uint32 socketSelecttime = sWorld.getConfig (CONFIG_SOCKET_SELECTTIME); |
| | 124 | numLoops = (sConfig.GetIntDefault ("MaxPingTime", 30) * (MINUTE * 1000000 / socketSelecttime)); |
| | 125 | loopCounter = 0; |
| | 126 | } |
| | 127 | |
| | 128 | void |
| | 129 | checkping () |
| | 130 | { |
| | 131 | // ping if need |
| | 132 | if ((++loopCounter) == numLoops) |
| | 133 | { |
| | 134 | loopCounter = 0; |
| | 135 | sLog.outDetail ("Ping MySQL to keep connection alive"); |
| | 136 | delete WorldDatabase.Query ("SELECT 1 FROM command LIMIT 1"); |
| | 137 | delete loginDatabase.Query ("SELECT 1 FROM realmlist LIMIT 1"); |
| | 138 | delete CharacterDatabase.Query ("SELECT 1 FROM bugreport LIMIT 1"); |
| | 139 | } |
| | 140 | } |
| | 141 | |
| | 142 | void |
| | 143 | run (void) |
| | 144 | { |
| | 145 | SocketHandler h; |
| | 146 | |
| | 147 | // Launch the RA listener socket |
| | 148 | ListenSocket<RASocket> RAListenSocket (h); |
| | 149 | bool usera = sConfig.GetBoolDefault ("Ra.Enable", false); |
| | 150 | |
| | 151 | if (usera) |
| | 152 | { |
| | 153 | port_t raport = sConfig.GetIntDefault ("Ra.Port", 3443); |
| | 154 | std::string stringip = sConfig.GetStringDefault ("Ra.IP", "0.0.0.0"); |
| | 155 | ipaddr_t raip; |
| | 156 | if (!Utility::u2ip (stringip, raip)) |
| | 157 | sLog.outError ("MaNGOS RA can not bind to ip %s", stringip.c_str ()); |
| | 158 | else if (RAListenSocket.Bind (raip, raport)) |
| | 159 | sLog.outError ("MaNGOS RA can not bind to port %d on %s", raport, stringip.c_str ()); |
| | 160 | else |
| | 161 | { |
| | 162 | h.Add (&RAListenSocket); |
| | 163 | |
| | 164 | sLog.outString ("Starting Remote access listner on port %d on %s", raport, stringip.c_str ()); |
| | 165 | } |
| | 166 | } |
| | 167 | |
| | 168 | // Socket Selet time is in microseconds , not miliseconds!! |
| | 169 | uint32 socketSelecttime = sWorld.getConfig (CONFIG_SOCKET_SELECTTIME); |
| | 170 | |
| | 171 | // if use ra spend time waiting for io, if not use ra ,just sleep |
| | 172 | if (usera) |
| | 173 | while (!World::m_stopEvent) |
| | 174 | { |
| | 175 | h.Select (0, socketSelecttime); |
| | 176 | checkping (); |
| | 177 | } |
| | 178 | else |
| | 179 | while (!World::m_stopEvent) |
| | 180 | { |
| | 181 | ZThread::Thread::sleep (static_cast<unsigned long> (socketSelecttime / 1000)); |
| | 182 | checkping (); |
| | 183 | } |
| | 184 | } |
| | 185 | }; |
| | 186 | |
| 157 | | ///- Launch the world listener socket |
| 158 | | port_t wsport = sWorld.getConfig(CONFIG_PORT_WORLD); |
| 159 | | std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0"); |
| 160 | | |
| 161 | | SocketHandler h; |
| 162 | | ListenSocket<WorldSocket> worldListenSocket(h); |
| 163 | | if (worldListenSocket.Bind(bind_ip.c_str(),wsport)) |
| 164 | | { |
| 165 | | clearOnlineAccounts(); |
| 166 | | sLog.outError("MaNGOS cannot bind to %s:%d",bind_ip.c_str(), wsport); |
| 167 | | return 1; |
| 168 | | } |
| 169 | | |
| 170 | | h.Add(&worldListenSocket); |
| 171 | | |
| 191 | | |
| 192 | | ///- Launch the RA listener socket |
| 193 | | ListenSocket<RASocket> RAListenSocket(h); |
| 194 | | if (sConfig.GetBoolDefault("Ra.Enable", false)) |
| 195 | | { |
| 196 | | port_t raport = sConfig.GetIntDefault( "Ra.Port", 3443 ); |
| 197 | | std::string stringip = sConfig.GetStringDefault( "Ra.IP", "0.0.0.0" ); |
| 198 | | ipaddr_t raip; |
| 199 | | if(!Utility::u2ip(stringip, raip)) |
| 200 | | sLog.outError( "MaNGOS RA can not bind to ip %s", stringip.c_str()); |
| 201 | | else if (RAListenSocket.Bind(raip, raport)) |
| 202 | | sLog.outError( "MaNGOS RA can not bind to port %d on %s", raport, stringip.c_str()); |
| 203 | | else |
| 204 | | { |
| 205 | | h.Add(&RAListenSocket); |
| 206 | | |
| 207 | | sLog.outString("Starting Remote access listner on port %d on %s", raport, stringip.c_str()); |
| 208 | | } |
| 209 | | } |
| | 251 | |
| | 252 | ZThread::Thread td2(new RARunnable); |
| 274 | | ///- Wait for termination signal |
| 275 | | while (!World::m_stopEvent) |
| 276 | | { |
| 277 | | ++Master::m_masterLoopCounter; |
| 278 | | #ifdef WIN32 |
| 279 | | if (m_ServiceStatus == 0) World::m_stopEvent = true; |
| 280 | | while (m_ServiceStatus == 2) Sleep(1000); |
| 281 | | #endif |
| 282 | | if (realPrevTime > realCurrTime) |
| 283 | | realPrevTime = 0; |
| 284 | | |
| 285 | | realCurrTime = getMSTime(); |
| 286 | | sWorldSocketMgr.Update( getMSTimeDiff(realPrevTime,realCurrTime) ); |
| 287 | | realPrevTime = realCurrTime; |
| 288 | | |
| 289 | | h.Select(0, socketSelecttime); |
| 290 | | |
| 291 | | // ping if need |
| 292 | | if( (++loopCounter) == numLoops ) |
| 293 | | { |
| 294 | | loopCounter = 0; |
| 295 | | sLog.outDetail("Ping MySQL to keep connection alive"); |
| 296 | | delete WorldDatabase.Query("SELECT 1 FROM command LIMIT 1"); |
| 297 | | delete loginDatabase.Query("SELECT 1 FROM realmlist LIMIT 1"); |
| 298 | | delete CharacterDatabase.Query("SELECT 1 FROM bugreport LIMIT 1"); |
| 299 | | } |
| 300 | | } |
| 301 | | |
| | 317 | ///- Launch the world listener socket |
| | 318 | port_t wsport = sWorld.getConfig (CONFIG_PORT_WORLD); |
| | 319 | std::string bind_ip = sConfig.GetStringDefault ("BindIP", "0.0.0.0"); |
| | 320 | |
| | 321 | if (sWorldSocketMgr->StartNetwork (wsport, bind_ip.c_str ()) == -1) |
| | 322 | { |
| | 323 | sLog.outError ("Failed to start network"); |
| | 324 | World::m_stopEvent = true; |
| | 325 | // go down and shutdown the server |
| | 326 | } |
| | 327 | |
| | 328 | sWorldSocketMgr->Wait (); |
| | 329 | |