Initial commit of Command & Conquer Generals and Command & Conquer Generals Zero Hour source code.

This commit is contained in:
LFeenanEA 2025-02-27 17:34:39 +00:00
parent 2e338c00cb
commit 3d0ee53a05
No known key found for this signature in database
GPG key ID: C6EBE8C2EA08F7E0
6072 changed files with 2283311 additions and 0 deletions

View file

@ -0,0 +1,328 @@
/*
** Command & Conquer Generals Zero Hour(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/>.
*/
/////////////////////////////////////////////////////////////////////////EA-V1
// $File: //depot/GeneralsMD/Staging/code/Libraries/Source/debug/netserv/netserv.cpp $
// $Author: mhoffe $
// $Revision: #1 $
// $DateTime: 2003/07/03 11:55:26 $
//
// ©2003 Electronic Arts
//
// Simple console based server for NET I/O connections
//////////////////////////////////////////////////////////////////////////////
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <malloc.h>
// Note: This implementation is quick'n'ugly. I've developed this
// program basically just for testing the net I/O class.
static char m_input[256];
static unsigned m_inputUsed;
static void InitConsole(void)
{
AllocConsole();
HANDLE h=GetStdHandle(STD_INPUT_HANDLE);
SetConsoleMode(h,0);
// make screen buffer same size as currently displayed area
// (prevents that our input line gets scrolled out of view)
h=GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(h,&info);
COORD newSize;
newSize.X=info.srWindow.Right+1;
newSize.Y=info.srWindow.Bottom+1;
SetConsoleScreenBufferSize(h,newSize);
// hide cursor
CONSOLE_CURSOR_INFO ci;
ci.dwSize=1;
ci.bVisible=FALSE;
SetConsoleCursorInfo(h,&ci);
}
static char *InputConsole(void)
{
// update our input buffer
HANDLE h=GetStdHandle(STD_INPUT_HANDLE);
bool returnChars=false;
for (;;)
{
DWORD dwRecords;
if (!GetNumberOfConsoleInputEvents(h,&dwRecords))
break;
if (!dwRecords)
break;
INPUT_RECORD record;
ReadConsoleInput(h,&record,1,&dwRecords);
if (record.EventType!=KEY_EVENT)
continue;
KEY_EVENT_RECORD &key=record.Event.KeyEvent;
if (!key.bKeyDown||!key.uChar.AsciiChar)
continue;
if (key.uChar.AsciiChar=='\r'||
key.uChar.AsciiChar=='\n')
{
m_input[m_inputUsed++]='\n';
returnChars=true;
break;
}
/// @todo_opt if somebody wants this can be improved by adding support for cursor keys, history, etc
if (key.uChar.AsciiChar=='\b')
{
if (m_inputUsed)
m_inputUsed--;
}
else if (((unsigned char)key.uChar.AsciiChar)>=' ')
{
if (m_inputUsed<sizeof(m_input)-1)
m_input[m_inputUsed++]=key.uChar.AsciiChar;
}
}
// update screen
h=GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(h,&info);
CHAR_INFO ci[sizeof(m_input)+1];
for (unsigned k=0;k<=sizeof(m_input);k++)
{
ci[k].Char.AsciiChar=k<m_inputUsed?m_input[k]:' ';
ci[k].Attributes=BACKGROUND_BLUE|FOREGROUND_BLUE|FOREGROUND_GREEN
|FOREGROUND_RED|FOREGROUND_INTENSITY;
}
// fake another cursor
if (GetTickCount()&512)
ci[m_inputUsed].Attributes=BACKGROUND_BLUE|BACKGROUND_GREEN
|BACKGROUND_RED|BACKGROUND_INTENSITY|FOREGROUND_BLUE;
COORD srcSize,srcCoord;
srcSize.X=sizeof(m_input); srcSize.Y=1;
srcCoord.X=srcCoord.Y=0;
SMALL_RECT r;
r.Left=r.Top=r.Bottom=0; r.Right=info.dwSize.X-1;
WriteConsoleOutput(h,ci+(m_inputUsed<=info.dwSize.X?0:m_inputUsed-info.dwSize.X),
srcSize,srcCoord,&r);
// return data now?
if (returnChars&&m_inputUsed>1)
{
m_input[--m_inputUsed]=0;
m_inputUsed=0;
return m_input;
}
return 0;
}
class Pipe
{
Pipe(const Pipe&);
Pipe& operator=(const Pipe&);
HANDLE m_pipe;
bool m_connected;
int m_state;
int m_stringType;
int m_len;
char *m_src;
char *m_str;
public:
Pipe(void):
m_pipe(INVALID_HANDLE_VALUE),
m_src(NULL), m_str(NULL), m_stringType(0)
{
}
~Pipe()
{
if (m_pipe!=INVALID_HANDLE_VALUE)
{
DisconnectNamedPipe(m_pipe);
CloseHandle(m_pipe);
free(m_src);
free(m_str);
}
}
bool Create(const char *name)
{
m_pipe=CreateNamedPipe(name,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE|PIPE_NOWAIT,
PIPE_UNLIMITED_INSTANCES,1024,1024,0,NULL);
m_connected=false;
return m_pipe!=INVALID_HANDLE_VALUE;
}
bool Connected(void)
{
if (!m_connected)
{
ConnectNamedPipe(m_pipe,NULL);
if (GetLastError()==ERROR_PIPE_CONNECTED)
{
DWORD dwDummy;
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),"\n<connect>\n",11,&dwDummy,NULL);
m_connected=true;
m_state=0;
}
}
return m_connected;
}
void Write(char msg)
{
DWORD dummy;
if (!WriteFile(m_pipe,&msg,1,&dummy,NULL)||!dummy)
{
char sp[30];
wsprintf(sp,"%c:%i/%i\n",msg,dummy,GetLastError());
DWORD dwDummy;
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),sp,strlen(sp),&dwDummy,NULL);
}
}
const char *Read(void)
{
DWORD read;
switch(m_state)
{
case 0:
if (!ReadFile(m_pipe,&m_stringType,1,&read,NULL))
break;
if (read==1)
m_state++;
return NULL;
case 1:
case 3:
if (!ReadFile(m_pipe,&m_len,4,&read,NULL))
break;
if (read==4)
{
if (m_state==1)
m_src=(char *)realloc(m_src,m_len+1);
else
m_str=(char *)realloc(m_str,m_len+1);
m_state++;
}
return NULL;
case 2:
if (!ReadFile(m_pipe,m_src,m_len,&read,NULL))
break;
if (read==m_len)
{
m_src[m_len]=0;
m_state++;
}
return NULL;
case 4:
if (!ReadFile(m_pipe,m_str,m_len,&read,NULL))
break;
if (read==m_len)
{
m_str[m_len]=0;
m_state=0;
return m_str;
}
return NULL;
}
if (GetLastError()==ERROR_BROKEN_PIPE)
{
DisconnectNamedPipe(m_pipe);
DWORD dwDummy;
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),"\n<disconnect>\n",14,&dwDummy,NULL);
m_connected=false;
}
return NULL;
}
};
int CALLBACK WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
InitConsole();
char buf1[200],buf2[400];
DWORD dwDummy=sizeof(buf1);
GetComputerName(buf1,&dwDummy);
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),buf2,
wsprintf(buf2,"\n\nSimple debug.net Server ready. Enter 'quit' to exit.\n\nLocal machine: %s\n\n",buf1),
&dwDummy,NULL);
Pipe p[10];
for (int k=0;k<10;k++)
if (!p[k].Create("\\\\.\\pipe\\ea_debug_v1"))
{
char msg[200];
wsprintf(msg,"Can't create named pipe (Code %i).",GetLastError());
MessageBox(NULL,msg,"Error",MB_OK);
return 1;
}
for (;;)
{
char *input=InputConsole();
if (input)
{
if (!strcmp(input,"quit"))
break;
}
for (int k=0;k<10;k++)
{
if (!p[k].Connected())
continue;
const char *msg=p[k].Read();
if (msg)
{
DWORD dwDummy;
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),msg,strlen(msg),&dwDummy,NULL);
}
if (input)
{
for (unsigned i=0;input[i];i++)
p[k].Write(input[i]);
p[k].Write('\n');
}
}
Sleep(10);
}
return 0;
}

View file

@ -0,0 +1,93 @@
# Microsoft Developer Studio Project File - Name="netserv" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=netserv - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "netserv.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "netserv.mak" CFG="netserv - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "netserv - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "netserv - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName "netserv"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "netserv - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "netserv - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386
!ENDIF
# Begin Target
# Name "netserv - Win32 Release"
# Name "netserv - Win32 Debug"
# Begin Source File
SOURCE=.\netserv.cpp
# End Source File
# End Target
# End Project