mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2025-12-16 07:31:40 -05:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
416
Code/Commando/GameResSend.cpp
Normal file
416
Code/Commando/GameResSend.cpp
Normal file
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
** 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/GameResSend.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 25 $
|
||||
* $Modtime: 1/14/02 10:40a $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "GameResSend.h"
|
||||
#include "GameData.h"
|
||||
#include "Player.h"
|
||||
#include "consolemode.h"
|
||||
#include <Combat\PlayerType.h>
|
||||
#include <WWOnline\GameResPacket.h>
|
||||
#include <WWOnline\WOLSession.h>
|
||||
#include <WWOnline\WOLProduct.h>
|
||||
#include <WWOnline\WOLUser.h>
|
||||
#include <WWLib\CPUDetect.h>
|
||||
#include <WWLib\VerChk.h>
|
||||
#include <WWLib\CPUDetect.h>
|
||||
#include <WWLib\global.h>
|
||||
#include <WWLib\md5.h>
|
||||
#include <WW3D2\DX8Wrapper.h>
|
||||
#include <windows.h>
|
||||
|
||||
using namespace WWOnline;
|
||||
|
||||
static void AddPlayerStats(GameResPacket& stats, cPlayer* player, WOL::Locale locale,
|
||||
int winnerID, bool teamGame);
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* SendGameResults
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Send game results for ladder ranking.
|
||||
*
|
||||
* INPUTS
|
||||
* TheGame - The game played.
|
||||
* Players - List of players.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void SendGameResults(unsigned long gameID, cGameData* theGame, SList<cPlayer>* playerList)
|
||||
{
|
||||
RefPtr<WWOnline::Session> session = WWOnline::Session::GetInstance(false);
|
||||
|
||||
if (!session.IsValid())
|
||||
{
|
||||
assert(session.IsValid() && "SendGameResults() WOLSession not instantiated.");
|
||||
WWDEBUG_SAY(("ERROR: SendGameResults() WOLSession not instantiated.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Gather game information
|
||||
//---------------------------------------------------------------------------
|
||||
GameResPacket stats;
|
||||
|
||||
// Unique identifier for this game session.
|
||||
stats.Add_Field("IDNO", gameID);
|
||||
|
||||
// Product SKU
|
||||
RefPtr<Product> product = Product::Current();
|
||||
unsigned long gameSKU = product->GetSKU();
|
||||
stats.Add_Field("GSKU", gameSKU);
|
||||
|
||||
// Version of executable.
|
||||
char filename[MAX_PATH];
|
||||
GetModuleFileName(NULL, filename, sizeof(filename));
|
||||
VS_FIXEDFILEINFO version;
|
||||
GetVersionInfo(filename, &version);
|
||||
stats.Add_Field("VERS", version.dwFileVersionMS);
|
||||
|
||||
// Executable build date
|
||||
FILETIME createTime;
|
||||
GetFileCreationTime(filename, &createTime);
|
||||
|
||||
SYSTEMTIME time;
|
||||
FileTimeToSystemTime(&createTime, &time);
|
||||
|
||||
char buildDate[20];
|
||||
sprintf(buildDate, "%02d/%02d/%04d %02d:%02d:%02d",
|
||||
time.wMonth, time.wDay, time.wYear, time.wHour, time.wMinute, time.wSecond);
|
||||
stats.Add_Field("DATE", buildDate);
|
||||
|
||||
// Proocessor information
|
||||
stats.Add_Field("PROC", (char*)CPUDetectClass::Get_Processor_String());
|
||||
stats.Add_Field("PSPD", (unsigned long)CPUDetectClass::Get_Processor_Speed());
|
||||
|
||||
// Amount of system memory on server
|
||||
MEMORYSTATUS memStatus;
|
||||
GlobalMemoryStatus(&memStatus);
|
||||
stats.Add_Field("SMEM", (unsigned long)memStatus.dwTotalPhys);
|
||||
|
||||
// Video card information
|
||||
DWORD cardInfo[4];
|
||||
if (ConsoleBox.Is_Exclusive()) {
|
||||
strcpy((char*)&cardInfo[0], "ConsoleMode");
|
||||
} else {
|
||||
const D3DADAPTER_IDENTIFIER8& adapter = DX8Wrapper::Get_Current_Adapter_Identifier();
|
||||
cardInfo[0] = adapter.VendorId;
|
||||
cardInfo[1] = adapter.DeviceId;
|
||||
cardInfo[2] = adapter.SubSysId;
|
||||
cardInfo[3] = adapter.Revision;
|
||||
}
|
||||
stats.Add_Field("SVID", (void*)cardInfo, sizeof(cardInfo));
|
||||
|
||||
// WOL Name of server
|
||||
const WideStringClass& owner = theGame->Get_Owner();
|
||||
StringClass serverName(true);
|
||||
owner.Convert_To(serverName);
|
||||
stats.Add_Field("SNAM", (char*)serverName.Peek_Buffer());
|
||||
|
||||
// Type of game played (Deathmatch, Capture the flag, CNC...)
|
||||
// char* gameMode = (char*)theGame->Get_Game_Type_Name();
|
||||
stats.Add_Field("MODE", "CNC");
|
||||
|
||||
// Name of the map used.
|
||||
char *map_name = (char*)(theGame->Get_Map_Name().Peek_Buffer());
|
||||
stats.Add_Field("GMAP", map_name);
|
||||
|
||||
// Was this a dedicated server?
|
||||
bool dedicatedServer = theGame->IsDedicated.Get();
|
||||
stats.Add_Field("DSVR", (char)dedicatedServer);
|
||||
|
||||
// Time game started
|
||||
LPSYSTEMTIME gameTime = theGame->Get_Game_Start_Time();
|
||||
char startTime[20];
|
||||
sprintf(startTime, "%02d/%02d/%04d %02d:%02d:%02d",
|
||||
gameTime->wMonth, gameTime->wDay, gameTime->wYear, gameTime->wHour, gameTime->wMinute, gameTime->wSecond);
|
||||
stats.Add_Field("TIME", startTime);
|
||||
|
||||
// Duration of game
|
||||
unsigned long duration = theGame->Get_Duration_Seconds();
|
||||
stats.Add_Field("DURA", duration);
|
||||
|
||||
// Average FPS
|
||||
unsigned long fps = theGame->Get_Frame_Count();
|
||||
|
||||
if (duration > 1)
|
||||
{
|
||||
fps = (fps / duration);
|
||||
}
|
||||
|
||||
stats.Add_Field("AFPS", fps);
|
||||
|
||||
// Type of tournament
|
||||
/*
|
||||
char gameType = 'I';
|
||||
|
||||
if (theGame->Is_Team_Game())
|
||||
{
|
||||
gameType = 'T';
|
||||
}
|
||||
*/
|
||||
char gameType = 'T';
|
||||
|
||||
if (theGame->IsClanGame.Is_True())
|
||||
{
|
||||
gameType = 'C';
|
||||
}
|
||||
|
||||
char ranked = (theGame->IsLaddered.Is_True() == true) ? 'Y' : 'N';
|
||||
|
||||
char tournament[5];
|
||||
sprintf(tournament, "%c%c ", gameType, ranked);
|
||||
stats.Add_Field("TRNY", tournament);
|
||||
|
||||
// Include clan information
|
||||
if (theGame->IsClanGame.Is_True())
|
||||
{
|
||||
unsigned long winningClan = 0;
|
||||
unsigned long losingClan = 0;
|
||||
|
||||
int winner = theGame->Get_Winner_ID();
|
||||
|
||||
SLNode<cPlayer>* playerNode = playerList->Head();
|
||||
|
||||
for (int index = 0; index < playerList->Get_Count(); index++)
|
||||
{
|
||||
cPlayer* player = playerNode->Data();
|
||||
|
||||
if (player->Is_Human())
|
||||
{
|
||||
RefPtr<UserData> user = session->FindUser(player->Get_Name());
|
||||
|
||||
if (user.IsValid() && (user->GetSquadID() != 0))
|
||||
{
|
||||
int playerType = player->Get_Player_Type();
|
||||
|
||||
if ((playerType == winner) && (winningClan == 0))
|
||||
{
|
||||
winningClan = user->GetSquadID();
|
||||
}
|
||||
else if (losingClan == 0)
|
||||
{
|
||||
losingClan = user->GetSquadID();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stats.Add_Field("CLN1", winningClan);
|
||||
stats.Add_Field("CLN2", losingClan);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Player information
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Determine the number of players in the game
|
||||
unsigned long numPlayers = 0;
|
||||
SLNode<cPlayer>* playerNode = playerList->Head();
|
||||
|
||||
for (int index = 0; index < playerList->Get_Count(); index++)
|
||||
{
|
||||
cPlayer* player = playerNode->Data();
|
||||
|
||||
if (player->Is_Human())
|
||||
{
|
||||
numPlayers++;
|
||||
}
|
||||
}
|
||||
|
||||
stats.Add_Field("PLRS", numPlayers);
|
||||
|
||||
// Gather per-player information
|
||||
int winnerID = theGame->Get_Winner_ID();
|
||||
playerNode = playerList->Head();
|
||||
|
||||
for (index = 0; index < playerList->Get_Count(); index++)
|
||||
{
|
||||
cPlayer* player = playerNode->Data();
|
||||
|
||||
if (player)
|
||||
{
|
||||
const WideStringClass& playerName = player->Get_Name();
|
||||
|
||||
// Player Location
|
||||
WOL::Locale locale = WOL::LOC_UNKNOWN;
|
||||
|
||||
RefPtr<UserData> user = session->FindUser((const WCHAR*)playerName);
|
||||
|
||||
if (user.IsValid())
|
||||
{
|
||||
locale = user->GetLocale();
|
||||
}
|
||||
|
||||
AddPlayerStats(stats, player, locale, winnerID, true);
|
||||
}
|
||||
|
||||
playerNode = playerNode->Next();
|
||||
}
|
||||
|
||||
unsigned long packetSize = 0;
|
||||
unsigned long sig_offset = 0;
|
||||
unsigned char* packet = stats.Create_Comms_Packet(packetSize, NULL, sig_offset);
|
||||
|
||||
WWDEBUG_SAY(("Sending game results packet. Size = %lu\n", packetSize));
|
||||
|
||||
#if(0)
|
||||
#ifdef _DEBUG
|
||||
HANDLE file = CreateFile("GameRes.dat", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (INVALID_HANDLE_VALUE != file)
|
||||
{
|
||||
// Write generic contents
|
||||
DWORD written;
|
||||
WriteFile(file, packet, packetSize, &written, NULL);
|
||||
CloseHandle(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
WWDEBUG_SAY(("Failed to create GameRes.dat file."));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
session->SendGameResults(packet, packetSize);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* AddPlayerStats
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* Stats - Game result packet to add player stats to.
|
||||
* Player - Player to add stats for.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void AddPlayerStats(GameResPacket& stats, cPlayer* player, WOL::Locale locale,
|
||||
int winnerID, bool isTeamed)
|
||||
{
|
||||
if (player->Is_Human())
|
||||
{
|
||||
// Players WOL name
|
||||
const WideStringClass& playerName = player->Get_Name();
|
||||
char name[10];
|
||||
int len = wcstombs(name, (const WCHAR*)playerName, 10);
|
||||
name[len] = 0;
|
||||
|
||||
stats.Add_Field("PNAM", name);
|
||||
stats.Add_Field("PLOC", (unsigned long)locale);
|
||||
|
||||
int playerType = player->Get_Player_Type();
|
||||
|
||||
// Team (bit 31:win/lose, bits 7-0:team (0 = none, 1 = GDI, 2= NOD)
|
||||
unsigned long team = 0;
|
||||
|
||||
if (isTeamed)
|
||||
{
|
||||
if (playerType == PLAYERTYPE_GDI)
|
||||
{
|
||||
team = 1;
|
||||
}
|
||||
else if (playerType == PLAYERTYPE_NOD)
|
||||
{
|
||||
team = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if ((isTeamed && playerType == winnerID) || (!isTeamed && player->Get_Id() == winnerID))
|
||||
{
|
||||
team |= 0x80000000;
|
||||
}
|
||||
|
||||
stats.Add_Field("TEAM", team);
|
||||
|
||||
// Score and other information
|
||||
unsigned long score = (unsigned long)max<int>(player->Get_Score(), 0);
|
||||
stats.Add_Field("PSCR", score);
|
||||
|
||||
stats.Add_Field("PPTS", (long)player->Get_Ladder_Points());
|
||||
stats.Add_Field("PTIM", (unsigned long)player->Get_Game_Time());
|
||||
stats.Add_Field("PHLT", (unsigned long)player->Get_Final_Health());
|
||||
stats.Add_Field("PKIL", (unsigned long)player->Get_Deaths());
|
||||
stats.Add_Field("EKIL", (unsigned long)player->Get_Enemies_Killed());
|
||||
stats.Add_Field("AKIL", (unsigned long)player->Get_Allies_Killed());
|
||||
stats.Add_Field("SHOT", (unsigned long)player->Get_Shots_Fired());
|
||||
stats.Add_Field("HEDF", (unsigned long)player->Get_Head_Shots());
|
||||
stats.Add_Field("TORF", (unsigned long)player->Get_Torso_Shots());
|
||||
stats.Add_Field("ARMF", (unsigned long)player->Get_Arm_Shots());
|
||||
stats.Add_Field("LEGF", (unsigned long)player->Get_Leg_Shots());
|
||||
stats.Add_Field("CRTF", (unsigned long)player->Get_Crotch_Shots());
|
||||
stats.Add_Field("PUPS", (unsigned long)player->Get_Powerups_Collected());
|
||||
stats.Add_Field("VKIL", (unsigned long)player->Get_Vehiclies_Destroyed());
|
||||
stats.Add_Field("VTIM", (unsigned long)player->Get_Vehicle_Time());
|
||||
stats.Add_Field("NKFV", (unsigned long)player->Get_Kills_From_Vehicle());
|
||||
stats.Add_Field("SQUI", (unsigned long)player->Get_Squishes());
|
||||
stats.Add_Field("PCRD", (unsigned long)player->Get_Credit_Grant());
|
||||
stats.Add_Field("BKIL", (unsigned long)player->Get_Building_Destroyed());
|
||||
stats.Add_Field("HEDR", (unsigned long)player->Get_Head_Hit());
|
||||
stats.Add_Field("TORR", (unsigned long)player->Get_Torso_Hit());
|
||||
stats.Add_Field("ARMR", (unsigned long)player->Get_Arm_Hit());
|
||||
stats.Add_Field("LEGR", (unsigned long)player->Get_Leg_Hit());
|
||||
stats.Add_Field("CRTR", (unsigned long)player->Get_Crotch_Hit());
|
||||
stats.Add_Field("FLGC", (unsigned long)0);//no more CTF! (unsigned long)player->Get_Flag_Caps());
|
||||
|
||||
// Weapon usage
|
||||
int numWeapons = min<int>(255, player->Get_Weapon_Fired_Count());
|
||||
|
||||
for (int wepIndex = 0; wepIndex < numWeapons; wepIndex++)
|
||||
{
|
||||
unsigned long weaponInfo[2] = {0,0};
|
||||
player->Get_Weapon_Fired(wepIndex, weaponInfo[0], weaponInfo[1]);
|
||||
|
||||
char token[5];
|
||||
sprintf(token, "WP%02X", wepIndex);
|
||||
stats.Add_Field(token, (void*)weaponInfo, sizeof(weaponInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user