khanat-opennel-code/code/nelns/login_system/nel_launcher_windows_ext2/connection.cpp

311 lines
7 KiB
C++

// NeLNS - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// Includes
//
#include "std_afx.h"
#include <nel/misc/md5.h>
#include <nel/misc/debug.h>
#include <nel/misc/path.h>
#include <nel/misc/thread.h>
#include <nel/net/tcp_sock.h>
#include <nel/net/login_client.h>
#include "nel_launcher_dlg.h"
#include "connection.h"
//
// Namespaces
//
using namespace std;
using namespace NLMISC;
using namespace NLNET;
//
// Variables
//
vector<CShard> Shards;
static CTcpSock sock;
static string Login, Password, ClientApp;
//
// Functions
//
static bool connect()
{
string server = ConfigFile.getVar("StartupHost").asString(0);
if(sock.connected())
return true;
try
{
// add the default port if no port in the cfg
if(server.find(':') == string::npos)
server+=":80";
sock.connect(CInetAddress(server));
if(!sock.connected())
{
nlwarning("Can't connect to web server '%s'", server.c_str());
goto end;
}
}
catch(Exception &e)
{
nlwarning("Can't connect to web server '%s': %s", server.c_str(), e.what());
goto end;
}
return true;
end:
if(sock.connected())
sock.close ();
return false;
}
static bool send(const string &url)
{
nlassert(sock.connected());
string buffer = "GET " + url + "\r\n";
uint32 size = buffer.size();
if(!url.empty())
{
if(sock.send((uint8 *)buffer.c_str(), size, false) != CSock::Ok)
{
nlwarning ("Can't send data to the server");
return false;
}
}
return true;
}
static bool receive(string &res)
{
nlassert(sock.connected());
uint32 size;
res = "";
uint8 buf[1024];
if(VerboseLog) nlinfo("Receiving");
while (true)
{
size = 1023;
if (sock.receive((uint8*)buf, size, false) == CSock::Ok)
{
if(VerboseLog) nlinfo("Received OK %d bytes", size);
buf[1023] = '\0';
res += (char*)buf;
//nlinfo("block received '%s'", buf);
}
else
{
if(VerboseLog) nlinfo("Received CLOSE %d bytes", size);
buf[size] = '\0';
res += (char*)buf;
//nlwarning ("server connection closed");
break;
}
}
//nlinfo("all received '%s'", res.c_str());
return true;
}
string checkLogin(const string &login, const string &password, const string &clientApp)
{
Shards.clear();
Login = Password = ClientApp = "";
if (ConfigFile.getVar("UseDirectClient").asBool())
{
ucstring pwd = ucstring(password);
CHashKeyMD5 hk = getMD5((uint8*)pwd.c_str(), pwd.size());
string cpwd = hk.toString();
nlinfo("The crypted password is %s", cpwd.c_str());
string result = CLoginClient::authenticate(ConfigFile.getVar("StartupHost").asString(), login, cpwd, clientApp);
if (!result.empty()) return result;
for(uint i = 0; i < CLoginClient::ShardList.size(); ++i)
{
nldebug("Shard '%u' '%s' '%u'", CLoginClient::ShardList[i].Id, CLoginClient::ShardList[i].Name.toString().c_str(), CLoginClient::ShardList[i].NbPlayers);
Shards.push_back(CShard("1", true,
CLoginClient::ShardList[i].Id, CLoginClient::ShardList[i].Name.toString(), CLoginClient::ShardList[i].NbPlayers,
"1", "1"));
}
Login = login;
Password = password;
ClientApp = clientApp;
return "";
}
if(!connect())
return "Can't connect (error code 1)";
if(VerboseLog) nlinfo("Connected");
if(!send(ConfigFile.getVar("StartupPage").asString()+"?login="+login+"&password="+password+"&clientApplication="+clientApp))
return "Can't send (error code 2)";
if(VerboseLog) nlinfo("Sent request login check");
string res;
if(!receive(res))
return "Can't receive (error code 3)";
if(VerboseLog) nlinfo("Received request login check");
if(res.empty())
return "Empty answer from server (error code 4)";
if(res[0] == '0')
{
// server returns an error
nlwarning("server error: %s", res.substr(2).c_str());
return res.substr(2);
}
else if(res[0] == '1')
{
// server returns ok, we have the list of shard
uint nbs = atoi(res.substr(2).c_str());
vector<string> lines;
explode(res, string("\n"), lines, true);
if(VerboseLog)
{
nlinfo ("Exploded, with nl, %d res", lines.size());
/* for (uint i = 0; i < lines.size(); i++)
{
nlinfo (" > '%s'", lines[i].c_str());
}*/
}
if(lines.size() != nbs+1)
{
nlwarning("bad shard lines number %d != %d", lines.size(), nbs+1);
nlwarning("'%s'", res.c_str());
return "bad lines numbers (error code 5)";
}
for(uint i = 1; i < lines.size(); i++)
{
vector<string> res;
explode(lines[i], string("|"), res);
if(VerboseLog)
{
nlinfo ("Exploded with '%s', %d res", "|", res.size());
/* for (uint i = 0; i < res.size(); i++)
{
nlinfo (" > '%s'", res[i].c_str());
}*/
}
if(res.size() != 7)
{
nlwarning("bad | numbers %d != %d", res.size(), 7);
nlwarning("'%s'", lines[i].c_str());
return "bad pipe numbers (error code 6)";
}
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]));
}
}
else
{
// server returns ???
nlwarning("%s", res.c_str());
return res;
}
Login = login;
Password = password;
ClientApp = clientApp;
return "";
}
string selectShard(uint32 shardId, string &cookie, string &addr)
{
cookie = addr = "";
if (ConfigFile.getVar("UseDirectClient").asBool())
return CLoginClient::wantToConnectToShard(shardId, addr, cookie);
if(!connect()) return "Can't connect (error code 7)";
if(Login.empty()) return "Empty Login (error code 8)";
if(Password.empty()) return "Empty Password (error code 9)";
if(ClientApp.empty()) return "Empty Client Application (error code 10)";
if(!send(ConfigFile.getVar("StartupPage").asString()+"?cmd=login&shardid="+toString(shardId)+"&login="+Login+"&password="+Password+"&clientApplication="+ClientApp))
return "Can't send (error code 11)";
string res;
if(!receive(res))
return "Can't receive (error code 12)";
if(res.empty())
return "Empty result (error code 13)";
if(res[0] == '0')
{
// server returns an error
nlwarning("server error: %s", res.substr(2).c_str());
return res.substr(2);
}
else if(res[0] == '1')
{
// server returns ok, we have the access
vector<string> line;
explode(res, string(" "), line, true);
if(line.size() != 2)
{
nlwarning("bad launch lines number %d != %d", line.size(), 2);
return "bad launch line number (error code 14)";
}
cookie = line[0].substr(2);
addr = line[1];
}
else
{
// server returns ???
nlwarning("%s", res.c_str());
return res;
}
return "";
}