Multiple login account support initial, needs a ton of work but can login and create account

This commit is contained in:
KimLS 2017-11-14 21:42:14 -08:00
parent da163be8db
commit 6b70faf141
18 changed files with 198 additions and 359 deletions

View File

@ -200,15 +200,15 @@ int16 Database::CheckStatus(uint32 account_id) {
return status;
}
uint32 Database::CreateAccount(const char* name, const char* password, int16 status, uint32 lsaccount_id) {
uint32 Database::CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id) {
std::string query;
if (password)
query = StringFormat("INSERT INTO account SET name='%s', password='%s', status=%i, lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",name,password,status, lsaccount_id);
query = StringFormat("INSERT INTO account SET name='%s', password='%s', status=%i, ls_id='%s', lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();", name, password, status, loginserver, lsaccount_id);
else
query = StringFormat("INSERT INTO account SET name='%s', status=%i, lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",name, status, lsaccount_id);
query = StringFormat("INSERT INTO account SET name='%s', status=%i, ls_id='%s', lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",name, status, loginserver, lsaccount_id);
Log(Logs::General, Logs::World_Server, "Account Attempting to be created: '%s' status: %i", name, status);
Log(Logs::General, Logs::World_Server, "Account Attempting to be created: '%s:%s' status: %i", loginserver, name, status);
auto results = QueryDatabase(query);
if (!results.Success()) {
@ -223,9 +223,9 @@ uint32 Database::CreateAccount(const char* name, const char* password, int16 sta
return results.LastInsertedID();
}
bool Database::DeleteAccount(const char* name) {
std::string query = StringFormat("DELETE FROM account WHERE name='%s';",name);
Log(Logs::General, Logs::World_Server, "Account Attempting to be deleted:'%s'", name);
bool Database::DeleteAccount(const char *loginserver, const char* name) {
std::string query = StringFormat("DELETE FROM account WHERE name='%s' AND ls_id='%s'", name, loginserver);
Log(Logs::General, Logs::World_Server, "Account Attempting to be deleted:'%s:%s'", loginserver, name);
auto results = QueryDatabase(query);
if (!results.Success()) {
@ -921,18 +921,6 @@ bool Database::SetVariable(const std::string varname, const std::string &varvalu
return true;
}
uint32 Database::GetMiniLoginAccount(char* ip)
{
std::string query = StringFormat("SELECT `id` FROM `account` WHERE `minilogin_ip` = '%s'", ip);
auto results = QueryDatabase(query);
if (!results.Success())
return 0;
auto row = results.begin();
return atoi(row[0]);
}
// Get zone starting points from DB
bool Database::GetSafePoints(const char* short_name, uint32 version, float* safe_x, float* safe_y, float* safe_z, int16* minstatus, uint8* minlevel, char *flag_needed) {
@ -1194,9 +1182,10 @@ bool Database::AddToNameFilter(const char* name) {
return true;
}
uint32 Database::GetAccountIDFromLSID(uint32 iLSID, char* oAccountName, int16* oStatus) {
uint32 Database::GetAccountIDFromLSID(const std::string& iLoginServer, uint32 iLSID, char* oAccountName, int16* oStatus) {
uint32 account_id = 0;
std::string query = StringFormat("SELECT id, name, status FROM account WHERE lsaccount_id=%i", iLSID);
//iLoginServer is set by config so don't need to worry about escaping it.
std::string query = StringFormat("SELECT id, name, status FROM account WHERE lsaccount_id=%i AND ls_id='%s'", iLSID, iLoginServer.c_str());
auto results = QueryDatabase(query);
if (!results.Success()) {
@ -1431,9 +1420,9 @@ uint32 Database::GetCharacterInfo(const char* iName, uint32* oAccID, uint32* oZo
return charid;
}
bool Database::UpdateLiveChar(char* charname,uint32 lsaccount_id) {
bool Database::UpdateLiveChar(char* charname, uint32 account_id) {
std::string query = StringFormat("UPDATE account SET charname='%s' WHERE id=%i;",charname, lsaccount_id);
std::string query = StringFormat("UPDATE account SET charname='%s' WHERE id=%i;", charname, account_id);
auto results = QueryDatabase(query);
if (!results.Success()){

View File

@ -174,18 +174,17 @@ public:
/* Account Related */
bool DeleteAccount(const char* name);
bool DeleteAccount(const char *loginserver, const char* name);
bool GetLiveChar(uint32 account_id, char* cname);
bool SetAccountStatus(const char* name, int16 status);
bool SetLocalPassword(uint32 accid, const char* password);
bool UpdateLiveChar(char* charname, uint32 lsaccount_id);
bool UpdateLiveChar(char* charname, uint32 account_id);
int16 CheckStatus(uint32 account_id);
uint32 CheckLogin(const char* name, const char* password, int16* oStatus = 0);
uint32 CreateAccount(const char* name, const char* password, int16 status, uint32 lsaccount_id = 0);
uint32 GetAccountIDFromLSID(uint32 iLSID, char* oAccountName = 0, int16* oStatus = 0);
uint32 GetMiniLoginAccount(char* ip);
uint32 CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id);
uint32 GetAccountIDFromLSID(const std::string& iLoginServer, uint32 iLSID, char* oAccountName = 0, int16* oStatus = 0);
uint8 GetAgreementFlag(uint32 acctid);
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);

View File

@ -70,6 +70,10 @@ void EQEmuConfig::do_world(TiXmlElement *ele)
if (text) {
LoginLegacy = atoi(text) > 0 ? true : false;
}
text = ParseTextBlock(sub_ele, "name", true);
if (text) {
LoginName = text;
}
text = ParseTextBlock(sub_ele, "account", true);
if (text) {
LoginAccount = text;
@ -97,6 +101,10 @@ void EQEmuConfig::do_world(TiXmlElement *ele)
if (text) {
loginconfig->LoginLegacy = atoi(text) > 0 ? true : false;
}
text = ParseTextBlock(sub_ele, "name", true);
if (text) {
loginconfig->LoginName = text;
}
text = ParseTextBlock(sub_ele, "account", true);
if (text) {
loginconfig->LoginAccount = text;
@ -394,6 +402,9 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
if (var_name == "LoginLegacy") {
return (itoa(LoginLegacy ? 1 : 0));
}
if (var_name == "LoginName") {
return LoginName;
}
if (var_name == "Locked") {
return (Locked ? "true" : "false");
}
@ -526,6 +537,7 @@ void EQEmuConfig::Dump() const
std::cout << "LoginPassword = " << LoginPassword << std::endl;
std::cout << "LoginPort = " << LoginPort << std::endl;
std::cout << "LoginLegacy = " << LoginLegacy << std::endl;
std::cout << "LoginName = " << LoginName << std::endl;
std::cout << "Locked = " << Locked << std::endl;
std::cout << "WorldTCPPort = " << WorldTCPPort << std::endl;
std::cout << "WorldIP = " << WorldIP << std::endl;

View File

@ -27,6 +27,7 @@ struct LoginConfig {
std::string LoginPassword;
uint16 LoginPort;
bool LoginLegacy;
std::string LoginName;
};
class EQEmuConfig : public XMLParser
@ -44,6 +45,7 @@ class EQEmuConfig : public XMLParser
std::string LoginPassword;
uint16 LoginPort;
bool LoginLegacy;
std::string LoginName;
uint32 LoginCount;
LinkedList<LoginConfig*> loginlist;
bool Locked;
@ -134,6 +136,7 @@ class EQEmuConfig : public XMLParser
LoginHost = "login.eqemulator.net";
LoginPort = 5998;
LoginLegacy = false;
LoginName = "eqemu";
// World
Locked = false;
WorldTCPPort = 9000;

View File

@ -395,7 +395,7 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) {
if (app->size != sizeof(LoginInfo_Struct)) {
return false;
}
LoginInfo_Struct *li=(LoginInfo_Struct *)app->pBuffer;
// Quagmire - max len for name is 18, pass 15
@ -405,60 +405,25 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) {
strn0cpy(password, (char*)&(li->login_info[strlen(name)+1]), 15);
if (strlen(password) <= 1) {
// TODO: Find out how to tell the client wrong username/password
Log(Logs::Detail, Logs::World_Server,"Login without a password");
Log(Logs::Detail, Logs::World_Server, "Login without a password");
return false;
}
is_player_zoning=(li->zoning==1);
is_player_zoning = (li->zoning == 1);
#ifdef IPBASED_AUTH_HACK
struct in_addr tmpip;
tmpip.s_addr = ip;
#endif
uint32 id=0;
bool minilogin = loginserverlist.MiniLogin();
if(minilogin){
struct in_addr miniip;
miniip.s_addr = ip;
id = database.GetMiniLoginAccount(inet_ntoa(miniip));
}
else if(strncasecmp(name, "LS#", 3) == 0)
id=atoi(&name[3]);
else if(database.GetAccountIDByName(name)){
int16 status = 0;
uint32 lsid = 0;
id = database.GetAccountIDByName(name, &status, &lsid);
}
else
id=atoi(name);
if (loginserverlist.Connected() == false && !is_player_zoning) {
Log(Logs::General, Logs::World_Server,"Error: Login server login while not connected to login server.");
uint32 id = atoi(name);
if (id == 0) {
Log(Logs::General, Logs::World_Server, "Login ID is 0, disconnecting.");
return false;
}
if (((cle = client_list.CheckAuth(name, password)) || (cle = client_list.CheckAuth(id, password))))
{
if (cle->AccountID() == 0 || (!minilogin && cle->LSID()==0)) {
Log(Logs::General, Logs::World_Server,"ID is 0. Is this server connected to minilogin?");
if (!minilogin) {
Log(Logs::General, Logs::World_Server, "If so you forget the minilogin variable...");
}
else {
Log(Logs::General, Logs::World_Server, "Could not find a minilogin account, verify ip address logging into minilogin is the same that is in your account table.");
}
return false;
}
if(minilogin){
cle->SetOnline();
WorldConfig::DisableStats();
Log(Logs::General, Logs::World_Server, "MiniLogin Account #%d",cle->AccountID());
}
else if (!is_player_zoning) {
if (cle = client_list.CheckAuth(id, password)) {
if (!is_player_zoning) {
// Track who is in and who is out of the game
char *inout= (char *) "";
if (cle->GetOnline() == CLE_Status_Never){
if (cle->GetOnline() == CLE_Status_Never) {
// Desktop -> Char Select
inout = (char *) "In";
}
@ -466,7 +431,7 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) {
// Game -> Char Select
inout=(char *) "Out";
}
// Always at Char select at this point.
// Either from a fresh client launch or coming back from the game.
// Exiting the game entirely does not come through here.
@ -480,10 +445,10 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) {
else {
cle->SetOnline();
}
const WorldConfig *Config=WorldConfig::get();
if(Config->UpdateStats){
if(Config->UpdateStats) {
auto pack = new ServerPacket;
pack->opcode = ServerOP_LSPlayerJoinWorld;
pack->size = sizeof(ServerLSPlayerJoinWorld_Struct);
@ -495,10 +460,10 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) {
loginserverlist.SendPacket(pack);
safe_delete(pack);
}
if (!is_player_zoning)
SendGuildList();
SendLogServer();
SendApproveWorld();
SendEnterWorld(cle->name());
@ -509,18 +474,13 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) {
database.LoginIP(cle->AccountID(), long2ip(GetIP()).c_str());
}
cle->SetIP(GetIP());
return true;
}
else {
// TODO: Find out how to tell the client wrong username/password
Log(Logs::Detail, Logs::World_Server,"Bad/Expired session key '%s'",name);
return false;
}
if (!cle)
return true;
cle->SetIP(GetIP());
return true;
}
bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app)

View File

@ -31,7 +31,7 @@ extern LoginServerList loginserverlist;
extern ClientList client_list;
extern volatile bool RunLoops;
ClientListEntry::ClientListEntry(uint32 in_id, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin, uint32 ip, uint8 local)
ClientListEntry::ClientListEntry(const char* iLoginServer, uint32 in_id, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin, uint32 ip, uint8 local)
: id(in_id)
{
ClearVars(true);
@ -39,9 +39,10 @@ ClientListEntry::ClientListEntry(uint32 in_id, uint32 iLSID, const char* iLoginN
pIP = ip;
pLSID = iLSID;
if(iLSID > 0)
paccountid = database.GetAccountIDFromLSID(iLSID, paccountname, &padmin);
paccountid = database.GetAccountIDFromLSID(iLoginServer, iLSID, paccountname, &padmin);
strn0cpy(plsname, iLoginName, sizeof(plsname));
strn0cpy(plskey, iLoginKey, sizeof(plskey));
strn0cpy(pLoginServer, iLoginServer, sizeof(pLoginServer));
pworldadmin = iWorldAdmin;
plocal=(local==1);
@ -52,27 +53,6 @@ ClientListEntry::ClientListEntry(uint32 in_id, uint32 iLSID, const char* iLoginN
memset(pLFGComments, 0, 64);
}
ClientListEntry::ClientListEntry(uint32 in_id, uint32 iAccID, const char* iAccName, MD5& iMD5Pass, int16 iAdmin)
: id(in_id)
{
ClearVars(true);
pIP = 0;
pLSID = 0;
pworldadmin = 0;
paccountid = iAccID;
strn0cpy(paccountname, iAccName, sizeof(paccountname));
pMD5Pass = iMD5Pass;
padmin = iAdmin;
pinstance = 0;
pLFGFromLevel = 0;
pLFGToLevel = 0;
pLFGMatchFilter = false;
memset(pLFGComments, 0, 64);
}
ClientListEntry::ClientListEntry(uint32 in_id, ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline)
: id(in_id)
{
@ -278,12 +258,12 @@ bool ClientListEntry::CheckStale() {
}
bool ClientListEntry::CheckAuth(uint32 iLSID, const char* iKey) {
if (strncmp(plskey, iKey,10) == 0) {
if (paccountid == 0 && LSID()>0) {
if (strncmp(plskey, iKey, 10) == 0) {
if (paccountid == 0 && LSID() > 0) {
int16 tmpStatus = WorldConfig::get()->DefaultStatus;
paccountid = database.CreateAccount(plsname, 0, tmpStatus, LSID());
paccountid = database.CreateAccount(plsname, 0, tmpStatus, pLoginServer, LSID());
if (!paccountid) {
Log(Logs::Detail, Logs::World_Server,"Error adding local account for LS login: '%s', duplicate name?" ,plsname);
Log(Logs::Detail, Logs::World_Server,"Error adding local account for LS login: '%s:%s', duplicate name?", pLoginServer, plsname);
return false;
}
strn0cpy(paccountname, plsname, sizeof(paccountname));
@ -298,21 +278,6 @@ bool ClientListEntry::CheckAuth(uint32 iLSID, const char* iKey) {
return false;
}
bool ClientListEntry::CheckAuth(const char* iName, MD5& iMD5Password) {
if (LSAccountID() == 0 && strcmp(paccountname, iName) == 0 && pMD5Pass == iMD5Password)
return true;
return false;
}
bool ClientListEntry::CheckAuth(uint32 id, const char* iKey, uint32 ip) {
if (pIP==ip && strncmp(plskey, iKey,10) == 0){
paccountid = id;
database.GetAccountFromID(id,paccountname,&padmin);
return true;
}
return false;
}
void ClientListEntry::ProcessTellQueue()
{
if (!Server())

View File

@ -21,8 +21,7 @@ struct ServerClientList_Struct;
class ClientListEntry {
public:
ClientListEntry(uint32 id, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0);
ClientListEntry(uint32 id, uint32 iAccID, const char* iAccName, MD5& iMD5Pass, int16 iAdmin = 0);
ClientListEntry(const char* iLoginServer, uint32 id, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0);
ClientListEntry(uint32 id, ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline);
~ClientListEntry();
bool CheckStale();
@ -30,8 +29,6 @@ public:
void LSUpdate(ZoneServer* zoneserver);
void LSZoneChange(ZoneToZone_Struct* ztz);
bool CheckAuth(uint32 iLSID, const char* key);
bool CheckAuth(const char* iName, MD5& iMD5Password);
bool CheckAuth(uint32 id, const char* key, uint32 ip);
void SetOnline(ZoneServer* iZS, int8 iOnline);
void SetOnline(int8 iOnline = CLE_Status_Online);
void SetChar(uint32 iCharID, const char* iCharName);
@ -45,6 +42,7 @@ public:
void Camp(ZoneServer* iZS = 0);
// Login Server stuff
inline const char* LoginServer() const { return pLoginServer; }
inline uint32 LSID() const { return pLSID; }
inline uint32 LSAccountID() const { return pLSID; }
inline const char* LSName() const { return plsname; }
@ -97,6 +95,7 @@ private:
uint8 stale;
// Login Server stuff
char pLoginServer[64]; //Loginserver we came from.
uint32 pLSID;
char plsname[32];
char plskey[16];

View File

@ -349,8 +349,8 @@ void ClientList::SendCLEList(const int16& admin, const char* to, WorldTCPConnect
}
void ClientList::CLEAdd(uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin, uint32 ip, uint8 local) {
auto tmp = new ClientListEntry(GetNextCLEID(), iLSID, iLoginName, iLoginKey, iWorldAdmin, ip, local);
void ClientList::CLEAdd(const char* iLoginServer, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin, uint32 ip, uint8 local) {
auto tmp = new ClientListEntry(iLoginServer, GetNextCLEID(), iLSID, iLoginName, iLoginKey, iWorldAdmin, ip, local);
clientlist.Append(tmp);
}
@ -410,18 +410,6 @@ void ClientList::CLEKeepAlive(uint32 numupdates, uint32* wid) {
}
}
ClientListEntry* ClientList::CheckAuth(uint32 id, const char* iKey, uint32 ip ) {
LinkedListIterator<ClientListEntry*> iterator(clientlist);
iterator.Reset();
while(iterator.MoreElements()) {
if (iterator.GetData()->CheckAuth(id, iKey, ip))
return iterator.GetData();
iterator.Advance();
}
return 0;
}
ClientListEntry* ClientList::CheckAuth(uint32 iLSID, const char* iKey) {
LinkedListIterator<ClientListEntry*> iterator(clientlist);
@ -434,31 +422,6 @@ ClientListEntry* ClientList::CheckAuth(uint32 iLSID, const char* iKey) {
return 0;
}
ClientListEntry* ClientList::CheckAuth(const char* iName, const char* iPassword) {
LinkedListIterator<ClientListEntry*> iterator(clientlist);
MD5 tmpMD5(iPassword);
iterator.Reset();
while(iterator.MoreElements()) {
if (iterator.GetData()->CheckAuth(iName, tmpMD5))
return iterator.GetData();
iterator.Advance();
}
int16 tmpadmin;
//Log.LogDebugType(Logs::Detail, Logs::World_Server,"Login with '%s' and '%s'", iName, iPassword);
uint32 accid = database.CheckLogin(iName, iPassword, &tmpadmin);
if (accid) {
uint32 lsid = 0;
database.GetAccountIDByName(iName, &tmpadmin, &lsid);
auto tmp = new ClientListEntry(GetNextCLEID(), lsid, iName, tmpMD5, tmpadmin, 0, 0);
clientlist.Append(tmp);
return tmp;
}
return 0;
}
void ClientList::SendOnlineGuildMembers(uint32 FromID, uint32 GuildID)
{
int PacketLength = 8;

View File

@ -51,8 +51,6 @@ public:
void ClientUpdate(ZoneServer* zoneserver, ServerClientList_Struct* scl);
void CLERemoveZSRef(ZoneServer* iZS);
ClientListEntry* CheckAuth(uint32 iLSID, const char* iKey);
ClientListEntry* CheckAuth(const char* iName, const char* iPassword);
ClientListEntry* CheckAuth(uint32 id, const char* iKey, uint32 ip);
ClientListEntry* FindCharacter(const char* name);
ClientListEntry* FindCLEByAccountID(uint32 iAccID);
ClientListEntry* FindCLEByCharacterID(uint32 iCharID);
@ -63,7 +61,7 @@ public:
void EnforceSessionLimit(uint32 iLSAccountID);
void CLCheckStale();
void CLEKeepAlive(uint32 numupdates, uint32* wid);
void CLEAdd(uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0);
void CLEAdd(const char* iLoginServer, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0);
void UpdateClientGuild(uint32 char_id, uint32 guild_id);
int GetClientCount();

View File

@ -15,17 +15,18 @@ extern ZSList zoneserver_list;
extern LoginServerList loginserverlist;
struct EQ::Net::ConsoleLoginStatus CheckLogin(const std::string& username, const std::string& password) {
//TODO REIMPLEMENT
struct EQ::Net::ConsoleLoginStatus ret;
ret.account_id = database.CheckLogin(username.c_str(), password.c_str());
if (ret.account_id == 0) {
return ret;
}
char account_name[64];
database.GetAccountName(ret.account_id, account_name);
ret.account_name = account_name;
ret.status = database.CheckStatus(ret.account_id);
//ret.account_id = database.CheckLogin(username.c_str(), password.c_str());
//if (ret.account_id == 0) {
// return ret;
//}
//
//char account_name[64];
//database.GetAccountName(ret.account_id, account_name);
//
//ret.account_name = account_name;
//ret.status = database.CheckStatus(ret.account_id);
return ret;
}
@ -379,21 +380,23 @@ void ConsoleFlag(EQ::Net::ConsoleServerConnection* connection, const std::string
}
void ConsoleSetPass(EQ::Net::ConsoleServerConnection* connection, const std::string& command, const std::vector<std::string>& args) {
if (args.size() != 2) {
connection->SendLine("Format: setpass accountname password");
}
else {
int16 tmpstatus = 0;
uint32 tmpid = database.GetAccountIDByName(args[0].c_str(), &tmpstatus);
if (!tmpid)
connection->SendLine("Error: Account not found");
else if (tmpstatus > connection->Admin())
connection->SendLine("Cannot change password: Account's status is higher than yours");
else if (database.SetLocalPassword(tmpid, args[1].c_str()))
connection->SendLine("Password changed.");
else
connection->SendLine("Error changing password.");
}
//TODO: REIMPLEMENT
//if (args.size() != 2) {
// connection->SendLine("Format: setpass accountname password");
//}
//else {
// int16 tmpstatus = 0;
// uint32 tmpid = database.GetAccountIDByName(args[0].c_str(), &tmpstatus);
// if (!tmpid)
// connection->SendLine("Error: Account not found");
// else if (tmpstatus > connection->Admin())
// connection->SendLine("Cannot change password: Account's status is higher than yours");
// else if (database.SetLocalPassword(tmpid, args[1].c_str()))
// connection->SendLine("Password changed.");
// else
// connection->SendLine("Error changing password.");
//}
}
void ConsoleVersion(EQ::Net::ConsoleServerConnection* connection, const std::string& command, const std::vector<std::string>& args) {

View File

@ -41,14 +41,15 @@ extern uint32 numzones;
extern uint32 numplayers;
extern volatile bool RunLoops;
LoginServer::LoginServer(const char* iAddress, uint16 iPort, const char* Account, const char* Password, bool legacy)
LoginServer::LoginServer(const char *Name, const char* iAddress, uint16 iPort, const char* Account, const char* Password, bool legacy)
{
strn0cpy(LoginServerAddress, iAddress, 256);
LoginServerPort = iPort;
strn0cpy(LoginAccount, Account, 31);
strn0cpy(LoginPassword, Password, 31);
LoginAccount = Account;
LoginPassword = Password;
CanAccountUpdate = false;
IsLegacy = legacy;
LoginName = Name;
Connect();
}
@ -60,7 +61,7 @@ void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) {
Log(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode);
UsertoWorldRequest_Struct* utwr = (UsertoWorldRequest_Struct*)p.Data();
uint32 id = database.GetAccountIDFromLSID(utwr->lsaccountid);
uint32 id = database.GetAccountIDFromLSID(LoginName, utwr->lsaccountid);
int16 status = database.CheckStatus(id);
auto outpack = new ServerPacket;
@ -110,7 +111,7 @@ void LoginServer::ProcessLSClientAuth(uint16_t opcode, EQ::Net::Packet &p) {
client_list.EnforceSessionLimit(slsca.lsaccount_id);
}
client_list.CLEAdd(slsca.lsaccount_id, slsca.name, slsca.key, slsca.worldadmin, slsca.ip, slsca.local);
client_list.CLEAdd(LoginName.c_str(), slsca.lsaccount_id, slsca.name, slsca.key, slsca.worldadmin, slsca.ip, slsca.local);
}
catch (std::exception &ex) {
LogF(Logs::General, Logs::Error, "Error parsing LSClientAuth packet from world.\n{0}", ex.what());
@ -154,19 +155,6 @@ void LoginServer::ProcessLSAccountUpdate(uint16_t opcode, EQ::Net::Packet &p) {
}
bool LoginServer::Connect() {
std::string tmp;
if (database.GetVariable("loginType", tmp) && strcasecmp(tmp.c_str(), "MinILogin") == 0) {
minilogin = true;
Log(Logs::Detail, Logs::World_Server, "Setting World to MiniLogin Server type");
}
else
minilogin = false;
if (minilogin && WorldConfig::get()->WorldAddress.length() == 0) {
Log(Logs::Detail, Logs::World_Server, "**** For minilogin to work, you need to set the <address> element in the <world> section.");
return false;
}
char errbuf[1024];
if ((LoginServerIP = ResolveIP(LoginServerAddress, errbuf)) == 0) {
Log(Logs::Detail, Logs::World_Server, "Unable to resolve '%s' to an IP.", LoginServerAddress);
@ -183,10 +171,7 @@ bool LoginServer::Connect() {
legacy_client->OnConnect([this](EQ::Net::ServertalkLegacyClient *client) {
if (client) {
Log(Logs::Detail, Logs::World_Server, "Connected to Legacy Loginserver: %s:%d", LoginServerAddress, LoginServerPort);
if (minilogin)
SendInfo();
else
SendNewInfo();
SendInfo();
SendStatus();
zoneserver_list.SendLSZones();
@ -212,10 +197,7 @@ bool LoginServer::Connect() {
client->OnConnect([this](EQ::Net::ServertalkClient *client) {
if (client) {
Log(Logs::Detail, Logs::World_Server, "Connected to Loginserver: %s:%d", LoginServerAddress, LoginServerPort);
if (minilogin)
SendInfo();
else
SendNewInfo();
SendInfo();
SendStatus();
zoneserver_list.SendLSZones();
@ -238,28 +220,10 @@ bool LoginServer::Connect() {
return true;
}
void LoginServer::SendInfo() {
const WorldConfig *Config = WorldConfig::get();
auto pack = new ServerPacket;
pack->opcode = ServerOP_LSInfo;
pack->size = sizeof(ServerLSInfo_Struct);
pack->pBuffer = new uchar[pack->size];
memset(pack->pBuffer, 0, pack->size);
ServerLSInfo_Struct* lsi = (ServerLSInfo_Struct*)pack->pBuffer;
strcpy(lsi->protocolversion, EQEMU_PROTOCOL_VERSION);
strcpy(lsi->serverversion, LOGIN_VERSION);
strcpy(lsi->name, Config->LongName.c_str());
strcpy(lsi->account, LoginAccount);
strcpy(lsi->password, LoginPassword);
strcpy(lsi->address, Config->WorldAddress.c_str());
SendPacket(pack);
delete pack;
}
void LoginServer::SendNewInfo() {
const WorldConfig *Config = WorldConfig::get();
auto pack = new ServerPacket;
pack->opcode = ServerOP_NewLSInfo;
pack->size = sizeof(ServerNewLSInfo_Struct);
@ -270,8 +234,8 @@ void LoginServer::SendNewInfo() {
strcpy(lsi->serverversion, LOGIN_VERSION);
strcpy(lsi->name, Config->LongName.c_str());
strcpy(lsi->shortname, Config->ShortName.c_str());
strcpy(lsi->account, LoginAccount);
strcpy(lsi->password, LoginPassword);
strn0cpy(lsi->account, LoginAccount.c_str(), 30);
strn0cpy(lsi->password, LoginPassword.c_str(), 30);
if (Config->WorldAddress.length())
strcpy(lsi->remote_address, Config->WorldAddress.c_str());
if (Config->LocalAddress.length())
@ -310,8 +274,8 @@ void LoginServer::SendAccountUpdate(ServerPacket* pack) {
ServerLSAccountUpdate_Struct* s = (ServerLSAccountUpdate_Struct *)pack->pBuffer;
if (CanUpdate()) {
Log(Logs::Detail, Logs::World_Server, "Sending ServerOP_LSAccountUpdate packet to loginserver: %s:%d", LoginServerAddress, LoginServerPort);
strn0cpy(s->worldaccount, LoginAccount, 30);
strn0cpy(s->worldpassword, LoginPassword, 30);
strn0cpy(s->worldaccount, LoginAccount.c_str(), 30);
strn0cpy(s->worldpassword, LoginPassword.c_str(), 30);
SendPacket(pack);
}
}

View File

@ -31,19 +31,17 @@
class LoginServer{
public:
LoginServer(const char*, uint16, const char*, const char*, bool legacy);
LoginServer(const char *, const char*, uint16, const char*, const char*, bool legacy);
~LoginServer();
bool Connect();
void SendInfo();
void SendNewInfo();
void SendStatus();
void SendPacket(ServerPacket* pack) { if (IsLegacy) legacy_client->SendPacket(pack); else client->SendPacket(pack); }
void SendAccountUpdate(ServerPacket* pack);
bool Connected() { return IsLegacy ? legacy_client->Connected() : client->Connected(); }
bool MiniLogin() { return minilogin; }
bool CanUpdate() { return CanAccountUpdate; }
private:
@ -54,16 +52,16 @@ private:
void ProcessLSRemoteAddr(uint16_t opcode, EQ::Net::Packet &p);
void ProcessLSAccountUpdate(uint16_t opcode, EQ::Net::Packet &p);
bool minilogin;
std::unique_ptr<EQ::Net::ServertalkClient> client;
std::unique_ptr<EQ::Net::ServertalkLegacyClient> legacy_client;
std::unique_ptr<EQ::Timer> statusupdate_timer;
char LoginServerAddress[256];
uint32 LoginServerIP;
uint16 LoginServerPort;
char LoginAccount[32];
char LoginPassword[32];
std::string LoginAccount;
std::string LoginPassword;
bool CanAccountUpdate;
bool IsLegacy;
std::string LoginName;
};
#endif

View File

@ -49,9 +49,9 @@ LoginServerList::LoginServerList() {
LoginServerList::~LoginServerList() {
}
void LoginServerList::Add(const char* iAddress, uint16 iPort, const char* Account, const char* Password, bool Legacy)
void LoginServerList::Add(const char* Name, const char* iAddress, uint16 iPort, const char* Account, const char* Password, bool Legacy)
{
auto loginserver = new LoginServer(iAddress, iPort, Account, Password, Legacy);
auto loginserver = new LoginServer(Name, iAddress, iPort, Account, Password, Legacy);
m_list.push_back(std::unique_ptr<LoginServer>(loginserver));
}
@ -63,14 +63,6 @@ bool LoginServerList::SendInfo() {
return true;
}
bool LoginServerList::SendNewInfo() {
for (auto &iter : m_list) {
(*iter).SendNewInfo();
}
return true;
}
bool LoginServerList::SendStatus() {
for (auto &iter : m_list) {
(*iter).SendStatus();
@ -118,16 +110,6 @@ bool LoginServerList::AllConnected() {
return true;
}
bool LoginServerList::MiniLogin() {
for (auto &iter : m_list) {
if ((*iter).MiniLogin()) {
return true;
}
}
return false;
}
bool LoginServerList::CanUpdate() {
for (auto &iter : m_list) {
if ((*iter).CanUpdate()) {

View File

@ -15,17 +15,15 @@ public:
LoginServerList();
~LoginServerList();
void Add(const char*, uint16, const char*, const char*, bool);
void Add(const char*, const char*, uint16, const char*, const char*, bool);
bool SendInfo();
bool SendNewInfo();
bool SendStatus();
bool SendPacket(ServerPacket *pack);
bool SendAccountUpdate(ServerPacket *pack);
bool Connected();
bool AllConnected();
bool MiniLogin();
bool CanUpdate();
size_t GetServerCount() const { return m_list.size(); }

View File

@ -157,7 +157,7 @@ int main(int argc, char** argv) {
// add login server config to list
if (Config->LoginCount == 0) {
if (Config->LoginHost.length()) {
loginserverlist.Add(Config->LoginHost.c_str(), Config->LoginPort, Config->LoginAccount.c_str(), Config->LoginPassword.c_str(), Config->LoginLegacy);
loginserverlist.Add(Config->LoginName.c_str(), Config->LoginHost.c_str(), Config->LoginPort, Config->LoginAccount.c_str(), Config->LoginPassword.c_str(), Config->LoginLegacy);
Log(Logs::General, Logs::World_Server, "Added loginserver %s:%i", Config->LoginHost.c_str(), Config->LoginPort);
}
}
@ -166,7 +166,7 @@ int main(int argc, char** argv) {
LinkedListIterator<LoginConfig*> iterator(loginlist);
iterator.Reset();
while (iterator.MoreElements()) {
loginserverlist.Add(iterator.GetData()->LoginHost.c_str(), iterator.GetData()->LoginPort, iterator.GetData()->LoginAccount.c_str(), iterator.GetData()->LoginPassword.c_str(),
loginserverlist.Add(iterator.GetData()->LoginName.c_str(), iterator.GetData()->LoginHost.c_str(), iterator.GetData()->LoginPort, iterator.GetData()->LoginAccount.c_str(), iterator.GetData()->LoginPassword.c_str(),
iterator.GetData()->LoginLegacy);
Log(Logs::General, Logs::World_Server, "Added loginserver %s:%i", iterator.GetData()->LoginHost.c_str(), iterator.GetData()->LoginPort);
iterator.Advance();
@ -213,23 +213,24 @@ int main(int argc, char** argv) {
}
}
else if (strcasecmp(argv[1], "adduser") == 0) {
if (argc == 5) {
if (Seperator::IsNumber(argv[4])) {
if (atoi(argv[4]) >= 0 && atoi(argv[4]) <= 255) {
if (database.CreateAccount(argv[2], argv[3], atoi(argv[4])) == 0) {
std::cerr << "database.CreateAccount failed." << std::endl;
return 1;
}
else {
std::cout << "Account created: Username='" << argv[2] << "', Password='" << argv[3] << "', status=" << argv[4] << std::endl;
return 0;
}
}
}
}
std::cout << "Usage: world adduser username password flag" << std::endl;
std::cout << "flag = 0, 1 or 2" << std::endl;
return 0;
//TODO: REIMPLEMENT
//if (argc == 5) {
// if (Seperator::IsNumber(argv[4])) {
// if (atoi(argv[4]) >= 0 && atoi(argv[4]) <= 255) {
// if (database.CreateAccount(argv[2], argv[3], atoi(argv[4])) == 0) {
// std::cerr << "database.CreateAccount failed." << std::endl;
// return 1;
// }
// else {
// std::cout << "Account created: Username='" << argv[2] << "', Password='" << argv[3] << "', status=" << argv[4] << std::endl;
// return 0;
// }
// }
// }
//}
//std::cout << "Usage: world adduser username password flag" << std::endl;
//std::cout << "flag = 0, 1 or 2" << std::endl;
//return 0;
}
else if (strcasecmp(argv[1], "flag") == 0) {
if (argc == 4) {

View File

@ -1405,6 +1405,7 @@ private:
uint32 WID;
uint32 account_id;
char account_name[30];
char loginserver[64];
uint32 lsaccountid;
char lskey[30];
int16 admin;

View File

@ -1283,16 +1283,17 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
database.LoadCharacterFactionValues(cid, factionvalues);
/* Load Character Account Data: Temp until I move */
query = StringFormat("SELECT `status`, `name`, `lsaccount_id`, `gmspeed`, `revoked`, `hideme`, `time_creation` FROM `account` WHERE `id` = %u", this->AccountID());
query = StringFormat("SELECT `status`, `name`, `ls_id`, `lsaccount_id`, `gmspeed`, `revoked`, `hideme`, `time_creation` FROM `account` WHERE `id` = %u", this->AccountID());
auto results = database.QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) {
admin = atoi(row[0]);
strncpy(account_name, row[1], 30);
lsaccountid = atoi(row[2]);
gmspeed = atoi(row[3]);
revoked = atoi(row[4]);
gm_hide_me = atoi(row[5]);
account_creation = atoul(row[6]);
strn0cpy(account_name, row[1], sizeof(account_name));
strn0cpy(loginserver, row[2], sizeof(loginserver));
lsaccountid = atoi(row[3]);
gmspeed = atoi(row[4]);
revoked = atoi(row[5]);
gm_hide_me = atoi(row[6]);
account_creation = atoul(row[7]);
}
/* Load Character Data */

View File

@ -1957,31 +1957,33 @@ void command_shutdown(Client *c, const Seperator *sep)
void command_delacct(Client *c, const Seperator *sep)
{
if(sep->arg[1][0] == 0)
c->Message(0, "Format: #delacct accountname");
else
if (database.DeleteAccount(sep->arg[1]))
c->Message(0, "The account was deleted.");
else
c->Message(0, "Unable to delete account.");
//TODO: REIMPLEMENT
// if(sep->arg[1][0] == 0)
// c->Message(0, "Format: #delacct accountname");
// else
// if (database.DeleteAccount(sep->arg[1]))
// c->Message(0, "The account was deleted.");
// else
// c->Message(0, "Unable to delete account.");
}
void command_setpass(Client *c, const Seperator *sep)
{
if(sep->argnum != 2)
c->Message(0, "Format: #setpass accountname password");
else {
int16 tmpstatus = 0;
uint32 tmpid = database.GetAccountIDByName(sep->arg[1], &tmpstatus);
if (!tmpid)
c->Message(0, "Error: Account not found");
else if (tmpstatus > c->Admin())
c->Message(0, "Cannot change password: Account's status is higher than yours");
else if (database.SetLocalPassword(tmpid, sep->arg[2]))
c->Message(0, "Password changed.");
else
c->Message(0, "Error changing password.");
}
//TODO: REIMPLEMENT
//if(sep->argnum != 2)
// c->Message(0, "Format: #setpass accountname password");
//else {
// int16 tmpstatus = 0;
// uint32 tmpid = database.GetAccountIDByName(sep->arg[1], &tmpstatus);
// if (!tmpid)
// c->Message(0, "Error: Account not found");
// else if (tmpstatus > c->Admin())
// c->Message(0, "Cannot change password: Account's status is higher than yours");
// else if (database.SetLocalPassword(tmpid, sep->arg[2]))
// c->Message(0, "Password changed.");
// else
// c->Message(0, "Error changing password.");
//}
}
void command_setlsinfo(Client *c, const Seperator *sep)
@ -4414,41 +4416,42 @@ void command_uptime(Client *c, const Seperator *sep)
void command_flag(Client *c, const Seperator *sep)
{
if(sep->arg[2][0] == 0) {
if (!c->GetTarget() || (c->GetTarget() && c->GetTarget() == c)) {
c->UpdateAdmin();
c->Message(0, "Refreshed your admin flag from DB.");
} else if (c->GetTarget() && c->GetTarget() != c && c->GetTarget()->IsClient()) {
c->GetTarget()->CastToClient()->UpdateAdmin();
c->Message(0, "%s's admin flag has been refreshed.", c->GetTarget()->GetName());
c->GetTarget()->Message(0, "%s refreshed your admin flag.", c->GetName());
}
}
else if (!sep->IsNumber(1) || atoi(sep->arg[1]) < -2 || atoi(sep->arg[1]) > 255 || strlen(sep->arg[2]) == 0)
c->Message(0, "Usage: #flag [status] [acctname]");
else if (c->Admin() < commandChangeFlags) {
//this check makes banning players by less than this level
//impossible, but i'll leave it in anyways
c->Message(0, "You may only refresh your own flag, doing so now.");
c->UpdateAdmin();
}
else {
if (atoi(sep->arg[1]) > c->Admin())
c->Message(0, "You cannot set people's status to higher than your own");
else if (atoi(sep->arg[1]) < 0 && c->Admin() < commandBanPlayers)
c->Message(0, "You have too low of status to suspend/ban");
else if (!database.SetAccountStatus(sep->argplus[2], atoi(sep->arg[1])))
c->Message(0, "Unable to set GM Flag.");
else {
c->Message(0, "Set GM Flag on account.");
auto pack = new ServerPacket(ServerOP_FlagUpdate, 6);
*((uint32*) pack->pBuffer) = database.GetAccountIDByName(sep->argplus[2]);
*((int16*) &pack->pBuffer[4]) = atoi(sep->arg[1]);
worldserver.SendPacket(pack);
delete pack;
}
}
//TODO: REIMPLEMENT
// if(sep->arg[2][0] == 0) {
// if (!c->GetTarget() || (c->GetTarget() && c->GetTarget() == c)) {
// c->UpdateAdmin();
// c->Message(0, "Refreshed your admin flag from DB.");
// } else if (c->GetTarget() && c->GetTarget() != c && c->GetTarget()->IsClient()) {
// c->GetTarget()->CastToClient()->UpdateAdmin();
// c->Message(0, "%s's admin flag has been refreshed.", c->GetTarget()->GetName());
// c->GetTarget()->Message(0, "%s refreshed your admin flag.", c->GetName());
// }
// }
// else if (!sep->IsNumber(1) || atoi(sep->arg[1]) < -2 || atoi(sep->arg[1]) > 255 || strlen(sep->arg[2]) == 0)
// c->Message(0, "Usage: #flag [status] [acctname]");
//
// else if (c->Admin() < commandChangeFlags) {
////this check makes banning players by less than this level
////impossible, but i'll leave it in anyways
// c->Message(0, "You may only refresh your own flag, doing so now.");
// c->UpdateAdmin();
// }
// else {
// if (atoi(sep->arg[1]) > c->Admin())
// c->Message(0, "You cannot set people's status to higher than your own");
// else if (atoi(sep->arg[1]) < 0 && c->Admin() < commandBanPlayers)
// c->Message(0, "You have too low of status to suspend/ban");
// else if (!database.SetAccountStatus(sep->argplus[2], atoi(sep->arg[1])))
// c->Message(0, "Unable to set GM Flag.");
// else {
// c->Message(0, "Set GM Flag on account.");
// auto pack = new ServerPacket(ServerOP_FlagUpdate, 6);
// *((uint32*) pack->pBuffer) = database.GetAccountIDByName(sep->argplus[2]);
// *((int16*) &pack->pBuffer[4]) = atoi(sep->arg[1]);
// worldserver.SendPacket(pack);
// delete pack;
// }
// }
}
void command_time(Client *c, const Seperator *sep)