| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610 |
- /*
- ** 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 <http://www.gnu.org/licenses/>.
- */
- /******************************************************************************
- *
- * FILE
- * $Archive: /Commando/Code/Commando/WOLQuickMatch.cpp $
- *
- * DESCRIPTION
- *
- * PROGRAMMER
- * $Author: Denzil_l $
- *
- * VERSION INFO
- * $Revision: 37 $
- * $Modtime: 2/20/02 5:30p $
- *
- ******************************************************************************/
- #include "WOLQuickMatch.h"
- #include <WWOnline\PingProfile.h>
- #include <WWOnline\WaitCondition.h>
- #include <WWOnline\WOLProduct.h>
- #include <WWOnline\WOLConnect.h>
- #include <WWOnline\WOLServer.h>
- #include <WWOnline\WOLLadder.h>
- #include <WWLib\CPUDetect.h>
- #include <WWDebug\WWDebug.h>
- #include "cnetwork.h"
- #include "translatedb.h"
- #include "string_ids.h"
- using namespace WWOnline;
- typedef void (*QMDispatchFunc)(WOLQuickMatch*, const wchar_t*);
- struct QMResponseDispatch
- {
- const wchar_t* Token;
- QMDispatchFunc Dispatch;
- };
- #define QUICKMATCH_CHANNELNAME L"lob_39_0"
- #define QUICKMATCH_BOTNAME L"matchbot"
- /******************************************************************************
- *
- * NAME
- * WOLQuickMatch::Create
- *
- * DESCRIPTION
- * Create an instance to a quickmatch game matcher.
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * Quickmatch - Quickmatch instance.
- *
- ******************************************************************************/
- WOLQuickMatch* WOLQuickMatch::Create(void)
- {
- WOLQuickMatch* match = new WOLQuickMatch;
- if (match)
- {
- if (match->FinalizeCreate())
- {
- return match;
- }
- match->Release_Ref();
- }
- return NULL;
- }
- /******************************************************************************
- *
- * NAME
- * WOLQuickMatch::WOLQuickMatch
- *
- * DESCRIPTION
- * Default constructor
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- WOLQuickMatch::WOLQuickMatch()
- {
- WWDEBUG_SAY(("WOLQuickMatch: Instantiating\n"));
- }
- /******************************************************************************
- *
- * NAME
- * WOLQuickMatch::~WOLQuickMatch
- *
- * DESCRIPTION
- * Destructor
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- WOLQuickMatch::~WOLQuickMatch()
- {
- WWDEBUG_SAY(("WOLQuickMatch: Destructing\n"));
- }
- /******************************************************************************
- *
- * NAME
- * WOLQuickMatch::FinalizeCreate
- *
- * DESCRIPTION
- * Creation initializaton / finalization
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * Success - True if successful
- *
- ******************************************************************************/
- bool WOLQuickMatch::FinalizeCreate(void)
- {
- mWOLSession = Session::GetInstance(false);
- if (!mWOLSession.IsValid())
- {
- WWDEBUG_SAY(("WOLQuickMatch: ERROR - WWOnline not instantiated\n"));
- return false;
- }
- return true;
- }
- /******************************************************************************
- *
- * NAME
- * WOLQuickMatch::ConnectClient
- *
- * DESCRIPTION
- * Connect a game client to the quickmatch bot.
- *
- * INPUTS
- * ChannelName - Name of matching channel
- * BotName - Name of matching bot
- *
- * RESULT
- * Wait - Wait condition to process.
- *
- ******************************************************************************/
- RefPtr<WaitCondition> WOLQuickMatch::ConnectClient(void)
- {
- WWDEBUG_SAY(("WOLQuickMatch: Connecting client to '%S' '%S'\n",
- QUICKMATCH_CHANNELNAME, QUICKMATCH_BOTNAME));
- // Make sure that we are logged on to WWOnline
- if (mWOLSession->GetConnectionStatus() != ConnectionConnected)
- {
- WWDEBUG_SAY(("WOLQuickMatch: ERROR - Not connected to WWOnline server\n"));
- RefPtr<SingleWait> wait = SingleWait::Create(TRANSLATE(IDS_WOL_CONNECTING));
- wait->EndWait(WaitCondition::Error, TRANSLATE(IDS_WOL_NOTCONNECTED));
- return wait;
- }
- // Generate client connect wait condition
- RefPtr<SerialWait> connectWait = SerialWait::Create();
- if (connectWait.IsValid())
- {
- Observer<ServerError>::NotifyMe(*mWOLSession);
- Observer<ChatMessage>::NotifyMe(*mWOLSession);
- // Request channel list
- RefPtr<WaitCondition> channelListWait = mWOLSession->GetNewChatChannelList();
- connectWait->Add(channelListWait);
- // Join the matching channel
- RefPtr<Product> product = Product::Current();
- WWASSERT(product.IsValid() && "WOLProduct not initialized.");
- const wchar_t* password = product->GetChannelPassword();
- RefPtr<WaitCondition> joinWait = mWOLSession->JoinChannel(QUICKMATCH_CHANNELNAME, password, 0);
- connectWait->Add(joinWait);
- // Make sure the matching bot is there.
- RefPtr<WaitCondition> findBotWait = GetUserWait::Create(mWOLSession, QUICKMATCH_BOTNAME);
- connectWait->Add(findBotWait);
- }
- return connectWait;
- }
- /******************************************************************************
- *
- * NAME
- * WOLQuickMatch::Disconnect
- *
- * DESCRIPTION
- * Disconnect from quickmatch
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * Wait - Disconnect wait condition to process.
- *
- ******************************************************************************/
- RefPtr<WaitCondition> WOLQuickMatch::Disconnect(void)
- {
- WWDEBUG_SAY(("WOLQuickMatch: Disconnecting\n"));
- Observer<ServerError>::StopObserving();
- Observer<ChatMessage>::StopObserving();
- // If we are in the matching channel then disconnect.
- RefPtr<ChannelData> channel = mWOLSession->GetCurrentChannel();
- if (channel.IsValid())
- {
- const WideStringClass& name = channel->GetName();
- if (name.Compare_No_Case(QUICKMATCH_CHANNELNAME) == 0)
- {
- return mWOLSession->LeaveChannel();
- }
- }
- return NULL;
- }
- /******************************************************************************
- *
- * NAME
- * WOLQuickMatch::SendClientInfo
- *
- * DESCRIPTION
- * Send client matching preferences to the quickmatch bot.
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * True if successful.
- *
- ******************************************************************************/
- bool WOLQuickMatch::SendClientInfo(void)
- {
- unsigned long ver = cNetwork::Get_Exe_Key();
- // Get CPU speed
- int speed = CPUDetectClass::Get_Processor_Speed();
- // Get amount of physical memory
- MEMORYSTATUS memStatus;
- GlobalMemoryStatus(&memStatus);
- unsigned long memory = (memStatus.dwTotalPhys / 1048576);
- //-------------------------------------------------------------------------
- // Gather pings
- //-------------------------------------------------------------------------
- const PingProfile& pings = GetLocalPingProfile();
- char pseudoPings[18] = {0};
- EncodePingProfile(pings, pseudoPings);
- //-------------------------------------------------------------------------
- // Get clients ladder points
- //-------------------------------------------------------------------------
- RefPtr<UserData> client = mWOLSession->GetCurrentUser();
- WWASSERT(client.IsValid());
- if (client.IsValid() == false)
- {
- return false;
- }
- int tpoints = 0;
- unsigned int played = 0;
- RefPtr<LadderData> ladder = client->GetTeamLadder();
- if (ladder.IsValid())
- {
- tpoints = ladder->GetPoints();
- played = ladder->GetReserved2();
- }
- //-------------------------------------------------------------------------
- // Generate client information message
- //-------------------------------------------------------------------------
- WideStringClass clientMsg(256, true);
- clientMsg.Format(L"CINFO VER=%lu CPU=%lu MEM=%lu TPOINTS=%ld PLAYED=%lu PINGS=%S",
- ver, speed, memory, tpoints, played, pseudoPings);
- WWDEBUG_SAY(("WOLQuickMatch: '%S'\n", (const WCHAR*)clientMsg));
- return mWOLSession->SendPrivateMessage(QUICKMATCH_BOTNAME, (const WCHAR*)clientMsg);
- }
- /******************************************************************************
- *
- * NAME
- * WOLQuickMatch::SendServerInfo
- *
- * DESCRIPTION
- * Send information describing the game,
- *
- * INPUTS
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- void WOLQuickMatch::SendServerInfo(const char* exInfo, const char* topic)
- {
- if (exInfo && topic)
- {
- #pragma message(__FILE__" *** HACK ALERT *** SINFO msg is imitating WOLAPI IRC topic!")
- // *** WARNING *** DANGER *** HACK ALERT ****
- //
- // The SINFO message sent to the matching bot is assembled in such
- // a way as to imitate the IRC topic string that WOLAPI produces.
- WideStringClass botMsg(0, true);
- botMsg.Format(L"SINFO %S%S", exInfo, topic);
- WWDEBUG_SAY(("WOLQuickMatch: '%S'\n", (const WCHAR*)botMsg));
- mWOLSession->SendPrivateMessage(QUICKMATCH_BOTNAME, botMsg);
- }
- }
- /******************************************************************************
- *
- * NAME
- * WOLQuickMatch::SendStatus
- *
- * DESCRIPTION
- *
- * INPUTS
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- void WOLQuickMatch::SendStatus(const wchar_t* statusMsg)
- {
- WWDEBUG_SAY(("WOLQuickMatch: Status '%S'\n", statusMsg));
- WideStringClass msg(256, true);
- msg = statusMsg;
- QuickMatchEvent status(QuickMatchEvent::QMMSG, msg);
- NotifyObservers(status);
- }
- /******************************************************************************
- *
- * NAME
- * WOLQuickMatch::ParseResponse
- *
- * DESCRIPTION
- * Handle response messages from the quickmatch bot.
- *
- * INPUTS
- * Message - Response message from quickmatch bot.
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- void WOLQuickMatch::ParseResponse(const wchar_t* message)
- {
- if (message)
- {
- static QMResponseDispatch _dispatch[] =
- {
- {L"INFO ", WOLQuickMatch::ProcessInfo},
- {L"ERROR ", WOLQuickMatch::ProcessError},
- {L"START ", WOLQuickMatch::ProcessStart},
- {NULL, WOLQuickMatch::ProcessUnknown}
- };
- int index = 0;
- const wchar_t* token = _dispatch[index].Token;
- while (token)
- {
- // Find the first occurance of the token in the message
- wchar_t* cmd = wcsstr(message, token);
- // If the token was found and it is at the start of the message
- // then return the type of message this is.
- if (cmd && cmd == message)
- {
- const wchar_t* data = (message + wcslen(token));
- _dispatch[index].Dispatch(this, data);
- }
- index++;
- token = _dispatch[index].Token;
- }
- }
- }
- /******************************************************************************
- *
- * NAME
- * WOLQuickMatch::ProcessInfo
- *
- * DESCRIPTION
- * Process information messages.
- *
- * INPUTS
- * Message -
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- void WOLQuickMatch::ProcessInfo(WOLQuickMatch* quickmatch, const wchar_t* data)
- {
- WideStringClass msg(255, true);
- msg = data;
- QuickMatchEvent status(QuickMatchEvent::QMINFO, msg);
- quickmatch->NotifyObservers(status);
- }
- /******************************************************************************
- *
- * NAME
- * WOLQuickMatch::ProcessError
- *
- * DESCRIPTION
- * Process error messages from the quickmatch bot.
- *
- * INPUTS
- * Message - Error message
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- void WOLQuickMatch::ProcessError(WOLQuickMatch* quickmatch, const wchar_t* data)
- {
- WideStringClass msg(255, true);
- msg = data;
- QuickMatchEvent status(QuickMatchEvent::QMERROR, msg);
- quickmatch->NotifyObservers(status);
- }
- /******************************************************************************
- *
- * NAME
- * WOLQuickMatch::ProcessStart
- *
- * DESCRIPTION
- * Process start message from the quickmatch bot.
- *
- * INPUTS
- * Data - Start game parameters
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- void WOLQuickMatch::ProcessStart(WOLQuickMatch* quickmatch, const wchar_t* data)
- {
- // Send message indicating successful match
- WideStringClass msg(255, true);
- msg.Format(TRANSLATE(IDS_MENU_QM_MATCHED_WITH), data);
- QuickMatchEvent status(QuickMatchEvent::QMMSG, msg);
- quickmatch->NotifyObservers(status);
- // Send message that we are matched.
- msg = data;
- QuickMatchEvent matchedEvent(QuickMatchEvent::QMMATCHED, msg);
- quickmatch->NotifyObservers(matchedEvent);
- }
- /******************************************************************************
- *
- * NAME
- * WOLQuickMatch::ProcessUnknown
- *
- * DESCRIPTION
- * Process unknown messages from the quickmatch bot.
- *
- * INPUTS
- * Message - Unknown message
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- void WOLQuickMatch::ProcessUnknown(WOLQuickMatch* quickmatch, const wchar_t* data)
- {
- WideStringClass msg(255, true);
- msg = data;
- QuickMatchEvent status(QuickMatchEvent::QMUNKNOWN, msg);
- quickmatch->NotifyObservers(status);
- }
- /******************************************************************************
- *
- * NAME
- * WOLQuickMatch::HandleNotification(ServerError)
- *
- * DESCRIPTION
- * Handle server errors.
- *
- * INPUTS
- * Error - Server error
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- void WOLQuickMatch::HandleNotification(ServerError& error)
- {
- const wchar_t* errorMsg = error.GetDescription();
- WWDEBUG_SAY(("WOLQuickMatch: ERROR - ServerError '%S'\n", errorMsg));
- QuickMatchEvent status(QuickMatchEvent::QMERROR, errorMsg);
- NotifyObservers(status);
- }
- /******************************************************************************
- *
- * NAME
- * WOLQuickMatch::HandleNotification(ChatMessageEvent)
- *
- * DESCRIPTION
- * Handle private messages coming from the matchbot.
- *
- * INPUTS
- * Message - Chat message
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- void WOLQuickMatch::HandleNotification(ChatMessage& message)
- {
- const WideStringClass& sender = message.GetSendersName();
- if (sender.Compare_No_Case(QUICKMATCH_BOTNAME) == 0)
- {
- WWDEBUG_SAY(("WOLQuickMatch: BotMsg - '%S'\n", message.GetMessage()));
- ParseResponse(message.GetMessage());
- }
- }
|