Initial commit of Command & Conquer Renegade source code.

This commit is contained in:
LFeenanEA
2025-02-27 16:39:46 +00:00
parent 74ab8fa5e0
commit 58ed459113
4918 changed files with 1366710 additions and 0 deletions

View File

@@ -0,0 +1,403 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Command & Conquer *
* *
* $Archive:: /Commando/Code/WWOnline/GameResField.cpp $*
* *
* $Author:: Denzil_l $*
* *
* $Modtime:: 9/20/01 9:43p $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "GameResField.h"
#include <string.h>
#include <assert.h>
#include <WWDebug\WWDebug.h>
// Get rid of the nameless struct/union warning
#pragma warning(disable: 4201)
#include <winsock.h>
#pragma warning(default: 4201)
namespace WWOnline {
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
GameResField::GameResField(char *id, char data)
{
strncpy(mID, id, sizeof(mID));
mDataType = TYPE_CHAR;
mSize = sizeof(data);
mData = new char[mSize];
memcpy(mData, &data, mSize);
mNext = NULL;
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
GameResField::GameResField(char *id, unsigned char data)
{
strncpy(mID, id, sizeof(mID));
mDataType = TYPE_UNSIGNED_CHAR;
mSize = sizeof(data);
mData = new char[mSize];
memcpy(mData, &data, mSize);
mNext = NULL;
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
GameResField::GameResField(char *id, short data)
{
strncpy(mID, id, sizeof(mID));
mDataType = TYPE_SHORT;
mSize = sizeof(data);
mData = new char[mSize];
memcpy(mData, &data, mSize);
mNext = NULL;
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
GameResField::GameResField(char *id, unsigned short data)
{
strncpy(mID, id, sizeof(mID));
mDataType = TYPE_UNSIGNED_SHORT;
mSize = sizeof(data);
mData = new char[mSize];
memcpy(mData, &data, mSize);
mNext = NULL;
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
GameResField::GameResField(char *id, long data)
{
strncpy(mID, id, sizeof(mID));
mDataType = TYPE_LONG;
mSize = sizeof(data);
mData = new char[mSize];
memcpy(mData, &data, mSize);
mNext = NULL;
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
GameResField::GameResField(char *id, unsigned long data)
{
strncpy(mID, id, sizeof(mID));
mDataType = TYPE_UNSIGNED_LONG;
mSize = sizeof(data);
mData = new char[mSize];
memcpy(mData, &data, mSize);
mNext = NULL;
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
GameResField::GameResField(char *id, char *data)
{
strncpy(mID, id, sizeof(mID));
mDataType = TYPE_STRING;
mSize = (unsigned short)(strlen(data)+1);
mData = new char[mSize];
memcpy(mData, data, mSize);
mNext = NULL;
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
GameResField::GameResField(char *id, void *data, int length)
{
strncpy(mID, id, sizeof(mID));
mDataType = TYPE_CHUNK;
mSize = (unsigned short)length;
mData = new char[mSize];
memcpy(mData, data, mSize);
mNext = NULL;
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
GameResField::~GameResField()
{
delete[](mData);
}
/**************************************************************************
* PACKETCLASS::HOST_TO_NET_FIELD -- Converts host field to net format *
* *
* INPUT: FIELD * to the data field we need to convert *
* *
* OUTPUT: none *
* *
* HISTORY: *
* 04/22/1996 PWG : Created. *
*========================================================================*/
void GameResField::Host_To_Net(void)
{
// Before we convert the data type, we should convert the actual data sent.
switch (mDataType)
{
case TYPE_CHAR:
case TYPE_UNSIGNED_CHAR:
case TYPE_STRING:
case TYPE_CHUNK:
break;
case TYPE_SHORT:
case TYPE_UNSIGNED_SHORT:
*((unsigned short *)mData) = htons(*((unsigned short *)mData));
break;
case TYPE_LONG:
case TYPE_UNSIGNED_LONG:
*((unsigned long *)mData) = htonl(*((unsigned long *)mData));
break;
// Might be good to insert some type of error message here for unknown
// datatypes.
default:
assert(!"GameResField: Unknown data type");
break;
}
// Finally convert over the data type and the size of the packet.
mDataType = htons(mDataType);
mSize = htons(mSize);
}
/**************************************************************************
* PACKETCLASS::NET_TO_HOST_FIELD -- Converts net field to host format *
* *
* INPUT: FIELD * to the data field we need to convert *
* *
* OUTPUT: none *
* *
* HISTORY: *
* 04/22/1996 PWG : Created. *
*========================================================================*/
void GameResField::Net_To_Host(void)
{
// Convert the variables to host order. This needs to be converted so
// the switch statement does compares on the data that follows.
mSize = ntohs(mSize);
mDataType = ntohs(mDataType);
// Before we convert the data type, we should convert the actual data sent.
switch (mDataType)
{
case TYPE_CHAR:
case TYPE_UNSIGNED_CHAR:
case TYPE_STRING:
case TYPE_CHUNK:
break;
case TYPE_SHORT:
case TYPE_UNSIGNED_SHORT:
*((unsigned short *)mData) = ntohs(*((unsigned short *)mData));
break;
case TYPE_LONG:
case TYPE_UNSIGNED_LONG:
*((unsigned long *)mData) = ntohl(*((unsigned long *)mData));
break;
// Might be good to insert some type of error message here for unknown
// datatypes.
default:
assert(!"GameResField: Unknown data type");
break;
}
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
#ifdef _DEBUG
void GameResField::DebugDump(void)
{
char id[5];
memcpy(id, mID, 4);
id[4] = 0;
switch (mDataType)
{
case TYPE_CHAR:
{
short data = *((char*)mData);
WWDEBUG_SAY(("[%4s] %d\n", id, data));
}
break;
case TYPE_UNSIGNED_CHAR:
{
short data = *((unsigned char*)mData);
WWDEBUG_SAY(("[%4s] %ld\n", id, data));
}
break;
case TYPE_SHORT:
WWDEBUG_SAY(("[%4s] %d\n", id, *((short*)mData)));
break;
case TYPE_LONG:
WWDEBUG_SAY(("[%4s] %ld\n", id, *((long*)mData)));
break;
case TYPE_UNSIGNED_SHORT:
WWDEBUG_SAY(("[%4s] %u\n", id, *((unsigned short*)mData)));
break;
case TYPE_UNSIGNED_LONG:
WWDEBUG_SAY(("[%4s] %lu\n", id, *((unsigned long*)mData)));
break;
case TYPE_STRING:
WWDEBUG_SAY(("[%4s] '%s'\n", id, mData));
break;
default:
WWDEBUG_SAY(("[%4s]\n", id));
break;
}
}
#endif
} // namespace WWOnline

View File

@@ -0,0 +1,92 @@
/*
** 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/WWOnline/GameResField.h $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 2 $
* $Modtime: 8/15/01 5:49p $
*
******************************************************************************/
#pragma once
#ifndef __GAMERESFIELD_H__
#define __GAMERESFIELD_H__
namespace WWOnline {
class GameResPacket;
#define GAMERESFIELD_HEADER_SIZE (sizeof(GameResField) - (sizeof(void *) * 2))
class GameResField {
public:
enum Type {
TYPE_CHAR = 1,
TYPE_UNSIGNED_CHAR,
TYPE_SHORT,
TYPE_UNSIGNED_SHORT,
TYPE_LONG,
TYPE_UNSIGNED_LONG,
TYPE_STRING,
TYPE_CHUNK = 20
};
friend class GameResPacket;
// Define constructors to be able to create all the different kinds
// of fields.
GameResField(void) {};
GameResField(char *id, char data);
GameResField(char *id, unsigned char data);
GameResField(char *id, short data);
GameResField(char *id, unsigned short data);
GameResField(char *id, long data);
GameResField(char *id, unsigned long data);
GameResField(char *id, char *data);
GameResField(char *id, void *data, int length);
~GameResField();
void Host_To_Net(void);
void Net_To_Host(void);
#ifdef _DEBUG
void DebugDump(void);
#endif
private:
char mID[4];
unsigned short mDataType;
unsigned short mSize;
void* mData;
GameResField* mNext;
};
} // namespace WWOnline
#endif __GAMERESFIELD_H__

View File

@@ -0,0 +1,481 @@
/*
** 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/WWOnline/GameResPacket.cpp $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 4 $
* $Modtime: 12/11/01 6:23p $
*
******************************************************************************/
#include "GameResPacket.h"
#include <assert.h>
#include <string.h>
#include <winsock.h>
namespace WWOnline {
/**************************************************************************
* GameResPacket::~GameResPacket -- destroys a packet class be freeing list *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* HISTORY: *
* 04/24/1996 PWG : Created. *
*========================================================================*/
GameResPacket::~GameResPacket(void)
{
GameResField* current;
GameResField* next;
// Loop through the entire field list and delete each entry.
for (current = mHead; current; current = next)
{
next = current->mNext;
delete current;
}
}
/**************************************************************************
* GameResPacket::ADD_FIELD -- Adds a GameResField entry to head of packet li *
* *
* INPUT: GameResField * - a properly constructed field class entry. *
* *
* OUTPUT: none *
* *
* HISTORY: *
* 04/24/1996 PWG : Created. *
*========================================================================*/
void GameResPacket::Add_Field(GameResField *field)
{
field->mNext = mHead;
mHead = field;
}
/**************************************************************************
* GameResPacket::GameResPacket -- Creates a Packet object from a COMMS packe *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 04/22/1996 PWG : Created. *
*========================================================================*/
GameResPacket::GameResPacket(unsigned char* curbuf)
{
// Pull the size and packet ID out of the linear packet stream.
mSize = ntohl(*(unsigned long*)curbuf);
curbuf += sizeof(mSize);
mID = ntohs(*(unsigned short*)curbuf);
curbuf += sizeof(mID);
mReserved = ntohs(*(unsigned short*)curbuf);
curbuf += sizeof(mReserved);
mHead = NULL;
// Calculate the remaining size so that we can loop through the
// packets and extract them.
unsigned long remaining_size = (mSize - (sizeof(mSize) + sizeof(mID) + sizeof(mReserved)));
// Loop through the linear packet until we run out of room and
// create a field for each.
while (remaining_size > 0)
{
GameResField* field = new GameResField;
// Copy the adjusted header into the buffer and then advance the buffer
memcpy(field, curbuf, GAMERESFIELD_HEADER_SIZE);
curbuf += GAMERESFIELD_HEADER_SIZE;
remaining_size -= GAMERESFIELD_HEADER_SIZE;
// Copy the data into the buffer
unsigned short size = ntohs(field->mSize);
field->mData = new unsigned char[size];
memcpy(field->mData, curbuf, size);
curbuf += size;
remaining_size -= size;
// Make sure we allow for the pad bytes.
int pad = (4 - (ntohs(field->mSize) & 3)) & 3;
curbuf += pad;
remaining_size -= pad;
// Convert the field back to the host format
field->Net_To_Host();
// Finally add the field to the field list in the packet
// structure.
Add_Field(field);
}
}
/**************************************************************************
* CREATE_COMMS_PACKET -- Walks field list creating a packet *
* *
* INPUT: short - the id of the packet so the server can identify it *
* unsigned short & - the size of the packet returned here *
* *
* OUTPUT: void * pointer to the linear packet data *
* *
* WARNINGS: This routine allocates memory that the user is responsible*
* for freeing. *
* *
* HISTORY: *
* 04/22/1996 PWG : Created. *
*========================================================================*/
unsigned char* GameResPacket::Create_Comms_Packet(unsigned long& size, char* sig_name, unsigned long& sig_offset)
{
GameResField* current;
sig_offset = 0;
// Size starts at 8 because that is the size of the packet header. (size[4] + id[2] + reserved[2])
size = (sizeof(mSize) + sizeof(mID) + sizeof(mReserved));
// Take a quick spin through and calculate the size of the packet we
// are building.
for (current = mHead; current; current = current->mNext)
{
size += (unsigned long)GAMERESFIELD_HEADER_SIZE; // add in packet header size
size += current->mSize; // add in data size
size += (4 - (current->mSize & 3)) & 3; // add in pad value to dword align next packet
}
// Now that we know the size allocate a buffer big enough to hold the
// packet.
unsigned char* bufferStart = new unsigned char[size];
unsigned char* curbuf = bufferStart;
// write the size into the packet header
*(unsigned long*)curbuf = htonl(size);
curbuf += sizeof(unsigned long);
*(unsigned short*)curbuf = htons(mID);
curbuf += sizeof(unsigned short);
*(unsigned short*)curbuf = htons(mReserved);
curbuf += sizeof(unsigned short);
// Ok now that the actual header information has been written we need to write out
// field information.
for (current = mHead; current; current = current->mNext)
{
#ifdef _DEBUG
current->DebugDump();
#endif
unsigned short fieldSize = current->mSize;
// Temporarily convert the packet to net format (this saves alot of
// effort, and seems safe...)
current->Host_To_Net();
// Copy the adjusted header into the buffer and then advance the buffer
memcpy(curbuf, current, GAMERESFIELD_HEADER_SIZE);
curbuf += GAMERESFIELD_HEADER_SIZE;
// If this is the sig data then make a note of the offset into the packet.
if (sig_name && strncmp(sig_name, current->mID, 4) == 0)
{
// If sig_offset isn't zero then that would indicate that there were multiple sig entries in the packet.
assert(sig_offset == 0);
sig_offset = (curbuf - bufferStart);
}
// Copy the data into the buffer and then advance the buffer
memcpy(curbuf, current->mData, fieldSize);
curbuf += fieldSize;
// Finally take care of any pad bytes by setting them to 0
int pad = ((4 - (fieldSize & 3)) & 3);
// If there is any pad left over, make sure you memset it
// to zeros, so it looks like a pad.
if (pad)
{
memset(curbuf, 0, pad);
curbuf += pad;
}
current->Net_To_Host();
}
return bufferStart;
}
/**************************************************************************
* GameResPacket::FIND_FIELD -- Finds a field if it exists in the packets *
* *
* INPUT: char * - the id of the field we are looking for. *
* *
* OUTPUT: GameResField * pointer to the field class *
* *
* HISTORY: *
* 04/23/1996 PWG : Created. *
*========================================================================*/
GameResField *GameResPacket::Find_Field(char *id)
{
for (GameResField *current = mHead; current; current = current->mNext)
{
if (strncmp(id, current->mID, 4) == 0)
return current;
}
return NULL;
}
/**************************************************************************
* GET_FIELD -- Find specified name and returns data *
* *
* INPUT: char * - the id of the field that holds the data. *
* char & - the reference to store the data into *
* *
* OUTPUT: true if the field was found, false if it was not. *
* *
* WARNINGS: The data reference is not changed if the field is not *
* found. *
* *
* HISTORY: *
* 04/23/1996 PWG : Created. *
*========================================================================*/
bool GameResPacket::Get_Field(char *id, char &data)
{
GameResField *field = Find_Field(id);
if (field)
{
data = *((char*)field->mData);
}
return((field) ? true : false);
}
/**************************************************************************
* GET_FIELD -- Find specified name and returns data *
* *
* INPUT: char * - the id of the field that holds the data. *
* unsigned char & - the reference to store the data into *
* *
* OUTPUT: true if the field was found, false if it was not. *
* *
* WARNINGS: The data reference is not changed if the field is not *
* found. *
* *
* HISTORY: *
* 04/23/1996 PWG : Created. *
*========================================================================*/
bool GameResPacket::Get_Field(char *id, unsigned char &data)
{
GameResField *field = Find_Field(id);
if (field)
{
data = *((unsigned char *)field->mData);
}
return((field) ? true : false);
}
/**************************************************************************
* GET_FIELD -- Find specified name and returns data *
* *
* INPUT: char * - the id of the field that holds the data. *
* short & - the reference to store the data into *
* *
* OUTPUT: true if the field was found, false if it was not. *
* *
* WARNINGS: The data reference is not changed if the field is not *
* found. *
* *
* HISTORY: *
* 04/23/1996 PWG : Created. *
*========================================================================*/
bool GameResPacket::Get_Field(char *id, short &data)
{
GameResField *field = Find_Field(id);
if (field)
{
data = *((short *)field->mData);
}
return((field) ? true : false);
}
/**************************************************************************
* GET_FIELD -- Find specified name and returns data *
* *
* INPUT: char * - the id of the field that holds the data. *
* unsigned short & - the reference to store the data into*
* *
* OUTPUT: true if the field was found, false if it was not. *
* *
* WARNINGS: The data reference is not changed if the field is not *
* found. *
* *
* HISTORY: *
* 04/23/1996 PWG : Created. *
*========================================================================*/
bool GameResPacket::Get_Field(char *id, unsigned short &data)
{
GameResField *field = Find_Field(id);
if (field)
{
data = *((unsigned short *)field->mData);
}
return((field) ? true : false);
}
/**************************************************************************
* GET_FIELD -- Find specified name and returns data *
* *
* INPUT: char * - the id of the field that holds the data. *
* long & - the reference to store the data into *
* *
* OUTPUT: true if the field was found, false if it was not. *
* *
* WARNINGS: The data reference is not changed if the field is not *
* found. *
* *
* HISTORY: *
* 04/23/1996 PWG : Created. *
*========================================================================*/
bool GameResPacket::Get_Field(char *id, long &data)
{
GameResField *field = Find_Field(id);
if (field)
{
data = *((long *)field->mData);
}
return((field) ? true : false);
}
/**************************************************************************
* GET_FIELD -- Find specified name and returns data as a string *
* *
* INPUT: char * - the id of the field that holds the data. *
* char * - the string to store the data into *
* *
* OUTPUT: true if the field was found, false if it was not. *
* *
* WARNINGS: The string is not changed if the field is not found. It *
* is assumed that the string variabled specified by the *
* pointer is large enough to hold the data. *
* *
* HISTORY: *
* 04/23/1996 PWG : Created. *
*========================================================================*/
bool GameResPacket::Get_Field(char *id, char *data)
{
GameResField *field = Find_Field(id);
if (field)
{
strcpy(data, (char *)field->mData);
}
return((field) ? true : false);
}
/**************************************************************************
* GET_FIELD -- Find specified name and returns data *
* *
* INPUT: char * - the id of the field that holds the data *
* unsigned long & - the reference to store the data into *
* *
* OUTPUT: true if the field was found, false if it was not. *
* *
* WARNINGS: The data reference is not changed if the field is not *
* found. *
* *
* HISTORY: *
* 04/23/1996 PWG : Created. *
*========================================================================*/
bool GameResPacket::Get_Field(char *id, unsigned long &data)
{
GameResField *field = Find_Field(id);
if (field)
{
data = *((unsigned long *)field->mData);
}
return((field) ? true : false);
}
/**************************************************************************
* GET_FIELD -- Find specified name and returns data *
* *
* INPUT: char * - the id of the field that holds the data. *
* void * - the reference to store the data into *
* int - the length of the buffer passed in *
* *
* OUTPUT: true if the field was found, false if it was not. *
* *
* WARNINGS: The data reference is not changed if the field is not *
* found. *
* *
* HISTORY: *
* 6/4/96 4:46PM ST : Created *
*========================================================================*/
bool GameResPacket::Get_Field(char *id, void *data, int &length)
{
GameResField *field = Find_Field(id);
if (field)
{
memcpy(data, field->mData, min((int)field->mSize, length));
length = (int) field->mSize;
}
return((field) ? true : false);
}
} // namespace WWOnline

View File

@@ -0,0 +1,102 @@
/*
** 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/WWOnline/GameResPacket.h $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 5 $
* $Modtime: 1/25/02 11:53a $
*
******************************************************************************/
#pragma once
#ifndef __GAMERESPACKET_H__
#define __GAMERESPACKET_H__
#pragma warning(disable : 4711)
#include "GameResField.h"
namespace WWOnline {
class GameResPacket {
public:
GameResPacket(short id = 0) :
mSize(0),
mID(id),
mReserved(0),
mHead(0)
{}
GameResPacket(unsigned char *cur_buf);
~GameResPacket(void);
// This function allows us to add a field to the start of the list. As the field is just
// a big linked list it makes no difference which end we add a member to.
void Add_Field(GameResField *field);
//
// These conveniance functions allow us to add a field directly to the list without
// having to worry about newing one first.
//
void Add_Field(char *field, char data) {Add_Field(new GameResField(field, data));};
void Add_Field(char *field, unsigned char data) {Add_Field(new GameResField(field, data));};
void Add_Field(char *field, short data) {Add_Field(new GameResField(field, data));};
void Add_Field(char *field, unsigned short data) {Add_Field(new GameResField(field, data));};
void Add_Field(char *field, long data) {Add_Field(new GameResField(field, data));};
void Add_Field(char *field, unsigned long data) {Add_Field(new GameResField(field, data));};
void Add_Field(char *field, char *data) {Add_Field(new GameResField(field, data));};
void Add_Field(char *field, void *data, int length) {Add_Field(new GameResField(field, data, length));};
//
// These functions search for a field of a given name in the list and
// return the data via a reference value.
//
GameResField *Find_Field(char *id);
bool Get_Field(char *id, char &data);
bool Get_Field(char *id, unsigned char &data);
bool Get_Field(char *id, short &data);
bool Get_Field(char *id, unsigned short &data);
bool Get_Field(char *id, long &data);
bool Get_Field(char *id, unsigned long &data);
bool Get_Field(char *id, char *data);
bool Get_Field(char *id, void *data, int &length);
unsigned char* Create_Comms_Packet(unsigned long& size, char* sig_name, unsigned long& sig_offset);
private:
unsigned long mSize;
unsigned short mID;
unsigned short mReserved;
GameResField* mHead;
GameResField* mCurrent;
};
} // namespace WWOnline
#endif

View File

@@ -0,0 +1,410 @@
/*
** 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/WWOnline/PingProfile.cpp $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 8 $
* $Modtime: 1/11/02 5:45p $
*
******************************************************************************/
#include "always.h"
#include "PingProfile.h"
#include <WWOnline\WOLSession.h>
#include <WWOnline\WOLServer.h>
#include <WWOnline\WOLString.h>
#include <WWLib\WideString.h>
#include <WWDebug\WWDebug.h>
#include <limits.h>
#include <math.h>
using namespace WWOnline;
static PingProfile gPingProfile;
/******************************************************************************
*
* NAME
* RecalculatePingProfile
*
* DESCRIPTION
* Calculate ping profile based on the current session ping times.
*
* INPUTS
* Session - WWOnline session
*
* RESULT
* True if ping times are valid
*
******************************************************************************/
bool RecalculatePingProfile(const RefPtr<Session>& session)
{
memset(gPingProfile.Pings, 0xFF, sizeof(gPingProfile.Pings));
if (session.IsValid())
{
const PingServerList& pingers = session->GetPingServerList();
// The ping profile holds up to eight pings.
unsigned int count = min<unsigned int>(8, pingers.size());
// If there aren't any ping servers then fail.
if (count > 0)
{
for (unsigned int index = 0; index < count; index++)
{
int pingTime = pingers[index]->GetPingTime();
// If a ping time is invalid then fail.
if (pingTime < 0)
{
return false;
}
// Clamp pings time to a maximum of 1000 ms
pingTime = min<int>(pingTime, 1000);
// Scale ping time to from 0-1000 to 0-255
gPingProfile.Pings[index] = (((unsigned long)pingTime * 255) / 1000);
}
return true;
}
}
return false;
}
/******************************************************************************
*
* NAME
* GetLocalPingProfile
*
* DESCRIPTION
* Get the ping profile for this client.
*
* INPUTS
* NONE
*
* RESULT
* Profile - Ping profile to for current session.
*
******************************************************************************/
const PingProfile& GetLocalPingProfile(void)
{
return gPingProfile;
}
/******************************************************************************
*
* NAME
* ComparePingProfile
*
* DESCRIPTION
* Calcualte the best time between two ping profiles.
*
* INPUTS
* Profile1 - Ping profile
* Profile2 - Ping profile
*
* RESULT
* Weight - Smallest time between two profiles.
*
******************************************************************************/
long ComparePingProfile(const PingProfile& ping1, const PingProfile& ping2)
{
long minWeight = LONG_MAX;
for (int index = 0; index < 8; index++)
{
long a = ping1.Pings[index];
long b = ping2.Pings[index];
long weight = (a * a) + (b * b);
minWeight = min<long>(weight, minWeight);
}
return minWeight;
}
/******************************************************************************
*
* NAME
* EncodePingProfile
*
* DESCRIPTION
* Encode the ping profile into a clear text string that can be transmited
* via chat.
*
* INPUTS
* Pings - Ping profile to encode.
* Buffer - Buffer to encode pings into.
*
* RESULT
* Length - Number of characters used to encode the profile.
*
******************************************************************************/
int EncodePingProfile(const PingProfile& pings, char* buffer)
{
assert(buffer != NULL);
if (buffer == NULL)
{
return 0;
}
char temp[18];
int count = sprintf(temp, "%02X%02X%02X%02X%02X%02X%02X%02X",
pings.Pings[0], pings.Pings[1], pings.Pings[2], pings.Pings[3],
pings.Pings[4], pings.Pings[5], pings.Pings[6], pings.Pings[7]);
strcat(buffer, temp);
return count;
}
/******************************************************************************
*
* NAME
* DecodePingProfile
*
* DESCRIPTION
* Decode the ping profile from clear text string.
*
* INPUTS
* String - Encode ping profile.
* Pings - Ping profile structure.
*
* RESULT
* NONE
*
******************************************************************************/
void DecodePingProfile(const char* buffer, PingProfile& pings)
{
if (buffer)
{
unsigned long ping[8];
sscanf(buffer, "%02X%02X%02X%02X%02X%02X%02X%02X",
&ping[0], &ping[1], &ping[2], &ping[3], &ping[4], &ping[5], &ping[6], &ping[7]);
pings.Pings[0] = ping[0];
pings.Pings[1] = ping[1];
pings.Pings[2] = ping[2];
pings.Pings[3] = ping[3];
pings.Pings[4] = ping[4];
pings.Pings[5] = ping[5];
pings.Pings[6] = ping[6];
pings.Pings[7] = ping[7];
}
else
{
memset(&pings, 0xFF, sizeof(pings));
}
}
/******************************************************************************
*
* NAME
* PingProfileWait::Create
*
* DESCRIPTION
* Create a wait condition to obtain an update ping profile.
*
* INPUTS
* Session - WWOnline session
*
* RESULT
* Wait - Wait condition to process.
*
******************************************************************************/
RefPtr<PingProfileWait> PingProfileWait::Create(void)
{
return new PingProfileWait;
}
/******************************************************************************
*
* NAME
* PingProfileWait::PingProfileWait
*
* DESCRIPTION
* Constructor
*
* INPUTS
*
* RESULT
*
******************************************************************************/
PingProfileWait::PingProfileWait() :
SingleWait(WOLSTRING("WOL_PINGPROFILEREQUEST")),
mCount(0)
{
WWDEBUG_SAY(("WOL: PingProfileWait Instantiated\n"));
mWOLSession = Session::GetInstance(false);
}
/******************************************************************************
*
* NAME
* PingProfileWait::~PingProfileWait
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
PingProfileWait::~PingProfileWait()
{
WWDEBUG_SAY(("WOL: PingProfileWait Destroyed\n"));
}
/******************************************************************************
*
* NAME
* PingProfileWait::WaitBeginning
*
* DESCRIPTION
* Begin wait condition
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void PingProfileWait::WaitBeginning(void)
{
WWDEBUG_SAY(("WOL: PingProfileWait Beginning\n"));
if (mWOLSession.IsValid() == false)
{
EndWait(Error, WOLSTRING("WOL_NOTINITIALIZED"));
return;
}
const PingServerList& pingers = mWOLSession->GetPingServerList();
// Handle up to eight servers
mCount = min<unsigned int>(8, pingers.size());
if (mCount == 0)
{
EndWait(Error, WOLSTRING("WOL_NOPINGSERVER"));
return;
}
Observer<RawPing>::NotifyMe(*mWOLSession);
bool pingsValid = true;
for (unsigned int index = 0; index < mCount; index++)
{
int pingTime = pingers[index]->GetPingTime();
// If a ping time is invalid then request it.
if (pingTime == -1)
{
pingsValid = false;
const char* address = pingers[index]->GetHostAddress();
mWOLSession->RequestPing(address);
}
}
if (pingsValid)
{
RecalculatePingProfile(mWOLSession);
EndWait(ConditionMet, WOLSTRING("WOL_PINGPROFILERECEIVED"));
}
}
/******************************************************************************
*
* NAME
* PingProfileWait::HandleNotification(RawPing)
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void PingProfileWait::HandleNotification(RawPing& ping)
{
if ((mEndResult == Waiting) && (mCount > 0))
{
const char* address = ping.GetHostAddress();
const PingServerList& pingers = mWOLSession->GetPingServerList();
for (unsigned int index = 0; index < pingers.size(); index++)
{
const char* pinger = pingers[index]->GetHostAddress();
if (stricmp(address, pinger) == 0)
{
WWDEBUG_SAY(("WOL: PingProfileWait received ping for '%s'\n", pingers[index]->GetData().name));
mCount--;
break;
}
}
if (mCount == 0)
{
RecalculatePingProfile(mWOLSession);
EndWait(ConditionMet, WOLSTRING("WOL_PINGPROFILERECEIVED"));
}
}
}

View File

@@ -0,0 +1,76 @@
/*
** 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/WWOnline/PingProfile.h $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 3 $
* $Modtime: 11/09/01 6:12p $
*
******************************************************************************/
#ifndef __PINGPROFILE_H__
#define __PINGPROFILE_H__
#include <WWOnline\WaitCondition.h>
namespace WWOnline
{
class RawPing;
class Session;
}
typedef struct {unsigned char Pings[8];} PingProfile;
const PingProfile& GetLocalPingProfile(void);
long ComparePingProfile(const PingProfile& ping1, const PingProfile& ping2);
int EncodePingProfile(const PingProfile& pings, char* buffer);
void DecodePingProfile(const char* buffer, PingProfile& pings);
class PingProfileWait :
public SingleWait,
protected Observer<WWOnline::RawPing>
{
public:
static RefPtr<PingProfileWait> Create(void);
void WaitBeginning(void);
protected:
PingProfileWait();
virtual ~PingProfileWait();
PingProfileWait(const PingProfileWait&);
const PingProfileWait& operator=(const PingProfileWait&);
void HandleNotification(WWOnline::RawPing& ping);
private:
RefPtr<WWOnline::Session> mWOLSession;
unsigned int mCount;
};
#endif // __PINGPROFILE_H__

View File

@@ -0,0 +1,87 @@
/*
** 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/WWOnline/RefCounted.h $
*
* DESCRIPTION
* Base class for reference counted objects.
* Use with the reference counting smart pointer RefPtr<Type>
*
* ReleaseReference() is virtual. This helps support cached object and
* singletons.
*
* PROGRAMMER
* Steven Clinard
* $Author: Denzil_l $
*
* VERSION INFO
* $Modtime: 7/06/01 11:18a $
* $Revision: 1 $
*
******************************************************************************/
#ifndef __REFCOUNTED_H__
#define __REFCOUNTED_H__
#include <assert.h>
class RefCounted
{
public:
// Add reference
inline void AddReference(void)
{++mRefCount;}
// Release reference
inline virtual void ReleaseReference(void)
{if (--mRefCount == 0) delete this;}
//! Retrieve current reference count.
inline unsigned long ReferenceCount(void) const
{return mRefCount;}
protected:
RefCounted() :
mRefCount(0)
{}
RefCounted(const RefCounted&) :
mRefCount(0)
{}
inline const RefCounted& operator=(const RefCounted&)
{}
virtual ~RefCounted()
{assert(mRefCount == 0);}
// Should not be allowed by default
inline virtual bool operator==(const RefCounted&) const
{return false;}
inline bool operator!=(const RefCounted&) const
{return false;}
private:
unsigned long mRefCount;
};
#endif // __REFCOUNTED_H__

365
Code/WWOnline/RefPtr.h Normal file
View File

@@ -0,0 +1,365 @@
/*
** 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/WWOnline/RefPtr.h $
*
* DESCRIPTION
* RefPtr<> and RefPtrConst<> are const-friendly, polymorphic reference
* counting smart pointers.
*
* The pointed-to class must be derived from RefCount.
*
* RefPtr<X> replaces X*
* RefPtrConst<X> replaces const X*
*
* Dynamic_Cast<X> replaces dynamic_cast<X*> and dynamic_cast<X&>
* Reinterpret_Cast<X> replaces reinterpret_cast<X*> and reinterpret_cast<X&>
* Const_Cast<X> replaces const_cast<X*> and const_cast<X&>
*
* IsValid() replaces (x != NULL)
*
* Member function Attach() or assigning RefPtr<X>() will NULL a pointer.
*
* Generally, RefPtr<> and RefPtrConst<> behave like their raw pointer
* counterparts, except of course they are reference counted and will delete
* the pointed-to object when the last reference is lost. The major
* syntatical differences are the use of RefPtrConst<> to represent a pointer
* to a constant object (I found it impossible to represent this within rc_ptr)
* and the use of the upper-case cast functions (it is not possible to overload
* these built-in functions).
*
* An explicit goal of this class is to completely avoid the "new" and "delete"
* operators in client code. The constructors for these pointers are private;
* they are friends of the pointed-to class. This forces the use of Factory
* Method functions (or similar) in the pointed-to class. Pointed-to classes
* should make the constructor protected or private to disallow clients from
* creating an instance with "new". If this is done, it becomes very difficult
* for the client to accidentally leak objects and/or misuse the pointed-to
* class or the reference counting pointers.
*
* PROGRAMMER
* Steven Clinard
* $Author: Denzil_l $
*
* VERSION INFO
* $Modtime: 7/06/01 4:23p $
* $Revision: 1 $
*
******************************************************************************/
#ifndef __REFPTR_H__
#define __REFPTR_H__
#include "RefCounted.h"
#include <stddef.h>
#include <assert.h>
template<typename Type> class RefPtr;
template<typename Type> class RefPtrConst;
class RefPtrBase
{
public:
inline bool operator==(const RefPtrBase& rhs) const
{return (mRefObject == rhs.mRefObject);}
inline bool operator!=(const RefPtrBase& rhs) const
{return !operator==(rhs);}
inline bool IsValid(void) const
{return (mRefObject != NULL);}
inline void Release(void)
{
if (IsValid())
{
mRefObject->ReleaseReference();
mRefObject = NULL;
}
}
protected:
RefPtrBase() :
mRefObject(NULL)
{}
RefPtrBase(RefCounted* object) :
mRefObject(object)
{
assert((mRefObject == NULL) || (mRefObject->ReferenceCount() == 0));
if (IsValid())
{
mRefObject->AddReference();
}
}
RefPtrBase(const RefPtrBase& object) :
mRefObject(object.mRefObject)
{
assert(!"RefPtrBase(const RefPtrBase&) - Why is this being called?");
if (IsValid())
{
mRefObject->AddReference();
}
}
virtual ~RefPtrBase()
{Release();}
const RefPtrBase& operator=(const RefPtrBase&);
inline RefCounted* const GetRefObject(void)
{return mRefObject;}
inline const RefCounted* const GetRefObject(void) const
{return mRefObject;}
inline void Attach(RefCounted* object)
{
// If objects are different
if (object != mRefObject)
{
// Add reference to new object
if (object != NULL)
{
object->AddReference();
}
// Release reference to old object
Release();
// Assign new object
mRefObject = object;
}
}
private:
RefCounted* mRefObject;
template<typename Derived>
friend RefPtr<Derived> Dynamic_Cast(RefPtrBase&);
template<typename Type>
friend RefPtr<Type> Reinterpret_Cast(RefPtrBase&);
};
template<typename Type> class RefPtr :
public RefPtrBase
{
public:
RefPtr() :
RefPtrBase()
{}
template<typename Derived>
RefPtr(const RefPtr<Derived>& derived) :
RefPtrBase()
{
Attach(static_cast<RefCounted*>(const_cast<Derived*>(derived.ReferencedObject())));
}
RefPtr(const RefPtr<Type>& object) :
RefPtrBase()
{
Attach(static_cast<RefCounted*>(const_cast<Type*>(object.ReferencedObject())));
}
virtual ~RefPtr()
{}
template<typename Derived>
inline const RefPtr<Type>& operator=(const RefPtr<Derived>& derived)
{
Attach(static_cast<RefCounted*>(const_cast<Derived*>(derived.ReferencedObject())));
return *this;
}
inline const RefPtr<Type>& operator=(const RefPtr<Type>& object)
{
Attach(static_cast<RefCounted*>(const_cast<Type*>(object.ReferencedObject())));
return *this;
}
inline Type& operator*() const
{
assert(IsValid());
return *const_cast<Type*>(ReferencedObject());
}
inline Type* const operator->() const
{
assert(IsValid());
return const_cast<Type*>(ReferencedObject());
}
// Template function for implicit conversion ops
template<typename NewType>
inline operator RefPtr<NewType>()
{return RefPtr<NewType>(GetRefObject());}
// These are public mostly because I can't seem to declare rc_ptr<Other> as a friend
inline Type* const ReferencedObject(void)
{return reinterpret_cast<Type*>(GetRefObject());}
inline const Type* const ReferencedObject(void) const
{return reinterpret_cast<const Type*>(GetRefObject());}
RefPtr(Type* object) :
RefPtrBase()
{
Attach(static_cast<RefCounted*>(object));
}
inline const RefPtr<Type>& operator=(Type* object)
{
Attach(static_cast<RefCounted*>(object));
return *this;
}
private:
friend RefPtr<Type> Dynamic_Cast(RefPtrBase&);
friend RefPtr<Type> Reinterpret_Cast(RefPtrBase&);
friend RefPtr<Type> Const_Cast(RefPtrConst<Type>&);
};
template<typename Type> class RefPtrConst :
public RefPtrBase
{
public:
RefPtrConst() :
RefPtrConst()
{}
template<typename Derived>
RefPtrConst(const RefPtr<Derived>& derived) :
RefPtrBase()
{
Attach(static_cast<RefCounted*>(derived.ReferencedObject()));
}
RefPtrConst(const RefPtr<Type>& object) :
RefPtrBase()
{
Attach(static_cast<RefCounted*>(const_cast<Type* const >(object.ReferencedObject())));
}
template<typename Derived>
RefPtrConst(const RefPtrConst<Derived>& derived) :
RefPtrBase()
{
Attach(static_cast<RefCounted*>(derived.ReferencedObject()));
}
RefPtrConst(const RefPtrConst<Type>& object) :
RefPtrBase()
{
Attach(static_cast<RefCounted*>(object.ReferencedObject()));
}
template<typename Derived>
inline const RefPtrConst<Type>& operator=(const RefPtr<Derived>& derived)
{
Attach(static_cast<RefCounted*>(derived.ReferencedObject()));
return *this;
}
inline const RefPtrConst<Type>& operator=(const RefPtr<Type>& object)
{
Attach(static_cast<RefCounted*>(object.ReferencedObject()));
return *this;
}
template<typename Derived>
inline const RefPtrConst<Type>& operator=(const RefPtrConst<Derived>& derived)
{
Attach(static_cast<RefCounted*>(derived.ReferencedObject()));
return *this;
}
inline const RefPtrConst<Type>& operator=(const RefPtrConst<Type>& object)
{
Attach(static_cast<RefCounted*>(object.ReferencedObject()));
return *this;
}
virtual ~RefPtrConst()
{}
inline const Type& operator*() const
{
assert(IsValid());
return *ReferencedObject();
}
inline const Type* const operator->() const
{
assert(IsValid());
return ReferencedObject();
}
// This is public mostly because I can't seem to declare rc_ptr<Other> as a friend
inline const Type* const ReferencedObject() const
{return reinterpret_cast<const Type*>(GetRefObject());}
RefPtrConst(const Type* object) :
RefPtrBase()
{
Attach(static_cast<RefCounted*>(object));
}
const RefPtrConst<Type>& operator=(const Type* object)
{
Attach(static_cast<RefCounted*>(object));
}
};
template<typename Derived>
RefPtr<Derived> Dynamic_Cast(RefPtrBase& base)
{
RefPtr<Derived> derived;
derived.Attach(base.GetRefObject());
return derived;
}
template<typename Type>
RefPtr<Type> Reinterpret_Cast(RefPtrBase& rhs)
{
RefPtr<Type> object;
object.Attach(rhs.GetRefObject());
return object;
}
template<typename Type>
RefPtr<Type> Const_Cast(RefPtrConst<Type>& rhs)
{
RefPtr<Type> object;
object.Attach(static_cast<RefCounted*>(rhs.ReferencedObject()));
return object;
}
#endif // __REFPTR_H__

View File

@@ -0,0 +1,61 @@
/*
** 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/WWOnline/WOLAgeCheck.h $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 1 $
* $Modtime: 7/09/01 6:03p $
*
******************************************************************************/
#ifndef __WOLAGECHECK_H__
#define __WOLAGECHECK_H__
namespace WWOnline {
class AgeCheckEvent
{
public:
AgeCheckEvent(int age, bool consent) :
mAge(age),
mConsent(consent)
{}
inline int GetAge()
const {return mAge;}
inline bool HasConsent() const
{return mConsent;}
private:
int mAge;
bool mConsent;
};
}
#endif // __WOLAGECHECK_H__

View File

@@ -0,0 +1,526 @@
/*
** 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/WWOnline/WOLChannel.cpp $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 23 $
* $Modtime: 1/17/02 12:04p $
*
******************************************************************************/
#include "always.h"
#include <stdlib.h>
#include "WOLChannel.h"
#include "WOLString.h"
#include <WOLAPI\ChatDefs.h>
#include <WWDebug\WWDebug.h>
namespace WWOnline {
/******************************************************************************
*
* NAME
* ChannelData::Create(WOL::Channel)
*
* DESCRIPTION
* Create Channel Data object from a WOLAPI channel.
*
* INPUTS
* WOLChannel - WOLAPI channel structure.
*
* RESULT
* Channel - Channel data object.
*
******************************************************************************/
RefPtr<ChannelData> ChannelData::Create(const WOL::Channel& wolChannel)
{
return new ChannelData(wolChannel);
}
/******************************************************************************
*
* NAME
* ChannelData::Create(Name, Password, Type)
*
* DESCRIPTION
* Create a new Channel Data object
*
* INPUTS
* Name - Name of channel.
* Password - Password needed to join channel
* Type - Type of channel
*
* RESULT
* Channel - Channel data object.
*
******************************************************************************/
RefPtr<ChannelData> ChannelData::Create(const wchar_t* name, const wchar_t* password, int type)
{
if (name && wcslen(name))
{
return new ChannelData(name, password, type);
}
return NULL;
}
/******************************************************************************
*
* NAME
* ChannelData::ChannelData(WOL::Channel)
*
* DESCRIPTION
* WOLAPI channel constructor
*
* INPUTS
* WOLChannel - WOLAPI channel structure.
*
* RESULT
* NONE
*
******************************************************************************/
ChannelData::ChannelData(const WOL::Channel& channel) :
mChannelName((char*)channel.name)
{
memcpy(&mData, &channel, sizeof(mData));
mData.next = NULL;
}
/******************************************************************************
*
* NAME
* ChannelData::ChannelData(Name, Password, Type)
*
* DESCRIPTION
* Named channel constructor
*
* INPUTS
* Name - Name of channel.
* Password - Password needed to join channel
* Type - Type of channel
*
* RESULT
* NONE
*
******************************************************************************/
ChannelData::ChannelData(const wchar_t* name, const wchar_t* password, int type) :
mChannelName(name)
{
memset(&mData, 0, sizeof(mData));
mData.type = type;
WWASSERT(name && "NULL channel name");
wcstombs((char*)mData.name, name, sizeof(mData.name));
mData.name[sizeof(mData.name) - 1] = 0;
if (password)
{
wcstombs((char*)mData.key, password, sizeof(mData.key));
}
}
/******************************************************************************
*
* NAME
* ChannelData::~ChannelData
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
ChannelData::~ChannelData()
{
}
/******************************************************************************
*
* NAME
* ChannelData::UpdateData
*
* DESCRIPTION
* Update channel data with the WOLAPI channel
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void ChannelData::UpdateData(const WOL::Channel& wolChannel)
{
wchar_t name[64];
mbstowcs(name, (const char*)wolChannel.name, sizeof(wolChannel.name));
name[sizeof(wolChannel.name) - 1] = 0;
WWASSERT(wcslen(name));
bool isValid = (!mChannelName.Is_Empty() && mChannelName.Compare_No_Case(name) == 0);
WWASSERT(isValid && "WOLChannelData::UpdateData() channel mismatch");
if (isValid)
{
memcpy(&mData, &wolChannel, sizeof(mData));
mData.next = NULL;
}
}
/******************************************************************************
*
* NAME
* ChannelData::SetLatency
*
* DESCRIPTION
* Update the channel latency.
*
* INPUTS
* Latency - Channel latency
*
* RESULT
* NONE
*
******************************************************************************/
void ChannelData::SetLatency(int latency)
{
mData.latency = latency;
}
/******************************************************************************
*
* NAME
* ChannelData::SetTopic
*
* DESCRIPTION
* Set the channel's topic
*
* INPUTS
* Topic - New channel topic string.
*
* RESULT
* NONE
*
******************************************************************************/
void ChannelData::SetTopic(const char* topic)
{
strncpy((char*)mData.topic, topic, sizeof(mData.topic));
mData.topic[sizeof(mData.topic) - 1] = 0;
}
/******************************************************************************
*
* NAME
* ChannelData::SetExtraInfo
*
* DESCRIPTION
* Set the channel's extra information.
*
* INPUTS
* ExInfo - Data to be kept in the channel's ExInfo field.
*
* RESULT
* NONE
*
******************************************************************************/
void ChannelData::SetExtraInfo(const char* exInfo)
{
strncpy((char*)mData.exInfo, exInfo, sizeof(mData.exInfo));
mData.exInfo[sizeof(mData.exInfo) - 1] = 0;
}
/******************************************************************************
*
* NAME
* ChannelData::IsPassworded
*
* DESCRIPTION
* Check if the channel requires a password to join.
*
* INPUTS
* NONE
*
* RESULT
* True if password required.
*
******************************************************************************/
bool ChannelData::IsPassworded(void) const
{
return ((mData.flags & CHAN_MODE_KEY) == CHAN_MODE_KEY);
}
/******************************************************************************
*
* NAME
* ChannelData::SetMinMaxUsers
*
* DESCRIPTION
* Set the number of users that can join this channel.
*
* INPUTS
* MinUsers - Minimum number of users required.
* MaxUsers - Maximum number of users allowed.
*
* RESULT
* NONE
*
******************************************************************************/
void ChannelData::SetMinMaxUsers(unsigned int minUsers, unsigned int maxUsers)
{
mData.minUsers = minUsers;
mData.maxUsers = maxUsers;
}
/******************************************************************************
*
* NAME
* ChannelData::SetOfficial
*
* DESCRIPTION
* Change the official state of this channel.
*
* INPUTS
* Official - Flag indicating if this channel is official or not.
*
* RESULT
* NONE
*
******************************************************************************/
void ChannelData::SetOfficial(bool official)
{
mData.official = official;
}
/******************************************************************************
*
* NAME
* ChannelData::SetTournament
*
* DESCRIPTION
* Set the type of tournament game this channel hosting.
*
* INPUTS
* Type - Type of tournament (0 = none)
*
* RESULT
* NONE
*
******************************************************************************/
void ChannelData::SetTournament(unsigned int tournamentType)
{
mData.tournament = tournamentType;
}
/******************************************************************************
*
* NAME
* GetChannelStatusFromHRESULT
*
* DESCRIPTION
* Get a channel status from the provided HRESULT
*
* INPUTS
* HRESULT - Error / Status code.
*
* RESULT
* ChannelStatus - Channel status
*
******************************************************************************/
ChannelStatus GetChannelStatusFromHResult(HRESULT result)
{
switch (result)
{
case CHAT_E_CHANNELEXISTS:
return ChannelExists;
break;
case CHAT_E_CHANNELDOESNOTEXIST:
return ChannelNotFound;
break;
case CHAT_E_BADCHANNELPASSWORD:
return ChannelBadPassword;
break;
case CHAT_E_CHANNELFULL:
return ChannelFull;
break;
case CHAT_E_BANNED:
return ChannelBanned;
break;
default:
break;
}
return ChannelError;
}
/******************************************************************************
*
* NAME
* GetChannelStatusDescription
*
* DESCRIPTION
* Get a channel status description for its status code.
*
* INPUTS
* Status - Channel status enumeration
*
* RESULT
* Description - Text description of channel status.
*
******************************************************************************/
const wchar_t* GetChannelStatusDescription(ChannelStatus status)
{
static const char* _statusDesc[] =
{
"WOL_CHANNELERROR",
"WOL_CHANNELLEFT",
"WOL_CHANNELJOINED",
"WOL_CHANNELCREATED",
"WOL_CHANNELNOTFOUND",
"WOL_CHANNELEXISTS",
"WOL_BADPASSWORD",
"WOL_CHANNELFULL",
"WOL_CHANNELBANNED",
"WOL_CHANNELKICKED",
"WOL_BLANK", // ChannelNewData
"WOL_CHANNELLEAVE"
};
WWASSERT(status >= 0 && status <= ChannelLeaving);
return WOLSTRING(_statusDesc[status + 1]);
}
// Find the channel node by name
ChannelList::iterator FindChannelNode(ChannelList& list, const char* name)
{
if (name == NULL)
{
return list.end();
}
ChannelList::iterator node = list.begin();
while (node != list.end())
{
WOL::Channel& wolChannel = (*node)->GetData();
if (stricmp(name, (const char*)wolChannel.name) == 0)
{
break;
}
node++;
}
return node;
}
// Find a channel in the specified list by ANSI name
RefPtr<ChannelData> FindChannelInList(ChannelList& list, const char* name)
{
if (name)
{
ChannelList::iterator node = list.begin();
while (node != list.end())
{
WOL::Channel& wolChannel = (*node)->GetData();
if (stricmp(name, (const char*)wolChannel.name) == 0)
{
return *node;
}
node++;
}
}
return NULL;
}
// Find a channel in the specified list by Unicode name.
RefPtr<ChannelData> FindChannelInList(ChannelList& list, const wchar_t* name)
{
if (name)
{
ChannelList::iterator node = list.begin();
while (node != list.end())
{
const WideStringClass& channame = (*node)->GetName();
if (channame.Compare_No_Case(name) == 0)
{
return *node;
}
node++;
}
}
return NULL;
}
} // namespace WWOnline

219
Code/WWOnline/WOLChannel.h Normal file
View File

@@ -0,0 +1,219 @@
/*
** 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/WWOnline/WOLChannel.h $
*
* DESCRIPTION
* Westwood Online channel representation.
*
* PROGRAMMER
* Denzil E. Long, Jr.
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 17 $
* $Modtime: 11/08/01 5:05p $
*
******************************************************************************/
#ifndef __WOLCHANNEL_H__
#define __WOLCHANNEL_H__
#include "RefCounted.h"
#include "RefPtr.h"
#include <WWLib\Notify.h>
#include <WWLib\WideString.h>
namespace WOL
{
#include <WOLAPI\wolapi.h>
}
#if defined(_MSC_VER)
#pragma warning(push, 3)
#endif
#include <list>
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
namespace WWOnline {
class ChannelData :
public RefCounted
{
public:
static RefPtr<ChannelData> Create(const WOL::Channel&);
static RefPtr<ChannelData> Create(const wchar_t* name, const wchar_t* password, int type);
const WideStringClass& GetName(void)
const {return mChannelName;}
int GetType(void) const
{return mData.type;}
void SetLatency(int latency);
int GetLatency(void) const
{return mData.latency;}
bool IsHidden(void) const
{return (mData.hidden != 0);}
void SetTopic(const char* topic);
const char* GetTopic(void) const
{return (const char*)mData.topic;}
void SetExtraInfo(const char* exInfo);
const char* GetExtraInfo(void) const
{return (const char*)mData.exInfo;}
// Check if this channel requires a password to join.
bool IsPassworded(void) const;
// Set the channels minimum and maximum users allowed.
void SetMinMaxUsers(unsigned int minUsers, unsigned int maxUsers);
// Get the minimum number of users for game.
inline unsigned int GetMinUsers(void) const
{return mData.minUsers;}
// Get the maximum number of users for game.
inline unsigned int GetMaxUsers(void) const
{return mData.maxUsers;}
inline unsigned int GetCurrentUsers(void) const
{return mData.currentUsers;}
// Set official status
void SetOfficial(bool official);
// Test if this channel is an official Westwood channel
inline bool IsOfficial(void) const
{return (mData.official != 0);}
// Set the tournament type this channel is hosting (0 = none)
void SetTournament(unsigned int tournamentType);
// Get the tournament type for this channel
inline unsigned int GetTournament(void) const
{return mData.tournament;}
inline unsigned int GetFlags(void) const
{return mData.flags;}
WOL::Channel& GetData(void)
{return mData;}
void UpdateData(const WOL::Channel&);
protected:
ChannelData(const WOL::Channel&);
ChannelData(const wchar_t* name, const wchar_t* password, int type);
virtual ~ChannelData();
ChannelData(const ChannelData&);
const ChannelData& operator=(const ChannelData&);
WOL::Channel mData;
WideStringClass mChannelName;
};
typedef enum
{
ChannelError = -1,
ChannelLeft = 0,
ChannelJoined,
ChannelCreated,
ChannelNotFound,
ChannelExists,
ChannelBadPassword,
ChannelFull,
ChannelBanned,
ChannelKicked,
ChannelNewData,
ChannelLeaving
} ChannelStatus;
ChannelStatus GetChannelStatusFromHResult(HRESULT result);
const wchar_t* GetChannelStatusDescription(ChannelStatus status);
class ChannelEvent :
public TypedEvent< ChannelEvent, const RefPtr<ChannelData> >
{
public:
ChannelStatus GetStatus(void) const
{return mStatus;}
ChannelEvent(ChannelStatus status, const RefPtr<ChannelData>& channel) :
TypedEvent< ChannelEvent, const RefPtr<ChannelData> >(channel),
mStatus(status)
{}
~ChannelEvent()
{}
protected:
ChannelStatus mStatus;
};
typedef std::list< RefPtr<ChannelData> > ChannelList;
class ChannelListEvent :
public TypedEvent<ChannelListEvent, ChannelList>
{
public:
typedef enum {Error = -1, NewList, Update, Remove} Event;
Event GetEvent(void) const
{return mEvent;}
int GetChannelType(void)
{return mType;}
ChannelListEvent(Event event, ChannelList& list, int type) :
TypedEvent<ChannelListEvent, ChannelList>(list),
mEvent(event),
mType(type)
{}
~ChannelListEvent()
{}
protected:
Event mEvent;
int mType;
};
ChannelList::iterator FindChannelNode(ChannelList& list, const char* name);
RefPtr<ChannelData> FindChannelInList(ChannelList& list, const wchar_t* name);
RefPtr<ChannelData> FindChannelInList(ChannelList& list, const char* name);
} // namespace WWOnline
#endif // __WOLCHANNEL_H__

View File

@@ -0,0 +1,310 @@
/*
** 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/WWOnline/WOLChatMsg.cpp $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 7 $
* $Modtime: 10/23/01 10:36a $
*
******************************************************************************/
#include "WOLChatMsg.h"
#include <WOLAPI\ChatDefs.h>
namespace WOL
{
#include <WOLAPI\wolapi.h>
}
namespace WWOnline {
/******************************************************************************
*
* NAME
* ChatMessage::ChatMessage
*
* DESCRIPTION
* Constructor (ANSI)
*
* INPUTS
* Sender - Name of message sender
* Message - Message to send
* Private - Flag indicating if message is private.
* Action - Flag indicating if message in an action.
*
* RESULT
*
******************************************************************************/
ChatMessage::ChatMessage(const WOL::User* sender, const char* message, bool isPrivate, bool isAction) :
mMessage(message),
mIsPrivate(isPrivate),
mIsAction(isAction),
mSenderFlags(0),
mSenderClanID(0)
{
if (sender)
{
mSenderName = (const char*)sender->name;
mSenderFlags = sender->flags;
mSenderClanID = sender->squadID;
}
}
/******************************************************************************
*
* NAME
* ChatMessage::ChatMessage
*
* DESCRIPTION
* Constructor (Unicode)
*
* INPUTS
* Sender - Name of message sender
* Message - Message to send
* Private - Flag indicating if message is private.
* Action - Flag indicating if message in an action.
*
* RESULT
* NONE
*
******************************************************************************/
ChatMessage::ChatMessage(const WOL::User* sender, const wchar_t* message, bool isPrivate, bool isAction) :
mMessage(message),
mIsPrivate(isPrivate),
mIsAction(isAction),
mSenderFlags(0),
mSenderClanID(0)
{
if (sender)
{
mSenderName = (const char*)sender->name;
mSenderFlags = sender->flags;
mSenderClanID = sender->squadID;
}
}
/******************************************************************************
*
* NAME
* ChatMessage::ChatMessage
*
* DESCRIPTION
* Constructor (Unicode)
*
* INPUTS
* Sender - Name of message sender
* Message - Message to send
* Private - Flag indicating if message is private.
* Action - Flag indicating if message in an action.
*
* RESULT
* NONE
*
******************************************************************************/
ChatMessage::ChatMessage(const wchar_t* sender, const wchar_t* message, bool isPrivate, bool isAction) :
mSenderName(sender),
mMessage(message),
mIsPrivate(isPrivate),
mIsAction(isAction),
mSenderFlags(CHAT_USER_MYSELF),
mSenderClanID(0)
{
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
ChatMessage::ChatMessage(const ChatMessage& chat)
{
*this = chat;
}
/******************************************************************************
*
* NAME
* ChatMessage::~ChatMessage
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
ChatMessage::~ChatMessage()
{
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
const ChatMessage& ChatMessage::operator=(const ChatMessage& chat)
{
mSenderName = chat.mSenderName;
mMessage = chat.mMessage;
mIsPrivate = chat.mIsPrivate;
mIsAction = chat.mIsAction;
mSenderFlags = chat.mSenderFlags;
mSenderClanID = chat.mSenderClanID;
return (*this);
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
bool ChatMessage::IsSenderMyself(void) const
{
return ((mSenderFlags & CHAT_USER_MYSELF) == CHAT_USER_MYSELF);
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
bool ChatMessage::IsSenderChannelOwner(void) const
{
return ((mSenderFlags & CHAT_USER_CHANNELOWNER) == CHAT_USER_CHANNELOWNER);
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
bool ChatMessage::IsSenderSquelched(void) const
{
return ((mSenderFlags & CHAT_USER_SQUELCHED) == CHAT_USER_SQUELCHED);
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
bool ChatMessage::IsSenderInClan(unsigned long clanID) const
{
return (mSenderClanID == clanID);
}
/******************************************************************************
*
* NAME
* InAnsiText
*
* DESCRIPTION
* Test if a Unicode string is within ANSI range.
*
* INPUTS
* Text - Unicode text to check.
*
* RESULT
* True if entire string is within ANSI range.
*
******************************************************************************/
bool IsAnsiText(const wchar_t* text)
{
for (int index = 0; text[index] != 0; index ++)
{
unsigned short value = text[index];
if (value > 255)
{
return false;
}
}
return true;
}
} // namespace WWOnline

101
Code/WWOnline/WOLChatMsg.h Normal file
View File

@@ -0,0 +1,101 @@
/*
** 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/WWOnline/WOLChatMsg.h $
*
* DESCRIPTION
* Chat Message representation.
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 6 $
* $Modtime: 10/23/01 10:19a $
*
******************************************************************************/
#ifndef __WOLCHATMSG_H__
#define __WOLCHATMSG_H__
#include <WWLib\WideString.h>
#ifdef _MSC_VER
#pragma warning (push,3)
#endif
#include <vector>
#ifdef _MSC_VER
#pragma warning (pop)
#endif
namespace WOL
{
struct User;
}
namespace WWOnline {
class ChatMessage
{
public:
ChatMessage(const WOL::User* sender, const char* message, bool isPrivate, bool isAction);
ChatMessage(const WOL::User* sender, const wchar_t* message, bool isPrivate, bool isAction);
ChatMessage(const wchar_t* sender, const wchar_t* message, bool isPrivate, bool isAction);
ChatMessage(const ChatMessage&);
virtual ~ChatMessage();
const ChatMessage& operator=(const ChatMessage&);
inline const WideStringClass& GetSendersName(void) const
{return mSenderName;}
inline const WideStringClass& GetMessage(void) const
{return mMessage;}
inline bool IsAction(void) const
{return mIsAction;}
inline bool IsPrivate(void) const
{return mIsPrivate;}
bool IsSenderMyself(void) const;
bool IsSenderChannelOwner(void) const;
bool IsSenderSquelched(void) const;
bool IsSenderInClan(unsigned long clanID) const;
protected:
WideStringClass mSenderName;
WideStringClass mMessage;
bool mIsPrivate;
bool mIsAction;
unsigned long mSenderFlags;
unsigned long mSenderClanID;
};
typedef std::vector<ChatMessage> ChatMessageList;
bool IsAnsiText(const wchar_t* text);
} // namespace WWOnline
#endif // __WOLCHATMSG_H__

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,185 @@
/*
** 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/WWOnline/WOLChatObserver.h $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Steve_t $
*
* VERSION INFO
* $Revision: 4 $
* $Modtime: 10/14/02 12:38p $
*
******************************************************************************/
#ifndef __WOLCHATOBSERVER_H__
#define __WOLCHATOBSERVER_H__
#include <objbase.h>
#include "RefPtr.h"
#include "WOLUser.h"
namespace WOL
{
#include <WOLAPI\wolapi.h>
}
namespace WWOnline {
class Session;
class SquadData;
class ChatObserver :
public WOL::IChatEvent
{
public:
ChatObserver();
void Init(Session& outer);
//---------------------------------------------------------------------------
// IUnknown methods
//---------------------------------------------------------------------------
virtual HRESULT STDMETHODCALLTYPE QueryInterface(const IID& iid, void** ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
//---------------------------------------------------------------------------
// IChatEvent Methods
//---------------------------------------------------------------------------
STDMETHOD(OnServerList)(HRESULT hr, WOL::Server* servers);
STDMETHOD(OnUpdateList)(HRESULT hr, WOL::Update* updates);
STDMETHOD(OnServerError)(HRESULT hr, LPCSTR ircmsg);
STDMETHOD(OnConnection)(HRESULT hr, LPCSTR motd);
STDMETHOD(OnMessageOfTheDay)(HRESULT hr, LPCSTR motd);
STDMETHOD(OnChannelList)(HRESULT hr, WOL::Channel* channels);
STDMETHOD(OnChannelCreate)(HRESULT hr, WOL::Channel* channel);
STDMETHOD(OnChannelJoin)(HRESULT hr, WOL::Channel* channel, WOL::User* user);
STDMETHOD(OnChannelLeave)(HRESULT hr, WOL::Channel* channel, WOL::User* user);
STDMETHOD(OnChannelTopic)(HRESULT hr, WOL::Channel* channel, LPCSTR topic);
STDMETHOD(OnPrivateAction)(HRESULT hr, WOL::User* user, LPCSTR action);
STDMETHOD(OnPublicAction)(HRESULT hr, WOL::Channel* channel, WOL::User* user, LPCSTR action);
STDMETHOD(OnUserList)(HRESULT hr, WOL::Channel* channel, WOL::User* users);
STDMETHOD(OnPublicMessage)(HRESULT hr, WOL::Channel* channel, WOL::User* user, LPCSTR message);
STDMETHOD(OnPrivateMessage)(HRESULT hr, WOL::User* user, LPCSTR message);
STDMETHOD(OnSystemMessage)(HRESULT hr, LPCSTR message);
STDMETHOD(OnNetStatus)(HRESULT hr);
STDMETHOD(OnLogout)(HRESULT status, WOL::User* user);
STDMETHOD(OnPrivateGameOptions)(HRESULT hr, WOL::User* user, LPCSTR options);
STDMETHOD(OnPublicGameOptions)(HRESULT hr, WOL::Channel* channel, WOL::User* user, LPCSTR options);
STDMETHOD(OnGameStart)(HRESULT hr, WOL::Channel* channel, WOL::User* users, int gameid);
STDMETHOD(OnUserKick)(HRESULT hr, WOL::Channel* channel, WOL::User* kicked, WOL::User* kicker);
STDMETHOD(OnUserIP)(HRESULT hr, WOL::User* user);
STDMETHOD(OnFind)(HRESULT hr, WOL::Channel* chan);
STDMETHOD(OnPageSend)(HRESULT hr);
STDMETHOD(OnPaged)(HRESULT hr, WOL::User* user, LPCSTR message);
STDMETHOD(OnServerBannedYou)(HRESULT hr, WOL::time_t bannedTill);
STDMETHOD(OnUserFlags)(HRESULT hr, LPCSTR name, unsigned int flags, unsigned int mask);
STDMETHOD(OnChannelBan)(HRESULT hr, LPCSTR name, int banned);
STDMETHOD(OnSquadInfo)(HRESULT hr, unsigned long id, WOL::Squad* squad);
STDMETHOD(OnUserLocale)(HRESULT hr, WOL::User* users);
STDMETHOD(OnUserTeam)(HRESULT hr, WOL::User* users);
STDMETHOD(OnSetLocale)(HRESULT hr, WOL::Locale newlocale);
STDMETHOD(OnSetTeam)(HRESULT hr, int newteam);
STDMETHOD(OnBuddyList)(HRESULT hr, WOL::User* buddyList);
STDMETHOD(OnBuddyAdd)(HRESULT hr, WOL::User* buddyAdded);
STDMETHOD(OnBuddyDelete)(HRESULT hr, WOL::User* buddyDeleted);
STDMETHOD(OnPublicUnicodeMessage)(HRESULT hr, WOL::Channel* channel, WOL::User* user, const unsigned short* message);
STDMETHOD(OnPrivateUnicodeMessage)(HRESULT hr, WOL::User* user, const unsigned short* message);
STDMETHOD(OnPrivateUnicodeAction)(HRESULT hr, WOL::User* user, const unsigned short* action);
STDMETHOD(OnPublicUnicodeAction)(HRESULT hr, WOL::Channel* channel, WOL::User* user, const unsigned short* action);
STDMETHOD(OnPagedUnicode)(HRESULT hr, WOL::User* user, const unsigned short* message);
STDMETHOD(OnServerTime)(HRESULT hr, WOL::time_t stime);
STDMETHOD(OnInsiderStatus)(HRESULT hr, WOL::User* users);
STDMETHOD(OnSetLocalIP)(HRESULT hr, LPCSTR message);
STDMETHOD(OnChannelListBegin)(HRESULT hr);
STDMETHOD(OnChannelListEntry)(HRESULT hr, WOL::Channel* channel);
STDMETHOD(OnChannelListEnd)(HRESULT hr);
protected:
virtual ~ChatObserver();
// prevent copy and assignment
ChatObserver(ChatObserver const &);
ChatObserver const & operator =(ChatObserver const &);
void AssignSquadToUsers(const UserList& users, const RefPtr<SquadData>& squad);
void ProcessSquadRequest(const RefPtr<SquadData>& squad);
void Kick_Spammer(WOL::User *wol_user);
private:
ULONG mRefCount;
Session* mOuter;
};
}
#endif // __WOLCHATOBSERVER_H__

2105
Code/WWOnline/WOLConnect.cpp Normal file

File diff suppressed because it is too large Load Diff

376
Code/WWOnline/WOLConnect.h Normal file
View File

@@ -0,0 +1,376 @@
/*
** 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/WWOnline/WOLConnect.h $
*
* DESCRIPTION
* Westwood Online wait conditions.
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 14 $
* $Modtime: 1/29/02 1:44p $
*
******************************************************************************/
#ifndef __WOLCONNECT_H__
#define __WOLCONNECT_H__
#include "WOLSession.h"
#include "WaitCondition.h"
#include "WOLChatMsg.h"
#include <WWLib\Notify.h>
#include <WWLib\WideString.h>
#include "RefPtr.h"
namespace WWOnline {
const wchar_t* const DefaultPassword = L"zotclot9";
//-----------------------------------------------------------------------------
// Retrieve serverlist wait condition
//-----------------------------------------------------------------------------
class ServerListWait :
public SingleWait,
public Observer<ServerError>,
public Observer<IRCServerList>
{
public:
static RefPtr<ServerListWait> Create(const RefPtr<Session>& session);
void WaitBeginning(void);
protected:
ServerListWait(const RefPtr<Session>&);
virtual ~ServerListWait();
ServerListWait(const ServerListWait&);
const ServerListWait& operator=(const ServerListWait&);
void HandleNotification(ServerError& serverError);
void HandleNotification(IRCServerList& serverList);
RefPtr<Session> mSession;
};
//-----------------------------------------------------------------------------
// Disconnect from WWOnline wait condition
//-----------------------------------------------------------------------------
class DisconnectWait :
public SingleWait,
public Observer<ServerError>,
public Observer<ConnectionStatus>
{
public:
static RefPtr<DisconnectWait> Create(const RefPtr<Session>& session);
void WaitBeginning(void);
void EndWait(WaitResult, const wchar_t*);
protected:
DisconnectWait(const RefPtr<Session>& session);
virtual ~DisconnectWait();
DisconnectWait(const DisconnectWait&);
const DisconnectWait& operator=(const DisconnectWait&);
void HandleNotification(ServerError& serverError);
void HandleNotification(ConnectionStatus& status);
RefPtr<Session> mSession;
};
//-----------------------------------------------------------------------------
// Connect to WWOnline wait condition
//-----------------------------------------------------------------------------
class ConnectWait :
public SingleWait,
public Observer<ServerError>,
public Observer<ConnectionStatus>
{
public:
static RefPtr<ConnectWait> Create(const RefPtr<Session>& session,
const RefPtr<ServerData>& server, const RefPtr<LoginInfo>& login);
void WaitBeginning(void);
void EndWait(WaitResult, const wchar_t*);
protected:
ConnectWait(const RefPtr<Session>& session, const RefPtr<ServerData>& server,
const RefPtr<LoginInfo>& login);
virtual ~ConnectWait();
ConnectWait(const ConnectWait&);
const ConnectWait& operator=(const ConnectWait&);
void HandleNotification(ServerError& serverError);
void HandleNotification(ConnectionStatus& status);
RefPtr<Session> mSession;
RefPtr<ServerData> mServer;
RefPtr<LoginInfo> mLogin;
};
//-----------------------------------------------------------------------------
// Request for chat channel list wait condition
//-----------------------------------------------------------------------------
class ChannelListWait :
public SingleWait,
public Observer<ServerError>,
public Observer<ConnectionStatus>,
public Observer<ChannelListEvent>
{
public:
static RefPtr<ChannelListWait> Create(const RefPtr<Session>& session, int type);
void WaitBeginning(void);
protected:
ChannelListWait(const RefPtr<Session>& session, int type);
virtual ~ChannelListWait();
ChannelListWait(const ChannelListWait&);
const ChannelListWait& operator=(const ChannelListWait&);
void HandleNotification(ServerError& serverError);
void HandleNotification(ConnectionStatus& status);
void HandleNotification(ChannelListEvent& event);
RefPtr<Session> mSession;
int mType;
};
//-----------------------------------------------------------------------------
// Request to leave a channel wait condition
//-----------------------------------------------------------------------------
class LeaveChannelWait :
public SingleWait,
public Observer<ServerError>,
public Observer<ConnectionStatus>,
public Observer<ChannelEvent>
{
public:
static RefPtr<LeaveChannelWait> Create(const RefPtr<Session>& session);
void WaitBeginning(void);
protected:
LeaveChannelWait(const RefPtr<Session>& session);
virtual ~LeaveChannelWait();
LeaveChannelWait(const LeaveChannelWait&);
const LeaveChannelWait& operator=(const LeaveChannelWait&);
void HandleNotification(ServerError& serverError);
void HandleNotification(ConnectionStatus& status);
void HandleNotification(ChannelEvent& status);
RefPtr<Session> mSession;
};
//-----------------------------------------------------------------------------
// Request to join a channel wait condition
//-----------------------------------------------------------------------------
class JoinChannelWait :
public SingleWait,
public Observer<ServerError>,
public Observer<ConnectionStatus>,
public Observer<ChannelEvent>
{
public:
static RefPtr<JoinChannelWait> Create(const RefPtr<Session>& session,
const RefPtr<ChannelData>& channel, const wchar_t* password);
static RefPtr<JoinChannelWait> Create(const RefPtr<Session>& session,
const wchar_t* channelName, const wchar_t* password, int type);
void WaitBeginning(void);
protected:
JoinChannelWait(const RefPtr<Session>& session, const RefPtr<ChannelData>& channel,
const wchar_t* password);
JoinChannelWait(const RefPtr<Session>& session, const wchar_t* channelName,
const wchar_t* password, int type);
virtual ~JoinChannelWait();
JoinChannelWait(const JoinChannelWait&);
const JoinChannelWait& operator=(const JoinChannelWait&);
void HandleNotification(ServerError& serverError);
void HandleNotification(ConnectionStatus& status);
void HandleNotification(ChannelEvent& status);
RefPtr<Session> mSession;
RefPtr<ChannelData> mChannel;
WideStringClass mChannelName;
WideStringClass mPassword;
int mType;
};
//-----------------------------------------------------------------------------
// Request to create a new channel wait condition
//-----------------------------------------------------------------------------
class CreateChannelWait :
public SingleWait,
public Observer<ServerError>,
public Observer<ConnectionStatus>,
public Observer<ChannelEvent>
{
public:
static RefPtr<CreateChannelWait> Create(const RefPtr<Session>& session,
const RefPtr<ChannelData>& channel, const wchar_t* password);
void WaitBeginning(void);
protected:
CreateChannelWait(const RefPtr<Session>& session, const RefPtr<ChannelData>& channel,
const wchar_t* password);
virtual ~CreateChannelWait();
CreateChannelWait(const CreateChannelWait&);
const CreateChannelWait& operator=(const CreateChannelWait&);
void HandleNotification(ServerError& serverError);
void HandleNotification(ConnectionStatus& status);
void HandleNotification(ChannelEvent& status);
RefPtr<Session> mSession;
RefPtr<ChannelData> mChannel;
WideStringClass mPassword;
};
//-----------------------------------------------------------------------------
// Request a new user list wait condition
//-----------------------------------------------------------------------------
class UserListWait :
public SerialWait,
public Observer<ServerError>,
public Observer<UserList>
{
public:
static RefPtr<UserListWait> Create(const RefPtr<Session>& session);
void WaitBeginning(void);
protected:
UserListWait(const RefPtr<Session>& session);
virtual ~UserListWait();
UserListWait(const UserListWait&);
const UserListWait& operator=(const UserListWait&);
void HandleNotification(ServerError&);
void HandleNotification(UserList&);
RefPtr<Session> mSession;
};
//-----------------------------------------------------------------------------
// Request to find a user wait condition
//-----------------------------------------------------------------------------
class GetUserWait :
public SerialWait
{
public:
static RefPtr<GetUserWait> Create(const RefPtr<Session>& session, const wchar_t* userName);
void WaitBeginning(void);
WaitResult GetResult(void);
protected:
GetUserWait(const RefPtr<Session>& session, const wchar_t* userName);
virtual ~GetUserWait();
GetUserWait(const GetUserWait&);
const GetUserWait& operator=(const GetUserWait&);
RefPtr<Session> mSession;
WideStringClass mUserName;
};
//-----------------------------------------------------------------------------
// Request to locate a user wait condition
//-----------------------------------------------------------------------------
class LocateUserWait :
public SingleWait,
public Observer<ServerError>,
public Observer<UserEvent>
{
public:
static RefPtr<LocateUserWait> Create(const RefPtr<Session>& session, const wchar_t* userName);
void WaitBeginning(void);
protected:
LocateUserWait(const RefPtr<Session>& session, const wchar_t* userName);
virtual ~LocateUserWait();
LocateUserWait(const LocateUserWait&);
const LocateUserWait& operator=(const LocateUserWait&);
void HandleNotification(ServerError&);
void HandleNotification(UserEvent&);
RefPtr<Session> mSession;
WideStringClass mUserName;
};
//-----------------------------------------------------------------------------
// Request to send a private message to a user wait condition
//-----------------------------------------------------------------------------
class SendMsgWait :
public SingleWait
{
public:
static RefPtr<SendMsgWait> Create(const RefPtr<Session>& session, ChatMessage& message);
void WaitBeginning(void);
protected:
SendMsgWait(const RefPtr<Session>& session, ChatMessage& message);
virtual ~SendMsgWait();
SendMsgWait(const SendMsgWait&);
const SendMsgWait& operator=(const SendMsgWait&);
RefPtr<Session> mSession;
ChatMessage mMessage;
};
}
#endif // __WOLCONNECT_H__

File diff suppressed because it is too large Load Diff

250
Code/WWOnline/WOLDownload.h Normal file
View File

@@ -0,0 +1,250 @@
/*
** 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/WWOnline/WOLDownload.h $
*
* DESCRIPTION
* This class specifies patch files to be downloaded from the server.
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 5 $
* $Modtime: 1/11/02 5:17p $
*
******************************************************************************/
#ifndef __WOLDOWNLOAD_H__
#define __WOLDOWNLOAD_H__
#include <atlbase.h>
#include "RefCounted.h"
#include "RefPtr.h"
#include "WaitCondition.h"
namespace WOL
{
#include <WOLAPI\wolapi.h>
}
namespace WWOnline {
class Session;
class DownloadEvent;
class Download :
public RefCounted,
public WOL::IDownloadEvent,
public Notifier<DownloadEvent>
{
public:
static RefPtr<Download> Create(const WOL::Update& patch);
bool Start(void);
void Stop(void);
bool IsDone(void) const;
void Process(void);
unsigned long GetSKU(void) const
{return mWOLUpdate.SKU;}
unsigned long GetVersion(void) const
{return mWOLUpdate.version;}
bool IsRequired(void) const
{return (mWOLUpdate.required != 0);}
const char* GetServerName(void) const
{return (const char*)mWOLUpdate.server;}
const char* GetLoginName(void) const
{return (const char*)mWOLUpdate.login;}
const char* GetPassword(void) const
{return (const char*)mWOLUpdate.password;}
const char* GetDownloadPath(void) const
{return (const char*)mWOLUpdate.patchpath;}
const char* GetFilename(void) const
{return (const char*)mWOLUpdate.patchfile;}
const char* GetLocalPath(void) const
{return (const char*)mWOLUpdate.localpath;}
int GetStatusCode(void) const
{return mStatusCode;}
const wchar_t* GetStatusText(void) const;
int GetErrorCode(void) const
{return mErrorCode;}
const wchar_t* GetErrorText(void) const;
void GetProgress(int& bytesRead, int& totalSize, int& timeElapsed, int& timeRemaining) const;
DECLARE_NOTIFIER(DownloadEvent)
protected:
typedef enum {DLError = 0, DLPending, DLDownloading, DLAborted, DLComplete} DLState;
Download(const WOL::Update& patch);
~Download();
bool CreateDownloadObject(void);
void ReleaseDownloadObject(void);
void SetError(int errorCode, const char* errorText);
const char* GetOnErrorText(int onErrorCode) const;
// Prevent copy and assignment.
Download(const Download&);
const Download& operator=(const Download&);
WOL::Update mWOLUpdate;
CComPtr<WOL::IDownload> mDownloadObject;
unsigned long mDownloadCookie;
DLState mState;
// Status / Error
int mStatusCode;
int mErrorCode;
const char* mErrorText;
// Progress
int mBytesRead;
int mTotalSize;
int mTimeElapsed;
int mTimeRemaining;
//---------------------------------------------------------------------------
// IUnknown methods
//---------------------------------------------------------------------------
protected:
virtual HRESULT STDMETHODCALLTYPE QueryInterface(const IID& iid, void** ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
//---------------------------------------------------------------------------
// IDownloadEvent Methods
//---------------------------------------------------------------------------
protected:
STDMETHOD(OnEnd)(void);
STDMETHOD(OnError)(int error);
STDMETHOD(OnProgressUpdate)(int bytesRead, int totalSize, int timeElapsed, int timeRemaining);
STDMETHOD(OnQueryResume)(void);
STDMETHOD(OnStatusUpdate)(int status);
};
typedef std::vector< RefPtr<Download> > DownloadList;
class DownloadEvent
{
public:
enum Event
{
DOWNLOAD_ERROR = -1,
DOWNLOAD_STATUS,
DOWNLOAD_BEGIN,
DOWNLOAD_PROGRESS,
DOWNLOAD_END,
DOWNLOAD_STOPPED,
DOWNLOAD_RESUME
};
Event GetEvent(void) const
{return mEvent;}
const RefPtr<Download>& GetDownload(void) const
{return mDownload;}
DownloadEvent(Event event, const RefPtr<Download>& download) :
mEvent(event),
mDownload(download)
{}
~DownloadEvent()
{}
protected:
// Prevent copy and assignment.
DownloadEvent(const DownloadEvent&);
const DownloadEvent& operator=(const DownloadEvent&);
Event mEvent;
const RefPtr<Download> mDownload;
};
typedef void (*DownloadWaitCallback)(DownloadEvent& event, unsigned long userdata);
class DownloadWait :
public SingleWait,
public Observer<DownloadEvent>
{
public:
static RefPtr<DownloadWait> Create(const DownloadList& files);
void WaitBeginning(void);
WaitResult GetResult(void);
void EndWait(WaitResult, const wchar_t*);
void SetCallback(DownloadWaitCallback callback, unsigned long userdata);
unsigned int GetDownloadCount(void) const
{return mFiles.size();}
const RefPtr<Download>& GetCurrentDownload(void) const
{return mCurrentDownload;}
protected:
DownloadWait(const DownloadList& files);
virtual ~DownloadWait();
// Prevent copy and assignment
DownloadWait(const DownloadWait&);
const DownloadWait& operator=(const DownloadWait&);
void DoCallback(DownloadEvent& event);
void HandleNotification(DownloadEvent&);
protected:
const DownloadList& mFiles;
int mFileIndex;
RefPtr<Download> mCurrentDownload;
DownloadWaitCallback mCallback;
unsigned long mUserdata;
};
} // namespace WWOnline
#endif // __WOLDOWNLOAD_H__

View File

@@ -0,0 +1,154 @@
/*
** 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/WWOnline/WOLErrorUtil.cpp $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 6 $
* $Modtime: 1/11/02 2:23p $
*
******************************************************************************/
#include "WOLErrorUtil.h"
#include <WOLAPI\ChatDefs.h>
#include <WOLAPI\NetUtilDefs.h>
#include <WOLAPI\DownloadDefs.h>
namespace WWOnline {
#define ADD_CASE(exp, msg) case exp: return msg;
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
const char* const GetChatErrorString(HRESULT hr)
{
switch (hr)
{
ADD_CASE(CHAT_E_NICKINUSE, "WOL_NICKINUSE");
ADD_CASE(CHAT_E_BADPASS, "WOL_BADPASSWORD");
ADD_CASE(CHAT_E_NONESUCH, "WOL_NONESUCH");
ADD_CASE(CHAT_E_CON_NETDOWN, "WOL_NETDOWN");
ADD_CASE(CHAT_E_CON_LOOKUP_FAILED, "WOL_FAILEDLOOKUP");
ADD_CASE(CHAT_E_CON_ERROR, "WOL_CONNECTERROR");
ADD_CASE(CHAT_E_TIMEOUT, "WOL_TIMEDOUT");
ADD_CASE(CHAT_E_MUSTPATCH, "WOL_PATCHREQUIRED");
ADD_CASE(CHAT_E_STATUSERROR, "WOL_STATUSERROR");
ADD_CASE(CHAT_E_UNKNOWNRESPONSE, "WOL_UNKNOWNERROR");
ADD_CASE(CHAT_E_CHANNELFULL, "WOL_CHANNELFULL");
ADD_CASE(CHAT_E_CHANNELEXISTS, "WOL_CHANNELCREATEERROR");
ADD_CASE(CHAT_E_CHANNELDOESNOTEXIST, "WOL_CHANNELNOTFOUND");
ADD_CASE(CHAT_E_BADCHANNELPASSWORD, "WOL_BADPASSWORD");
ADD_CASE(CHAT_E_BANNED, "WOL_BANNED");
ADD_CASE(CHAT_E_NOT_OPER, "WOL_NOTCHANOP");
ADD_CASE(CHAT_E_DISABLED, "WOL_ACCOUNTDISABLED");
ADD_CASE(CHAT_E_SERIALBANNED, "WOL_SERIALBANNED");
ADD_CASE(CHAT_E_SERIALDUP, "WOL_SERIALDUPLICATE");
ADD_CASE(CHAT_E_SERIALUNKNOWN, "WOL_SERIALUNKNOWN");
ADD_CASE(CHAT_E_SKUSERIALMISMATCH, "WOL_SERIALSKUMISMATCH");
ADD_CASE(CHAT_E_NOTCONNECTED, "WOL_NOTCONNECTED");
ADD_CASE(CHAT_E_NOCHANNEL, "WOL_CHANNELNOTFOUND");
ADD_CASE(CHAT_E_NOTIMPLEMENTED, "WOL_NOTIMPLEMENTED");
ADD_CASE(CHAT_E_PENDINGREQUEST, "WOL_PENDINGREQUEST");
ADD_CASE(CHAT_E_PARAMERROR, "WOL_PARAMERROR");
ADD_CASE(CHAT_E_LEAVECHANNEL, "WOL_CHANNELLEAVEERROR");
ADD_CASE(CHAT_E_JOINCHANNEL, "WOL_CHANNELJOINERROR");
ADD_CASE(CHAT_E_UNKNOWNCHANNEL, "WOL_CHANNELNOTFOUND");
default:
return "WOL_UNKNOWNERROR";
break;
}
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
const char* const GetNetUtilErrorString(HRESULT hr)
{
switch (hr)
{
ADD_CASE(NETUTIL_E_ERROR, "WOL_ERROR");
ADD_CASE(NETUTIL_E_BUSY, "WOL_BUSY");
ADD_CASE(NETUTIL_E_TIMEOUT, "WOL_TIMEDOUT");
ADD_CASE(NETUTIL_E_INVALIDFIELD, "WOL_PARAMERROR");
ADD_CASE(NETUTIL_E_CANTVERIFY, "WOL_CANTVERIFY");
default:
return "WOL_UNKNOWNERROR";
}
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
const char* const GetDownloadErrorString(HRESULT hr)
{
switch (hr)
{
ADD_CASE(DOWNLOADEVENT_NOSUCHSERVER, "WOL_DOWNLOADNOSERVER");
ADD_CASE(DOWNLOADEVENT_COULDNOTCONNECT, "WOL_DOWNLOADCONNECTERROR");
ADD_CASE(DOWNLOADEVENT_LOGINFAILED, "WOL_DOWNLOADLOGINERROR");
ADD_CASE(DOWNLOADEVENT_NOSUCHFILE, "WOL_DOWNLOADFNF");
ADD_CASE(DOWNLOADEVENT_LOCALFILEOPENFAILED, "WOL_DOWNLOADOPENERROR");
ADD_CASE(DOWNLOADEVENT_TCPERROR, "WOL_DOWNLOADIOERROR");
ADD_CASE(DOWNLOADEVENT_DISCONNECTERROR, "WOL_DOWNLOADDISCONNECTERROR");
default:
return "WOL_UNKNOWNERROR";
}
}
}

View File

@@ -0,0 +1,48 @@
/*
** 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/WWOnline/WOLErrorUtil.h $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 2 $
* $Modtime: 7/12/01 4:26p $
*
******************************************************************************/
#ifndef __WOLERROR_H__
#define __WOLERROR_H__
#include <objbase.h>
namespace WWOnline {
const char* const GetChatErrorString(HRESULT hr);
const char* const GetNetUtilErrorString(HRESULT hr);
const char* const GetDownloadErrorString(HRESULT hr);
}
#endif // __WOLERROR_H__

257
Code/WWOnline/WOLGame.cpp Normal file
View File

@@ -0,0 +1,257 @@
/*
** 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/WWOnline/WOLGame.cpp $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Steve_t $
*
* VERSION INFO
* $Revision: 10 $
* $Modtime: 8/21/02 12:30p $
*
******************************************************************************/
#include "always.h"
#include "WOLGame.h"
#include "WOLSession.h"
#include "WOLChannel.h"
#include "WOLString.h"
#include "WOLErrorUtil.h"
namespace WWOnline {
/******************************************************************************
*
* NAME
* GameStartEvent::GameStartEvent
*
* DESCRIPTION
* Constructor
*
* INPUTS
* Channel - Channel game is in.
* UserList - List of users in game.
* GameID - Game ID for this game.
*
* RESULT
* NONE
*
******************************************************************************/
GameStartEvent::GameStartEvent(const RefPtr<ChannelData>& channel, const UserList& users, unsigned long gameID) :
mResult(S_OK),
mChannel(channel),
mGameID(gameID)
{
for (unsigned int index = 0; index < users.size(); index++)
{
mPlayers.push_back(users[index]);
}
}
/******************************************************************************
*
* NAME
* GameStartEvent::GetErrorDescription
*
* DESCRIPTION
* Get text description of error condition.
*
* INPUTS
* NONE
*
* RESULT
* ErrorText - Error text description.
*
******************************************************************************/
const char* GameStartEvent::GetErrorDescription(void) const
{
return GetChatErrorString(mResult);
}
/******************************************************************************
*
* NAME
* GameStartWait::Create
*
* DESCRIPTION
* Create a game start wait condition.
*
* INPUTS
* Players - Players in game.
*
* RESULT
* Wait - Wait condition to process for game start.
*
******************************************************************************/
RefPtr<GameStartWait> GameStartWait::Create(const UserList& players, void(*timeout_callback)(void))
{
return new GameStartWait(players, timeout_callback);
}
/******************************************************************************
*
* NAME
* GameStartWait::GameStartWait
*
* DESCRIPTION
* Constructor
*
* INPUTS
* Players -
*
* RESULT
* NONE
*
******************************************************************************/
GameStartWait::GameStartWait(const UserList& players, void(*timeout_callback)(void)) :
SingleWait(WOLSTRING("WOL_GAMEIDFETCH")),
mPlayers(players)
{
mTimeoutCallback = timeout_callback;
WWDEBUG_SAY(("WOL: GameStartWait Create\n"));
}
/******************************************************************************
*
* NAME
* GameStartWait::~GameStartWait
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
GameStartWait::~GameStartWait()
{
WWDEBUG_SAY(("WOL: GameStartWait End %S\n", mEndText));
}
/******************************************************************************
*
* NAME
* GameStartWait::WaitBeginning
*
* DESCRIPTION
* Begin game start wait condition.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void GameStartWait::WaitBeginning(void)
{
WWDEBUG_SAY(("WOL: GameStartWait Begin\n"));
RefPtr<Session> session = Session::GetInstance(false);
if (!session.IsValid())
{
WWDEBUG_SAY(("WOLERROR: WOLSession not initialized\n"));
EndWait(Error, WOLSTRING("WOL_NOTINITIALIZED"));
}
Observer<GameStartEvent>::NotifyMe(*session);
HRESULT hr = session->GetChatObject()->RequestGameStart(mPlayers);
if (FAILED(hr))
{
WWDEBUG_SAY(("WOLERROR: GameStartWait %s\n", GetChatErrorString(hr)));
EndWait(Error, WOLSTRING("WOL_GAMEIDERROR"));
}
}
/******************************************************************************
*
* NAME
* GameStartWait::HandleNotification(GameStartEvent)
*
* DESCRIPTION
* Handle game start.
*
* INPUTS
* Event - Game start event.
*
* RESULT
* NONE
*
******************************************************************************/
void GameStartWait::HandleNotification(GameStartEvent& start)
{
if (mEndResult == Waiting)
{
if (start.IsSuccess())
{
EndWait(ConditionMet, WOLSTRING("WOL_GAMEIDRECEIVED"));
}
else
{
const char* text = start.GetErrorDescription();
WWDEBUG_SAY(("WOLERROR: GameStartWait %s\n", text));
EndWait(Error, WOLSTRING(text));
}
}
}
//
// Override base class to check for timeout
//
void GameStartWait::EndWait(WaitResult result, const wchar_t* endText)
{
WWDEBUG_SAY(("GameStartWait::EndWait\n"));
if (result == TimeOut && mTimeoutCallback) {
mTimeoutCallback();
}
SingleWait::EndWait(result, endText);
}
} // namespace WWOnline

111
Code/WWOnline/WOLGame.h Normal file
View File

@@ -0,0 +1,111 @@
/*
** 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/WWOnline/WOLGame.h $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Steve_t $
*
* VERSION INFO
* $Revision: 6 $
* $Modtime: 8/21/02 12:31p $
*
******************************************************************************/
#ifndef __WOLGAME_H__
#define __WOLGAME_H__
#include "RefPtr.h"
#include "WOLUser.h"
#include "WaitCondition.h"
#include <WWLib\Notify.h>
namespace WWOnline {
class ChannelData;
class GameStartEvent
{
public:
const RefPtr<ChannelData>& GetChannel(void) const
{return mChannel;}
const UserList& GetPlayers(void) const
{return mPlayers;}
const unsigned long GetGameID(void) const
{return mGameID;}
bool IsSuccess(void) const
{return SUCCEEDED(mResult);}
const char* GetErrorDescription(void) const;
GameStartEvent(HRESULT result) :
mResult(result),
mGameID(0)
{}
GameStartEvent(const RefPtr<ChannelData>& channel, const UserList& users, unsigned long gameID);
~GameStartEvent()
{}
protected:
GameStartEvent(const GameStartEvent&);
const GameStartEvent operator=(const GameStartEvent&);
private:
HRESULT mResult;
RefPtr<ChannelData> mChannel;
UserList mPlayers;
unsigned long mGameID;
};
class GameStartWait :
public SingleWait,
public Observer<GameStartEvent>
{
public:
static RefPtr<GameStartWait> Create(const UserList& players, void(*callback)(void) = NULL);
void WaitBeginning(void);
protected:
GameStartWait(const UserList& players, void(*callback)(void) = NULL);
virtual ~GameStartWait();
// Prevent copy and assignment
GameStartWait(const GameStartWait&);
const GameStartWait& operator=(const GameStartWait&);
void HandleNotification(GameStartEvent&);
void EndWait(WaitResult result, const wchar_t* endText);
void (*mTimeoutCallback)(void);
NativeWOLUserList mPlayers;
};
}
#endif // __WOLGAME_H__

View File

@@ -0,0 +1,92 @@
/*
** 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/WWOnline/WOLGameOptions.cpp $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 4 $
* $Modtime: 9/20/01 6:22p $
*
******************************************************************************/
#include "WOLGameOptions.h"
namespace WWOnline {
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
GameOptionsMessage::GameOptionsMessage(const WOL::User* user, const WOL::Channel* channel,
const char* options, bool isPrivate) :
mOptions(options),
mIsPrivate(isPrivate)
{
if (user)
{
memcpy(&mUser, user, sizeof(mUser));
}
else
{
memset(&mUser, 0, sizeof(mUser));
}
if (channel)
{
memcpy(&mChannel, &channel, sizeof(mChannel));
}
else
{
memset(&mChannel, 0, sizeof(mChannel));
}
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
GameOptionsMessage::~GameOptionsMessage()
{
}
} // namespace WWOnline

View File

@@ -0,0 +1,93 @@
/*
** 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/WWOnline/WOLGameOptions.h $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 4 $
* $Modtime: 10/04/01 10:28p $
*
******************************************************************************/
#ifndef __WOLGAMEOPTIONS_H__
#define __WOLGAMEOPTIONS_H__
#include "RefPtr.h"
#include <WWLib\WWString.h>
namespace WOL
{
#include "wolapi.h"
}
#ifdef _MSC_VER
#pragma warning (push,3)
#endif
#include <vector>
#ifdef _MSC_VER
#pragma warning (pop)
#endif
namespace WWOnline {
class GameOptionsMessage
{
public:
GameOptionsMessage(const WOL::User* user, const WOL::Channel* channel, const char* options, bool isPrivate);
virtual ~GameOptionsMessage();
inline const char* GetSendersName(void) const
{return (const char*)mUser.name;}
inline const WOL::User& GetWOLUser(void) const
{return mUser;}
inline const WOL::Channel& GetWOLChannel(void) const
{return mChannel;}
inline const StringClass& GetOptions(void) const
{return mOptions;}
inline bool IsPrivate(void) const
{return mIsPrivate;}
protected:
WOL::User mUser;
WOL::Channel mChannel;
StringClass mOptions;
bool mIsPrivate;
private:
GameOptionsMessage(const GameOptionsMessage&);
const GameOptionsMessage& operator=(const GameOptionsMessage&);
};
}
#endif // __WOLGAMEOPTIONS_H__

204
Code/WWOnline/WOLLadder.cpp Normal file
View File

@@ -0,0 +1,204 @@
/*
** 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/WWOnline/WOLLadder.cpp $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 7 $
* $Modtime: 12/03/01 3:22p $
*
******************************************************************************/
#include <string.h>
#include <memory.h>
#include "WOLLadder.h"
#include <WWDebug\WWDebug.h>
namespace WWOnline {
/******************************************************************************
*
* NAME
* LadderData::Create
*
* DESCRIPTION
*
* INPUTS
* WOLLadder - WOLAPI ladder structure
*
* RESULT
* Ladder -
*
******************************************************************************/
RefPtr<LadderData> LadderData::Create(const WOL::Ladder& ladder, long time)
{
return new LadderData(ladder, time);
}
/******************************************************************************
*
* NAME
* LadderData::LadderData
*
* DESCRIPTION
* Constructor
*
* INPUTS
* WOLLadder - WOLAPI ladder structure
*
* RESULT
* NONE
*
******************************************************************************/
LadderData::LadderData(const WOL::Ladder& ladder, long time) :
mTimeStamp(time)
{
// WWDEBUG_SAY(("WOL: Instantiating LadderData\n"));
memcpy(&mData, &ladder, sizeof(mData));
mData.next = NULL;
}
/******************************************************************************
*
* NAME
* LadderData::~LadderData
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
LadderData::~LadderData()
{
// WWDEBUG_SAY(("WOL: Destructing LadderData\n"));
}
/******************************************************************************
*
* NAME
* LadderData::UpdateData
*
* DESCRIPTION
* Update the ladder information
*
* INPUTS
* WOLLadder - WOLAPI ladder structure
*
* RESULT
* Updated - True if ladder data was updated.
*
******************************************************************************/
bool LadderData::UpdateData(const WOL::Ladder& ladder, long time)
{
if (time > mTimeStamp)
{
memcpy(&mData, &ladder, sizeof(mData));
mData.next = NULL;
return true;
}
return false;
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
LadderInfoEvent::LadderInfoEvent(const wchar_t* requested, const WOL::Ladder& ladder, long time) :
mRequestedName(requested),
mWOLLadder(ladder),
mTimeStamp(time)
{
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
*
******************************************************************************/
bool LadderInfoEvent::IsRanked(void) const
{
return (strlen((const char*)mWOLLadder.login_name) > 0);
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
*
******************************************************************************/
LadderType LadderInfoEvent::GetLadderType(void) const
{
LadderType type = (LadderType)(mWOLLadder.sku & LADDERTYPE_MASK);
if (type == 0)
{
type = LadderType_Individual;
}
return type;
}
} // namespace WWOnline

141
Code/WWOnline/WOLLadder.h Normal file
View File

@@ -0,0 +1,141 @@
/*
** 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/WWOnline/WOLLadder.h $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 6 $
* $Modtime: 1/25/02 11:51a $
*
******************************************************************************/
#ifndef __WOLLADDER_H__
#define __WOLLADDER_H__
#pragma warning(disable : 4711)
#include "RefCounted.h"
#include "RefPtr.h"
namespace WOL
{
#include <wolapi\wolapi.h>
}
namespace WWOnline {
typedef enum
{
LadderType_Individual = (1<<16L),
LadderType_Clan = (1<<23L),
LadderType_Team = (1<<24L)
} LadderType;
#define LADDERTYPE_MASK (LadderType_Individual | LadderType_Clan | LadderType_Team)
class LadderData :
public RefCounted
{
public:
static RefPtr<LadderData> Create(const WOL::Ladder& ladder, long time);
bool UpdateData(const WOL::Ladder& ladder, long time);
const char* GetName(void) const
{return (const char*)mData.login_name;}
unsigned int GetWins(void) const
{return mData.wins;}
unsigned int GetLosses(void) const
{return mData.losses;}
unsigned int GetPoints(void) const
{return mData.points;}
unsigned int GetKills(void) const
{return mData.kills;}
unsigned int GetRung(void) const
{return mData.rung;}
unsigned int GetReserved1(void) const
{return mData.reserved1;}
unsigned int GetReserved2(void) const
{return mData.reserved2;}
long GetTimeStamp(void) const
{return mTimeStamp;}
WOL::Ladder& GetData()
{return mData;}
protected:
LadderData(const WOL::Ladder& ladder, long time);
virtual ~LadderData();
WOL::Ladder mData;
long mTimeStamp;
};
class LadderInfoEvent
{
public:
LadderInfoEvent(const wchar_t* requested, const WOL::Ladder& ladder, long time);
virtual ~LadderInfoEvent()
{}
bool IsRanked(void) const;
LadderType GetLadderType(void) const;
const wchar_t* GetRequestedName(void) const
{return mRequestedName;}
const char* GetReceivedName(void) const
{return (const char*)mWOLLadder.login_name;}
const WOL::Ladder& GetWOLLadder(void) const
{return mWOLLadder;}
long GetTimeStamp(void) const
{return mTimeStamp;}
protected:
// Prevent copy and assignment
LadderInfoEvent(const LadderInfoEvent&);
const LadderInfoEvent& operator=(const LadderInfoEvent&);
const wchar_t* mRequestedName;
const WOL::Ladder& mWOLLadder;
long mTimeStamp;
};
}
#endif // __WOLLADDER_H__

View File

@@ -0,0 +1,58 @@
/*
** 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/WWOnline/WOLLangCodes.h $
*
* DESCRIPTION
* Westwood Online Product Language Codes.
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 1 $
* $Modtime: 2/06/02 2:53p $
*
******************************************************************************/
#ifndef __WOLLANGCODE_H__
#define __WOLLANGCODE_H__
namespace WWOnline {
typedef enum
{
LANGCODE_USA = 0,
LANGCODE_UK,
LANGCODE_GERMAN,
LANGCODE_FRENCH,
LANGCODE_DUTCH,
LANGCODE_ITALIAN,
LANGCODE_JAPANESE,
LANGCODE_SPANISH,
LANGCODE_SCANDINAVIAN,
LANGCODE_KOREAN,
LANGCODE_CHINESE
} LANGCODE;
}
#endif // __WOLLANGCODE_H__

View File

@@ -0,0 +1,620 @@
/*
** 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/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 <atlbase.h>
#include "WOLLoginInfo.h"
#include "WOLSession.h"
#include <WWLib\WWString.h>
#include <WWDebug\WWDebug.h>
namespace WOL
{
#include <WOLAPI\wolapi.h>
}
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 = Session::GetInstance(false);
if (session.IsValid() && session->IsStoreLoginAllowed())
{
// Four logins allowed per user
_mLoginList.reserve(4);
const CComPtr<WOL::IChat>& 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<LoginInfo> 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> 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<LoginInfo> login = list[index];
WWASSERT(login.IsValid());
const WideStringClass& nickname = login->GetNickname();
if (nickname.Compare_No_Case(name) == 0)
{
return login;
}
}
}
return NULL;
}
RefPtr<LoginInfo> 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> 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> 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 = Session::GetInstance(false);
if (session.IsValid() && session->IsStoreLoginAllowed())
{
const CComPtr<WOL::IChat>& 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 = Session::GetInstance(false);
if (session.IsValid())
{
const CComPtr<WOL::IChat>& 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 = Session::GetInstance(false);
if (session.IsValid() && session->IsStoreLoginAllowed())
{
int index = IndexOf();
if (index != 0)
{
const CComPtr<WOL::IChat>& 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 = Session::GetInstance(false);
if (session.IsValid())
{
char username[64];
wcstombs(username, nick, sizeof(username));
const CComPtr<WOL::IChat>& 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 = Session::GetInstance(false);
if (session.IsValid() && session->IsStoreLoginAllowed())
{
const CComPtr<WOL::IChat>& 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

View File

@@ -0,0 +1,149 @@
/*
** 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/WWOnline/WOLLoginInfo.h $
*
* 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: 10 $
* $Modtime: 1/18/02 11:46p $
*
******************************************************************************/
#ifndef __WOLLOGININFO_H__
#define __WOLLOGININFO_H__
#include "RefCounted.h"
#include "RefPtr.h"
#include <WWLib\WideString.h>
namespace WOL
{
#include <wolapi\wolapi.h>
}
#if defined(_MSC_VER)
#pragma warning(push, 3)
#endif
#include <vector>
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
namespace WWOnline {
class LoginInfo;
typedef std::vector< RefPtr<LoginInfo> > LoginInfoList;
class LoginInfo :
public RefCounted
{
public:
static const LoginInfoList& GetList(void);
static void ClearList(void);
static RefPtr<LoginInfo> Find(const wchar_t* nickname);
static RefPtr<LoginInfo> Find(const char* nickname);
static RefPtr<LoginInfo> Create(const wchar_t* nickname, const wchar_t* password, bool isEncrypted);
static RefPtr<LoginInfo> Create(const char* nickname, const char* password, bool isEncrypted);
static void StoreLogin(const char* nickname, const char* password, bool isEncrypted,
WOL::Locale locale);
const WideStringClass& GetNickname(void) const
{return mNickname;}
const WideStringClass& GetPassword(void) const
{return mPassword;}
void SetPassword(const wchar_t* password, bool isEncrypted);
bool IsPasswordEncrypted(void) const
{return mIsPasswordEncrypted;}
void SetLocale(WOL::Locale locale);
WOL::Locale GetLocale(void);
bool IsStored(void) const
{return mIsStored;}
// Remeber the login
void Remember(bool store);
// Delete login from local storage
void Forget(bool purge);
protected:
LoginInfo(const wchar_t* nickname, const wchar_t* password, bool isEncrypted);
virtual ~LoginInfo();
// Prevent copy and assignment
LoginInfo(const LoginInfo&);
const LoginInfo& operator=(const LoginInfo&);
static int IndexOf(const wchar_t* nickname);
int IndexOf(void) const;
private:
static LoginInfoList _mLoginList;
WideStringClass mNickname;
WideStringClass mPassword;
WOL::Locale mLocale;
bool mIsPasswordEncrypted;
bool mIsStored;
};
class NewLoginInfoEvent
{
public:
NewLoginInfoEvent(const RefPtr<LoginInfo>& login, const WideStringClass& message) :
mLogin(login), mMessage(message)
{}
const RefPtr<LoginInfo>& GetLogin(void) const
{return mLogin;}
const WideStringClass& GetMessage(void) const
{return mMessage;}
private:
NewLoginInfoEvent(const NewLoginInfoEvent&);
const NewLoginInfoEvent& operator=(const NewLoginInfoEvent&);
RefPtr<LoginInfo> mLogin;
WideStringClass mMessage;
};
}
#endif // __WOLLOGININFO_H__

View File

@@ -0,0 +1,648 @@
/*
** 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/WWOnline/WOLNetUtilObserver.cpp $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 25 $
* $Modtime: 2/21/02 5:36p $
*
******************************************************************************/
#include <atlbase.h>
#include "WOLNetUtilObserver.h"
#include "WOLSession.h"
#include "WOLLadder.h"
#include "WOLServer.h"
#include "WOLErrorUtil.h"
namespace WWOnline {
/******************************************************************************
*
* NAME
* NetUtilObserver::NetUtilObserver
*
* DESCRIPTION
* Constructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
NetUtilObserver::NetUtilObserver() :
mRefCount(1),
mOuter(NULL)
{
WWDEBUG_SAY(("WOL: NetUtilObserver Instantiated\n"));
}
/******************************************************************************
*
* NAME
* NetUtilObserver::~NetUtilObserver
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
NetUtilObserver::~NetUtilObserver()
{
WWDEBUG_SAY(("WOL: NetUtilObserver Destroyed\n"));
}
/******************************************************************************
*
* NAME
* NetUtilObserver::Init
*
* DESCRIPTION
* Initialize Net utility observer
*
* INPUTS
* WOLSession - Outer session
*
* RESULT
* NONE
*
******************************************************************************/
void NetUtilObserver::Init(Session& outer)
{
mOuter = &outer;
}
/****************************************************************************
*
* NAME
* IUnknown::QueryInterface
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
****************************************************************************/
STDMETHODIMP NetUtilObserver::QueryInterface(const IID& iid, void** ppv)
{
if ((iid == IID_IUnknown) || (iid == WOL::IID_INetUtilEvent))
{
*ppv = static_cast<WOL::INetUtilEvent*>(this);
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
static_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
/****************************************************************************
*
* NAME
* IUnknown::AddRef
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
*
****************************************************************************/
ULONG STDMETHODCALLTYPE NetUtilObserver::AddRef(void)
{
InterlockedIncrement((LPLONG)&mRefCount);
return mRefCount;
}
/****************************************************************************
*
* NAME
* IUnknown::Release
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
*
****************************************************************************/
ULONG STDMETHODCALLTYPE NetUtilObserver::Release(void)
{
InterlockedDecrement((LPLONG)&mRefCount);
if (mRefCount == 0)
{
delete this;
return 0;
}
return mRefCount;
}
/******************************************************************************
*
* NAME
* NetUtilObserver::OnPing
*
* DESCRIPTION
* Handle ping result response to a ping request
*
* INPUTS
* Result - Error / Status code
* Time - Ping time
* IP - IP Address
* Handle - Ping request handle
*
* RESULT
*
******************************************************************************/
STDMETHODIMP NetUtilObserver::OnPing(HRESULT result, int time, unsigned long ip, int handle)
{
if (mOuter == NULL)
{
WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
WWASSERT(mOuter && "Session not initialized");
return S_OK;
}
if (FAILED(result))
{
WWDEBUG_SAY(("WOLERROR: OnPing '%s'\n", GetNetUtilErrorString(result)));
return S_OK;
}
// Find the ping request
int pingIndex = -1;
for (unsigned int index = 0; index < mOuter->mPingRequests.size(); index++)
{
if (mOuter->mPingRequests[index].GetHandle() == handle)
{
pingIndex = index;
break;
}
}
if ((pingIndex >= 0) && ((unsigned)pingIndex < mOuter->mPingRequests.size()))
{
RawPing* ping = &mOuter->mPingRequests[pingIndex];
ping->SetTime(time);
ping->SetIPAddress(ip);
WWDEBUG_SAY(("WOL: OnPing %s = %d\n", ping->GetHostAddress(), time));
// Automatically update ping time for ping servers.
mOuter->UpdatePingServerTime(ping->GetHostAddress(), time);
// Notify others about the ping result.
mOuter->NotifyObservers(*ping);
// Remove ping from request list.
std::vector<RawPing>::iterator iter = mOuter->mPingRequests.begin();
while (iter != mOuter->mPingRequests.end())
{
if (iter == ping)
{
mOuter->mPingRequests.erase(iter);
mOuter->mPingsPending--;
break;
}
iter++;
}
}
return S_OK;
}
/******************************************************************************
*
* NAME
* NetUtilObserver::OnLadderList
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
STDMETHODIMP NetUtilObserver::OnLadderList(HRESULT result, WOL::Ladder* list,
int rungCount, long timeStamp, int keyRung)
{
if (mOuter == NULL)
{
WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
WWASSERT(mOuter && "Session not initialized");
return S_OK;
}
if (FAILED(result) || (list == NULL))
{
WWDEBUG_SAY(("WOLERROR: OnLadderList '%s'\n", GetNetUtilErrorString(result)));
// Clear the ladder type we requested (in order)
if (mOuter->mLadderPending & LadderType_Individual)
{
mOuter->mLadderPending &= ~LadderType_Individual;
}
else if (mOuter->mLadderPending & LadderType_Team)
{
mOuter->mLadderPending &= ~LadderType_Team;
}
else if (mOuter->mLadderPending & LadderType_Clan)
{
mOuter->mLadderPending &= ~LadderType_Clan;
}
else
{
mOuter->mLadderPending &= ~LADDERTYPE_MASK;
}
// If there are no pending ladders then remove the satisfied requests
if ((mOuter->mLadderPending & LADDERTYPE_MASK) == 0)
{
for (unsigned int count = 0; count < mOuter->mLadderPending; count++)
{
mOuter->mLadderRequests.pop_front();
}
mOuter->mLadderPending = 0;
}
return S_OK;
}
//---------------------------------------------------------------------------
// Handle ladder information for individual users.
//---------------------------------------------------------------------------
if (keyRung == -1)
{
ProcessLadderListResults(list, timeStamp);
return S_OK;
}
//---------------------------------------------------------------------------
// Handle ladder search results
//---------------------------------------------------------------------------
LadderList ladders;
WOL::Ladder* wolLadder = list;
while (wolLadder)
{
RefPtr<LadderData> data = LadderData::Create(*wolLadder, timeStamp);
if (data.IsValid())
{
ladders.push_back(data);
}
wolLadder = wolLadder->next;
}
mOuter->NotifyObservers(ladders);
return S_OK;
}
/******************************************************************************
*
* NAME
* NetUtilObserver::ProcessLadderListResults
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void NetUtilObserver::ProcessLadderListResults(WOL::Ladder* list, long timeStamp)
{
if (mOuter->mLadderPending)
{
// Within a given request, ladder results are guaranteed to be in order.
WOL::Ladder* wolLadder = list;
// Extract the ladder request type from the hiword of the SKU
LadderType type = (LadderType)(wolLadder->sku & LADDERTYPE_MASK);
if (type == 0)
{
type = LadderType_Individual;
}
Session::LadderRequestList::iterator request = mOuter->mLadderRequests.begin();
unsigned int ladderCount = 0;
while (wolLadder)
{
// Get the name of the user we requested information for.
const WCHAR* requestName = wcschr(*request, L':');
WWASSERT(requestName != NULL && "Invalid ladder request");
requestName++;
wchar_t ladderName[64];
mbstowcs(ladderName, (const char*)wolLadder->login_name, sizeof(wolLadder->login_name));
WWDEBUG_SAY(("WOL: LadderInfo [%08lX] Requested '%S', Received '%S'\n", type, requestName, ladderName));
// If the ladder name matches the requested name then there is ladder info available.
bool hasLadderData = (wcsicmp(requestName, ladderName) == 0);
if (type == LadderType_Clan)
{
RefPtr<SquadData> squad = SquadData::FindByAbbr(requestName);
if (squad.IsValid())
{
// Update / create ladder information for this clan
RefPtr<LadderData> ladderData = squad->GetLadder();
if (ladderData.IsValid())
{
ladderData->UpdateData(*wolLadder, timeStamp);
}
else if (hasLadderData)
{
ladderData = LadderData::Create(*wolLadder, timeStamp);
WWASSERT(ladderData.IsValid());
squad->SetLadder(ladderData);
}
// Notify others about updated clan ladder information
NotifyClanLadderUpdate(mOuter->mUsers, squad);
NotifyClanLadderUpdate(mOuter->mBuddies, squad);
}
}
else
{
RefPtr<UserData> user = mOuter->GetUserOrBuddy(requestName);
// Update users with new ladder information.
if (user.IsValid())
{
RefPtr<LadderData> ladderData = user->GetLadderFromType(type);
if (ladderData.IsValid())
{
ladderData->UpdateData(*wolLadder, timeStamp);
}
else if (hasLadderData)
{
ladderData = LadderData::Create(*wolLadder, timeStamp);
WWASSERT(ladderData.IsValid());
if (ladderData.IsValid())
{
user->SetLadderFromType(ladderData, type);
}
}
// Notify others that the ladder information for this user has changed.
UserEvent event(UserEvent::LadderInfo, user);
mOuter->NotifyObservers(event);
}
}
// Notify others about the raw ladder information
LadderInfoEvent ladderEvent(ladderName, *wolLadder, timeStamp);
mOuter->NotifyObservers(ladderEvent);
request++;
ladderCount++;
wolLadder = wolLadder->next;
}
// Clear the ladder type we received
mOuter->mLadderPending &= ~type;
// If there are no pending ladders then remove the satisfied requests
if ((mOuter->mLadderPending & LADDERTYPE_MASK) == 0)
{
WWASSERT(ladderCount == mOuter->mLadderPending && "LadderInfo received doesn't match number requested");
for (unsigned int count = 0; count < mOuter->mLadderPending; ++count)
{
mOuter->mLadderRequests.pop_front();
}
mOuter->mLadderPending = 0;
}
}
}
void NetUtilObserver::NotifyClanLadderUpdate(const UserList& users, const RefPtr<SquadData>& squad)
{
const unsigned int userCount = users.size();
for (unsigned int index = 0; index < userCount; ++index)
{
const RefPtr<UserData>& user = users[index];
if (user.IsValid() && (user->GetSquadID() == squad->GetID()))
{
// Notify others that this user received squad information
UserEvent event(UserEvent::LadderInfo, user);
mOuter->NotifyObservers(event);
}
}
}
/******************************************************************************
*
* NAME
* NetUtilObserver::OnGameresSent
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
STDMETHODIMP NetUtilObserver::OnGameresSent(HRESULT)
{
WWDEBUG_SAY(("WOLWARNING: OnGameresSent() not implemented\n"));
return S_OK;
}
/******************************************************************************
*
* NAME
* NetUtilObserver::OnNewNick
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
STDMETHODIMP NetUtilObserver::OnNewNick(HRESULT result, LPCSTR message, LPCSTR nickname, LPCSTR password)
{
if (mOuter == NULL)
{
WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
WWASSERT(mOuter && "Session not initialized");
return S_OK;
}
if (FAILED(result))
{
WWDEBUG_SAY(("WOLERROR: OnNewNick '%s'\n", GetNetUtilErrorString(result)));
return S_OK;
}
RefPtr<LoginInfo> login;
if (result == S_OK)
{
login = LoginInfo::Create(nickname, password, true);
}
NewLoginInfoEvent event(login, message);
mOuter->NotifyObservers(event);
return S_OK;
}
/******************************************************************************
*
* NAME
* NetUtilObserver::OnAgeCheck
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
STDMETHODIMP NetUtilObserver::OnAgeCheck(HRESULT result, int years, int consent)
{
if (mOuter == NULL)
{
WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
WWASSERT(mOuter && "Session not initialized");
return S_OK;
}
if (FAILED(result))
{
WWDEBUG_SAY(("WOLERROR: OnAgeCheck '%s'\n", GetNetUtilErrorString(result)));
return S_OK;
}
AgeCheckEvent event(years, consent != 0);
mOuter->NotifyObservers(event);
return S_OK;
}
/******************************************************************************
*
* NAME
* NetUtilObserver::OnWDTState
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
STDMETHODIMP NetUtilObserver::OnWDTState(HRESULT result, unsigned char* , int )
{
WWDEBUG_SAY(("WOLWARNING: OnWDTState not implemented\n"));
return S_OK;
}
/******************************************************************************
*
* NAME
* NetUtilObserver::OnHighscore
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
STDMETHODIMP NetUtilObserver::OnHighscore(HRESULT result, WOL::Highscore* list,
int count, long time, int keyRung)
{
WWDEBUG_SAY(("WOLWARNING: OnHighscore not implemented\n"));
return S_OK;
}
} // namespace WWOnline

View File

@@ -0,0 +1,101 @@
/*
** 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/WWOnline/WOLNetUtilObserver.h $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 4 $
* $Modtime: 1/22/02 5:53p $
*
******************************************************************************/
#ifndef __WOLNETUTILOBSERVER_H__
#define __WOLNETUTILOBSERVER_H__
#include <windows.h>
#include "WOLUser.h"
namespace WOL
{
#include <WOLAPI\wolapi.h>
}
template<typename T> class RefPtr;
namespace WWOnline {
class Session;
class SquadData;
class NetUtilObserver :
public WOL::INetUtilEvent
{
public:
NetUtilObserver();
void Init(Session& outer);
//---------------------------------------------------------------------------
// IUnknown methods
//---------------------------------------------------------------------------
virtual HRESULT STDMETHODCALLTYPE QueryInterface(const IID& iid, void** ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
//---------------------------------------------------------------------------
// INetUtilEvent Methods
//---------------------------------------------------------------------------
STDMETHOD(OnPing)(HRESULT hr, int time, unsigned long ip, int handle);
STDMETHOD(OnLadderList)(HRESULT hr, WOL::Ladder* list, int count, long time, int keyRung);
STDMETHOD(OnGameresSent)(HRESULT hr);
STDMETHOD(OnNewNick)(HRESULT hr, LPCSTR message, LPCSTR nick, LPCSTR pass);
STDMETHOD(OnAgeCheck)(HRESULT hr, int years, int consent);
STDMETHOD(OnWDTState)(HRESULT hr, unsigned char* state, int length);
STDMETHOD(OnHighscore)(HRESULT hr, WOL::Highscore* list, int count, long time, int keyRung);
protected:
virtual ~NetUtilObserver();
NetUtilObserver(const NetUtilObserver&);
const NetUtilObserver& operator=(const NetUtilObserver&);
void ProcessLadderListResults(WOL::Ladder* list, long timeStamp);
void NotifyClanLadderUpdate(const UserList& users, const RefPtr<SquadData>& squad);
private:
ULONG mRefCount;
Session* mOuter;
};
}
#endif // _WOLNETUTILOBSERVER_H__

View File

@@ -0,0 +1,156 @@
/*
** 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/WWOnline/WOLPageMsg.cpp $
*
* DESCRIPTION
* Page message
*
* PROGRAMMER
* Denzil E. Long, Jr.
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 6 $
* $Modtime: 12/19/01 2:12p $
*
******************************************************************************/
#include "WOLPageMsg.h"
namespace WOL
{
#include <WOLAPI\chatdefs.h>
}
namespace WWOnline {
/******************************************************************************
*
* NAME
* PageMessage::PageMessage
*
* DESCRIPTION
* Constructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
PageMessage::PageMessage(const char* pagersName, const char* message) :
mPager(pagersName),
mMessage(message)
{
}
/******************************************************************************
*
* NAME
* PageMessage::PageMessage
*
* DESCRIPTION
* Constructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
PageMessage::PageMessage(const wchar_t* pagersName, const wchar_t* message) :
mPager(pagersName),
mMessage(message)
{
}
/******************************************************************************
*
* NAME
* PageMessage::PageMessage
*
* DESCRIPTION
* Copy constructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
PageMessage::PageMessage(const PageMessage& page)
{
*this = page;
}
/******************************************************************************
*
* NAME
* PageMessage::~PageMessage
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
PageMessage::~PageMessage()
{
}
/******************************************************************************
*
* NAME
* PageMessage::operator=
*
* DESCRIPTION
* Assignment operator
*
* INPUTS
*
* RESULT
*
******************************************************************************/
const PageMessage& PageMessage::operator=(const PageMessage& page)
{
mPager = page.mPager;
mMessage = page.mMessage;
return (*this);
}
} // namespace WWOnline

View File

@@ -0,0 +1,85 @@
/*
** 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/WWOnline/WOLPageMsg.h $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 5 $
* $Modtime: 12/19/01 2:00p $
*
******************************************************************************/
#ifndef __WOLPAGEMSG_H__
#define __WOLPAGEMSG_H__
#include <WWLib\WideString.h>
#ifdef _MSC_VER
#pragma warning (push,3)
#endif
#include <vector>
#ifdef _MSC_VER
#pragma warning (pop)
#endif
namespace WWOnline {
class PageMessage
{
public:
PageMessage(const char* pagersName, const char* message);
PageMessage(const wchar_t* pagersName, const wchar_t* message);
PageMessage(const PageMessage&);
virtual ~PageMessage();
const PageMessage& operator=(const PageMessage&);
inline const WideStringClass& GetPagersName(void) const
{return mPager;}
inline const WideStringClass& GetPageMessage(void) const
{return mMessage;}
protected:
WideStringClass mPager;
WideStringClass mMessage;
};
typedef enum
{
PAGESEND_ERROR = 0,
PAGESEND_OFFLINE,
PAGESEND_HIDING,
PAGESEND_SENT,
} PageSendStatus;
typedef std::vector<PageMessage> PageMessageList;
} // namespace WWOnline
#endif // __WOLPAGEMSG_H__

82
Code/WWOnline/WOLPing.h Normal file
View File

@@ -0,0 +1,82 @@
/*
** 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/WWOnline/WOLPing.h $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 3 $
* $Modtime: 8/28/01 2:25p $
*
******************************************************************************/
#ifndef __WOLPING_H__
#define __WOLPING_H__
#include <WWLib\WWString.h>
namespace WWOnline {
class RawPing
{
public:
RawPing(const char* host, unsigned long ip, int time) :
mHostAddress(host),
mIP(ip),
mTime(time),
mHandle(-1)
{}
inline const char* GetHostAddress(void) const
{return mHostAddress.Peek_Buffer();}
inline void SetIPAddress(unsigned long ip)
{mIP = ip;}
inline unsigned long GetIPAddress(void) const
{return mIP;}
inline void SetTime(int time)
{mTime = time;}
inline int GetTime(void) const
{return mTime;}
inline void SetHandle(int handle)
{mHandle = handle;}
inline int GetHandle(void) const
{return mHandle;}
private:
StringClass mHostAddress;
unsigned long mIP;
int mTime;
int mHandle;
};
}
#endif // __WOLPING_H__

View File

@@ -0,0 +1,200 @@
/*
** 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/WWOnline/WOLProduct.cpp $
*
* DESCRIPTION
* This class specifies product-specific information, such as SKU.
*
* Client code should create a Product::Initializer object. This will create
* a Product object and set it as the current product. Creating additional
* Initializer objects will replace the current product information. This
* will change the application's "identity" on the fly; this may cause
* problems if Westwood Online activity is in progress. I don't expect there
* to be any need to do this, except perhaps during early product development.
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 4 $
* $Modtime: 1/25/02 6:45p $
*
******************************************************************************/
#include "WOLProduct.h"
#include <WWLib\win.h>
namespace WWOnline {
/******************************************************************************
*
* NAME
* CurrentProduct
*
* DESCRIPTION
* Current WWOnline product.
*
* INPUTS
* NONE
*
* RESULT
* Product -
*
******************************************************************************/
static RefPtr<Product>& CurrentProduct(void)
{
static RefPtr<Product> _current;
return _current;
}
/******************************************************************************
*
* NAME
* Product::Current
*
* DESCRIPTION
* Get the current WWOnline product
*
* INPUTS
* NONE
*
* RESULT
*
******************************************************************************/
RefPtr<Product> Product::Current(void)
{
return CurrentProduct().ReferencedObject();
}
/******************************************************************************
*
* NAME
* Product::Create
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
RefPtr<Product> Product::Create(const char* registryPath, int gameCode,
const wchar_t* chanPass, unsigned long ladderSKU)
{
return new Product(registryPath, gameCode, chanPass, ladderSKU);
}
/******************************************************************************
*
* NAME
* Product::Product
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
Product::Product(const char* registryPath, int gameCode, const wchar_t* chanPass, unsigned long ladderSKU) :
mRegistryPath(registryPath),
mProductSKU(0),
mLadderSKU(0),
mProductVersion(0),
mLanguageCode(0),
mGameCode(gameCode),
mChannelPassword(chanPass)
{
WWASSERT(registryPath && "Invalid parameter");
HKEY rKey;
LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, registryPath, 0, KEY_READ, &rKey);
if (result == ERROR_SUCCESS)
{
// Get SKU
DWORD type;
DWORD sku = 0;
DWORD sizeOfBuffer = sizeof(sku);
result = RegQueryValueEx(rKey, "SKU", NULL, &type, (unsigned char*)&sku, &sizeOfBuffer);
mProductSKU = sku;
mLanguageCode = (sku & 0xFF);
mLadderSKU = ladderSKU;
// Get version
DWORD version = 0;
sizeOfBuffer = sizeof(version);
result = RegQueryValueEx(rKey, "Version", NULL, &type, (unsigned char*)&version, &sizeOfBuffer);
mProductVersion = version;
RegCloseKey(rKey);
}
}
/******************************************************************************
*
* NAME
* WOLProduct::Initializer
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
Product::Initializer::Initializer(const char* registryPath, int gameCode,
const wchar_t* chanPass, unsigned long ladderSKU)
{
CurrentProduct() = Product::Create(registryPath, gameCode, chanPass, ladderSKU);
}
/******************************************************************************
*
* NAME
* WOLProduct::Initializer
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
Product::Initializer::~Initializer()
{
}
}

106
Code/WWOnline/WOLProduct.h Normal file
View File

@@ -0,0 +1,106 @@
/*
** 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/WWOnline/WOLProduct.h $
*
* DESCRIPTION
* This class specifies product-specific information, such as SKU.
*
* Client code should create a Product::Initializer object. This will create
* a Product object and set it as the current product. Creating additional
* Initializer objects will replace the current product information. This
* will change the application's "identity" on the fly; this may cause
* problems if Westwood Online activity is in progress. I don't expect there
* to be any need to do this, except perhaps during early product development.
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 4 $
* $Modtime: 1/25/02 6:45p $
*
******************************************************************************/
#ifndef __WOLPRODUCT_H__
#define __WOLPRODUCT_H__
#include "RefCounted.h"
#include "RefPtr.h"
#include <WWLib\WWString.h>
#include <WWLib\WideString.h>
namespace WWOnline {
class Product :
public RefCounted
{
public:
static RefPtr<Product> Current(void);
const char* GetRegistryPath(void) const
{return mRegistryPath;}
unsigned long GetSKU(void) const
{return mProductSKU;}
unsigned long GetLanguageSKU(void) const
{return mProductSKU | mLanguageCode;}
unsigned long GetLadderSKU(void) const
{return mLadderSKU;}
unsigned long GetLanguageCode(void) const
{return mLanguageCode;}
unsigned long GetVersion(void) const
{return mProductVersion;}
long GetGameCode(void) const
{return mGameCode;}
const wchar_t* GetChannelPassword(void) const
{return mChannelPassword;}
class Initializer
{
public:
Initializer(const char* registryPath, int gameCode, const wchar_t* chanPass, unsigned long ladderSKU);
~Initializer();
};
private:
friend class Initializer;
static RefPtr<Product> Create(const char* registryPath, int gameCode, const wchar_t* chanPass, unsigned long ladderSKU);
Product(const char* registryPath, int gameCode, const wchar_t* chanPass, unsigned long ladderSKU);
StringClass mRegistryPath;
unsigned long mProductSKU;
unsigned long mProductVersion;
unsigned long mLanguageCode;
unsigned long mLadderSKU;
long mGameCode;
WideStringClass mChannelPassword;
};
}
#endif // __WOLPRODUCT_H__

420
Code/WWOnline/WOLServer.cpp Normal file
View File

@@ -0,0 +1,420 @@
/*
** 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/WWOnline/WOLServer.cpp $
*
* DESCRIPTION
* These classes encapsulate a Westwood Online Server.
*
* This is a base class. Derived classes include (but not necessarily limited to)
* ChatServer, GameResultsServer, LadderServer, and WDTServer.
*
* Server primarily repackages the WOL Server struct
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 14 $
* $Modtime: 1/12/02 9:42p $
*
******************************************************************************/
#include <stdlib.h>
#include "WOLServer.h"
#include "WOLProduct.h"
#include <commando\_globals.h>
#include <string.h>
#include <WWDebug\WWDebug.h>
#include <WWLib\Registry.h>
namespace WWOnline {
/******************************************************************************
*
* NAME
* ServerData::ServerData
*
* DESCRIPTION
* Constructor
*
* INPUTS
* Server - WOLAPI Server structure representing server.
*
* RESULT
* NONE
*
******************************************************************************/
ServerData::ServerData(const WOL::Server& server)
{
memcpy(&mData, &server, sizeof(mData));
mData.next = NULL;
}
/******************************************************************************
*
* NAME
* ServerData::~ServerData
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
ServerData::~ServerData()
{
WWDEBUG_SAY(("WOL: Destructing ServerData %s:%s\n", mData.connlabel, mData.name));
}
/******************************************************************************
*
* NAME
* IRCServerData::Create
*
* DESCRIPTION
* Create a IRC server instance.
*
* INPUTS
* Server - WOLAPI server structure
*
* RESULT
* Instance of IRC server class.
*
******************************************************************************/
RefPtr<IRCServerData> IRCServerData::Create(const WOL::Server& server)
{
WWASSERT((strcmp((char*)server.connlabel, "IRC") == 0) || (strcmp((char*)server.connlabel, "IGS") == 0));
return new IRCServerData(server);
}
/******************************************************************************
*
* NAME
* IRCServerData::IRCServerData
*
* DESCRIPTION
* Constructor
*
* INPUTS
* Server - WOLAPI server structure
*
* RESULT
* NONE
*
******************************************************************************/
IRCServerData::IRCServerData(const WOL::Server& server) :
ServerData(server),
mMatchesLanguageCode(false),
mHasLanguageCode(false)
{
mIsGameServer = (strcmp((char*)server.connlabel, "IGS") == 0);
RefPtr<Product> product = Product::Current();
WWASSERT(product.IsValid() && "WWOnline product not initialized.");
char* namePart = strchr((char*)server.name, ':');
if (namePart)
{
namePart++;
}
char name[sizeof(server.name) + 1];
strcpy(name, (char*)server.name);
char* langPart = strtok(name, ":");
if (namePart && langPart)
{
char* token = strtok(langPart, ",");
if (token)
{
long productLangCode = product->GetLanguageCode();
do
{
long langCode = atol(token);
if (langCode == productLangCode)
{
mMatchesLanguageCode = true;
}
token = strtok(NULL, ",");
} while (token);
}
}
if (namePart)
{
mServerName = namePart;
mHasLanguageCode = true;
}
else
{
mServerName = (char*)server.name;
}
}
/******************************************************************************
*
* NAME
* HostPortServerData::HostPortServerData
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
HostPortServerData::HostPortServerData(const WOL::Server& server) :
ServerData(server)
{
char data[sizeof(server.conndata) + 1];
strcpy(data, (char*)server.conndata);
char* token = strtok(data, ";");
WWASSERT(token);
if (token)
{
token = strtok(NULL, ";");
}
WWASSERT(token);
if (token)
{
mHostAddress = token;
token = strtok(NULL, ";");
}
WWASSERT(token);
if (token)
{
mHostPort = atol(token);
}
}
/******************************************************************************
*
* NAME
* LadderServerData::Create
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
RefPtr<LadderServerData> LadderServerData::Create(const WOL::Server& server)
{
WWASSERT(strcmp((char*)server.connlabel, "LAD") == 0);
return new LadderServerData(server);
}
/******************************************************************************
*
* NAME
* LadderServerData::LadderServerData
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
LadderServerData::LadderServerData(const WOL::Server& server) :
HostPortServerData(server)
{
}
/******************************************************************************
*
* NAME
* GameResultsServerData::Create
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
RefPtr<GameResultsServerData> GameResultsServerData::Create(const WOL::Server& server)
{
WWASSERT(strcmp((char*)server.connlabel, "GAM") == 0);
return new GameResultsServerData(server);
}
/******************************************************************************
*
* NAME
* GameResultsServerData::GameResultsServerData
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
GameResultsServerData::GameResultsServerData(const WOL::Server& server) :
HostPortServerData(server)
{
}
/******************************************************************************
*
* NAME
* WDTServerData::Create
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
RefPtr<WDTServerData> WDTServerData::Create(const WOL::Server& server)
{
WWASSERT(strcmp((char*)server.connlabel, "WDT") == 0);
return new WDTServerData(server);
}
/******************************************************************************
*
* NAME
* WDTServerData::WDTServerData
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
WDTServerData::WDTServerData(const WOL::Server& server) :
HostPortServerData(server)
{
}
/******************************************************************************
*
* NAME
* MGLServerData::Create
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
RefPtr<MGLServerData> MGLServerData::Create(const WOL::Server& server)
{
WWASSERT(strcmp((char*)server.connlabel, "MGL") == 0);
return new MGLServerData(server);
}
/******************************************************************************
*
* NAME
* MGLServerData::MGLServerData
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
MGLServerData::MGLServerData(const WOL::Server& server) :
HostPortServerData(server)
{
WWDEBUG_SAY(("WOL: ManglerServer %s:%d\n", GetHostAddress(), GetPort()));
}
RefPtr<PingServerData> PingServerData::Create(const WOL::Server& server)
{
WWASSERT(strcmp((char*)server.connlabel, "PNG") == 0);
return new PingServerData(server);
}
PingServerData::PingServerData(const WOL::Server& server) :
HostPortServerData(server),
mPingTime(-1)
{
WWDEBUG_SAY(("WOL: PingServer %s:%d\n", GetHostAddress(), GetPort()));
}
void PingServerData::SetPingTime(int time)
{
mPingTime = time;
// Save the ping time in the registry.
RegistryClass reg(APPLICATION_SUB_KEY_NAME_SERVER_LIST);
reg.Set_Int(GetHostAddress(), time);
}
}

255
Code/WWOnline/WOLServer.h Normal file
View File

@@ -0,0 +1,255 @@
/*
** 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/WWOnline/WOLServer.h $
*
* DESCRIPTION
* These classes encapsulate a Westwood Online Server.
*
* This is a base class. Derived classes include (but not necessarily limited to)
* ChatServer, GameResultsServer, LadderServer, and WDTServer.
*
* Server primarily repackages the WOL Server struct
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 11 $
* $Modtime: 1/11/02 5:40p $
*
******************************************************************************/
#ifndef __WOLSERVER_H__
#define __WOLSERVER_H__
#include "RefCounted.h"
#include "RefPtr.h"
#include "WOLString.h"
#include <WWLib\WWString.h>
namespace WOL
{
#include <WOLAPI\wolapi.h>
}
namespace WWOnline {
class ServerData :
public RefCounted
{
public:
inline WOL::Server& GetData(void)
{return mData;}
inline const int GetTimeZone(void) const
{return mData.timezone;}
inline const float GetLongitude(void) const
{return mData.longitude;}
inline const float GetLattitude(void) const
{return mData.lattitude;}
protected:
ServerData(const WOL::Server&);
virtual ~ServerData();
WOL::Server mData;
};
// base class for chat and game servers
class IRCServerData :
public ServerData
{
public:
static RefPtr<IRCServerData> Create(const WOL::Server&);
inline const char* GetName(void) const
{return mServerName;}
inline bool IsGameServer(void) const
{return mIsGameServer;}
inline bool HasLanguageCode(void) const
{return mHasLanguageCode;}
inline bool MatchesLanguageCode(void) const
{return mMatchesLanguageCode;}
protected:
IRCServerData(const WOL::Server&);
virtual ~IRCServerData()
{}
private:
StringClass mServerName;
bool mIsGameServer;
bool mMatchesLanguageCode;
bool mHasLanguageCode;
};
// base class for non-chat/non-game servers
class HostPortServerData :
public ServerData
{
public:
inline const char* GetName(void) const
{return (const char*)mData.name;}
inline const char* GetHostAddress(void) const
{return mHostAddress;}
inline unsigned int GetPort(void) const
{return mHostPort;}
protected:
HostPortServerData(const WOL::Server&);
virtual ~HostPortServerData()
{}
private:
StringClass mHostAddress;
unsigned int mHostPort;
};
class LadderServerData :
public HostPortServerData
{
public:
static RefPtr<LadderServerData> Create(const WOL::Server&);
private:
LadderServerData(const WOL::Server&);
virtual ~LadderServerData()
{}
LadderServerData(const LadderServerData&);
const LadderServerData& operator=(const LadderServerData&);
};
class GameResultsServerData :
public HostPortServerData
{
public:
static RefPtr<GameResultsServerData> Create(const WOL::Server&);
private:
GameResultsServerData(const WOL::Server&);
virtual ~GameResultsServerData()
{}
GameResultsServerData(const GameResultsServerData&);
const GameResultsServerData& operator=(const GameResultsServerData&);
};
class WDTServerData :
public HostPortServerData
{
public:
static RefPtr<WDTServerData> Create(const WOL::Server&);
private:
WDTServerData(const WOL::Server&);
virtual ~WDTServerData()
{}
WDTServerData(const WDTServerData&);
const WDTServerData& operator=(const WDTServerData&);
};
class MGLServerData :
public HostPortServerData
{
public:
static RefPtr<MGLServerData> Create(const WOL::Server&);
private:
MGLServerData(const WOL::Server&);
virtual ~MGLServerData()
{}
MGLServerData(const MGLServerData&);
const MGLServerData& operator=(const MGLServerData&);
};
class PingServerData :
public HostPortServerData
{
public:
static RefPtr<PingServerData> Create(const WOL::Server&);
void SetPingTime(int time);
inline int GetPingTime(void) const
{return mPingTime;}
protected:
PingServerData(const WOL::Server&);
virtual ~PingServerData()
{}
// Prevent copy and assignment
PingServerData(const PingServerData&);
const PingServerData& operator=(const PingServerData&);
private:
int mPingTime;
};
class ServerError
{
public:
ServerError(int code, const char* description, unsigned long data = 0) :
mCode(code),
mDescription(description),
mData(data)
{}
inline int GetErrorCode(void)
{return mCode;}
inline const wchar_t* GetDescription(void) const
{return WOLSTRING(mDescription);}
inline unsigned int GetData(void) const
{return mData;}
private:
ServerError(const ServerError&);
const ServerError& operator=(const ServerError&);
int mCode;
StringClass mDescription;
unsigned long mData;
};
} // namespace WWOnline
#endif // __WOLSERVER_H__

3474
Code/WWOnline/WOLSession.cpp Normal file

File diff suppressed because it is too large Load Diff

572
Code/WWOnline/WOLSession.h Normal file
View File

@@ -0,0 +1,572 @@
/*
** 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/WWOnline/WOLSession.h $
*
* DESCRIPTION
* WOLSession is the entryway to Westwood Online. An object of this type
* must exist in order to do anything WOL related. There should only be one
* instance of this; retrieve it via GetInstance.
*
* PROGRAMMER
* Steve Clinard & Denzil E. Long, Jr.
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 54 $
* $Modtime: 1/25/02 5:02p $
*
******************************************************************************/
#ifndef __WOLSESSION_H__
#define __WOLSESSION_H__
#include <atlbase.h>
#include "WOLLoginInfo.h"
#include "WOLUser.h"
#include "WOLChannel.h"
#include "WOLPing.h"
#include "WOLAgeCheck.h"
#include "WOLDownload.h"
#include "WOLPageMsg.h"
#include "RefPtr.h"
#include <WWLib\Notify.h>
#include <WWLib\WideString.h>
namespace WOL
{
#include <WOLAPI\wolapi.h>
}
#if defined(_MSC_VER)
#pragma warning(push, 3)
#endif
#include <vector>
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
class WaitCondition;
namespace WWOnline {
// The version of WOLAPI this product was build with.
#define WOLAPI_BUILD_VERSION MAKELONG(19,1)
class ChatObserver;
class NetUtilObserver;
class ServerError;
class ServerData;
class ChannelData;
class LadderServerData;
class GameResultsServerData;
class WDTServerData;
class GameOptionsMessage;
class GameStartEvent;
class SquadEvent;
class ChatMessage;
class ConnectWait;
class DisconnectWait;
class IRCServerData;
typedef std::vector< RefPtr<IRCServerData> > IRCServerList;
class MGLServerData;
typedef std::vector< RefPtr<MGLServerData> > MGLServerList;
class PingServerData;
typedef std::vector< RefPtr<PingServerData> > PingServerList;
typedef std::vector< RefPtr<LadderData> > LadderList;
enum ConnectionStatus {ConnectionDisconnected, ConnectionDisconnecting, ConnectionConnecting, ConnectionConnected};
class MessageOfTheDayType;
typedef TypedEvent<MessageOfTheDayType, WideStringClass> MessageOfTheDayEvent;
// Information request flags
#define REQUEST_LOCALE (1<<0L)
#define REQUEST_SQUADINFO (1<<1L)
#define REQUEST_TEAMINFO (1<<2L)
#define REQUEST_LADDERINFO (1<<3L)
#define REQUEST_ALL (REQUEST_LOCALE|REQUEST_SQUADINFO|REQUEST_TEAMINFO|REQUEST_LADDERINFO)
#define REQUEST_NONE 0
class Session :
public RefCounted,
public Notifier<ServerError>,
public Notifier<ConnectionStatus>,
public Notifier<IRCServerList>,
public Notifier<ChannelListEvent>,
public Notifier<UserList>,
public Notifier<UserEvent>,
public Notifier<BuddyEvent>,
public Notifier<ChannelEvent>,
public Notifier<MessageOfTheDayEvent>,
public Notifier<ChatMessage>,
public Notifier<PageMessage>,
public Notifier<PageSendStatus>,
public Notifier<GameOptionsMessage>,
public Notifier<GameStartEvent>,
public Notifier<RawPing>,
public Notifier<LadderInfoEvent>,
public Notifier<LadderList>,
public Notifier<SquadEvent>,
public Notifier<NewLoginInfoEvent>,
public Notifier<AgeCheckEvent>,
public Notifier<UserIPEvent>
{
public:
// Retrieve WWOnline session instance.
static RefPtr<Session> GetInstance(bool okToCreate = false);
void Reset(void);
// Yeild time for WWOnline processing.
virtual bool Process(void);
// Retrieve pointer to IChat object
const CComPtr<WOL::IChat>& GetChatObject(void) const
{return mChat;}
// Retrieve pointer to INetUtil object
const CComPtr<WOL::INetUtil>& GetNetUtilObject(void) const
{return mNetUtil;}
// Obtain current patch download list
DownloadList& GetPatchDownloadList(void)
{return mPatchFiles;}
// Retrieve connection status
ConnectionStatus GetConnectionStatus(void) const
{return mCurrentConnectionStatus;}
//-------------------------------------------------------------------------
// Server Methods
//-------------------------------------------------------------------------
// Retrieve new server list
RefPtr<WaitCondition> GetNewServerList(void);
// Submit request for new server list
bool RequestServerList(bool just_kidding = false);
// Obtain current server list
const IRCServerList& GetIRCServerList(void)
{return mIRCServers;}
const MGLServerList& GetManglerServerList(void)
{return mMGLServers;}
const PingServerList& GetPingServerList(void)
{return mPingServers;}
// Retrieve current server
const RefPtr<IRCServerData>& GetCurrentServer(void) const
{return mCurrentServer;}
// Retrieve current login
const RefPtr<LoginInfo>& GetCurrentLogin(void) const
{return mCurrentLogin;}
// Login into server
RefPtr<WaitCondition> LoginServer(const RefPtr<IRCServerData>&, const RefPtr<LoginInfo>&);
// Disconnection from current server.
RefPtr<WaitCondition> Logout(void);
// Retrieve message of the day
const WideStringClass& GetMessageOfTheDay(void) const
{return mMessageOfTheDay;}
//-------------------------------------------------------------------------
// Channel Methods
//-------------------------------------------------------------------------
bool EnableProgressiveChannelList(bool enable);
// Submit request for new channel list
bool RequestChannelList(int channelType, bool autoPing);
// Look for a channel with the specified name in the current channel list.
RefPtr<ChannelData> FindChannel(const wchar_t* name);
RefPtr<ChannelData> FindChannel(const char* name);
// Create a new channel
RefPtr<WaitCondition> CreateChannel(const wchar_t* channelName, const wchar_t* password, int type);
RefPtr<WaitCondition> CreateChannel(const RefPtr<ChannelData>&, const wchar_t* password);
// Join a channel
RefPtr<WaitCondition> JoinChannel(const RefPtr<ChannelData>& channel, const wchar_t* password);
RefPtr<WaitCondition> JoinChannel(const wchar_t* name, const wchar_t* password, int type);
bool RequestChannelJoin(const RefPtr<ChannelData>& channel, const wchar_t* password);
// Leave the current channel.
RefPtr<WaitCondition> LeaveChannel(void);
bool RequestLeaveChannel(void);
// Obtain current channel
const RefPtr<ChannelData>& GetCurrentChannel(void) const
{return mCurrentChannel;}
const char* GetChannelTopic(void) const;
// Send the current channels topic to the server.
bool SendChannelTopic(void);
// Send the current channels extra info to the server.
bool SendChannelExtraInfo(void);
// Retrieve current channel status
ChannelStatus GetChannelStatus(void) const
{return mCurrentChannelStatus;}
// Retrieve new chat channel list
RefPtr<WaitCondition> GetNewChatChannelList(void);
// Obtain current channel list.
const ChannelList& GetChatChannelList(void)
{return mChatChannels;}
RefPtr<ChannelData> FindChatChannel(const wchar_t* name);
RefPtr<ChannelData> FindChatChannel(const char* name);
// Retrieve new game channel list
RefPtr<WaitCondition> GetNewGameChannelList(void);
// Submit request for new game channel list.
bool RequestGameChannelList(void);
// Obtain current game channel list
const ChannelList& GetGameChannelList(void)
{return mGameChannels;}
RefPtr<ChannelData> FindGameChannel(const wchar_t* name);
RefPtr<ChannelData> FindGameChannel(const char* name);
//-------------------------------------------------------------------------
// User Methods
//-------------------------------------------------------------------------
// Request a new user list
bool RequestUserList(void);
// Obtian current user list
const UserList& GetUserList(void)
{return mUsers;}
// Find specified user
RefPtr<UserData> FindUser(const wchar_t* userName);
// Obtain current user
RefPtr<UserData> GetCurrentUser(void) const
{return mCurrentUser;}
// Test is specified user is the current one.
bool IsCurrentUser(const RefPtr<UserData>&) const;
bool IsCurrentUser(const wchar_t* username) const;
// Change the locale for the user currently logged in.
bool ChangeCurrentUserLocale(WOL::Locale locale);
// Squelch / unsquelch user messages. Prevents messages from specified user.
bool SquelchUser(const RefPtr<UserData>& user, bool squelched);
// Kick a user from the current channel. Kicking is only allowed for
// channel owners.
bool KickUser(const wchar_t* username);
// Ban / unban a user from the current channel. Banning is only allowed for
// channel owners.
bool BanUser(const wchar_t* username, bool banned);
// Send a page to a user.
bool PageUser(const wchar_t* userName, const wchar_t* message);
// Request a users online location
unsigned long GetAutoRequestFlags(void) const
{return mAutoRequestFlags;}
void SetAutoRequestFlags(unsigned long flags)
{mAutoRequestFlags = flags;}
void RequestUserDetails(const RefPtr<UserData>& user, unsigned long requestFlags);
void RequestLocateUser(const wchar_t* userName);
void RequestLocateUser(const RefPtr<UserData>& user);
// Request users locale
void RequestUserLocale(const wchar_t* userName);
// Request information about a squad by Squad ID
void RequestSquadInfoByID(unsigned long squadID);
// Request information about a squad by member name
void RequestSquadInfoByMemberName(const wchar_t* memberName);
// Request users team information
void RequestTeamInfo(const wchar_t* userName);
// Request users ladder information
void RequestLadderInfo(const wchar_t* name, unsigned long type);
//-------------------------------------------------------------------------
// Buddy Methods
//-------------------------------------------------------------------------
// Obtian current buddy list
const UserList& GetBuddyList(void) const
{return mBuddies;}
// Find specified buddy
RefPtr<UserData> FindBuddy(const wchar_t* buddyName)
{return FindUserInList(buddyName, mBuddies);}
bool RequestBuddyList(void);
bool AddBuddy(const wchar_t* buddyName);
bool RemoveBuddy(const wchar_t* buddyName);
//-------------------------------------------------------------------------
// Chatting Methods
//-------------------------------------------------------------------------
bool AllowFindPage(bool allowFind, bool allowPage);
// Enable / disable filtering of bad language
bool SetBadLanguageFilter(bool enabled);
bool SendPublicMessage(const char* message);
bool SendPublicMessage(const wchar_t* message);
bool SendPublicAction(const char* action);
bool SendPublicAction(const wchar_t* action);
bool SendPrivateMessage(const wchar_t* username, const wchar_t* message);
bool SendPrivateMessage(const UserList& users, const char* message);
bool SendPrivateMessage(const UserList& users, const wchar_t* message);
bool SendPrivateAction(const UserList& users, const char* action);
bool SendPrivateAction(const UserList& users, const wchar_t* action);
bool SendPublicGameOptions(const char* options);
bool SendPrivateGameOptions(const wchar_t* user, const char* options);
bool SendPrivateGameOptions(const UserList& users, const char* options);
//-------------------------------------------------------------------------
// Utility Methods
//-------------------------------------------------------------------------
void GetLocaleStrings(std::vector<WideStringClass>& localeStrings);
void EnablePinging(bool enable);
void RequestPing(const char* address, int timeout = 1000);
unsigned int GetPendingPingCount(void) const
{return mPingsPending;}
bool SendGameResults(unsigned char* packet, unsigned long length);
bool RequestUserIP(char *user_name);
time_t GetServerTime(void)
{return mServerTime;}
//-------------------------------------------------------------------------
// IGR (Internet Gaming Room) support
//-------------------------------------------------------------------------
bool IsStoreLoginAllowed(void);
bool IsAutoLoginAllowed(void);
bool IsRunRegAppAllowed(void);
//-------------------------------------------------------------------------
// Insider status support
//-------------------------------------------------------------------------
void RequestInsiderStatus(void);
void RequestServerTime(void);
bool IsCurrUserInsider(void)
{return mIsInsider;}
//-------------------------------------------------------------------------
// Event notification
//-------------------------------------------------------------------------
DECLARE_NOTIFIER(ServerError)
DECLARE_NOTIFIER(ConnectionStatus)
DECLARE_NOTIFIER(IRCServerList)
DECLARE_NOTIFIER(ChannelListEvent)
DECLARE_NOTIFIER(UserList)
DECLARE_NOTIFIER(UserEvent)
DECLARE_NOTIFIER(BuddyEvent)
DECLARE_NOTIFIER(ChannelEvent)
DECLARE_NOTIFIER(MessageOfTheDayEvent)
DECLARE_NOTIFIER(ChatMessage)
DECLARE_NOTIFIER(PageMessage)
DECLARE_NOTIFIER(PageSendStatus)
DECLARE_NOTIFIER(GameOptionsMessage)
DECLARE_NOTIFIER(GameStartEvent)
DECLARE_NOTIFIER(RawPing)
DECLARE_NOTIFIER(LadderInfoEvent)
DECLARE_NOTIFIER(LadderList)
DECLARE_NOTIFIER(SquadEvent)
DECLARE_NOTIFIER(NewLoginInfoEvent)
DECLARE_NOTIFIER(AgeCheckEvent)
DECLARE_NOTIFIER(UserIPEvent)
protected:
friend ChatObserver;
friend NetUtilObserver;
friend Download;
friend ConnectWait;
friend DisconnectWait;
Session();
virtual ~Session();
// Disallow copy and assignment
Session(const Session&);
const Session& operator=(const Session&);
virtual void ReleaseReference(void);
bool FinalizeCreate(void);
void UpdatePingServerTime(const char* name, int time);
void AutoRequestUserDetails(const RefPtr<UserData>& user);
RefPtr<UserData> GetUserOrBuddy(const wchar_t*);
const CComPtr<WOL::IIGROptions>& GetIGRObject(void);
private:
void ClearServers(void);
void MakeLocateUserRequests(void);
void MakeSquadRequests(void);
void MakeLocaleRequests(void);
void MakeTeamRequests(void);
void MakeLadderRequests(void);
void MakePingRequests(void);
CComPtr<WOL::IChat> mChat;
CComPtr<WOL::IChatEvent> mChatEvents;
unsigned long mChatCookie;
CComPtr<WOL::INetUtil> mNetUtil;
CComPtr<WOL::INetUtilEvent> mNetUtilEvents;
unsigned long mNetUtilCookie;
CComPtr<WOL::IIGROptions> mIGRObject;
// Server data
bool mRequestingServerList;
IRCServerList mIRCServers;
RefPtr<LadderServerData> mLadderServer;
RefPtr<GameResultsServerData> mGameResultsServer;
RefPtr<WDTServerData> mWDTServer;
MGLServerList mMGLServers;
PingServerList mPingServers;
bool mIgnoreServerLists;
// Insider status data
bool mIsInsider;
time_t mServerTime;
// Patch data
DownloadList mPatchFiles;
// Connection state
ConnectionStatus mCurrentConnectionStatus;
RefPtr<IRCServerData> mPendingServer;
RefPtr<IRCServerData> mCurrentServer;
RefPtr<LoginInfo> mPendingLogin;
RefPtr<LoginInfo> mCurrentLogin;
// Channel data
ChannelList mChatChannels;
ChannelList mGameChannels;
int mRequestedChannelType;
ChannelList mIncommingChatChannels;
ChannelList mIncommingGameChannels;
RefPtr<ChannelData> mPendingChannel;
RefPtr<ChannelData> mCurrentChannel;
ChannelStatus mCurrentChannelStatus;
// User data
UserList mUsers;
RefPtr<UserData> mCurrentUser;
UserList mLocatePendingUsers;
RefPtr<UserData> mLocatingUser;
UserList mBuddies;
unsigned long mAutoRequestFlags;
// Squad Request queues
typedef std::vector<WideStringClass> SquadRequestColl;
SquadRequestColl mSquadRequests;
SquadRequestColl mSquadPending;
typedef std::vector<WideStringClass> LocaleRequestColl;
LocaleRequestColl mLocaleRequests;
typedef std::vector<WideStringClass> TeamRequestColl;
TeamRequestColl mTeamRequests;
typedef std::list<WideStringClass> LadderRequestList;
LadderRequestList mLadderRequests;
unsigned long mLadderPending;
// Misc.
WideStringClass mMessageOfTheDay;
std::vector<RawPing> mPingRequests;
unsigned int mPingsPending;
int mPingEnable;
unsigned long mLastUserDataRequestTime;
static RefPtr<Session> _mInstance;
};
class ChatAdvisement :
public RefCounted
{
public:
static RefPtr<ChatAdvisement> Create(const CComPtr<WOL::IChat>&, const CComPtr<WOL::IChatEvent>&);
private:
ChatAdvisement(const CComPtr<WOL::IChat>&, const CComPtr<WOL::IChatEvent>&);
virtual ~ChatAdvisement();
// Prevent copy and assignment
ChatAdvisement(const ChatAdvisement&);
const ChatAdvisement& operator=(const ChatAdvisement&);
CComPtr<WOL::IChat> mChat;
unsigned long mChatCookie;
};
} // using namespace WWOnline
#endif // __WOLSESSION_H__

267
Code/WWOnline/WOLSquad.cpp Normal file
View File

@@ -0,0 +1,267 @@
/*
** 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/WWOnline/WOLSquad.cpp $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 9 $
* $Modtime: 1/12/02 9:45p $
*
******************************************************************************/
#include <stdlib.h>
#include <memory.h>
#include "WOLSquad.h"
#include <WWDebug\WWDebug.h>
namespace WWOnline {
SquadData::SquadColl SquadData::_mSquadColl;
/******************************************************************************
*
* NAME
* SquadData::Reset
*
* DESCRIPTION
* Release all cached squads
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void SquadData::Reset(void)
{
_mSquadColl.clear();
}
/******************************************************************************
*
* NAME
* SquadData::FindByID
*
* DESCRIPTION
* Find a squad in the local cache by its ID
*
* INPUTS
* SquadID - ID of squad to search for.
*
* RESULT
* Squad - Reference to squad
*
******************************************************************************/
RefPtr<SquadData> SquadData::FindByID(unsigned long id)
{
const unsigned int count = _mSquadColl.size();
for (unsigned int index = 0; index < count; ++index)
{
const RefPtr<SquadData>& squad = _mSquadColl[index];
WWASSERT(squad.IsValid());
if (squad->GetID() == id)
{
return squad;
}
}
return NULL;
}
/******************************************************************************
*
* NAME
* SquadData::FindByAbbr
*
* DESCRIPTION
* Find a squad in the local cache by its abbreviation.
*
* INPUTS
* Abbr - Abbreviation of squad to search for.
*
* RESULT
* Squad - Reference to squad
*
******************************************************************************/
RefPtr<SquadData> SquadData::FindByAbbr(const wchar_t* abbr)
{
if (abbr && (wcslen(abbr) > 0))
{
char squadAbbr[64];
wcstombs(squadAbbr, abbr, sizeof(squadAbbr));
squadAbbr[sizeof(squadAbbr) - 1] = 0;
const unsigned int count = _mSquadColl.size();
for (unsigned int index = 0; index < count; ++index)
{
const RefPtr<SquadData>& squad = _mSquadColl[index];
WWASSERT(squad.IsValid());
if ((strcmp(squad->GetAbbr(), squadAbbr) == 0))
{
return squad;
}
}
}
return NULL;
}
/******************************************************************************
*
* NAME
* SquadData::Create
*
* DESCRIPTION
* Create a squad data
*
* INPUTS
* WOLSquad - WOLAPI squad data structure
*
* RESULT
* SquadData - Instance of squad data.
*
******************************************************************************/
RefPtr<SquadData> SquadData::Create(const WOL::Squad& wolSquad)
{
if (wolSquad.id == 0)
{
return NULL;
}
RefPtr<SquadData> squad = FindByID(wolSquad.id);
if (squad.IsValid())
{
squad->UpdateData(wolSquad);
}
else
{
squad = new SquadData(wolSquad);
_mSquadColl.push_back(squad);
}
return squad;
}
/******************************************************************************
*
* NAME
* SquadData::SquadData
*
* DESCRIPTION
* Constructor
*
* INPUTS
* WOLSquad - WOLAPI squad structure
*
* RESULT
* NONE
*
******************************************************************************/
SquadData::SquadData(const WOL::Squad& squad)
{
WWDEBUG_SAY(("WOL: Instantiating SquadData '%s'\n", (char*)squad.name));
UpdateData(squad);
}
/******************************************************************************
*
* NAME
* SquadData::~SquadData
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
SquadData::~SquadData()
{
WWDEBUG_SAY(("WOL: Destructing SquadData '%s'\n", (char*)mData.name));
}
/******************************************************************************
*
* NAME
* SquadData::UpdateData
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void SquadData::UpdateData(const WOL::Squad& squad)
{
memcpy(&mData, &squad, sizeof(mData));
mData.next = NULL;
}
/******************************************************************************
*
* NAME
* SquadData::SetLadder
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void SquadData::SetLadder(const RefPtr<LadderData>& ladder)
{
mLadder = ladder;
}
} // namespace WWOnline

175
Code/WWOnline/WOLSquad.h Normal file
View File

@@ -0,0 +1,175 @@
/*
** 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/WWOnline/WOLSquad.h $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 8 $
* $Modtime: 12/10/01 5:15p $
*
******************************************************************************/
#ifndef __WOLSQUAD_H__
#define __WOLSQUAD_H__
#include "RefCounted.h"
#include "RefPtr.h"
#include <WWLib\WideString.h>
#include "WOLLadder.h"
namespace WOL
{
#include <wolapi\wolapi.h>
}
#if defined(_MSC_VER)
#pragma warning(push, 3)
#endif
#include <vector>
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
namespace WWOnline {
class SquadData :
public RefCounted
{
public:
static void Reset(void);
// Find a squad by its ID
static RefPtr<SquadData> FindByID(unsigned long);
// Find a squad by its abbreviation
static RefPtr<SquadData> FindByAbbr(const wchar_t* abbr);
// Create SquadData instance from WOL::Squad
static RefPtr<SquadData> Create(const WOL::Squad&);
// Update the squad information
void UpdateData(const WOL::Squad&);
// Get raw WOL::Squad data
WOL::Squad& GetData(void)
{return mData;}
// Get ID of this squad
unsigned long GetID(void) const
{return mData.id;}
// Get full name of this squad
const char* GetName(void) const
{return (const char*)mData.name;}
// Get abbreviated name of this squad
const char* GetAbbr(void) const
{return (const char*)mData.abbreviation;}
// Get the number of members in this squad
int GetMemberCount(void) const
{return mData.members;}
// Get the squads rank
int GetRank(void) const
{return mData.rank;}
int GetTeam(void) const
{return mData.team;}
int GetStatus(void) const
{return mData.status;}
// Get the email address for this squad
const char* GetEmailAddress(void) const
{return (const char*)mData.email;}
// Get the ICQ address for this squad
const char* GetICQAddress(void) const
{return (const char*)mData.icq;}
// Get the squads motto
const char* GetMotto(void) const
{return (const char*)mData.motto;}
// Get the homepage URL for this squad
const char* GetHomepageURL(void) const
{return (const char*)mData.url;}
// Get the ladder ranking informatio for this squad.
RefPtr<LadderData> GetLadder(void) const
{return mLadder;}
// Set ladder ranking information for this squad
void SetLadder(const RefPtr<LadderData>&);
protected:
SquadData(const WOL::Squad&);
virtual ~SquadData();
private:
SquadData(const SquadData&);
const SquadData& operator=(const SquadData&);
WOL::Squad mData;
RefPtr<LadderData> mLadder;
typedef std::vector<RefPtr<SquadData> > SquadColl;
static SquadColl _mSquadColl;
};
class SquadEvent
{
public:
SquadEvent(const wchar_t* memberName, const RefPtr<SquadData>& squadData) :
mMemberName(memberName),
mSquadData(squadData)
{}
~SquadEvent()
{}
const wchar_t* GetMemberName(void) const
{return mMemberName;}
const RefPtr<SquadData>& GetSquadData(void) const
{return mSquadData;}
protected:
// Prevent copy and assignment
SquadEvent(const SquadEvent&);
const SquadEvent& operator=(const SquadEvent&);
const wchar_t* mMemberName;
RefPtr<SquadData> mSquadData;
};
}
#endif __WOLSQUAD_H__

View File

@@ -0,0 +1,43 @@
/*
** 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/>.
*/
#include "WOLString.h"
namespace WWOnline {
static const wchar_t* DefaultMapper(const char*)
{
return L"<WOL String lookup not set>";
}
WOLStringLookupFunc WOLString::_mLookupFunc = DefaultMapper;
void WOLString::SetLookupFunc(WOLStringLookupFunc func)
{
if (func == NULL)
{
_mLookupFunc = DefaultMapper;
}
else
{
_mLookupFunc = func;
}
}
} // namespace WWOnline

64
Code/WWOnline/WOLString.h Normal file
View File

@@ -0,0 +1,64 @@
/*
** 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/WWOnline/WOLString.h $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 2 $
* $Modtime: 1/11/02 7:26p $
*
******************************************************************************/
#ifndef __WOLSTRING_H__
#define __WOLSTRING_H__
#include <stdlib.h>
namespace WWOnline {
// warning C4514: unreferenced inline function has been removed
#pragma warning(disable : 4514)
typedef const wchar_t* (*WOLStringLookupFunc)(const char* token);
class WOLString
{
public:
static void SetLookupFunc(WOLStringLookupFunc);
static const wchar_t* Lookup(const char* token)
{return _mLookupFunc(token);}
private:
static WOLStringLookupFunc _mLookupFunc;
};
} // namespace WWOnline
#define WOLSTRING(token) WWOnline::WOLString::Lookup(token)
#endif // __WOLSTRING_H__

601
Code/WWOnline/WOLUser.cpp Normal file
View File

@@ -0,0 +1,601 @@
/*
** 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/WWOnline/WOLUser.cpp $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Steve_t $
*
* VERSION INFO
* $Revision: 19 $
* $Modtime: 10/10/02 10:38a $
*
******************************************************************************/
#include "always.h"
#include "WOLUser.h"
#include "WOLChannel.h"
#include "WOLSquad.h"
#include "WOLLadder.h"
#include <WWDebug\WWDebug.h>
namespace WWOnline {
/******************************************************************************
*
* NAME
* UserData::Create
*
* DESCRIPTION
* Create a new User data instance
*
* INPUTS
* WOLUser - Wolapi user structure
*
* RESULT
* User -
*
******************************************************************************/
RefPtr<UserData> UserData::Create(const WOL::User& user)
{
return new UserData(user);
}
/******************************************************************************
*
* NAME
* UserData::Create
*
* DESCRIPTION
* Create a new User data instance
*
* INPUTS
* Name - Name of user
*
* RESULT
* User -
*
******************************************************************************/
RefPtr<UserData> UserData::Create(const wchar_t* name)
{
if (name)
{
WOL::User user;
memset(&user, 0, sizeof(user));
wcstombs((char*)user.name, name, sizeof(user.name));
user.name[sizeof(user.name) - 1] = 0;
return Create(user);
}
return RefPtr<UserData>();
}
/******************************************************************************
*
* NAME
* UserData::UserData
*
* DESCRIPTION
* Constructor
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
UserData::UserData(const WOL::User& user) :
mUserName((char*)user.name),
mLocation(USERLOCATION_UNKNOWN)
{
WWDEBUG_SAY(("WOL: Instantiating UserData '%S'\n", (const WCHAR*)mUserName));
memcpy(&mData, &user, sizeof(mData));
mKickTimer = 0;
mData.next = NULL;
}
/******************************************************************************
*
* NAME
* UserData::~UserData
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
UserData::~UserData()
{
WWDEBUG_SAY(("WOL: Destructing UserData '%S'\n", (const WCHAR*)mUserName));
}
/******************************************************************************
*
* NAME
* UserData::UpdateData
*
* DESCRIPTION
*
* INPUTS
* WOlUser - WOL user structure to update with.
*
* RESULT
* NONE
*
******************************************************************************/
void UserData::UpdateData(const WOL::User& wolUser)
{
wchar_t name[64];
mbstowcs(name, (const char*)wolUser.name, sizeof(wolUser.name));
name[sizeof(wolUser.name) - 1] = 0;
WWASSERT(wcslen(name) && "Empty user name");
bool isValid = (!mUserName.Is_Empty() && mUserName.Compare_No_Case(name) == 0);
WWASSERT(isValid && "WOLUserData::UpdateData() mismatch");
if (isValid)
{
if (mData.squadID != wolUser.squadID)
{
mSquad.Release();
mData.squadID = wolUser.squadID;
}
}
}
/******************************************************************************
*
* NAME
* UserData::Squelch
*
* DESCRIPTION
*
* INPUTS
* OnOff - Squelch state
*
* RESULT
* NONE
*
******************************************************************************/
void UserData::Squelch(bool onoff)
{
mData.flags = (onoff == true) ?
(mData.flags | CHAT_USER_SQUELCHED) : (mData.flags ^ CHAT_USER_SQUELCHED);
}
/******************************************************************************
*
* NAME
* UserData::SetLocation
*
* DESCRIPTION
* Set the users location.
*
* INPUTS
* Location - User's location
*
* RESULT
* NONE
*
******************************************************************************/
void UserData::SetLocation(UserLocation location)
{
mLocation = location;
}
/******************************************************************************
*
* NAME
* UserData::SetChannel
*
* DESCRIPTION
* Set the channel the user is in.
*
* INPUTS
* Channel - Channel user is in.
*
* RESULT
* NONE
*
******************************************************************************/
void UserData::SetChannel(const RefPtr<ChannelData>& channel)
{
mChannel = channel;
}
/******************************************************************************
*
* NAME
* UserData::SetSquad
*
* DESCRIPTION
* Associate a squad for this user.
*
* INPUTS
* Squad
*
* RESULT
* NONE
*
******************************************************************************/
void UserData::SetSquad(const RefPtr<SquadData>& squadData)
{
mSquad = squadData;
if (squadData.IsValid())
{
mData.squadID = squadData->GetID();
// Syncronize common data with updated squad information.
strncpy((char*)mData.squadname, squadData->GetName(), sizeof(mData.squadname));
mData.squadname[sizeof(mData.squadname) - 1] = 0;
strncpy((char*)mData.squadabbrev, squadData->GetAbbr(), sizeof(mData.squadabbrev));
mData.squadabbrev[sizeof(mData.squadabbrev) - 1] = 0;
}
else
{
mData.squadname[0] = 0;
mData.squadabbrev[0] = 0;
}
}
/******************************************************************************
*
* NAME
* UserData::SetTeam
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void UserData::SetTeam(int team)
{
mData.team = team;
}
/******************************************************************************
*
* NAME
* UserData::SetLocale
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void UserData::SetLocale(WOL::Locale locale)
{
if (locale >= WOL::LOC_UNKNOWN && locale <= WOL::LOC_TURKEY)
{
mData.locale = locale;
}
}
/******************************************************************************
*
* NAME
* UserData::SetLadder
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void UserData::SetLadder(const RefPtr<LadderData>& ladder)
{
mUserLadder = ladder;
}
/******************************************************************************
*
* NAME
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
RefPtr<LadderData> UserData::GetClanLadder(void) const
{
if (mSquad.IsValid())
{
return mSquad->GetLadder();
}
return NULL;
}
/******************************************************************************
*
* NAME
* UserData::SetTeamLadder
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void UserData::SetTeamLadder(const RefPtr<LadderData>& ladder)
{
mTeamLadder = ladder;
}
/******************************************************************************
*
* NAME
* UserData::
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void UserData::SetLadderFromType(const RefPtr<LadderData>& ladder, LadderType type)
{
if (type == LadderType_Team)
{
SetTeamLadder(ladder);
return;
}
if (type == LadderType_Clan)
{
if (mSquad.IsValid())
{
mSquad->SetLadder(ladder);
}
return;
}
SetLadder(ladder);
}
/******************************************************************************
*
* NAME
* UserData::
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
RefPtr<LadderData> UserData::GetLadderFromType(LadderType type)
{
if (type == LadderType_Team)
{
return GetTeamLadder();
}
if (type == LadderType_Clan)
{
return GetClanLadder();
}
return GetLadder();
}
/******************************************************************************
*
* NAME
* NativeWOLUserList::
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
NativeWOLUserList::NativeWOLUserList(const UserList& users) :
mNativeList(NULL)
{
int count = users.size();
if (count > 0)
{
mNativeList = new WOL::User[count];
if (mNativeList)
{
for (int index = 0; index < count; index++)
{
WOL::User* wolUser = &users[index]->GetData();
memcpy(&mNativeList[index], wolUser, sizeof(WOL::User));
if (index == (count - 1))
{
mNativeList[index].next = NULL;
}
else
{
mNativeList[index].next = &mNativeList[index + 1];
}
}
}
}
}
/******************************************************************************
*
* NAME
* NativeWOLUserList::
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
NativeWOLUserList::~NativeWOLUserList()
{
if (mNativeList)
{
delete []mNativeList;
}
}
/******************************************************************************
*
* NAME
* FindUserInList
*
* DESCRIPTION
* Search for a user with the specified name in the list.
*
* INPUTS
* Name - Name of user to search for.
* List - UserData list to search.
*
* RESULT
* User -
*
******************************************************************************/
RefPtr<UserData> FindUserInList(const wchar_t* username, const UserList& list)
{
for (unsigned int index = 0; index < list.size(); index++)
{
const WideStringClass& name = list[index]->GetName();
if (name.Compare_No_Case(username) == 0)
{
return list[index];
}
}
return RefPtr<UserData>();
}
/******************************************************************************
*
* NAME
* RemoveUserInList
*
* DESCRIPTION
* Remove the
*
* INPUTS
* Name - Name of user to remove.
* List - UserData list to search.
*
* RESULT
* Removed - User removed from list.
*
******************************************************************************/
RefPtr<UserData> RemoveUserInList(const wchar_t* username, UserList& list)
{
RefPtr<UserData> removedUser;
UserList::iterator iter = list.begin();
while (iter != list.end())
{
const WideStringClass& name = (*iter)->GetName();
if (name.Compare_No_Case(username) == 0)
{
removedUser = *iter;
list.erase(iter);
break;
}
iter++;
}
return removedUser;
}
} // namespace WWOnline

287
Code/WWOnline/WOLUser.h Normal file
View File

@@ -0,0 +1,287 @@
/*
** 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/WWOnline/WOLUser.h $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Steve_t $
*
* VERSION INFO
* $Revision: 19 $
* $Modtime: 10/10/02 10:17a $
*
******************************************************************************/
#ifndef __WOLUSER_H__
#define __WOLUSER_H__
// Disable warning about exception handling not being enabled.
#pragma warning(disable : 4530)
#include <atlbase.h>
#include "RefCounted.h"
#include "RefPtr.h"
#include <WWLib\Notify.h>
#include <WWLib\WideString.h>
#include "WOLChannel.h"
#include "WOLSquad.h"
#include "WOLLadder.h"
namespace WOL
{
#include <wolapi\wolapi.h>
#include <wolapi\chatdefs.h>
}
#if defined(_MSC_VER)
#pragma warning(push, 3)
#endif
#include <vector>
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
namespace WWOnline {
typedef enum
{
USERLOCATION_UNKNOWN = 0,
USERLOCATION_OFFLINE,
USERLOCATION_HIDING,
USERLOCATION_NO_CHANNEL,
USERLOCATION_IN_CHANNEL
} UserLocation;
class UserData :
public RefCounted
{
public:
// Create new User
static RefPtr<UserData> Create(const WOL::User&);
static RefPtr<UserData> Create(const wchar_t*);
// Get WOL::User data
WOL::User& GetData(void)
{return mData;}
void UpdateData(const WOL::User&);
// Get user's name
const WideStringClass& GetName(void) const
{return mUserName;}
// Check if this user is the one logged in.
bool IsMe(void) const
{return ((mData.flags & CHAT_USER_MYSELF) == CHAT_USER_MYSELF);}
// Check if this user is the channel owner.
bool IsChannelOwner(void) const
{return ((mData.flags & CHAT_USER_CHANNELOWNER) == CHAT_USER_CHANNELOWNER);}
// Check if this user has the floor to speak
bool HasVoice(void) const
{return ((mData.flags & CHAT_USER_VOICE) == CHAT_USER_VOICE);}
// Check if this user is squelched
bool IsSquelched(void) const
{return ((mData.flags & CHAT_USER_SQUELCHED) == CHAT_USER_SQUELCHED);}
// Squelch this user
void Squelch(bool onoff);
// Get the users location (IE: Offline, Hiding, In channel, etc...)
UserLocation GetLocation(void) const
{return mLocation;}
// Set the users location
void SetLocation(UserLocation location);
// Get the channel the user is in (If available)
const RefPtr<ChannelData> GetChannel(void)
{return mChannel;}
// Set the channel the user is in
void SetChannel(const RefPtr<ChannelData>& channel);
// Get user's clan ID
unsigned long GetSquadID(void) const
{return mData.squadID;}
// Get access user's Clan data (This is shared with all other users in the same clan)
RefPtr<SquadData> GetSquad(void) const
{return mSquad;}
// Set user's clan data
void SetSquad(const RefPtr<SquadData>&);
// Get user's team
int GetTeam(void) const
{return mData.team;}
// Set user's team
void SetTeam(int);
// Get user's locale (IE: US, Germany, Korea, etc...)
WOL::Locale GetLocale(void) const
{return mData.locale;}
// Set user's locale
void SetLocale(WOL::Locale);
// Set user's ladder
void SetLadder(const RefPtr<LadderData>&);
// Get user's ladder
RefPtr<LadderData> GetLadder(void) const
{return mUserLadder;}
// Get the ladder ranking data for the users clan
RefPtr<LadderData> GetClanLadder(void) const;
void SetTeamLadder(const RefPtr<LadderData>&);
RefPtr<LadderData> GetTeamLadder(void) const
{return mTeamLadder;}
void SetLadderFromType(const RefPtr<LadderData>& ladder, LadderType ladderType);
RefPtr<LadderData> GetLadderFromType(LadderType ladderType);
unsigned long mKickTimer;
private:
UserData(const WOL::User&);
virtual ~UserData();
// Prevent copy and assignment
UserData(const UserData&);
const UserData& operator=(const UserData&);
WOL::User mData;
WideStringClass mUserName;
UserLocation mLocation;
int mUserTeam;
RefPtr<ChannelData> mChannel;
RefPtr<SquadData> mSquad;
RefPtr<LadderData> mUserLadder;
RefPtr<LadderData> mTeamLadder;
};
typedef std::vector< RefPtr<UserData> > UserList;
class UserEvent :
public TypedEvent< UserEvent, const RefPtr<UserData> >
{
public:
enum Event {Error = 0, NewData, Join, Leave, Located, Kicked, Banned, Locale, SquadInfo, LadderInfo};
Event GetEvent(void) const
{return mEvent;}
UserEvent(Event event, const RefPtr<UserData>& user) :
TypedEvent< UserEvent, const RefPtr<UserData> >(user),
mEvent(event)
{}
~UserEvent()
{}
private:
Event mEvent;
};
class BuddyEvent :
public TypedEvent< BuddyEvent, const UserList >
{
public:
enum Event {Added = 0, Deleted, NewList};
Event GetEvent(void) const
{return mEvent;}
BuddyEvent(Event event, const UserList& list) :
TypedEvent<BuddyEvent, const UserList>(list),
mEvent(event)
{}
~BuddyEvent()
{}
private:
Event mEvent;
};
class NativeWOLUserList
{
public:
NativeWOLUserList(const UserList& users);
~NativeWOLUserList();
operator const WOL::User*(void)
{return mNativeList;}
operator WOL::User*(void)
{return mNativeList;}
protected:
NativeWOLUserList(const NativeWOLUserList&);
const NativeWOLUserList& operator=(const NativeWOLUserList&);
WOL::User* mNativeList;
};
class UserIPEvent :
public TypedEvent< UserIPEvent, const WOL::User >
{
public:
enum Event {Error = 0, GotIP};
Event GetEvent(void) const
{return mEvent;}
UserIPEvent(Event event, const WOL::User &user) :
TypedEvent<UserIPEvent, const WOL::User>(user),
mEvent(event)
{}
~UserIPEvent()
{}
private:
Event mEvent;
};
RefPtr<UserData> FindUserInList(const wchar_t* name, const UserList& list);
RefPtr<UserData> RemoveUserInList(const wchar_t* name, UserList& list);
} // namespace WWOnline
#endif // __WOLUSER_H__

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,344 @@
/*
** 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/WWOnline/WaitCondition.h $
*
* DESCRIPTION
* This class encapsulates a wait condition.
*
* To wait on an event, create a wait condition. Pass the condition, or a
* set of conditions, to WaitingCondition::Wait_For(). This will block
* until the conditions are met, the user cancels the wait, or the timeout
* is reached. This will also cause the wait popup to be displayed.
*
* PROGRAMMER
* Steven Clinard
* $Author: Denzil_l $
*
* VERSION INFO
* $Modtime: 1/18/02 3:08p $
* $Revision: 9 $
*
******************************************************************************/
#ifndef __WAITCONDITION_H__
#define __WAITCONDITION_H__
#include "RefCounted.h"
#include "RefPtr.h"
#include <WWLib\Notify.h>
#include <WWLib\CallbackHook.h>
#include <WWLib\WideString.h>
#if defined(_MSC_VER)
#pragma warning(push, 3)
#endif
#include <vector>
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
class CallbackHook;
class WaitCondition :
public RefCounted
{
public:
enum WaitResult {Waiting, ConditionMet, UserCancel, TimeOut, Error};
// Wait for this condition
virtual WaitResult WaitFor(CallbackHook& hook, unsigned long timeout = 30000);
/* Wait_Beginning is called when the wait actually begins.
* This useful if the activity being monitored should only begin after the
* wait has started.
*
* Normally, the request should begin as soon as possible and the condition
* may be met before the wait begins; this avoids the whole wait popup in
* the first place.
*
* Serially chained waits may require prerequisite conditions to be met
* before the request that initiates this wait. In this case, a derived
* wait class could override Wait_Beginning to make the request.
*/
virtual void WaitBeginning(void) = 0;
// Get the result of the wait in progress.
virtual WaitResult GetResult(void) = 0;
// End the wait.
virtual void EndWait(WaitResult, const wchar_t*) = 0;
// Get a text description of completed wait
virtual const wchar_t* GetResultText(void) const = 0;
// Get a text description of the wait in progress.
virtual const wchar_t* GetWaitText(void) const = 0;
// Get the timeout in milliseconds for this wait condition
virtual unsigned long GetTimeout(void) const = 0;
protected:
WaitCondition();
virtual ~WaitCondition();
WaitCondition(const WaitCondition&);
const WaitCondition& operator=(const WaitCondition&);
};
// Waits for a single event.
class SingleWait :
public WaitCondition
{
public:
static RefPtr<SingleWait> Create(const wchar_t* waitText, unsigned long timeout = 30000);
virtual void WaitBeginning(void);
virtual WaitResult GetResult(void);
virtual void EndWait(WaitResult, const wchar_t*);
virtual const wchar_t* GetResultText(void) const;
virtual const wchar_t* GetWaitText(void) const;
virtual void SetWaitText(const wchar_t* waitText);
virtual unsigned long GetTimeout(void) const;
protected:
SingleWait(const wchar_t* waitText, unsigned long timeout = 30000);
virtual ~SingleWait();
SingleWait(const SingleWait&);
const SingleWait& operator=(const SingleWait&);
WaitResult mEndResult;
WideStringClass mEndText;
WideStringClass mWaitText;
unsigned long mTimeout;
unsigned long mStartTime;
};
// Waits for multiple events.
// All events must be satisfied and must occur in the order in which they are added.
class SerialWait :
public WaitCondition
{
public:
static RefPtr<SerialWait> Create(void);
void Add(const RefPtr<WaitCondition>&);
int RemainingWaits(void) const;
virtual void WaitBeginning(void);
virtual WaitResult GetResult(void);
virtual void EndWait(WaitResult, const wchar_t*);
virtual const wchar_t* GetResultText(void) const;
virtual const wchar_t* GetWaitText(void) const;
virtual unsigned long GetTimeout(void) const;
protected:
SerialWait();
virtual ~SerialWait();
SerialWait(const SerialWait&);
const SerialWait& operator=(const SerialWait&);
std::vector< RefPtr<WaitCondition> > mWaits;
mutable int mCurrentWait;
mutable WaitResult mEndResult;
mutable WideStringClass mEndText;
unsigned long mMaxTimeout;
unsigned long mStartTime;
};
// Waits for multiple events.
// All events are started at the same time. All events must be satisfied,
// but may occur in any order.
class ANDWait :
public WaitCondition
{
public:
static RefPtr<ANDWait> Create(const wchar_t*);
void Add(const RefPtr<WaitCondition>&);
virtual void WaitBeginning(void);
virtual WaitResult GetResult(void);
virtual void EndWait(WaitResult, const wchar_t*);
virtual const wchar_t* GetResultText(void) const;
virtual const wchar_t* GetWaitText(void) const;
virtual unsigned long GetTimeout(void) const;
protected:
ANDWait(const wchar_t*);
virtual ~ANDWait();
ANDWait(const ANDWait&);
const ANDWait& operator=(const ANDWait&);
std::vector< RefPtr<WaitCondition> > mWaits;
mutable WaitResult mEndResult;
mutable WideStringClass mEndText;
WideStringClass mWaitText;
unsigned long mMaxTimeout;
unsigned long mStartTime;
};
// ORWait: Waits for multiple events.
// All events are started at the same time. Wait ends when any event is satisfied.
class ORWait :
public WaitCondition
{
public:
static RefPtr<ORWait> Create(const wchar_t*);
void Add(const RefPtr<WaitCondition>&);
virtual void WaitBeginning(void);
virtual WaitResult GetResult(void);
virtual void EndWait(WaitResult, const wchar_t*);
virtual const wchar_t* GetResultText(void) const;
virtual const wchar_t* GetWaitText(void) const;
virtual unsigned long GetTimeout(void) const
{return mMaxTimeout;}
protected:
ORWait(const wchar_t*);
virtual ~ORWait();
ORWait(const ORWait&);
const ORWait& operator=(const ORWait&);
std::vector< RefPtr<WaitCondition> > mWaits;
mutable WaitResult mEndResult;
mutable WideStringClass mEndText;
WideStringClass mWaitText;
unsigned long mMaxTimeout;
unsigned long mStartTime;
};
// Wait for an event from a notifier
template<typename Event> class EventWait :
public SingleWait,
public Observer<Event>
{
public:
static RefPtr< EventWait<Event> > Create(const wchar_t* waitText)
{new EventWait(waitText);}
static RefPtr< EventWait<Event> > CreateAndObserve(Notifier<Event>& notifier,
const wchar_t* waitText)
{
EventWait<Event>* wait = new EventWait(waitText);
notifier.AddObserver(*wait);
return wait;
}
virtual void HandleNotification(Event&)
{if (mEndResult == Waiting) {EndWait(ConditionMet);}}
protected:
EventWait(const wchar_t* waitText) :
SingleWait(waitText)
{}
EventWait(const EventWait<Event>&);
const EventWait<Event>& operator=(const EventWait<Event>&);
};
// Wait for an event with a particular value from a notifier
template<typename Event> class EventValueWait :
public SingleWait,
public Observer<Event>
{
public:
static RefPtr< EventValueWait<Event> > Create(const Event& value, const wchar_t* waitText)
{new EventValueWait(value, waitText);}
static RefPtr< EventValueWait<Event> > CreateAndObserve(Notifier<Event>& notifier,
const Event value, const wchar_t* waitText)
{
EventValueWait<Event>* wait = new EventValueWait(value, waitText);
notifier.AddObserver(*wait);
return wait;
}
virtual void HandleNotification(Event& event)
{
if (mEndResult == Waiting)
{
if (event == mMatchValue)
{
EndWait(ConditionMet, L"");
}
else
{
EndWait(mEndResult, L"");
}
}
}
protected:
EventValueWait(const Event& value, const wchar_t* waitText) :
SingleWait(waitText),
mMatchValue(value)
{}
EventValueWait(const EventValueWait<Event>&);
const EventValueWait& operator=(const EventValueWait&);
Event mMatchValue;
};
#endif // __WAITCONDITION_H__