Files
firestorm/Gameleap/code/mw4/Libraries/server/server.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

384 lines
8.4 KiB
C++

#include "comline.hpp"
//#include <exception>
#include <stdio.h>
#include "comline.h"
static void* __cdecl operator new (unsigned int size)
{
return malloc (size);
}
static void __cdecl operator delete (void *buffer)
{
free (buffer);
}
using namespace NCOMLINE;
CCommandLineServer *NCOMLINE::n_CurServer = NULL;
void ExecuteLine(const unsigned char * pszString)
{
if (n_CurServer)
n_CurServer->ExecuteLine ((const char *) pszString);
}
int NumOutputLines(void)
{
if (n_CurServer)
return n_CurServer->NumOutputLines ();
return 0;
}
void GetOutputLine(int size,unsigned char * pszString)
{
if (n_CurServer)
n_CurServer->GetOutputLine (size,pszString);
}
void Shutdown(void)
{
#ifdef LAB_ONLY
RPC_STATUS status;
status = RpcMgmtStopServerListening(NULL);
if (!status)
{
status = RpcServerUnregisterIf(NULL, NULL, FALSE);
}
#endif
}
DWORD WINAPI NCOMLINE::ServerThreadProc (void *p1)
{
#if LAB_ONLY
CCommandLineServer *data;
data = static_cast<CCommandLineServer *> (p1);
WaitForSingleObject (data->m_Semaphore,INFINITE);
ReleaseSemaphore (data->m_ExitSemaphore,1,NULL);
ReleaseSemaphore (data->m_Semaphore,1,NULL);
RPC_STATUS status;
unsigned char * pszProtocolSequence1 = (unsigned char *) "ncacn_ip_tcp";
unsigned char * pszEndpoint1 = (unsigned char *) "1404";
unsigned char * pszProtocolSequence2 = (unsigned char *) "ncalrpc";
unsigned char * pszEndpoint2 = (unsigned char *) "ComLine";
unsigned char * pszSecurity = (unsigned char *) NULL;
unsigned int cMinCalls = 1;
unsigned int cMaxCalls = 20;
unsigned int fDontWait = FALSE;
// status = RpcServerUseAllProtseqs (cMaxCalls,pszSecurity);
status = RpcServerUseProtseqEp(pszProtocolSequence1,cMaxCalls,pszEndpoint1,pszSecurity); // Security descriptor
if (status)
return (status);
status = RpcServerUseProtseqEp(pszProtocolSequence2,cMaxCalls,pszEndpoint2,pszSecurity); // Security descriptor
if (status)
return (status);
RPC_BINDING_VECTOR *inq;
status = RpcServerInqBindings (&inq);
status = RpcServerRegisterIf(ComLine_ServerIfHandle, // interface to register
NULL, // MgrTypeUuid
NULL); // MgrEpv; null means use default
if (status)
return (status);
status = RpcServerListen(cMinCalls,cMaxCalls,fDontWait);
if (status)
return status;
WaitForSingleObject (data->m_ExitSemaphore,INFINITE);
#endif
return 0;
}
void CCommandLineServer::PushLine (const LineData& data)
{
CRITICAL_CONTROL (m_Critical);
if (!m_Inited)
return;
if (m_NumLines == m_SizeLines)
{
int i;
LineData *temp;
temp = new LineData[m_SizeLines+50];
for (i=0;i<m_NumLines;i++)
{
temp[i] = m_Lines[i];
}
delete[] m_Lines;
m_Lines = temp;
m_SizeLines+=50;
}
m_Lines[m_NumLines] = data;
m_NumLines++;
}
void CCommandLineServer::RemoveLine (void)
{
int i;
CRITICAL_CONTROL (m_Critical);
if (!m_Inited)
return;
assert (m_NumLines);
m_NumLines--;
for (i=0;i<m_NumLines;i++)
{
m_Lines[i] = m_Lines[i+1];
}
}
void CCommandLineServer::PushCommand (const CommandMap& data)
{
CRITICAL_CONTROL (m_Critical);
if (!m_Inited)
return;
if (m_NumLines == m_SizeLines)
{
int i;
CommandMap *temp;
temp = new CommandMap[m_SizeCommands+50];
for (i=0;i<m_NumCommands;i++)
{
temp[i] = m_Commands[i];
}
delete[] m_Commands;
m_Commands = temp;
m_SizeCommands+=50;
}
m_Commands[m_NumCommands] = data;
m_NumCommands++;
}
CCommandLineServer::CCommandLineServer (void)
{
m_Inited = false;
m_Lines = NULL;
m_NumLines = 0;
m_SizeLines = 0;
m_Commands = NULL;
m_NumCommands = 0;
m_SizeCommands = 0;
m_Semaphore = NULL;
m_ExitSemaphore = NULL;
m_Thread = NULL;
hMappedFile=NULL;
#if LAB_ONLY
hMappedFile=CreateFileMapping( (HANDLE)0xffffffff, //-1 hFile flag
NULL, // no sharing allowed
PAGE_READONLY|SEC_RESERVE, // no writing or physical space allocated
0, // high-byte size
4, // low byte size
"AHF_COMLINE_FILE"); // use class string as file name
if (hMappedFile!=NULL && GetLastError() == ERROR_ALREADY_EXISTS)
{
//another T2 is running, it just hasn't created it's window yet
CloseHandle(hMappedFile);
hMappedFile=NULL;
return;
}
m_Lines = new LineData[50];
m_NumLines = 0;
m_SizeLines = 50;
PushLine (LineData ("Command Line server started",LINE_OUTPUT));
m_Commands = new CommandMap[50];
m_NumCommands = 0;
m_SizeCommands = 50;
m_Semaphore = CreateSemaphore (NULL,0,1,NULL);
if (!m_Semaphore)
assert (false);
m_ExitSemaphore = CreateSemaphore (NULL,0,1,NULL);
if (!m_ExitSemaphore)
assert (false);
m_Thread = CreateThread (NULL,0,NCOMLINE::ServerThreadProc,(void *) this,0,&m_ThreadID);
if (!m_Thread)
assert (false);
ReleaseSemaphore (m_Semaphore,1,NULL);
WaitForSingleObject (m_ExitSemaphore,INFINITE);
WaitForSingleObject (m_Semaphore,INFINITE);
n_CurServer = this;
m_Inited = true;
#endif
}
CCommandLineServer::~CCommandLineServer (void)
{
if (!m_Inited)
return;
#ifdef LAB_ONLY
RPC_STATUS status;
status = RpcMgmtStopServerListening(NULL);
if (!status)
{
status = RpcServerUnregisterIf(NULL, NULL, FALSE);
}
#endif
n_CurServer = NULL;
ReleaseSemaphore (m_ExitSemaphore,1,NULL);
WaitForSingleObject (m_Thread,INFINITE);
CloseHandle (m_ExitSemaphore);
CloseHandle (m_Semaphore);
CloseHandle (m_Thread);
if (hMappedFile)
CloseHandle (hMappedFile);
hMappedFile = NULL;
delete[] m_Lines;
delete[] m_Commands;
m_Inited = false;
}
void CCommandLineServer::PushLine (const char *line)
{
CRITICAL_CONTROL (m_Critical);
if (!m_Inited)
return;
LineData data (line,LINE_OUTPUT);
PushLine (data);
}
void CCommandLineServer::ExecuteLine (const char *line)
{
CRITICAL_CONTROL (m_Critical);
int iter;
LineData data (line,LINE_COMMAND);
CCom_String name (line);
if (!m_Inited)
return;
ParseLine (data);
if (data.m_ComBreak != name.GetLength ())
{
name.SetAt (data.m_ComBreak,0);
}
for (iter = 0;iter<m_NumCommands;iter++)
{
if (m_Commands[iter].m_Command == name)
break;
}
if (iter != m_NumCommands)
{
if (!m_Commands[iter].m_Function (this,data))
PushLine (LineData ("Function failed",LINE_OUTPUT));
}
else
{
PushLine (LineData ("Function not found",LINE_OUTPUT));
}
}
void CCommandLineServer::ParseLine (LineData& data)
{
char *buf;
int i,size;
bool ignore;
CRITICAL_CONTROL (m_Critical);
ignore = false;
data.m_Data.TrimLeft ();
data.m_ComBreak = -1;
size = data.m_Data.GetLength ();
buf = data.m_Data.GetBuffer (0);
for (i=0;i<size;i++,buf++)
{
if ((*buf == ' ') && !ignore)
{
data.m_ArgBreak[data.m_NumArgs] = i;
data.m_NumArgs++;
}
else if (*buf == '\"')
{
ignore = !ignore;
}
}
data.m_Data.ReleaseBuffer ();
data.m_ArgBreak[data.m_NumArgs] = data.m_Data.GetLength ();
data.m_NumArgs++;
data.m_ComBreak = data.m_ArgBreak[0];
}
int CCommandLineServer::NumOutputLines(void)
{
return m_NumLines;
}
void CCommandLineServer::GetOutputLine(int size,unsigned char * pszString)
{
CRITICAL_CONTROL (m_Critical);
LineData *iter;
iter = m_Lines;
if (m_NumLines)
{
const char *buffer = (LPCTSTR) iter->m_Data;
strncpy ((char *) pszString,buffer,size-1);
pszString[size-1] = 0;
RemoveLine ();
}
else
pszString[0] = 0;
}
bool CCommandLineServer::AddCommand (NCOMLINE::ComFunc func,const CCom_String& name)
{
CRITICAL_CONTROL (m_Critical);
int iter;
if (!m_Inited)
return false;
for (iter = 0;iter<m_NumCommands;iter++)
{
if (m_Commands[iter].m_Command == name)
break;
}
if (iter != m_NumCommands)
m_Commands[iter].m_Function = func;
else
PushCommand (CommandMap (name,func));
return true;
}
bool CCommandLineServer::RemoveCommand (const CCom_String& name)
{
CRITICAL_CONTROL (m_Critical);
int iter;
int i;
if (!m_Inited)
return false;
for (iter = 0;iter<m_NumCommands;iter++)
{
if (m_Commands[iter].m_Command == name)
break;
}
if (iter == m_NumCommands)
return false;
m_NumCommands--;
for (i=iter;i<m_NumCommands;i++)
{
m_Commands[i] = m_Commands[i+1];
}
return true;
}