Use configured resolution for login/outgame/ingame
[ryzomcore.git] / nelns / login_service / login_service.cpp
blob94c280c198faa05d5ba14a14d6113aae8cc8cf7d
1 // NeLNS - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (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 Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif // HAVE_CONFIG_H
21 #ifndef NELNS_CONFIG
22 #define NELNS_CONFIG ""
23 #endif // NELNS_CONFIG
25 #ifndef NELNS_LOGS
26 #define NELNS_LOGS ""
27 #endif // NELNS_LOGS
29 #ifndef NELNS_STATE
30 #define NELNS_STATE ""
31 #endif // NELNS_STATE
33 #include "nel/misc/types_nl.h"
35 #include <cstdio>
36 #include <ctype.h>
37 #include <cmath>
39 #include <vector>
40 #include <map>
42 #include "nel/misc/debug.h"
43 #include "nel/misc/config_file.h"
44 #include "nel/misc/displayer.h"
45 #include "nel/misc/command.h"
46 #include "nel/misc/log.h"
47 #include "nel/misc/window_displayer.h"
48 #include "nel/misc/path.h"
50 #include "nel/net/service.h"
51 #include "nel/net/login_cookie.h"
53 #include "login_service.h"
54 #include "connection_client.h"
55 #include "connection_ws.h"
56 #include "connection_web.h"
57 #include "mysql_helper.h"
61 // Namespaces
64 using namespace std;
65 using namespace NLMISC;
66 using namespace NLNET;
70 // Variables
74 // store specific user information
75 NLMISC::CFileDisplayer *Fd = NULL;
76 NLMISC::CStdDisplayer Sd;
77 NLMISC::CLog *Output = NULL;
79 //uint32 CUser::NextUserId = 1; // 0 is reserved
81 //vector<CUser> Users;
82 //vector<CShard> Shards;
84 vector<CShard> Shards;
88 // Functions
91 sint findShard (sint32 shardId)
93 for (sint i = 0; i < (sint) Shards.size (); i++)
95 if (Shards[i].ShardId == shardId)
97 return i;
100 // shard not found
101 return -1;
104 sint findShardWithSId (TServiceId sid)
106 for (sint i = 0; i < (sint) Shards.size (); i++)
108 if (Shards[i].SId == sid)
110 return i;
113 // shard not found
114 return -1;
118 // transform "192.168.1.1:80" into "192.168.1.1"
119 string removePort (const string &addr)
121 return addr.substr (0, addr.find (":"));
124 void checkClients ()
126 nldebug ("checkClients ()");
127 /*for (uint i = 0; i < Users.size (); i++)
129 switch (Users[i].State)
131 case CUser::Offline:
132 nlassert (Users[i].SockId == NULL);
133 nlassert (!Users[i].Cookie.isValid());
134 nlassert (Users[i].ShardId == NULL);
135 break;
136 case CUser::Authorized:
137 nlassert (Users[i].SockId != NULL);
138 nlassert (Users[i].Cookie.isValid());
139 nlassert (Users[i].ShardId == NULL);
140 break;
141 case CUser::Awaiting:
142 nlassert (Users[i].SockId == NULL);
143 nlassert (!Users[i].Cookie.isValid());
144 nlassert (Users[i].ShardId == NULL);
145 break;
146 case CUser::Online:
147 nlassert (Users[i].SockId == NULL);
148 nlassert (!Users[i].Cookie.isValid());
149 nlassert (Users[i].ShardId != NULL);
150 break;
151 default:
152 nlstop;
153 break;
158 /*void disconnectClient (CUser &user, bool disconnectClient, bool disconnectShard)
160 nlinfo ("User %d '%s' need to be disconnect (%d %d %d)", user.Id, user.Login.c_str(), user.State, disconnectClient, disconnectShard);
162 switch (user.State)
164 case CUser::Offline:
165 break;
167 case CUser::Authorized:
168 if (disconnectClient)
170 CNetManager::getNetBase("LS")->disconnect(user.SockId);
172 user.Cookie.clear ();
173 break;
175 case CUser::Awaiting:
176 break;
178 case CUser::Online:
179 if (disconnectShard)
181 // ask the WS to disconnect the player from the shard
182 CMessage msgout (CNetManager::getNetBase("WSLS")->getSIDA (), "DC");
183 msgout.serial (user.Id);
184 CNetManager::send ("WSLS", msgout, user.ShardId);
186 user.ShardId = NULL;
187 break;
189 default:
190 nlstop;
191 break;
194 user.SockId = NULL;
195 user.State = CUser::Offline;
198 sint findUser (uint32 Id)
200 /* for (sint i = 0; i < (sint) Users.size (); i++)
202 if (Users[i].Id == Id)
204 return i;
207 // user not found
208 */ return -1;
211 string CUser::Authorize (TSockId sender, CCallbackNetBase &netbase)
213 string reason;
215 switch (State)
217 case Offline:
218 State = Authorized;
219 SockId = sender;
220 Cookie = CLoginCookie(netbase.hostAddress(sender).internalIPAddress(), Id);
221 break;
223 case Authorized:
224 nlwarning ("user %d already authorized! disconnect him and the other one", Id);
225 reason = "You are already authorized (another user uses your account?)";
226 disconnectClient (*this, true, true);
227 disconnectClient (Users[findUser(Id)], true, true);
228 break;
230 case Awaiting:
231 nlwarning ("user %d already awaiting! disconnect the new user and the other one", Id);
232 reason = "You are already awaiting (another user uses your account?)";
233 disconnectClient (*this, true, true);
234 disconnectClient (Users[findUser(Id)], true, true);
235 break;
237 case Online:
238 nlwarning ("user %d already online! disconnect the new user and the other one", Id);
239 reason = "You are already online (another user uses your account?)";
240 disconnectClient (*this, true, true);
241 disconnectClient (Users[findUser(Id)], true, true);
242 break;
244 default:
245 reason = "default case should never occurs, there's a bug in the login_service.cpp";
246 nlstop;
247 break;
249 return reason;
252 void displayShards ()
254 ICommand::execute ("shards", *InfoLog);
257 void displayUsers ()
259 ICommand::execute ("users", *InfoLog);
264 ////////////////////////////////////////////////////////////////////////////////////////////////
265 ////////////////////////////////////////////////////////////////////////////////////////////////
266 /////////////// SERVICE IMPLEMENTATION /////////////////////////////////////////////////////////
267 ////////////////////////////////////////////////////////////////////////////////////////////////
268 ////////////////////////////////////////////////////////////////////////////////////////////////
270 void beep (uint freq, uint nb, uint beepDuration, uint pauseDuration)
272 #ifdef NL_OS_WINDOWS
275 if (IService::getInstance()->ConfigFile.getVar ("Beep").asInt() == 1)
277 for (uint i = 0; i < nb; i++)
279 Beep (freq, beepDuration);
280 nlSleep (pauseDuration);
284 catch (Exception &)
287 #endif // NL_OS_WINDOWS
290 class CLoginService : public IService
292 public:
294 bool UseDirectClient;
296 CLoginService () : UseDirectClient(false) { }
298 /// Init the service, load the universal time.
299 void init ()
301 beep ();
303 Output = new CLog;
305 if(ConfigFile.exists("UseDirectClient"))
306 UseDirectClient = ConfigFile.getVar("UseDirectClient").asBool();
308 string fn = IService::getInstance()->SaveFilesDirectory;
309 fn += "login_service.stat";
310 nlinfo("Login stat in directory '%s'", fn.c_str());
311 Fd = new NLMISC::CFileDisplayer(fn);
312 Output->addDisplayer (Fd);
313 if (WindowDisplayer) Output->addDisplayer (WindowDisplayer);
315 // Initialize the database access
316 sqlInit();
318 connectionWSInit ();
320 if(UseDirectClient)
321 connectionClientInit ();
322 else
323 connectionWebInit ();
325 Output->displayNL ("Login Service initialized");
328 bool update ()
330 connectionWSUpdate ();
331 if(UseDirectClient)
332 connectionClientUpdate ();
333 else
334 connectionWebUpdate ();
335 return true;
338 /// release the service, save the universal time
339 void release ()
341 connectionWSRelease ();
342 if(UseDirectClient)
343 connectionClientRelease ();
344 else
345 connectionWebRelease ();
347 Output->displayNL ("Login Service released");
351 // Service instantiation
352 NLNET_SERVICE_MAIN (CLoginService, "LS", "login_service", 49999, EmptyCallbackArray, NELNS_CONFIG, NELNS_LOGS);
355 // Variables
358 NLMISC_DYNVARIABLE(uint, OnlineUsersNumber, "number of actually connected users")
360 // we can only read the value
361 if (get)
363 //uint32 nbusers = 0;
364 //for (uint i = 0; i < Users.size(); i++)
366 // if (Users[i].State == CUser::Online)
367 // nbusers++;
369 *pointer = NbPlayers;
374 // Commands
377 NLMISC_COMMAND (shards, "displays the list of all registered shards", "")
379 if(args.size() != 0) return false;
381 log.displayNL ("Display the %d registered shards :", Shards.size());
382 for (uint i = 0; i < Shards.size(); i++)
384 log.displayNL ("* ShardId: %d SId: %d NbPlayers: %d", Shards[i].ShardId, Shards[i].SId.get(), Shards[i].NbPlayers);
385 CUnifiedNetwork::getInstance()->displayUnifiedConnection (Shards[i].SId, &log);
387 log.displayNL ("End of the list");
389 return true;
392 NLMISC_COMMAND (shardDatabase, "displays the list of all shards in the database", "")
394 if(args.size() != 0) return false;
396 CMysqlResult result;
397 MYSQL_ROW row;
398 sint32 nbrow;
400 string reason = sqlQuery("select ShardId, WsAddr, NbPlayers, Name, Online, ClientApplication, Version, DynPatchURL from shard", nbrow, row, result);
401 if(!reason.empty()) { log.displayNL("Display registered users failed; '%s'", reason.c_str()); return true; }
403 log.displayNL("Display the %d shards in the database :", nbrow);
404 log.displayNL(" > ShardId, WsAddr, NbPlayers, Name, Online, ClientApplication, Version, DynPatchURL");
406 if (nbrow != 0) while(row != 0)
408 log.displayNL(" > '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s'", row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]);
409 row = mysql_fetch_row(result);
412 log.displayNL("End of the list");
414 return true;
417 NLMISC_COMMAND (registeredUsers, "displays the list of all registered users", "")
419 if(args.size() != 0) return false;
421 CMysqlResult result;
422 MYSQL_ROW row;
423 sint32 nbrow;
425 string reason = sqlQuery("select UId, Login, Password, ShardId, State, Privilege, ExtendedPrivilege, Cookie from user", nbrow, row, result);
426 if(!reason.empty()) { log.displayNL("Display registered users failed; '%s'", reason.c_str()); return true; }
428 log.displayNL("Display the %d registered users :", nbrow);
429 log.displayNL(" > UId, Login, Password, ShardId, State, Privilege, ExtendedPrivilege, Cookie");
431 if (nbrow != 0) while(row != 0)
433 log.displayNL(" > '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s'", row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]);
434 row = mysql_fetch_row(result);
437 log.displayNL("End of the list");
439 return true;
442 NLMISC_COMMAND (onlineUsers, "displays the list of online users", "")
444 if(args.size() != 0) return false;
446 CMysqlResult result;
447 MYSQL_ROW row;
448 sint32 nbrow;
450 uint32 nbusers = 0, nbwait = 0;
451 log.displayNL ("Display the online users :");
453 string reason = sqlQuery("select UId, Login, Password, ShardId, State, Privilege, ExtendedPrivilege, Cookie from user where State='Online'", nbrow, row, result);
454 if(!reason.empty()) { log.displayNL("Display online users failed; '%s'", reason.c_str()); return true; }
455 if (nbrow != 0) while(row != 0)
457 log.displayNL(" > '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s'", row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]);
458 row = mysql_fetch_row(result);
460 nbusers = nbrow;
462 reason = sqlQuery("select UId, Login, Password, ShardId, State, Privilege, ExtendedPrivilege, Cookie from user where State='Waiting'", nbrow, row, result);
463 if(!reason.empty()) { log.displayNL("Display waiting users failed; '%s'", reason.c_str()); return true; }
464 if (nbrow != 0) while(row != 0)
466 log.displayNL(" > '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s'", row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]);
467 row = mysql_fetch_row(result);
469 nbwait = nbrow;
471 reason = sqlQuery("select UId, Login, Password, ShardId, State, Privilege, ExtendedPrivilege, Cookie from user where State='Authorized'", nbrow, row, result);
472 if(!reason.empty()) { log.displayNL("Display authorized users failed; '%s'", reason.c_str()); return true; }
473 if (nbrow != 0) while(row != 0)
475 log.displayNL(" > '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s'", row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]);
476 row = mysql_fetch_row(result);
479 log.displayNL ("End of the list (%d online users, %d waiting, %d authorized)", nbusers, nbwait, nbrow);
481 return true;