/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU 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 General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /****************************************************************************** * * FILE * $Archive: /Commando/Code/WWOnline/WOLLoginInfo.cpp $ * * DESCRIPTION * LoginInfo encapsulates a user's persona login information. * LoginInfo handles the storage/retrival of nicknames/passwords also. * * PROGRAMMER * $Author: Denzil_l $ * * VERSION INFO * $Revision: 15 $ * $Modtime: 1/18/02 11:50p $ * ******************************************************************************/ #include #include "WOLLoginInfo.h" #include "WOLSession.h" #include #include namespace WOL { #include } namespace WWOnline { #define MAX_NICKNAMES 32 LoginInfoList LoginInfo::_mLoginList; /****************************************************************************** * * NAME * LoginInfo::GetList * * DESCRIPTION * Get a list of all the cached WWOnline logins. * * INPUTS * NONE * * RESULT * LoginList - List to populate with WWOnline logins. * ******************************************************************************/ const LoginInfoList& LoginInfo::GetList(void) { if (_mLoginList.empty()) { RefPtr session = Session::GetInstance(false); if (session.IsValid() && session->IsStoreLoginAllowed()) { // Four logins allowed per user _mLoginList.reserve(4); const CComPtr& chat = session->GetChatObject(); for (int index = 1; index <= MAX_NICKNAMES; ++index) { const char* nickname = NULL; const char* password = NULL; chat->GetNick(index, &nickname, &password); if (nickname && (strlen(nickname) > 0)) { RefPtr login = Create(nickname, password, true); if (login.IsValid()) { WOL::Locale locale = WOL::LOC_UNKNOWN; chat->GetNickLocale(index, &locale); login->SetLocale(locale); login->mIsStored = true; _mLoginList.push_back(login); } } } } } return _mLoginList; } /****************************************************************************** * * NAME * LoginInfo::ClearList * * DESCRIPTION * * INPUTS * NONE * * RESULT * NONE * ******************************************************************************/ void LoginInfo::ClearList(void) { _mLoginList.clear(); } /****************************************************************************** * * NAME * LoginInfo::Find * * DESCRIPTION * Search for a login with a specified nickname. * * INPUTS * Nickname - Nickname of login to search for. * * RESULT * Login - Login matching specified name; if available. * ******************************************************************************/ RefPtr LoginInfo::Find(const wchar_t* name) { if (name) { const LoginInfoList& list = GetList(); const unsigned int count = list.size(); for (unsigned int index = 0; index < count; ++index) { RefPtr login = list[index]; WWASSERT(login.IsValid()); const WideStringClass& nickname = login->GetNickname(); if (nickname.Compare_No_Case(name) == 0) { return login; } } } return NULL; } RefPtr LoginInfo::Find(const char* nickname) { WideStringClass wideNickname(0, true); wideNickname = nickname; return Find(wideNickname); } /****************************************************************************** * * NAME * LoginInfo::Create * * DESCRIPTION * Create a login info instance * * INPUTS * Nickname - Login username * Password - Login password * IsEncrypted - True if the password is encrypted. * * RESULT * LoginInfo - Instance of newly created login information. * ******************************************************************************/ RefPtr LoginInfo::Create(const wchar_t* nickname, const wchar_t* password, bool isEncrypted) { if (nickname && (wcslen(nickname) > 0)) { return new LoginInfo(nickname, password, isEncrypted); } return NULL; } RefPtr LoginInfo::Create(const char* nickname, const char* password, bool isEncrypted) { if (nickname && (strlen(nickname) > 0)) { WideStringClass name(0, true); name = nickname; WideStringClass pass(0, true); pass = password; return new LoginInfo(name, pass, isEncrypted); } return NULL; } /****************************************************************************** * * NAME * LoginInfo::LoginInfo * * DESCRIPTION * Constructor * * INPUTS * Nickname - Login username * Password - Login password * IsEncrypted - True if the password is encrypted. * * RESULT * NONE * ******************************************************************************/ LoginInfo::LoginInfo(const wchar_t* nickname, const wchar_t* password, bool isEncrypted) : mNickname(nickname), mPassword(password), mLocale(WOL::LOC_UNKNOWN), mIsPasswordEncrypted(isEncrypted), mIsStored(false) { WWDEBUG_SAY(("WOL: Instantiating LoginInfo %S\n", (const WCHAR*)mNickname)); if (mNickname.Get_Length() > 9) { mNickname[9] = 0; } } /****************************************************************************** * * NAME * LoginInfo::~LoginInfo * * DESCRIPTION * Destructor * * INPUTS * * RESULT * ******************************************************************************/ LoginInfo::~LoginInfo() { WWDEBUG_SAY(("WOL: Destructing LoginInfo %S\n", (const WCHAR*)mNickname)); } /****************************************************************************** * * NAME * LoginInfo::SetPassword * * DESCRIPTION * Set the password for this login. * * INPUTS * Password - New password * Encrypted - True if password is encrypted. * * RESULT * NONE * ******************************************************************************/ void LoginInfo::SetPassword(const wchar_t* password, bool isEncrypted) { if (password != NULL) { mPassword = password; mIsPasswordEncrypted = isEncrypted; } else { mPassword = L""; mIsPasswordEncrypted = false; } } /****************************************************************************** * * NAME * LoginInfo::SetLocale * * DESCRIPTION * Set the locale for this login. * * INPUTS * Locale - New locale. * * RESULT * NONE * ******************************************************************************/ void LoginInfo::SetLocale(WOL::Locale locale) { mLocale = locale; int index = IndexOf(); if (index != 0) { RefPtr session = Session::GetInstance(false); if (session.IsValid() && session->IsStoreLoginAllowed()) { const CComPtr& chat = session->GetChatObject(); WWASSERT(chat); chat->SetNickLocale(index, locale); } } } /****************************************************************************** * * NAME * LoginInfo::GetLocale * * DESCRIPTION * Returns the current locale for this login. * * INPUTS * NONE * * RESULT * Locale - Locale for this login. * ******************************************************************************/ WOL::Locale LoginInfo::GetLocale(void) { if (mLocale == WOL::LOC_UNKNOWN) { int index = IndexOf(); if (index != 0) { RefPtr session = Session::GetInstance(false); if (session.IsValid()) { const CComPtr& chat = session->GetChatObject(); WWASSERT(chat); chat->GetNickLocale(index, &mLocale); } } } return mLocale; } /****************************************************************************** * * NAME * LoginInfo::Remember * * DESCRIPTION * Remember this login. If the store flag is true then the login is written * to disk for retrieval in later sessions. * * INPUTS * Store - True to store this login to the disk. * * RESULT * NONE * ******************************************************************************/ void LoginInfo::Remember(bool store) { if (store) { mIsStored = true; int index = IndexOf(); if (index == 0) { StringClass name(64, true); mNickname.Convert_To(name); StringClass pass(64, true); mPassword.Convert_To(pass); // Store login information into the registry StoreLogin(name.Peek_Buffer(), pass.Peek_Buffer(), mIsPasswordEncrypted, mLocale); } } // If the login is not in the list then add it now. bool found = false; LoginInfoList::iterator iter = _mLoginList.begin(); while (iter != _mLoginList.end()) { if (iter->ReferencedObject() == this) { found = true; break; } iter++; } if (!found) { _mLoginList.push_back(this); } } /****************************************************************************** * * NAME * LoginInfo::Forget * * DESCRIPTION * Forget about this login. If the purge flag is true then the login * is deleted from disk. * * INPUTS * Purge - True to purge this login from the disk. * * RESULT * NONE * ******************************************************************************/ void LoginInfo::Forget(bool purge) { if (purge) { mIsStored = false; // Remove login for the persist cache RefPtr session = Session::GetInstance(false); if (session.IsValid() && session->IsStoreLoginAllowed()) { int index = IndexOf(); if (index != 0) { const CComPtr& chat = session->GetChatObject(); chat->SetNick(index, "", "", false); chat->SetNickLocale(index, WOL::LOC_UNKNOWN); } } } // Remove login from the list LoginInfoList::iterator iter = _mLoginList.begin(); while (iter != _mLoginList.end()) { if (iter->ReferencedObject() == this) { _mLoginList.erase(iter); break; } iter++; } } /****************************************************************************** * * NAME * LoginInfo::IndexOf * * DESCRIPTION * * INPUTS * * RESULT * ******************************************************************************/ int LoginInfo::IndexOf(const wchar_t* nick) { RefPtr session = Session::GetInstance(false); if (session.IsValid()) { char username[64]; wcstombs(username, nick, sizeof(username)); const CComPtr& chat = session->GetChatObject(); for (int index = 1; index <= MAX_NICKNAMES; ++index) { const char* nickname = NULL; const char* password = NULL; HRESULT result = chat->GetNick(index, &nickname, &password); if (SUCCEEDED(result)) { if (nickname && (strlen(nickname) > 0) && (stricmp(username, nickname) == 0)) { return index; } } } } return 0; } /****************************************************************************** * * NAME * LoginInfo::IndexOf * * DESCRIPTION * * INPUTS * NONE * * RESULT * Index - * ******************************************************************************/ int LoginInfo::IndexOf(void) const { return IndexOf(mNickname); } /****************************************************************************** * * NAME * LoginInfo::StoreLogin * * DESCRIPTION * Store login information. * * INPUTS * Nickname - Login nickname * Password - Login password * IsPassEncrytped - True if the password is already encrypted. * * RESULT * NONE * ******************************************************************************/ void LoginInfo::StoreLogin(const char* nickname, const char* password, bool isPasswordEncrypted, WOL::Locale locale) { RefPtr session = Session::GetInstance(false); if (session.IsValid() && session->IsStoreLoginAllowed()) { const CComPtr& chat = session->GetChatObject(); // Find the next empty slot for (int index = 1; index <= MAX_NICKNAMES; ++index) { const char* slotNick = NULL; const char* slotPass = NULL; chat->GetNick(index, &slotNick, &slotPass); if ((slotNick == NULL) || strlen(slotNick) == 0) { break; } } if (index > MAX_NICKNAMES) { // All slots taken! Kill the last one index = MAX_NICKNAMES; } chat->SetNick(index, nickname, password, !isPasswordEncrypted); chat->SetNickLocale(index, locale); } } } // namespace WWOnline