Merge branch '164-crash-on-patching-and-possibly-right-after-login' into 'main/atys...
[ryzomcore.git] / nelns / login_system / nel_launcher_qt / connection.cpp
blobda487c91f7d33953e2d03247a9fd372ea79d75ae
1 #include "connection.h"
2 #include <iostream>
3 #include <nel/misc/ucstring.h>
4 #include <nel/misc/md5.h>
5 #include <nel/net/sock.h>
6 #include <nel/net/login_client.h>
8 #include "nel_launcher_dlg.h"
10 bool CNelLauncherConnection::connect()
12 std::string server = ConfigFile.getVar("StartupHost").asString(0);
14 if(m_Sock.connected())
15 return true;
17 try
19 // add the default port if no port in the cfg
20 if(server.find(':') == std::string::npos)
21 server+=":80";
22 m_Sock.connect(NLNET::CInetAddress(server));
23 if(!m_Sock.connected())
25 nlwarning("Can't connect to web server '%s'", server.c_str());
26 goto end;
29 catch(NLMISC::Exception &e)
31 nlwarning("Can't connect to web server '%s': %s", server.c_str(), e.what());
32 goto end;
35 return true;
37 end:
39 if(m_Sock.connected())
40 m_Sock.close ();
42 return false;
45 bool CNelLauncherConnection::send(const std::string &url)
47 nlassert(m_Sock.connected());
49 std::string buffer = "GET " + url + "\r\n";
50 uint32 size = buffer.size();
51 if(!url.empty())
53 if(m_Sock.send((uint8 *)buffer.c_str(), size, false) != NLNET::CSock::Ok)
55 nlwarning ("Can't send data to the server");
56 return false;
59 return true;
62 bool CNelLauncherConnection::receive(std::string &res)
64 nlassert(m_Sock.connected());
66 uint32 size;
67 res = "";
69 uint8 buf[1024];
71 //if(VerboseLog) nlinfo("Receiving");
73 while (true)
75 size = 1023;
77 if(m_Sock.receive((uint8*)buf, size, false) == NLNET::CSock::Ok)
79 //if(VerboseLog) nlinfo("Received OK %d bytes", size);
80 buf[1023] = '\0';
81 res += (char*)buf;
82 //nlinfo("block received '%s'", buf);
84 else
86 //if(VerboseLog) nlinfo("Received CLOSE %d bytes", size);
87 buf[size] = '\0';
88 res += (char*)buf;
89 //nlwarning ("server connection closed");
90 break;
94 // trim off whitespace.
95 res = NLMISC::trim(res);
96 nlinfo("all received '%s'", res.c_str());
97 return true;
100 std::string CNelLauncherConnection::checkLogin(const std::string &login, const std::string &password, const std::string &clientApp)
102 m_Shards.clear();
103 m_Login = m_Password = m_ClientApp = "";
105 if(ConfigFile.exists("UseDirectClient") && ConfigFile.getVar("UseDirectClient").asBool())
107 ucstring pwd = ucstring(password);
108 NLMISC::CHashKeyMD5 hk = NLMISC::getMD5((uint8*)pwd.c_str(), pwd.size());
109 std::string cpwd = hk.toString();
110 nlinfo("The crypted password is %s", cpwd.c_str());
111 std::string result = NLNET::CLoginClient::authenticate(ConfigFile.getVar("StartupHost").asString(), login, cpwd, clientApp);
112 if (!result.empty()) return result;
113 for(uint i = 0; i < NLNET::CLoginClient::ShardList.size(); ++i)
115 nldebug("Shard '%u' '%s' '%u'", NLNET::CLoginClient::ShardList[i].Id, NLNET::CLoginClient::ShardList[i].Name.toString().c_str(), NLNET::CLoginClient::ShardList[i].NbPlayers);
116 m_Shards.push_back(CShard("1", true,
117 NLNET::CLoginClient::ShardList[i].Id, NLNET::CLoginClient::ShardList[i].Name.toString(), NLNET::CLoginClient::ShardList[i].NbPlayers,
118 "1", "1"));
120 m_Login = login;
121 m_Password = password;
122 m_ClientApp = clientApp;
123 return "";
126 if(!connect())
127 return "Can't connect (error code 1)";
129 //if(VerboseLog) nlinfo("Connected");
131 if(!send(ConfigFile.getVar("StartupPage").asString()+"?login="+login+"&password="+password+"&clientApplication="+clientApp))
132 return "Can't send (error code 2)";
134 //if(VerboseLog) nlinfo("Sent request login check");
136 std::string res;
138 if(!receive(res))
139 return "Can't receive (error code 3)";
141 //if(VerboseLog) nlinfo("Received request login check");
143 if(res.empty())
144 return "Empty answer from server (error code 4)";
146 if(res[0] == '0')
148 // server returns an error
149 nlwarning("server error: %s", res.substr(2).c_str());
150 return res.substr(2);
152 else if(res[0] == '1')
154 // server returns ok, we have the list of shard
155 uint nbs = atoi(res.substr(2).c_str());
156 std::vector<std::string> lines;
158 NLMISC::explode(res, std::string("\n"), lines, true);
160 // if(VerboseLog)
161 // {
162 //nlinfo ("Exploded, with nl, %d res", lines.size());
163 /* for (uint i = 0; i < lines.size(); i++)
165 nlinfo (" > '%s'", lines[i].c_str());
167 // }
169 if(lines.size() != nbs+1)
171 nlwarning("bad shard lines number %d != %d", lines.size(), nbs+1);
172 nlwarning("'%s'", res.c_str());
173 return "bad lines numbers (error code 5)";
176 for(uint i = 1; i < lines.size(); i++)
178 std::vector<std::string> res;
179 NLMISC::explode(lines[i], std::string("|"), res);
181 // if(VerboseLog)
182 // {
183 // nlinfo ("Exploded with '%s', %d res", "|", res.size());
184 /* for (uint i = 0; i < res.size(); i++)
186 nlinfo (" > '%s'", res[i].c_str());
188 // }
190 if(res.size() != 7)
192 nlwarning("bad | numbers %d != %d", res.size(), 7);
193 nlwarning("'%s'", lines[i].c_str());
194 return "bad pipe numbers (error code 6)";
196 m_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]));
199 else
201 // server returns ???
202 nlwarning("%s", res.c_str());
203 return res;
206 m_Login = login;
207 m_Password = password;
208 m_ClientApp = clientApp;
210 return "";
213 std::string CNelLauncherConnection::selectShard(uint32 shardId, std::string &cookie, std::string &addr)
215 cookie = addr = "";
217 if(ConfigFile.exists("UseDirectClient") && ConfigFile.getVar("UseDirectClient").asBool())
218 return NLNET::CLoginClient::wantToConnectToShard(shardId, addr, cookie);
220 if(!connect()) return "Can't connect (error code 7)";
222 if(m_Login.empty()) return "Empty Login (error code 8)";
223 if(m_Password.empty()) return "Empty Password (error code 9)";
224 if(m_ClientApp.empty()) return "Empty Client Application (error code 10)";
226 if(!send(ConfigFile.getVar("StartupPage").asString()+"?cmd=login&shardid="+NLMISC::toString(shardId)+"&login="+m_Login+"&password="+m_Password+"&clientApplication="+m_ClientApp))
227 return "Can't send (error code 11)";
229 std::string res;
231 if(!receive(res))
232 return "Can't receive (error code 12)";
234 if(res.empty())
235 return "Empty result (error code 13)";
237 if(res[0] == '0')
239 // server returns an error
240 nlwarning("server error: %s", res.substr(2).c_str());
241 return res.substr(2);
243 else if(res[0] == '1')
245 // server returns ok, we have the access
247 std::vector<std::string> line;
248 NLMISC::explode(res, std::string(" "), line, true);
250 if(line.size() != 2)
252 nlwarning("bad launch lines number %d != %d", line.size(), 2);
253 return "bad launch line number (error code 14)";
256 cookie = line[0].substr(2);
257 addr = line[1];
259 else
261 // server returns ???
262 nlwarning("%s", res.c_str());
263 return res;
266 return "";