Merge branch '164-crash-on-patching-and-possibly-right-after-login' into 'main/atys...
[ryzomcore.git] / nelns / login_system / nel_launcher_windows_ext2 / connection.cpp
blob4a935c8b13d3290fbb0d409f018c69982bf06624
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/>.
18 // Includes
21 #include "std_afx.h"
23 #include <nel/misc/md5.h>
24 #include <nel/misc/debug.h>
25 #include <nel/misc/path.h>
26 #include <nel/misc/thread.h>
27 #include <nel/net/tcp_sock.h>
28 #include <nel/net/login_client.h>
30 #include "nel_launcher_dlg.h"
31 #include "connection.h"
35 // Namespaces
38 using namespace std;
39 using namespace NLMISC;
40 using namespace NLNET;
44 // Variables
47 vector<CShard> Shards;
49 static CTcpSock sock;
51 static string Login, Password, ClientApp;
54 // Functions
57 static bool connect()
59 string server = ConfigFile.getVar("StartupHost").asString(0);
61 if(sock.connected())
62 return true;
64 try
66 // add the default port if no port in the cfg
67 if(server.find(':') == string::npos)
68 server+=":80";
69 sock.connect(CInetAddress(server));
70 if(!sock.connected())
72 nlwarning("Can't connect to web server '%s'", server.c_str());
73 goto end;
76 catch(Exception &e)
78 nlwarning("Can't connect to web server '%s': %s", server.c_str(), e.what());
79 goto end;
82 return true;
84 end:
86 if(sock.connected())
87 sock.close ();
89 return false;
92 static bool send(const string &url)
94 nlassert(sock.connected());
96 string buffer = "GET " + url + "\r\n";
97 uint32 size = buffer.size();
98 if(!url.empty())
100 if(sock.send((uint8 *)buffer.c_str(), size, false) != CSock::Ok)
102 nlwarning ("Can't send data to the server");
103 return false;
106 return true;
109 static bool receive(string &res)
111 nlassert(sock.connected());
113 uint32 size;
114 res = "";
116 uint8 buf[1024];
118 if(VerboseLog) nlinfo("Receiving");
120 while (true)
122 size = 1023;
124 if (sock.receive((uint8*)buf, size, false) == CSock::Ok)
126 if(VerboseLog) nlinfo("Received OK %d bytes", size);
127 buf[1023] = '\0';
128 res += (char*)buf;
129 //nlinfo("block received '%s'", buf);
131 else
133 if(VerboseLog) nlinfo("Received CLOSE %d bytes", size);
134 buf[size] = '\0';
135 res += (char*)buf;
136 //nlwarning ("server connection closed");
137 break;
140 //nlinfo("all received '%s'", res.c_str());
141 return true;
144 string checkLogin(const string &login, const string &password, const string &clientApp)
146 Shards.clear();
147 Login = Password = ClientApp = "";
149 if (ConfigFile.getVar("UseDirectClient").asBool())
151 ucstring pwd = ucstring(password);
152 CHashKeyMD5 hk = getMD5((uint8*)pwd.c_str(), pwd.size());
153 string cpwd = hk.toString();
154 nlinfo("The crypted password is %s", cpwd.c_str());
155 string result = CLoginClient::authenticate(ConfigFile.getVar("StartupHost").asString(), login, cpwd, clientApp);
156 if (!result.empty()) return result;
157 for(uint i = 0; i < CLoginClient::ShardList.size(); ++i)
159 nldebug("Shard '%u' '%s' '%u'", CLoginClient::ShardList[i].Id, CLoginClient::ShardList[i].Name.toString().c_str(), CLoginClient::ShardList[i].NbPlayers);
160 Shards.push_back(CShard("1", true,
161 CLoginClient::ShardList[i].Id, CLoginClient::ShardList[i].Name.toString(), CLoginClient::ShardList[i].NbPlayers,
162 "1", "1"));
164 Login = login;
165 Password = password;
166 ClientApp = clientApp;
167 return "";
170 if(!connect())
171 return "Can't connect (error code 1)";
173 if(VerboseLog) nlinfo("Connected");
175 if(!send(ConfigFile.getVar("StartupPage").asString()+"?login="+login+"&password="+password+"&clientApplication="+clientApp))
176 return "Can't send (error code 2)";
178 if(VerboseLog) nlinfo("Sent request login check");
180 string res;
182 if(!receive(res))
183 return "Can't receive (error code 3)";
185 if(VerboseLog) nlinfo("Received request login check");
187 if(res.empty())
188 return "Empty answer from server (error code 4)";
190 if(res[0] == '0')
192 // server returns an error
193 nlwarning("server error: %s", res.substr(2).c_str());
194 return res.substr(2);
196 else if(res[0] == '1')
198 // server returns ok, we have the list of shard
199 uint nbs = atoi(res.substr(2).c_str());
200 vector<string> lines;
202 explode(res, string("\n"), lines, true);
204 if(VerboseLog)
206 nlinfo ("Exploded, with nl, %d res", lines.size());
207 /* for (uint i = 0; i < lines.size(); i++)
209 nlinfo (" > '%s'", lines[i].c_str());
213 if(lines.size() != nbs+1)
215 nlwarning("bad shard lines number %d != %d", lines.size(), nbs+1);
216 nlwarning("'%s'", res.c_str());
217 return "bad lines numbers (error code 5)";
220 for(uint i = 1; i < lines.size(); i++)
222 vector<string> res;
223 explode(lines[i], string("|"), res);
225 if(VerboseLog)
227 nlinfo ("Exploded with '%s', %d res", "|", res.size());
228 /* for (uint i = 0; i < res.size(); i++)
230 nlinfo (" > '%s'", res[i].c_str());
234 if(res.size() != 7)
236 nlwarning("bad | numbers %d != %d", res.size(), 7);
237 nlwarning("'%s'", lines[i].c_str());
238 return "bad pipe numbers (error code 6)";
240 Shards.push_back(CShard(res[0], atoi(res[1].c_str())>0, atoi(res[2].c_str()), res[3], atoi(res[4].c_str()), res[5], res[6]));
243 else
245 // server returns ???
246 nlwarning("%s", res.c_str());
247 return res;
250 Login = login;
251 Password = password;
252 ClientApp = clientApp;
254 return "";
257 string selectShard(uint32 shardId, string &cookie, string &addr)
259 cookie = addr = "";
261 if (ConfigFile.getVar("UseDirectClient").asBool())
262 return CLoginClient::wantToConnectToShard(shardId, addr, cookie);
264 if(!connect()) return "Can't connect (error code 7)";
266 if(Login.empty()) return "Empty Login (error code 8)";
267 if(Password.empty()) return "Empty Password (error code 9)";
268 if(ClientApp.empty()) return "Empty Client Application (error code 10)";
270 if(!send(ConfigFile.getVar("StartupPage").asString()+"?cmd=login&shardid="+toString(shardId)+"&login="+Login+"&password="+Password+"&clientApplication="+ClientApp))
271 return "Can't send (error code 11)";
273 string res;
275 if(!receive(res))
276 return "Can't receive (error code 12)";
278 if(res.empty())
279 return "Empty result (error code 13)";
281 if(res[0] == '0')
283 // server returns an error
284 nlwarning("server error: %s", res.substr(2).c_str());
285 return res.substr(2);
287 else if(res[0] == '1')
289 // server returns ok, we have the access
291 vector<string> line;
292 explode(res, string(" "), line, true);
294 if(line.size() != 2)
296 nlwarning("bad launch lines number %d != %d", line.size(), 2);
297 return "bad launch line number (error code 14)";
300 cookie = line[0].substr(2);
301 addr = line[1];
303 else
305 // server returns ???
306 nlwarning("%s", res.c_str());
307 return res;
310 return "";