CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

PACKET.CPP (20016B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 /***************************************************************************
     17  *                                                                         *
     18  *                 Project Name : Westwood Auto Registration App           *
     19  *                                                                         *
     20  *                    File Name : PACKET.CPP                               *
     21  *                                                                         *
     22  *                   Programmer : Philip W. Gorrow                         *
     23  *                                                                         *
     24  *                   Start Date : 04/22/96                                 *
     25  *                                                                         *
     26  *                  Last Update : April 24, 1996 [PWG]                     *
     27  *                                                                         *
     28  *-------------------------------------------------------------------------*
     29  * Functions:                                                              *
     30  *   *PacketClass::Find_Field -- Finds a field if it exists in the packets *
     31  *   Get_Field -- Find specified name and returns data                     *
     32  *   PacketClass::~PacketClass -- destroys a packet class be freeing list  *
     33  *   PacketClass::Add_Field -- Adds a FieldClass entry to head of packet li*
     34  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     35 #if (0) //PG
     36 
     37 #include <stdlib.h>
     38 #include <mem.h>
     39 #include <string.h>
     40 
     41 enum {false=0,true=1};
     42 typedef int bool;
     43 
     44 #include "packet.h"
     45 
     46 
     47 /**************************************************************************
     48  * PACKETCLASS::~PACKETCLASS -- destroys a packet class be freeing list   *
     49  *                                                                        *
     50  * INPUT:		none                                                       *
     51  *                                                                        *
     52  * OUTPUT:     none																		  *
     53  *                                                                        *
     54  * HISTORY:                                                               *
     55  *   04/24/1996 PWG : Created.                                            *
     56  *========================================================================*/
     57 PacketClass::~PacketClass(void)
     58 {
     59 	FieldClass *current;
     60 	FieldClass *next;
     61 	//
     62 	// Loop through the entire field list and delete each entry.
     63 	//
     64 	for (current = Head; current; current = next) {
     65 		next = current->Next;
     66 		delete current;
     67 	}
     68 }
     69 
     70 
     71 /**************************************************************************
     72  * PACKETCLASS::ADD_FIELD -- Adds a FieldClass entry to head of packet li *
     73  *                                                                        *
     74  * INPUT:		FieldClass * - a properly constructed field class entry.	  *
     75  *                                                                        *
     76  * OUTPUT:     none                                                       *
     77  *                                                                        *
     78  * HISTORY:                                                               *
     79  *   04/24/1996 PWG : Created.                                            *
     80  *========================================================================*/
     81 void PacketClass::Add_Field(FieldClass *field)
     82 {
     83 	field->Next = Head;
     84 	Head = field;
     85 }
     86 
     87 /**************************************************************************
     88  * PACKETCLASS::PACKETCLASS -- Creates a Packet object from a COMMS packe *
     89  *                                                                        *
     90  * INPUT:                                                                 *
     91  *                                                                        *
     92  * OUTPUT:                                                                *
     93  *                                                                        *
     94  * WARNINGS:                                                              *
     95  *                                                                        *
     96  * HISTORY:                                                               *
     97  *   04/22/1996 PWG : Created.                                            *
     98  *========================================================================*/
     99 PacketClass::PacketClass(char *curbuf)
    100 {
    101 	int remaining_size;
    102 	//
    103 	// Pull the size and packet ID out of the linear packet stream.
    104 	//
    105 	Size = *(unsigned short *)curbuf;
    106 	curbuf += sizeof (unsigned short);
    107 	Size = ntohs(Size);
    108 	ID	  = *(short *)curbuf;
    109 	curbuf += sizeof (short);
    110 	ID   = ntohs(ID);
    111 	Head = NULL;
    112 
    113 	//
    114 	// Calculate the remaining size so that we can loop through the
    115 	//   packets and extract them.
    116 	//
    117 	remaining_size = Size - 4;
    118 
    119 	//
    120 	// Loop through the linear packet until we run out of room and
    121 	// create a field for each.
    122 	//
    123 	while (remaining_size > 0) {
    124 		FieldClass *field = new FieldClass;
    125 
    126 		//
    127 		// Copy the adjusted header into the buffer and then advance the buffer
    128 		//
    129 		memcpy(field, curbuf, FIELD_HEADER_SIZE);
    130 		curbuf += FIELD_HEADER_SIZE;
    131 		remaining_size   -= FIELD_HEADER_SIZE;
    132 
    133 		//
    134 		// Copy the data into the buffer
    135 		//
    136 		int size			= ntohs(field->Size);
    137 		field->Data		= new char[size];
    138 		memcpy(field->Data, curbuf, size);
    139 		curbuf			+= size;
    140 		remaining_size	-= size;
    141 		//
    142 		// Make sure we allow for the pad bytes.
    143 		//
    144 		int pad = (4 - (ntohs(field->Size) & 3)) & 3;
    145 		curbuf += pad;
    146 		remaining_size   -= pad;
    147 
    148 		//
    149 		// Convert the field back to the host format
    150 		//
    151 		field->Net_To_Host();
    152 
    153 		//
    154 		// Finally add the field to the field list in the packet
    155 		// structure.
    156 		//
    157 		Add_Field(field);
    158 	}
    159 }
    160 
    161 /**************************************************************************
    162  * CREATE_COMMS_PACKET -- Walks field list creating a packet              *
    163  *                                                                        *
    164  * INPUT:		short - the id of the packet so the server can identify it *
    165  *					unsigned short & - the size of the packet returned here    *
    166  *                                                                        *
    167  * OUTPUT:     void * pointer to the linear packet data                   *
    168  *                                                                        *
    169  * WARNINGS: 	This routine allocates memory that the user is responsible *
    170  *  				for freeing.															  *
    171  *                                                                        *
    172  * HISTORY:                                                               *
    173  *   04/22/1996 PWG : Created.                                            *
    174  *========================================================================*/
    175 char *PacketClass::Create_Comms_Packet(int &size)
    176 {
    177 	FieldClass *current;
    178 
    179 	//
    180 	// Size starts at four because that is the size of the packet header.
    181 	//
    182 	size = 4;
    183 
    184 	//
    185 	// Take a quick spin through and calculate the size of the packet we
    186 	//   are building.
    187 	//
    188 	for (current = Head; current; current=current->Next) {
    189 		size += (unsigned short)FIELD_HEADER_SIZE;			// add in packet header size
    190 		size += current->Size;				// add in data size
    191 		size += (4 - (size & 3)) & 3; 	// add in pad value to dword align next packet
    192 	}
    193 
    194 	//
    195 	// Now that we know the size allocate a buffer big enough to hold the
    196 	// packet.
    197 	//
    198 	char *retval = new char[size];
    199 	char *curbuf = retval;
    200 
    201 	//
    202 	// write the size into the packet header
    203 	//
    204 	*(unsigned short *)curbuf = (unsigned short)htons((unsigned short)size);
    205 	curbuf += sizeof (unsigned short);
    206 	*(short *)curbuf = htons(ID);
    207 	curbuf += sizeof (short);
    208 
    209 	//
    210 	// Ok now that the actual header information has been written we need to write out
    211 	// field information.
    212 	//
    213 	for (current = Head; current; current = current->Next) {
    214 		//
    215 		// Temporarily convert the packet to net format (this saves alot of
    216 		//   effort, and seems safe...)
    217 		//
    218 		current->Host_To_Net();
    219 
    220 		//
    221 		// Copy the adjusted header into the buffer and then advance the buffer
    222 		//
    223 		memcpy(curbuf, current, FIELD_HEADER_SIZE);
    224 		curbuf += FIELD_HEADER_SIZE;
    225 
    226 		//
    227 		// Copy the data into the buffer and then advance the buffer
    228 		//
    229 		memcpy(curbuf, current->Data, ntohs(current->Size));
    230 		curbuf += ntohs(current->Size);
    231 
    232 		//
    233 		// Finally take care of any pad bytes by setting them to 0
    234 		//
    235 		int pad = (4 - (ntohs(current->Size) & 3)) & 3;
    236 
    237 		//
    238 		//	If there is any pad left over, make sure you memset it
    239 		// to zeros, so it looks like a pad.
    240 		//
    241 		if (pad) {
    242 			memset(curbuf, 0, pad);
    243 			curbuf += pad;
    244 		}
    245 
    246 		current->Net_To_Host();
    247 	}
    248 	return(retval);
    249 }
    250 
    251 
    252 /**************************************************************************
    253  * PACKETCLASS::FIND_FIELD -- Finds a field if it exists in the packets   *
    254  *                                                                        *
    255  * INPUT:		char *  - the id of the field we are looking for.			  *
    256  *                                                                        *
    257  * OUTPUT:     FieldClass * pointer to the field class                    *
    258  *                                                                        *
    259  * HISTORY:                                                               *
    260  *   04/23/1996 PWG : Created.                                            *
    261  *========================================================================*/
    262 FieldClass *PacketClass::Find_Field(char *id)
    263 {
    264 	for (FieldClass *current = Head; current; current = current->Next) {
    265 		if ( strncmp(id, current->ID, 4) == 0)
    266 			return current;
    267 	}
    268 	return NULL;
    269 }
    270 
    271 
    272 /**************************************************************************
    273  * GET_FIELD -- Find specified name and returns data                      *
    274  *                                                                        *
    275  * INPUT:		char *   - the id of the field that holds the data.		  *
    276  *					char &   - the reference to store the data into				  *
    277  *                                                                        *
    278  * OUTPUT:		true if the field was found, false if it was not.			  *
    279  *                                                                        *
    280  * WARNINGS:	The data reference is not changed if the field is not		  *
    281  *					found.																	  *
    282  *                                                                        *
    283  * HISTORY:                                                               *
    284  *   04/23/1996 PWG : Created.                                            *
    285  *========================================================================*/
    286 bool PacketClass::Get_Field(char *id, char &data)
    287 {
    288 	FieldClass *field = Find_Field(id);
    289 	if (field) {
    290 		data = *((char *)field->Data);
    291 	}
    292 	return((field) ? true : false);
    293 }
    294 
    295 
    296 /**************************************************************************
    297  * GET_FIELD -- Find specified name and returns data                      *
    298  *                                                                        *
    299  * INPUT:		char *   - the id of the field that holds the data.		  *
    300  *					unsigned char &   - the reference to store the data into	  *
    301  *                                                                        *
    302  * OUTPUT:		true if the field was found, false if it was not.			  *
    303  *                                                                        *
    304  * WARNINGS:	The data reference is not changed if the field is not		  *
    305  *					found.																	  *
    306  *                                                                        *
    307  * HISTORY:                                                               *
    308  *   04/23/1996 PWG : Created.                                            *
    309  *========================================================================*/
    310 bool PacketClass::Get_Field(char *id, unsigned char &data)
    311 {
    312 	FieldClass *field = Find_Field(id);
    313 	if (field) {
    314 		data = *((unsigned char *)field->Data);
    315 	}
    316 	return((field) ? true : false);
    317 }
    318 
    319 
    320 /**************************************************************************
    321  * GET_FIELD -- Find specified name and returns data                      *
    322  *                                                                        *
    323  * INPUT:		char *   - the id of the field that holds the data.		  *
    324  *					short &   - the reference to store the data into	        *
    325  *                                                                        *
    326  * OUTPUT:		true if the field was found, false if it was not.			  *
    327  *                                                                        *
    328  * WARNINGS:	The data reference is not changed if the field is not		  *
    329  *					found.																	  *
    330  *                                                                        *
    331  * HISTORY:                                                               *
    332  *   04/23/1996 PWG : Created.                                            *
    333  *========================================================================*/
    334 bool PacketClass::Get_Field(char *id, short &data)
    335 {
    336 	FieldClass *field = Find_Field(id);
    337 	if (field) {
    338 		data = *((short *)field->Data);
    339 	}
    340 	return((field) ? true : false);
    341 }
    342 
    343 
    344 /**************************************************************************
    345  * GET_FIELD -- Find specified name and returns data                      *
    346  *                                                                        *
    347  * INPUT:		char *   - the id of the field that holds the data.		  *
    348  *					unsigned short &   - the reference to store the data into  *
    349  *                                                                        *
    350  * OUTPUT:		true if the field was found, false if it was not.			  *
    351  *                                                                        *
    352  * WARNINGS:	The data reference is not changed if the field is not		  *
    353  *					found.																	  *
    354  *                                                                        *
    355  * HISTORY:                                                               *
    356  *   04/23/1996 PWG : Created.                                            *
    357  *========================================================================*/
    358 bool PacketClass::Get_Field(char *id, unsigned short &data)
    359 {
    360 	FieldClass *field = Find_Field(id);
    361 	if (field) {
    362 		data = *((unsigned short *)field->Data);
    363 	}
    364 	return((field) ? true : false);
    365 }
    366 
    367 
    368 /**************************************************************************
    369  * GET_FIELD -- Find specified name and returns data                      *
    370  *                                                                        *
    371  * INPUT:		char *   - the id of the field that holds the data.		  *
    372  *					long &   - the reference to store the data into  			  *
    373  *                                                                        *
    374  * OUTPUT:		true if the field was found, false if it was not.			  *
    375  *                                                                        *
    376  * WARNINGS:	The data reference is not changed if the field is not		  *
    377  *					found.																	  *
    378  *                                                                        *
    379  * HISTORY:                                                               *
    380  *   04/23/1996 PWG : Created.                                            *
    381  *========================================================================*/
    382 bool PacketClass::Get_Field(char *id, long &data)
    383 {
    384 	FieldClass *field = Find_Field(id);
    385 	if (field) {
    386 		data = *((long *)field->Data);
    387 	}
    388 	return((field) ? true : false);
    389 }
    390 
    391 /**************************************************************************
    392  * GET_FIELD -- Find specified name and returns data as a string          *
    393  *                                                                        *
    394  * INPUT:		char *   - the id of the field that holds the data.		  *
    395  *					char *   - the string to store the data into					  *
    396  *                                                                        *
    397  * OUTPUT:		true if the field was found, false if it was not.			  *
    398  *                                                                        *
    399  * WARNINGS:	The string is not changed if the field is not found.  It   *
    400  *					is assumed that the string variabled specified by the      *
    401  *					pointer is large enough to hold the data.						  *
    402  *                                                                        *
    403  * HISTORY:                                                               *
    404  *   04/23/1996 PWG : Created.                                            *
    405  *========================================================================*/
    406 bool PacketClass::Get_Field(char *id, char *data)
    407 {
    408 	FieldClass *field = Find_Field(id);
    409 	if (field) {
    410 		strcpy(data, (char *)field->Data);
    411 	}
    412 	return((field) ? true : false);
    413 }
    414 
    415 /**************************************************************************
    416  * GET_FIELD -- Find specified name and returns data                      *
    417  *                                                                        *
    418  * INPUT:		char *   - the id of the field that holds the data.		  *
    419  *					unsigned long &   - the reference to store the data into   *
    420  *                                                                        *
    421  * OUTPUT:		true if the field was found, false if it was not.			  *
    422  *                                                                        *
    423  * WARNINGS:	The data reference is not changed if the field is not		  *
    424  *					found.																	  *
    425  *                                                                        *
    426  * HISTORY:                                                               *
    427  *   04/23/1996 PWG : Created.                                            *
    428  *========================================================================*/
    429 bool PacketClass::Get_Field(char *id, unsigned long &data)
    430 {
    431 	FieldClass *field = Find_Field(id);
    432 	if (field) {
    433 		data = *((unsigned long *)field->Data);
    434 	}
    435 	return((field) ? true : false);
    436 }
    437 
    438 
    439 /**************************************************************************
    440  * GET_FIELD -- Find specified name and returns data                      *
    441  *                                                                        *
    442  * INPUT:		char *   - the id of the field that holds the data.		    *
    443  *				void * - the reference to store the data into                *
    444  *           int    - the length of the buffer passed in                  *
    445  *                                                                        *
    446  * OUTPUT:		true if the field was found, false if it was not.			 *
    447  *                                                                        *
    448  * WARNINGS:	The data reference is not changed if the field is not		    *
    449  *					found.																	 *
    450  *                                                                        *
    451  * HISTORY:                                                               *
    452  *   6/4/96 4:46PM ST : Created                                           *
    453  *========================================================================*/
    454 bool PacketClass::Get_Field(char *id, void *data, int &length)
    455 {
    456 	FieldClass *field = Find_Field(id);
    457 	if (field) {
    458 		memcpy (data, field->Data, min(field->Size, length));
    459 		length = (int) field->Size;
    460 	}
    461 	return((field) ? true : false);
    462 }
    463 #endif