1 // NeLNS - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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/>.
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"
39 using namespace NLMISC
;
40 using namespace NLNET
;
47 vector
<CShard
> Shards
;
51 static string Login
, Password
, ClientApp
;
59 string server
= ConfigFile
.getVar("StartupHost").asString(0);
66 // add the default port if no port in the cfg
67 if(server
.find(':') == string::npos
)
69 sock
.connect(CInetAddress(server
));
72 nlwarning("Can't connect to web server '%s'", server
.c_str());
78 nlwarning("Can't connect to web server '%s': %s", server
.c_str(), e
.what());
92 static bool send(const string
&url
)
94 nlassert(sock
.connected());
96 string buffer
= "GET " + url
+ "\r\n";
97 uint32 size
= buffer
.size();
100 if(sock
.send((uint8
*)buffer
.c_str(), size
, false) != CSock::Ok
)
102 nlwarning ("Can't send data to the server");
109 static bool receive(string
&res
)
111 nlassert(sock
.connected());
118 if(VerboseLog
) nlinfo("Receiving");
124 if (sock
.receive((uint8
*)buf
, size
, false) == CSock::Ok
)
126 if(VerboseLog
) nlinfo("Received OK %d bytes", size
);
129 //nlinfo("block received '%s'", buf);
133 if(VerboseLog
) nlinfo("Received CLOSE %d bytes", size
);
136 //nlwarning ("server connection closed");
140 //nlinfo("all received '%s'", res.c_str());
144 string
checkLogin(const string
&login
, const string
&password
, const string
&clientApp
)
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
,
166 ClientApp
= clientApp
;
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");
183 return "Can't receive (error code 3)";
185 if(VerboseLog
) nlinfo("Received request login check");
188 return "Empty answer from server (error code 4)";
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);
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
++)
223 explode(lines
[i
], string("|"), res
);
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());
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]));
245 // server returns ???
246 nlwarning("%s", res
.c_str());
252 ClientApp
= clientApp
;
257 string
selectShard(uint32 shardId
, string
&cookie
, string
&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)";
276 return "Can't receive (error code 12)";
279 return "Empty result (error code 13)";
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
292 explode(res
, string(" "), line
, true);
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);
305 // server returns ???
306 nlwarning("%s", res
.c_str());