| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463 |
- /*
- ** Command & Conquer Red Alert(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/>.
- */
- /***************************************************************************
- * *
- * Project Name : Westwood Auto Registration App *
- * *
- * File Name : PACKET.CPP *
- * *
- * Programmer : Philip W. Gorrow *
- * *
- * Start Date : 04/22/96 *
- * *
- * Last Update : April 24, 1996 [PWG] *
- * *
- *-------------------------------------------------------------------------*
- * Functions: *
- * *PacketClass::Find_Field -- Finds a field if it exists in the packets *
- * Get_Field -- Find specified name and returns data *
- * PacketClass::~PacketClass -- destroys a packet class be freeing list *
- * PacketClass::Add_Field -- Adds a FieldClass entry to head of packet li*
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include <stdlib.h>
- #include <mem.h>
- #include <string.h>
- enum {false=0,true=1};
- typedef int bool;
- #include "packet.h"
- /**************************************************************************
- * PACKETCLASS::~PACKETCLASS -- destroys a packet class be freeing list *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * HISTORY: *
- * 04/24/1996 PWG : Created. *
- *========================================================================*/
- PacketClass::~PacketClass(void)
- {
- FieldClass *current;
- FieldClass *next;
- //
- // Loop through the entire field list and delete each entry.
- //
- for (current = Head; current; current = next) {
- next = current->Next;
- delete current;
- }
- }
- /**************************************************************************
- * PACKETCLASS::ADD_FIELD -- Adds a FieldClass entry to head of packet li *
- * *
- * INPUT: FieldClass * - a properly constructed field class entry. *
- * *
- * OUTPUT: none *
- * *
- * HISTORY: *
- * 04/24/1996 PWG : Created. *
- *========================================================================*/
- void PacketClass::Add_Field(FieldClass *field)
- {
- field->Next = Head;
- Head = field;
- }
- /**************************************************************************
- * PACKETCLASS::PACKETCLASS -- Creates a Packet object from a COMMS packe *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 04/22/1996 PWG : Created. *
- *========================================================================*/
- PacketClass::PacketClass(char *curbuf)
- {
- int remaining_size;
- //
- // Pull the size and packet ID out of the linear packet stream.
- //
- Size = *(unsigned short *)curbuf;
- curbuf += sizeof (unsigned short);
- Size = ntohs(Size);
- ID = *(short *)curbuf;
- curbuf += sizeof (short);
- ID = ntohs(ID);
- Head = NULL;
- //
- // Calculate the remaining size so that we can loop through the
- // packets and extract them.
- //
- remaining_size = Size - 4;
- //
- // Loop through the linear packet until we run out of room and
- // create a field for each.
- //
- while (remaining_size > 0) {
- FieldClass *field = new FieldClass;
- //
- // Copy the adjusted header into the buffer and then advance the buffer
- //
- memcpy(field, curbuf, FIELD_HEADER_SIZE);
- curbuf += FIELD_HEADER_SIZE;
- remaining_size -= FIELD_HEADER_SIZE;
- //
- // Copy the data into the buffer
- //
- int size = ntohs(field->Size);
- field->Data = new char[size];
- memcpy(field->Data, curbuf, size);
- curbuf += size;
- remaining_size -= size;
- //
- // Make sure we allow for the pad bytes.
- //
- int pad = (4 - (ntohs(field->Size) & 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. *
- *========================================================================*/
- char *PacketClass::Create_Comms_Packet(int &size)
- {
- FieldClass *current;
- //
- // Size starts at four because that is the size of the packet header.
- //
- size = 4;
- //
- // Take a quick spin through and calculate the size of the packet we
- // are building.
- //
- for (current = Head; current; current=current->Next) {
- size += (unsigned short)FIELD_HEADER_SIZE; // add in packet header size
- size += current->Size; // add in data size
- size += (4 - (size & 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.
- //
- char *retval = new char[size];
- char *curbuf = retval;
- //
- // write the size into the packet header
- //
- *(unsigned short *)curbuf = (unsigned short)htons((unsigned short)size);
- curbuf += sizeof (unsigned short);
- *(short *)curbuf = htons(ID);
- curbuf += sizeof (short);
- //
- // Ok now that the actual header information has been written we need to write out
- // field information.
- //
- for (current = Head; current; current = current->Next) {
- //
- // 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, FIELD_HEADER_SIZE);
- curbuf += FIELD_HEADER_SIZE;
- //
- // Copy the data into the buffer and then advance the buffer
- //
- memcpy(curbuf, current->Data, ntohs(current->Size));
- curbuf += ntohs(current->Size);
- //
- // Finally take care of any pad bytes by setting them to 0
- //
- int pad = (4 - (ntohs(current->Size) & 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(retval);
- }
- /**************************************************************************
- * PACKETCLASS::FIND_FIELD -- Finds a field if it exists in the packets *
- * *
- * INPUT: char * - the id of the field we are looking for. *
- * *
- * OUTPUT: FieldClass * pointer to the field class *
- * *
- * HISTORY: *
- * 04/23/1996 PWG : Created. *
- *========================================================================*/
- FieldClass *PacketClass::Find_Field(char *id)
- {
- for (FieldClass *current = Head; current; current = current->Next) {
- if ( strncmp(id, current->ID, 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 PacketClass::Get_Field(char *id, char &data)
- {
- FieldClass *field = Find_Field(id);
- if (field) {
- data = *((char *)field->Data);
- }
- 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 PacketClass::Get_Field(char *id, unsigned char &data)
- {
- FieldClass *field = Find_Field(id);
- if (field) {
- data = *((unsigned char *)field->Data);
- }
- 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 PacketClass::Get_Field(char *id, short &data)
- {
- FieldClass *field = Find_Field(id);
- if (field) {
- data = *((short *)field->Data);
- }
- 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 PacketClass::Get_Field(char *id, unsigned short &data)
- {
- FieldClass *field = Find_Field(id);
- if (field) {
- data = *((unsigned short *)field->Data);
- }
- 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 PacketClass::Get_Field(char *id, long &data)
- {
- FieldClass *field = Find_Field(id);
- if (field) {
- data = *((long *)field->Data);
- }
- 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 PacketClass::Get_Field(char *id, char *data)
- {
- FieldClass *field = Find_Field(id);
- if (field) {
- strcpy(data, (char *)field->Data);
- }
- 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 PacketClass::Get_Field(char *id, unsigned long &data)
- {
- FieldClass *field = Find_Field(id);
- if (field) {
- data = *((unsigned long *)field->Data);
- }
- 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 PacketClass::Get_Field(char *id, void *data, int &length)
- {
- FieldClass *field = Find_Field(id);
- if (field) {
- memcpy (data, field->Data, min(field->Size, length));
- length = (int) field->Size;
- }
- return((field) ? true : false);
- }
|