236 lines
7.1 KiB
C++
236 lines
7.1 KiB
C++
/*
|
|
** 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/>.
|
|
*/
|
|
|
|
/***********************************************************************************************
|
|
*** Confidential - Westwood Studios ***
|
|
***********************************************************************************************
|
|
* *
|
|
* Project Name : Commando *
|
|
* *
|
|
* $Archive:: /Commando/Code/Commando/gamespyauthmgr.cpp $*
|
|
* *
|
|
* $Author:: Tom_s $*
|
|
* *
|
|
* $Modtime:: 2/22/02 5:41p $*
|
|
* *
|
|
* $Revision:: 3 $*
|
|
* *
|
|
*---------------------------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
#include "gamespyauthmgr.h"
|
|
|
|
#include "gamespyscchallengeevent.h"
|
|
#include "playermanager.h"
|
|
#include "cnetwork.h"
|
|
#include "gamespyadmin.h"
|
|
#include "cdkeyauth.h"
|
|
#include "sctextobj.h"
|
|
#include "translatedb.h"
|
|
#include "string_ids.h"
|
|
|
|
//
|
|
// Class statics
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
cGameSpyAuthMgr::Think
|
|
(
|
|
void
|
|
)
|
|
{
|
|
WWASSERT(cNetwork::I_Am_Server());
|
|
WWASSERT(cGameSpyAdmin::Is_Gamespy_Game());
|
|
|
|
//
|
|
// Process all the players
|
|
//
|
|
|
|
WWASSERT(cPlayerManager::Get_Player_Object_List() != NULL);
|
|
|
|
for (
|
|
SLNode<cPlayer> * player_node = cPlayerManager::Get_Player_Object_List()->Head();
|
|
player_node != NULL;
|
|
player_node = player_node->Next())
|
|
{
|
|
cPlayer * p_player = player_node->Data();
|
|
WWASSERT(p_player != NULL);
|
|
|
|
if (!p_player->Is_Alive_And_Kicking())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
switch (p_player->Get_GameSpy_Auth_State())
|
|
{
|
|
case GAMESPY_AUTH_STATE_INITIAL:
|
|
{
|
|
if (cNetwork::I_Am_Client() && p_player->Get_Id() == cNetwork::Get_My_Id())
|
|
{
|
|
//
|
|
// Do not bother authenticating the server's local client.
|
|
//
|
|
p_player->Set_GameSpy_Auth_State(GAMESPY_AUTH_STATE_ACCEPTED);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Challenge this player
|
|
//
|
|
StringClass challenge_string;
|
|
challenge_string.Format("%s", CCDKeyAuth::GenChallenge(8));
|
|
|
|
p_player->Set_GameSpy_Auth_State(GAMESPY_AUTH_STATE_CHALLENGED);
|
|
p_player->Set_GameSpy_Challenge_String(challenge_string);
|
|
|
|
cGameSpyScChallengeEvent * p_event = new cGameSpyScChallengeEvent;
|
|
p_event->Init(p_player->Get_Id(), challenge_string);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case GAMESPY_AUTH_STATE_CHALLENGED:
|
|
{
|
|
DWORD time_now_ms = TIMEGETTIME();
|
|
if (time_now_ms - p_player->Get_GameSpy_Auth_State_Entry_Time_Ms() >
|
|
CHALLENGE_RESPONSE_TIMEOUT_MS)
|
|
{
|
|
//
|
|
// We challenged this guy and he hasn't responded in the required
|
|
// time. We are going to have to boot him out.
|
|
//
|
|
int player_id = p_player->Get_Id();
|
|
|
|
WWDEBUG_SAY(("cGameSpyAuthMgr::Think: player %d timed out on challenge response.\n",
|
|
player_id));
|
|
|
|
//p_player->Set_GameSpy_Auth_State(GAMESPY_AUTH_STATE_REJECTING);
|
|
//Evict_Player(player_id);
|
|
cGameSpyAuthMgr::Initiate_Auth_Rejection(player_id);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case GAMESPY_AUTH_STATE_VALIDATING:
|
|
{
|
|
//
|
|
// At this stage I am not implementing any timeout for GameSpy to
|
|
// authenticate this user.
|
|
//
|
|
break;
|
|
}
|
|
|
|
case GAMESPY_AUTH_STATE_ACCEPTED:
|
|
{
|
|
//
|
|
// The only peaceful, harmonious state.
|
|
//
|
|
break;
|
|
}
|
|
|
|
case GAMESPY_AUTH_STATE_REJECTING:
|
|
{
|
|
DWORD time_now_ms = TIMEGETTIME();
|
|
if (time_now_ms - p_player->Get_GameSpy_Auth_State_Entry_Time_Ms() >
|
|
REJECTION_DELAY_MS)
|
|
{
|
|
p_player->Set_GameSpy_Auth_State(GAMESPY_AUTH_STATE_REJECTED);
|
|
Evict_Player(p_player->Get_Id());
|
|
}
|
|
break;
|
|
}
|
|
|
|
case GAMESPY_AUTH_STATE_REJECTED:
|
|
{
|
|
//
|
|
// Do nothing
|
|
//
|
|
break;
|
|
}
|
|
|
|
default:
|
|
DIE;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
cGameSpyAuthMgr::Initiate_Auth_Rejection
|
|
(
|
|
int player_id
|
|
)
|
|
{
|
|
WWDEBUG_SAY(("cGameSpyAuthMgr::Initiate_Auth_Rejection(%d)\n", player_id));
|
|
|
|
WWASSERT(cNetwork::I_Am_Server());
|
|
WWASSERT(cGameSpyAdmin::Is_Gamespy_Game());
|
|
|
|
cPlayer * p_player = cPlayerManager::Find_Player(player_id);
|
|
|
|
if (p_player != NULL)
|
|
{
|
|
cScTextObj * p_message = new cScTextObj;
|
|
//p_message->Init(L"CD Authentication failed. Please quit.", TEXT_MESSAGE_PRIVATE, true, HOST_TEXT_SENDER, player_id);
|
|
p_message->Init(TRANSLATE(IDS_MP_CD_AUTH_FAILED), TEXT_MESSAGE_PRIVATE, true, HOST_TEXT_SENDER, player_id);
|
|
|
|
p_player->Set_GameSpy_Auth_State(GAMESPY_AUTH_STATE_REJECTING);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
cGameSpyAuthMgr::Evict_Player
|
|
(
|
|
int player_id
|
|
)
|
|
{
|
|
WWDEBUG_SAY(("cGameSpyAuthMgr::Evict_Player(%d)\n", player_id));
|
|
|
|
WWASSERT(cNetwork::I_Am_Server());
|
|
WWASSERT(cGameSpyAdmin::Is_Gamespy_Game());
|
|
|
|
//
|
|
// The behaviour presently is fairly brutal - no feedback to evicted player.
|
|
// This is fine if he is a cracker, but other cases exist. TODO_AUTH.
|
|
//
|
|
|
|
cNetwork::Server_Kill_Connection(player_id);
|
|
cNetwork::Cleanup_After_Client(player_id);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
LPCSTR
|
|
cGameSpyAuthMgr::Describe_Auth_State
|
|
(
|
|
GAMESPY_AUTH_STATE_ENUM state
|
|
)
|
|
{
|
|
switch (state)
|
|
{
|
|
case GAMESPY_AUTH_STATE_INITIAL: return "INITIAL";
|
|
case GAMESPY_AUTH_STATE_CHALLENGED: return "CHALLENGED";
|
|
case GAMESPY_AUTH_STATE_VALIDATING: return "VALIDATING";
|
|
case GAMESPY_AUTH_STATE_ACCEPTED: return "ACCEPTED";
|
|
case GAMESPY_AUTH_STATE_REJECTING: return "REJECTING";
|
|
case GAMESPY_AUTH_STATE_REJECTED: return "REJECTED";
|
|
default: DIE; return "bollocks"; // avoid compiler warning;
|
|
}
|
|
}
|