Enhanced rechecker api

This commit is contained in:
s1lent 2017-09-21 23:43:22 +07:00 committed by s1lentq
parent 4727659db0
commit bb2bb4453f
93 changed files with 6885 additions and 732 deletions

View File

@ -1,11 +1,12 @@
NAME = rechecker
COMPILER = /opt/intel/bin/icpc
BIN_SUFFIX = i386
OBJECTS = src/main.cpp src/meta_api.cpp src/dllapi.cpp src/cmdexec.cpp \
src/engine_rehlds.cpp src/h_export.cpp src/resource.cpp \
src/sdk_util.cpp src/hookchains_impl.cpp src/rechecker_api_impl.cpp public/interface.cpp
LINK = -lm -ldl -static-intel -static-libgcc -no-intel-extensions
LINK = -lm -ldl -static-intel -static-libgcc -no-intel-extensions -fno-exceptions
OPT_FLAGS = -O3 -msse3 -ipo -no-prec-div -fp-model fast=2 -funroll-loops -fomit-frame-pointer -fno-stack-protector
@ -17,7 +18,7 @@ CFLAGS = $(OPT_FLAGS)
CFLAGS += -g0 -fvisibility=hidden -DNOMINMAX -fvisibility-inlines-hidden\
-DNDEBUG -Dlinux -D__linux__ -std=c++11 -shared -wd147,274 -fasm-blocks\
-Qoption,cpp,--treat_func_as_string_literal_cpp -fno-rtti\
-D_byteswap_ulong=_bswap
-D_byteswap_ulong=_bswap -D_mkdir=mkdir -D_stricmp=strcasecmp
OBJ_LINUX := $(OBJECTS:%.c=$(BIN_DIR)/%.o)
@ -28,15 +29,15 @@ all:
mkdir -p $(BIN_DIR)
mkdir -p $(BIN_DIR)/sdk
$(MAKE) $(NAME) && strip -x $(BIN_DIR)/$(NAME)_mm_i386.so
$(MAKE) $(NAME) && strip -x $(BIN_DIR)/$(NAME)_mm_$(BIN_SUFFIX).so
$(NAME): $(OBJ_LINUX)
$(COMPILER) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -o$(BIN_DIR)/$(NAME)_mm_i386.so
$(COMPILER) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -o$(BIN_DIR)/$(NAME)_mm_$(BIN_SUFFIX).so
check:
cppcheck $(INCLUDE) --quiet --max-configs=100 -D__linux__ -DNDEBUG -DHAVE_STDINT_H .
debug:
debug:
$(MAKE) all DEBUG=false
default: all
@ -44,6 +45,4 @@ default: all
clean:
rm -rf Release/sdk/*.o
rm -rf Release/*.o
rm -rf Release/$(NAME)_mm_i386.so
rm -rf Release/$(NAME)_mm_$(BIN_SUFFIX).so

154
common/BaseSystemModule.cpp Normal file
View File

@ -0,0 +1,154 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#include "precompiled.h"
char *BaseSystemModule::GetName()
{
return m_Name;
}
char *BaseSystemModule::GetType()
{
return "GenericModule";
}
char *BaseSystemModule::GetStatusLine()
{
return "No status available.\n";
}
void BaseSystemModule::ExecuteCommand(int commandID, char *commandLine)
{
m_System->DPrintf("WARNING! Undeclared ExecuteCommand().\n");
}
extern int COM_BuildNumber();
int BaseSystemModule::GetVersion()
{
return COM_BuildNumber();
}
int BaseSystemModule::GetSerial()
{
return m_Serial;
}
IBaseSystem *BaseSystemModule::GetSystem()
{
return m_System;
}
bool BaseSystemModule::Init(IBaseSystem *system, int serial, char *name)
{
if (!system)
return false;
m_State = MODULE_INITIALIZING;
m_System = system;
m_Serial = serial;
m_SystemTime = 0;
if (name) {
strcopy(m_Name, name);
}
return true;
}
void BaseSystemModule::RunFrame(double time)
{
m_SystemTime = time;
}
void BaseSystemModule::ShutDown()
{
if (m_State == MODULE_DISCONNECTED)
return;
m_Listener.Clear();
m_State = MODULE_DISCONNECTED;
if (!m_System->RemoveModule(this))
{
m_System->DPrintf("ERROR! BaseSystemModule::ShutDown: faild to remove module %s.\n", m_Name);
}
}
void BaseSystemModule::RegisterListener(ISystemModule *module)
{
ISystemModule *listener = (ISystemModule *)m_Listener.GetFirst();
while (listener)
{
if (listener->GetSerial() == module->GetSerial())
{
m_System->DPrintf("WARNING! BaseSystemModule::RegisterListener: module %s already added.\n", module->GetName());
return;
}
listener = (ISystemModule *)m_Listener.GetNext();
}
m_Listener.Add(module);
}
void BaseSystemModule::RemoveListener(ISystemModule *module)
{
ISystemModule *listener = (ISystemModule *)m_Listener.GetFirst();
while (listener)
{
if (listener->GetSerial() == module->GetSerial())
{
m_Listener.Remove(module);
return;
}
listener = (ISystemModule *)m_Listener.GetNext();
}
}
void BaseSystemModule::FireSignal(unsigned int signal, void *data)
{
ISystemModule *listener = (ISystemModule *)m_Listener.GetFirst();
while (listener)
{
listener->ReceiveSignal(this, signal, data);
listener = (ISystemModule *)m_Listener.GetNext();
}
}
void BaseSystemModule::ReceiveSignal(ISystemModule *module, unsigned int signal, void *data)
{
m_System->DPrintf("WARNING! Unhandled signal (%i) from module %s.\n", signal, module->GetName());
}
int BaseSystemModule::GetState()
{
return m_State;
}

75
common/BaseSystemModule.h Normal file
View File

@ -0,0 +1,75 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
#include "ObjectList.h"
#include "IBaseSystem.h"
// C4250 - 'class1' : inherits 'BaseSystemModule::member' via dominance
#pragma warning(disable:4250)
class BaseSystemModule: virtual public ISystemModule {
public:
BaseSystemModule() : m_State(MODULE_UNDEFINED) {}
virtual ~BaseSystemModule() {}
virtual bool Init(IBaseSystem *system, int serial, char *name);
virtual void RunFrame(double time);
virtual void ReceiveSignal(ISystemModule *module, unsigned int signal, void *data);
virtual void ExecuteCommand(int commandID, char *commandLine);
virtual void RegisterListener(ISystemModule *module);
virtual void RemoveListener(ISystemModule *module);
virtual IBaseSystem *GetSystem();
virtual int GetSerial();
virtual char *GetStatusLine();
virtual char *GetType();
virtual char *GetName();
enum ModuleState {
MODULE_UNDEFINED = 0,
MODULE_INITIALIZING,
MODULE_CONNECTING,
MODULE_RUNNING,
MODULE_DISCONNECTED
};
virtual int GetState();
virtual int GetVersion();
virtual void ShutDown();
virtual char *GetBaseDir() { return ""; }
void FireSignal(unsigned int signal, void *data = nullptr);
protected:
IBaseSystem *m_System;
ObjectList m_Listener;
char m_Name[255];
unsigned int m_State;
unsigned int m_Serial;
double m_SystemTime;
};

54
common/IAdminServer.h Normal file
View File

@ -0,0 +1,54 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
#include "interface.h"
// handle to a game window
typedef unsigned int ManageServerUIHandle_t;
class IManageServer;
// Purpose: Interface to server administration functions
class IAdminServer: public IBaseInterface
{
public:
// opens a manage server dialog for a local server
virtual ManageServerUIHandle_t OpenManageServerDialog(const char *serverName, const char *gameDir) = 0;
// opens a manage server dialog to a remote server
virtual ManageServerUIHandle_t OpenManageServerDialog(unsigned int gameIP, unsigned int gamePort, const char *password) = 0;
// forces the game info dialog closed
virtual void CloseManageServerDialog(ManageServerUIHandle_t gameDialog) = 0;
// Gets a handle to the interface
virtual IManageServer *GetManageServerInterface(ManageServerUIHandle_t handle) = 0;
};
#define ADMINSERVER_INTERFACE_VERSION "AdminServer002"

91
common/IBaseSystem.h Normal file
View File

@ -0,0 +1,91 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
#if defined(_WIN32)
#define LIBRARY_PREFIX "dll"
#elif defined(OSX)
#define LIBRARY_PREFIX "dylib"
#else
#define LIBRARY_PREFIX "so"
#endif
#include "ISystemModule.h"
#include "IVGuiModule.h"
class Panel;
class ObjectList;
class IFileSystem;
class IBaseSystem: virtual public ISystemModule {
public:
virtual ~IBaseSystem() {}
virtual double GetTime() = 0;
virtual unsigned int GetTick() = 0;
virtual void SetFPS(float fps) = 0;
virtual void Printf(char *fmt, ...) = 0;
virtual void DPrintf(char *fmt, ...) = 0;
virtual void RedirectOutput(char *buffer = nullptr, int maxSize = 0) = 0;
virtual IFileSystem *GetFileSystem() = 0;
virtual unsigned char *LoadFile(const char *name, int *length = nullptr) = 0;
virtual void FreeFile(unsigned char *fileHandle) = 0;
virtual void SetTitle(char *text) = 0;
virtual void SetStatusLine(char *text) = 0;
virtual void ShowConsole(bool visible) = 0;
virtual void LogConsole(char *filename) = 0;
virtual bool InitVGUI(IVGuiModule *module) = 0;
#ifdef _WIN32
virtual Panel *GetPanel() = 0;
#endif // _WIN32
virtual bool RegisterCommand(char *name, ISystemModule *module, int commandID) = 0;
virtual void GetCommandMatches(char *string, ObjectList *pMatchList) = 0;
virtual void ExecuteString(char *commands) = 0;
virtual void ExecuteFile(char *filename) = 0;
virtual void Errorf(char *fmt, ...) = 0;
virtual char *CheckParam(char *param) = 0;
virtual bool AddModule(ISystemModule *module, char *name) = 0;
virtual ISystemModule *GetModule(char *interfacename, char *library, char *instancename = nullptr) = 0;
virtual bool RemoveModule(ISystemModule *module) = 0;
virtual void Stop() = 0;
virtual char *GetBaseDir() = 0;
};
#define BASESYSTEM_INTERFACE_VERSION "basesystem002"

93
common/IDemoPlayer.h Normal file
View File

@ -0,0 +1,93 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
#include "ref_params.h"
class IWorld;
class IProxy;
class DirectorCmd;
class IBaseSystem;
class ISystemModule;
class IObjectContainer;
class IDemoPlayer {
public:
virtual ~IDemoPlayer() {}
virtual bool Init(IBaseSystem *system, int serial, char *name) = 0;
virtual void RunFrame(double time) = 0;
virtual void ReceiveSignal(ISystemModule *module, unsigned int signal, void *data) = 0;
virtual void ExecuteCommand(int commandID, char *commandLine) = 0;
virtual void RegisterListener(ISystemModule *module) = 0;
virtual void RemoveListener(ISystemModule *module) = 0;
virtual IBaseSystem *GetSystem() = 0;
virtual int GetSerial() = 0;
virtual char *GetStatusLine() = 0;
virtual char *GetType() = 0;
virtual char *GetName() = 0;
virtual int GetState() = 0;
virtual int GetVersion() = 0;
virtual void ShutDown() = 0;
virtual void NewGame(IWorld *world, IProxy *proxy = nullptr) = 0;
virtual char *GetModName() = 0;
virtual void WriteCommands(BitBuffer *stream, float startTime, float endTime) = 0;
virtual int AddCommand(DirectorCmd *cmd) = 0;
virtual bool RemoveCommand(int index) = 0;
virtual DirectorCmd *GetLastCommand() = 0;
virtual IObjectContainer *GetCommands() = 0;
virtual void SetWorldTime(double time, bool relative) = 0;
virtual void SetTimeScale(float scale) = 0;
virtual void SetPaused(bool state) = 0;
virtual void SetEditMode(bool state) = 0;
virtual void SetMasterMode(bool state) = 0;
virtual bool IsPaused() = 0;
virtual bool IsLoading() = 0;
virtual bool IsActive() = 0;
virtual bool IsEditMode() = 0;
virtual bool IsMasterMode() = 0;
virtual void RemoveFrames(double starttime, double endtime) = 0;
virtual void ExecuteDirectorCmd(DirectorCmd *cmd) = 0;
virtual double GetWorldTime() = 0;
virtual double GetStartTime() = 0;
virtual double GetEndTime() = 0;
virtual float GetTimeScale() = 0;
virtual IWorld *GetWorld() = 0;
virtual char *GetFileName() = 0;
virtual bool SaveGame(char *filename) = 0;
virtual bool LoadGame(char *filename) = 0;
virtual void Stop() = 0;
virtual void ForceHLTV(bool state) = 0;
virtual void GetDemoViewInfo(ref_params_t *rp, float *view, int *viewmodel) = 0;
virtual int ReadDemoMessage(unsigned char *buffer, int size) = 0;
virtual void ReadNetchanState(int *incoming_sequence, int *incoming_acknowledged, int *incoming_reliable_acknowledged, int *incoming_reliable_sequence, int *outgoing_sequence, int *reliable_sequence, int *last_reliable_sequence) = 0;
};
#define DEMOPLAYER_INTERFACE_VERSION "demoplayer001"

71
common/IEngineWrapper.h Normal file
View File

@ -0,0 +1,71 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
#include "event_args.h"
#include "cdll_int.h"
class IBaseSystem;
class IEngineWrapper {
public:
virtual ~IEngineWrapper() {}
virtual bool Init(IBaseSystem *system, int serial, char *name) = 0;
virtual void RunFrame(double time) = 0;
virtual void ReceiveSignal(ISystemModule *module, unsigned int signal, void *data) = 0;
virtual void ExecuteCommand(int commandID, char *commandLine) = 0;
virtual void RegisterListener(ISystemModule *module) = 0;
virtual void RemoveListener(ISystemModule *module) = 0;
virtual IBaseSystem *GetSystem() = 0;
virtual int GetSerial() = 0;
virtual char *GetStatusLine() = 0;
virtual char *GetType() = 0;
virtual char *GetName() = 0;
virtual int GetState() = 0;
virtual int GetVersion() = 0;
virtual void ShutDown() = 0;
virtual bool GetViewOrigin(float *origin) = 0;
virtual bool GetViewAngles(float *angles) = 0;
virtual int GetTraceEntity() = 0;
virtual float GetCvarFloat(char *szName) = 0;
virtual char *GetCvarString(char *szName) = 0;
virtual void SetCvar(char *szName, char *szValue) = 0;
virtual void Cbuf_AddText(char *text) = 0;
virtual void DemoUpdateClientData(client_data_t *cdat) = 0;
virtual void CL_QueueEvent(int flags, int index, float delay, event_args_t *pargs) = 0;
virtual void HudWeaponAnim(int iAnim, int body) = 0;
virtual void CL_DemoPlaySound(int channel, char* sample, float attenuation, float volume, int flags, int pitch) = 0;
virtual void ClientDLL_ReadDemoBuffer(int size, unsigned char *buffer) = 0;
};
#define ENGINEWRAPPER_INTERFACE_VERSION "enginewrapper001"

47
common/IObjectContainer.h Normal file
View File

@ -0,0 +1,47 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
class IObjectContainer {
public:
virtual ~IObjectContainer() {}
virtual void Init() = 0;
virtual bool Add(void *newObject) = 0;
virtual bool Remove(void *object) = 0;
virtual void Clear(bool freeElementsMemory) = 0;
virtual void *GetFirst() = 0;
virtual void *GetNext() = 0;
virtual int CountElements() = 0;
virtual bool Contains(void *object) = 0;
virtual bool IsEmpty() = 0;
};

57
common/ISystemModule.h Normal file
View File

@ -0,0 +1,57 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
#include "interface.h"
class IBaseSystem;
class ISystemModule;
class ISystemModule: public IBaseInterface {
public:
virtual ~ISystemModule() {}
virtual bool Init(IBaseSystem *system, int serial, char *name) = 0;
virtual void RunFrame(double time) = 0;
virtual void ReceiveSignal(ISystemModule *module, unsigned int signal, void *data = nullptr) = 0;
virtual void ExecuteCommand(int commandID, char *commandLine) = 0;
virtual void RegisterListener(ISystemModule *module) = 0;
virtual void RemoveListener(ISystemModule *module) = 0;
virtual IBaseSystem *GetSystem() = 0;
virtual int GetSerial() = 0;
virtual char *GetStatusLine() = 0;
virtual char *GetType() = 0;
virtual char *GetName() = 0;
virtual int GetState() = 0;
virtual int GetVersion() = 0;
virtual void ShutDown() = 0;
};

76
common/IVGuiModule.h Normal file
View File

@ -0,0 +1,76 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
#include <vgui/VGUI.h>
#include "interface.h"
// Purpose: Standard interface to loading vgui modules
class IVGuiModule: public IBaseInterface
{
public:
// called first to setup the module with the vgui
// returns true on success, false on failure
virtual bool Initialize(CreateInterfaceFn *vguiFactories, int factoryCount) = 0;
// called after all the modules have been initialized
// modules should use this time to link to all the other module interfaces
virtual bool PostInitialize(CreateInterfaceFn *modules = nullptr, int factoryCount = 0) = 0;
// called when the module is selected from the menu or otherwise activated
virtual bool Activate() = 0;
// returns true if the module is successfully initialized and available
virtual bool IsValid() = 0;
// requests that the UI is temporarily disabled and all data files saved
virtual void Deactivate() = 0;
// restart from a Deactivate()
virtual void Reactivate() = 0;
// called when the module is about to be shutdown
virtual void Shutdown() = 0;
// returns a handle to the main module panel
virtual vgui2::VPANEL GetPanel() = 0;
// sets the parent of the main module panel
virtual void SetParent(vgui2::VPANEL parent) = 0;
// messages sent through through the panel returned by GetPanel():
//
// "ConnectedToGame" "ip" "port" "gamedir"
// "DisconnectedFromGame"
// "ActiveGameName" "name"
// "LoadingStarted" "type" "name"
// "LoadingFinished" "type" "name"
};
#define VGUIMODULE_INTERFACE_VERSION "VGuiModuleAdminServer001"

515
common/ObjectDictionary.cpp Normal file
View File

@ -0,0 +1,515 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#include "precompiled.h"
ObjectDictionary::ObjectDictionary()
{
m_currentEntry = 0;
m_findKey = 0;
m_entries = nullptr;
memset(m_cache, 0, sizeof(m_cache));
m_cacheIndex = 0;
m_size = 0;
m_maxSize = 0;
}
ObjectDictionary::~ObjectDictionary()
{
if (m_entries) {
free(m_entries);
}
}
void ObjectDictionary::Clear(bool freeObjectssMemory)
{
if (freeObjectssMemory)
{
for (int i = 0; i < m_size; i++)
{
void *obj = m_entries[i].object;
if (obj) {
free(obj);
}
}
}
m_size = 0;
CheckSize();
ClearCache();
}
bool ObjectDictionary::Add(void *object, float key)
{
if (m_size == m_maxSize && !CheckSize())
return false;
entry_t *p;
if (m_size && key < m_entries[m_size - 1].key)
{
p = &m_entries[FindClosestAsIndex(key)];
entry_t *e1 = &m_entries[m_size];
entry_t *e2 = &m_entries[m_size - 1];
while (p->key <= key) { p++; }
while (p != e1)
{
e1->object = e2->object;
e1->key = e2->key;
e1--;
e2--;
}
}
else
p = &m_entries[m_size];
p->key = key;
p->object = object;
m_size++;
ClearCache();
AddToCache(p);
return true;
}
int ObjectDictionary::FindClosestAsIndex(float key)
{
if (m_size <= 0)
return -1;
if (key <= m_entries->key)
return 0;
int index = FindKeyInCache(key);
if (index >= 0) {
return index;
}
int middle;
int first = 0;
int last = m_size - 1;
float keyMiddle, keyNext;
if (key < m_entries[last].key)
{
while (true)
{
middle = (last + first) >> 1;
keyMiddle = m_entries[middle].key;
if (keyMiddle == key)
break;
if (keyMiddle < key)
{
if (m_entries[middle + 1].key >= key)
{
if (m_entries[middle + 1].key - key < key - keyMiddle)
++middle;
break;
}
first = (last + first) >> 1;
}
else
{
last = (last + first) >> 1;
}
}
}
else
{
middle = last;
}
keyNext = m_entries[middle - 1].key;
while (keyNext == key) {
keyNext = m_entries[middle--].key;
}
AddToCache(&m_entries[middle], key);
return middle;
}
void ObjectDictionary::ClearCache()
{
memset(m_cache, 0, sizeof(m_cache));
m_cacheIndex = 0;
}
bool ObjectDictionary::RemoveIndex(int index, bool freeObjectMemory)
{
if (index < 0 || index >= m_size)
return false;
entry_t *p = &m_entries[m_size - 1];
entry_t *e1 = &m_entries[index];
entry_t *e2 = &m_entries[index + 1];
if (freeObjectMemory && e1->object)
free(e1->object);
while (p != e1)
{
e1->object = e2->object;
e1->key = e2->key;
e1++;
e2++;
}
p->object = nullptr;
p->key = 0;
m_size--;
CheckSize();
ClearCache();
return false;
}
bool ObjectDictionary::RemoveIndexRange(int minIndex, int maxIndex)
{
if (minIndex > maxIndex)
{
if (maxIndex < 0)
maxIndex = 0;
if (minIndex >= m_size)
minIndex = m_size - 1;
}
else
{
if (minIndex < 0)
minIndex = 0;
if (maxIndex >= m_size)
maxIndex = m_size - 1;
}
int offset = minIndex + maxIndex - 1;
m_size -= offset;
CheckSize();
return true;
}
bool ObjectDictionary::Remove(void *object)
{
bool found = false;
for (int i = 0; i < m_size; i++)
{
if (m_entries[i].object == object) {
RemoveIndex(i);
found = true;
}
}
return found ? true : false;
}
bool ObjectDictionary::RemoveSingle(void *object)
{
for (int i = 0; i < m_size; i++)
{
if (m_entries[i].object == object) {
RemoveIndex(i);
return true;
}
}
return false;
}
bool ObjectDictionary::RemoveKey(float key)
{
int i = FindClosestAsIndex(key);
if (m_entries[i].key == key)
{
int j = i;
do {
++j;
}
while (key == m_entries[j + 1].key);
return RemoveIndexRange(i, j);
}
return false;
}
bool ObjectDictionary::CheckSize()
{
int newSize = m_maxSize;
if (m_size == m_maxSize)
{
newSize = 1 - (int)(m_maxSize * -1.25f);
}
else if (m_maxSize * 0.5f > m_size)
{
newSize = (int)(m_maxSize * 0.75f);
}
if (newSize != m_maxSize)
{
entry_t *newEntries = (entry_t *)malloc(sizeof(entry_t) * newSize);
if (!newEntries)
return false;
memset(&newEntries[m_size], 0, sizeof(entry_t) * (newSize - m_size));
if (m_entries && m_size)
{
memcpy(newEntries, m_entries, sizeof(entry_t) * m_size);
free(m_entries);
}
m_entries = newEntries;
m_maxSize = newSize;
}
return true;
}
void ObjectDictionary::Init()
{
m_size = 0;
m_maxSize = 0;
m_entries = nullptr;
CheckSize();
ClearCache();
}
void ObjectDictionary::Init(int baseSize)
{
m_size = 0;
m_maxSize = 0;
m_entries = (entry_t *)Mem_ZeroMalloc(sizeof(entry_t) * baseSize);
if (m_entries) {
m_maxSize = baseSize;
}
}
bool ObjectDictionary::Add(void *object)
{
return Add(object, 0);
}
int ObjectDictionary::CountElements()
{
return m_size;
}
bool ObjectDictionary::IsEmpty()
{
return (m_size == 0) ? true : false;
}
bool ObjectDictionary::Contains(void *object)
{
if (FindObjectInCache(object) >= 0)
return true;
for (int i = 0; i < m_size; i++)
{
entry_t *e = &m_entries[i];
if (e->object == object) {
AddToCache(e);
return true;
}
}
return false;
}
void *ObjectDictionary::GetFirst()
{
m_currentEntry = 0;
return GetNext();
}
void *ObjectDictionary::GetLast()
{
return (m_size > 0) ? m_entries[m_size - 1].object : nullptr;
}
bool ObjectDictionary::ChangeKey(void *object, float newKey)
{
int pos = FindObjectInCache(object);
if (pos < 0)
{
for (pos = 0; pos < m_size; pos++)
{
if (m_entries[pos].object == object) {
AddToCache(&m_entries[pos]);
break;
}
}
if (pos == m_size) {
return false;
}
}
entry_t *p, *e;
p = &m_entries[pos];
if (p->key == newKey)
return false;
int newpos = FindClosestAsIndex(newKey);
e = &m_entries[newpos];
if (pos < newpos)
{
if (e->key > newKey)
e--;
entry_t *e2 = &m_entries[pos + 1];
while (p < e)
{
p->object = e2->object;
p->key = e2->key;
p++;
e2++;
}
}
else if (pos > newpos)
{
if (e->key > newKey)
e++;
entry_t *e2 = &m_entries[pos - 1];
while (p > e)
{
p->object = e2->object;
p->key = e2->key;
p--;
e2--;
}
}
p->object = object;
p->key = newKey;
ClearCache();
return true;
}
bool ObjectDictionary::UnsafeChangeKey(void *object, float newKey)
{
int pos = FindObjectInCache(object);
if (pos < 0)
{
for (pos = 0; pos < m_size; pos++)
{
if (m_entries[pos].object == object) {
break;
}
}
if (pos == m_size) {
return false;
}
}
m_entries[pos].key = newKey;
ClearCache();
return true;
}
void ObjectDictionary::AddToCache(entry_t *entry)
{
int i = (m_cacheIndex % MAX_OBJECT_CACHE);
m_cache[i].object = entry;
m_cache[i].key = entry->key;
m_cacheIndex++;
}
void ObjectDictionary::AddToCache(entry_t *entry, float key)
{
int i = (m_cacheIndex % MAX_OBJECT_CACHE);
m_cache[i].object = entry;
m_cache[i].key = key;
m_cacheIndex++;
}
int ObjectDictionary::FindKeyInCache(float key)
{
for (auto& ch : m_cache)
{
if (ch.object && ch.key == key) {
return (entry_t *)ch.object - m_entries;
}
}
return -1;
}
int ObjectDictionary::FindObjectInCache(void *object)
{
for (auto& ch : m_cache)
{
if (ch.object && ch.object == object) {
return (entry_t *)ch.object - m_entries;
}
}
return -1;
}
void *ObjectDictionary::FindClosestKey(float key)
{
m_currentEntry = FindClosestAsIndex(key);
return GetNext();
}
void *ObjectDictionary::GetNext()
{
if (m_currentEntry < 0 || m_currentEntry >= m_size)
return nullptr;
return m_entries[m_currentEntry++].object;
}
void *ObjectDictionary::FindExactKey(float key)
{
if ((m_currentEntry = FindClosestAsIndex(key)) < 0)
return nullptr;
return (m_entries[m_currentEntry].key == key) ? GetNext() : nullptr;
}

94
common/ObjectDictionary.h Normal file
View File

@ -0,0 +1,94 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
#include "IObjectContainer.h"
class ObjectDictionary: public IObjectContainer {
public:
ObjectDictionary();
virtual ~ObjectDictionary();
void Init();
void Init(int baseSize);
bool Add(void *object);
bool Contains(void *object);
bool IsEmpty();
int CountElements();
void Clear(bool freeObjectssMemory = false);
bool Add(void *object, float key);
bool ChangeKey(void *object, float newKey);
bool UnsafeChangeKey(void *object, float newKey);
bool Remove(void *object);
bool RemoveSingle(void *object);
bool RemoveKey(float key);
bool RemoveRange(float startKey, float endKey);
void *FindClosestKey(float key);
void *FindExactKey(float key);
void *GetFirst();
void *GetLast();
void *GetNext();
int FindKeyInCache(float key);
int FindObjectInCache(void *object);
void ClearCache();
bool CheckSize();
typedef struct entry_s {
void *object;
float key;
} entry_t;
void AddToCache(entry_t *entry);
void AddToCache(entry_t *entry, float key);
bool RemoveIndex(int index, bool freeObjectMemory = false);
bool RemoveIndexRange(int minIndex, int maxIndex);
int FindClosestAsIndex(float key);
protected:
int m_currentEntry;
float m_findKey;
enum { MAX_OBJECT_CACHE = 32 };
entry_t *m_entries;
entry_t m_cache[MAX_OBJECT_CACHE];
int m_cacheIndex;
int m_size;
int m_maxSize;
};

259
common/ObjectList.cpp Normal file
View File

@ -0,0 +1,259 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#include "precompiled.h"
ObjectList::ObjectList()
{
m_head = m_tail = m_current = nullptr;
m_number = 0;
}
ObjectList::~ObjectList()
{
Clear(false);
}
bool ObjectList::AddHead(void *newObject)
{
// create new element
element_t *newElement = (element_t *)Mem_ZeroMalloc(sizeof(element_t));
// out of memory
if (!newElement)
return false;
// insert element
newElement->object = newObject;
if (m_head)
{
newElement->next = m_head;
m_head->prev = newElement;
}
m_head = newElement;
// if list was empty set new m_tail
if (!m_tail)
m_tail = m_head;
m_number++;
return true;
}
void *ObjectList::RemoveHead()
{
void *retObj;
// check m_head is present
if (m_head)
{
retObj = m_head->object;
element_t *newHead = m_head->next;
if (newHead)
newHead->prev = nullptr;
// if only one element is in list also update m_tail
// if we remove this prev element
if (m_tail == m_head)
m_tail = nullptr;
free(m_head);
m_head = newHead;
m_number--;
}
else
retObj = nullptr;
return retObj;
}
bool ObjectList::AddTail(void *newObject)
{
// create new element
element_t *newElement = (element_t *)Mem_ZeroMalloc(sizeof(element_t));
// out of memory
if (!newElement)
return false;
// insert element
newElement->object = newObject;
if (m_tail)
{
newElement->prev = m_tail;
m_tail->next = newElement;
}
m_tail = newElement;
// if list was empty set new m_tail
if (!m_head)
m_head = m_tail;
m_number++;
return true;
}
void *ObjectList::RemoveTail()
{
void *retObj;
// check m_tail is present
if (m_tail)
{
retObj = m_tail->object;
element_t *newTail = m_tail->prev;
if (newTail)
newTail->next = nullptr;
// if only one element is in list also update m_tail
// if we remove this prev element
if (m_head == m_tail)
m_head = nullptr;
free(m_tail);
m_tail = newTail;
m_number--;
}
else
retObj = nullptr;
return retObj;
}
bool ObjectList::IsEmpty()
{
return (m_head == nullptr);
}
int ObjectList::CountElements()
{
return m_number;
}
bool ObjectList::Contains(void *object)
{
element_t *e = m_head;
while (e && e->object != object) { e = e->next; }
if (e)
{
m_current = e;
return true;
}
else
{
return false;
}
}
void ObjectList::Clear(bool freeElementsMemory)
{
element_t *ne;
element_t *e = m_head;
while (e)
{
ne = e->next;
if (freeElementsMemory && e->object)
free(e->object);
free(e);
e = ne;
}
m_head = m_tail = m_current = nullptr;
m_number = 0;
}
bool ObjectList::Remove(void *object)
{
element_t *e = m_head;
while (e && e->object != object) { e = e->next; }
if (e)
{
if (e->prev) e->prev->next = e->next;
if (e->next) e->next->prev = e->prev;
if (m_head == e) m_head = e->next;
if (m_tail == e) m_tail = e->prev;
if (m_current == e) m_current= e->next;
free(e);
m_number--;
}
return (e != nullptr);
}
void ObjectList::Init()
{
m_head = m_tail = m_current = nullptr;
m_number = 0;
}
void *ObjectList::GetFirst()
{
if (m_head)
{
m_current = m_head->next;
return m_head->object;
}
else
{
m_current = nullptr;
return nullptr;
}
}
void *ObjectList::GetNext()
{
void *retObj = nullptr;
if (m_current)
{
retObj = m_current->object;
m_current = m_current->next;
}
return retObj;
}
bool ObjectList::Add(void *newObject)
{
return AddTail(newObject);
}

65
common/ObjectList.h Normal file
View File

@ -0,0 +1,65 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
#include "IObjectContainer.h"
class ObjectList: public IObjectContainer {
public:
void Init();
bool Add(void *newObject);
void *GetFirst();
void *GetNext();
ObjectList();
virtual ~ObjectList();
void Clear(bool freeElementsMemory = false);
int CountElements();
void *RemoveTail();
void *RemoveHead();
bool AddTail(void *newObject);
bool AddHead(void *newObject);
bool Remove(void *object);
bool Contains(void *object);
bool IsEmpty();
typedef struct element_s {
struct element_s *prev; // pointer to the last element or NULL
struct element_s *next; // pointer to the next elemnet or NULL
void *object; // the element's object
} element_t;
protected:
element_t *m_head; // first element in list
element_t *m_tail; // last element in list
element_t *m_current; // current element in list
int m_number;
};

211
common/SteamAppStartUp.cpp Normal file
View File

@ -0,0 +1,211 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#include "precompiled.h"
#ifdef _WIN32
#include "SteamAppStartup.h"
#define WIN32_LEAN_AND_MEAN
#include <assert.h>
#include <windows.h>
#include <process.h>
#include <direct.h>
#include <stdio.h>
#include <sys/stat.h>
#define STEAM_PARM "-steam"
bool FileExists(const char *fileName)
{
struct _stat statbuf;
return (_stat(fileName, &statbuf) == 0);
}
// Handles launching the game indirectly via steam
void LaunchSelfViaSteam(const char *params)
{
// calculate the details of our launch
char appPath[MAX_PATH];
::GetModuleFileName((HINSTANCE)GetModuleHandle(NULL), appPath, sizeof(appPath));
// strip out the exe name
char *slash = strrchr(appPath, '\\');
if (slash)
{
*slash = '\0';
}
// save out our details to the registry
HKEY hKey;
if (ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER, "Software\\Valve\\Steam", &hKey))
{
DWORD dwType = REG_SZ;
DWORD dwSize = static_cast<DWORD>( strlen(appPath) + 1 );
RegSetValueEx(hKey, "TempAppPath", NULL, dwType, (LPBYTE)appPath, dwSize);
dwSize = static_cast<DWORD>( strlen(params) + 1 );
RegSetValueEx(hKey, "TempAppCmdLine", NULL, dwType, (LPBYTE)params, dwSize);
// clear out the appID (since we don't know it yet)
dwType = REG_DWORD;
int appID = -1;
RegSetValueEx(hKey, "TempAppID", NULL, dwType, (LPBYTE)&appID, sizeof(appID));
RegCloseKey(hKey);
}
// search for an active steam instance
HWND hwnd = ::FindWindow("Valve_SteamIPC_Class", "Hidden Window");
if (hwnd)
{
::PostMessage(hwnd, WM_USER + 3, 0, 0);
}
else
{
// couldn't find steam, find and launch it
// first, search backwards through our current set of directories
char steamExe[MAX_PATH] = "";
char dir[MAX_PATH];
if (::GetCurrentDirectoryA(sizeof(dir), dir))
{
char *slash = strrchr(dir, '\\');
while (slash)
{
// see if steam_dev.exe is in the directory first
slash[1] = 0;
strcat(slash, "steam_dev.exe");
FILE *f = fopen(dir, "rb");
if (f)
{
// found it
fclose(f);
strcpy(steamExe, dir);
break;
}
// see if steam.exe is in the directory
slash[1] = 0;
strcat(slash, "steam.exe");
f = fopen(dir, "rb");
if (f)
{
// found it
fclose(f);
strcpy(steamExe, dir);
break;
}
// kill the string at the slash
slash[0] = 0;
// move to the previous slash
slash = strrchr(dir, '\\');
}
}
if (!steamExe[0])
{
// still not found, use the one in the registry
HKEY hKey;
if (ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER, "Software\\Valve\\Steam", &hKey))
{
DWORD dwType;
DWORD dwSize = sizeof(steamExe);
RegQueryValueEx(hKey, "SteamExe", NULL, &dwType, (LPBYTE)steamExe, &dwSize);
RegCloseKey(hKey);
}
}
if (!steamExe[0])
{
// still no path, error
::MessageBox(NULL, "Error running game: could not find steam.exe to launch", "Fatal Error", MB_OK | MB_ICONERROR);
return;
}
// fix any slashes
for (char *slash = steamExe; *slash; slash++)
{
if (*slash == '/')
{
*slash = '\\';
}
}
// change to the steam directory
strcpy(dir, steamExe);
char *delimiter = strrchr(dir, '\\');
if (delimiter)
{
*delimiter = 0;
_chdir(dir);
}
// exec steam.exe, in silent mode, with the launch app param
char *args[4] = { steamExe, "-silent", "-applaunch", '\0' };
_spawnv(_P_NOWAIT, steamExe, args);
}
}
// Launches steam if necessary
bool ShouldLaunchAppViaSteam(const char *lpCmdLine, const char *steamFilesystemDllName, const char *stdioFilesystemDllName)
{
// see if steam is on the command line
const char *steamStr = strstr(lpCmdLine, STEAM_PARM);
// check the character following it is a whitespace or null
if (steamStr)
{
const char *postChar = steamStr + strlen(STEAM_PARM);
if (*postChar == 0 || isspace(*postChar))
{
// we're running under steam already, let the app continue
return false;
}
}
// we're not running under steam, see which filesystems are available
if (FileExists(stdioFilesystemDllName))
{
// we're being run with a stdio filesystem, so we can continue without steam
return false;
}
// make sure we have a steam filesystem available
if (!FileExists(steamFilesystemDllName))
{
return false;
}
// we have the steam filesystem, and no stdio filesystem, so we must need to be run under steam
// launch steam
LaunchSelfViaSteam(lpCmdLine);
return true;
}
#endif // _WIN32

37
common/SteamAppStartUp.h Normal file
View File

@ -0,0 +1,37 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
// Call this first thing at startup
// Works out if the app is a steam app that is being ran outside of steam,
// and if so, launches steam and tells it to run us as a steam app
//
// if it returns true, then exit
// if it ruturns false, then continue with normal startup
bool ShouldLaunchAppViaSteam(const char *cmdLine, const char *steamFilesystemDllName, const char *stdioFilesystemDllName);

324
common/TextConsoleUnix.cpp Normal file
View File

@ -0,0 +1,324 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#include "precompiled.h"
#if !defined(_WIN32)
#include "TextConsoleUnix.h"
#include "icommandline.h"
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <signal.h>
CTextConsoleUnix console;
CTextConsoleUnix::~CTextConsoleUnix()
{
CTextConsoleUnix::ShutDown();
}
bool CTextConsoleUnix::Init(IBaseSystem *system)
{
static struct termios termNew;
sigset_t block_ttou;
sigemptyset(&block_ttou);
sigaddset(&block_ttou, SIGTTOU);
sigprocmask(SIG_BLOCK, &block_ttou, NULL);
tty = stdout;
// this code is for echo-ing key presses to the connected tty
// (which is != STDOUT)
if (isatty(STDIN_FILENO))
{
tty = fopen(ctermid(NULL), "w+");
if (!tty)
{
printf("Unable to open tty(%s) for output\n", ctermid(NULL));
tty = stdout;
}
else
{
// turn buffering off
setbuf(tty, NULL);
}
}
else
{
tty = fopen("/dev/null", "w+");
if (!tty)
{
tty = stdout;
}
}
tcgetattr(STDIN_FILENO, &termStored);
memcpy(&termNew, &termStored, sizeof(struct termios));
// Disable canonical mode, and set buffer size to 1 byte
termNew.c_lflag &= (~ICANON);
termNew.c_cc[ VMIN ] = 1;
termNew.c_cc[ VTIME ] = 0;
// disable echo
termNew.c_lflag &= (~ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &termNew);
sigprocmask(SIG_UNBLOCK, &block_ttou, NULL);
return CTextConsole::Init();
}
void CTextConsoleUnix::ShutDown()
{
sigset_t block_ttou;
sigemptyset(&block_ttou);
sigaddset(&block_ttou, SIGTTOU);
sigprocmask(SIG_BLOCK, &block_ttou, NULL);
tcsetattr(STDIN_FILENO, TCSANOW, &termStored);
sigprocmask(SIG_UNBLOCK, &block_ttou, NULL);
CTextConsole::ShutDown();
}
// return 0 if the kb isn't hit
int CTextConsoleUnix::kbhit()
{
fd_set rfds;
struct timeval tv;
// Watch stdin (fd 0) to see when it has input.
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
// Return immediately.
tv.tv_sec = 0;
tv.tv_usec = 0;
// Must be in raw or cbreak mode for this to work correctly.
return select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tv) != -1 && FD_ISSET(STDIN_FILENO, &rfds);
}
char *CTextConsoleUnix::GetLine()
{
// early return for 99.999% case :)
if (!kbhit())
return NULL;
escape_sequence_t es;
es = ESCAPE_CLEAR;
sigset_t block_ttou;
sigemptyset(&block_ttou);
sigaddset(&block_ttou, SIGTTOU);
sigaddset(&block_ttou, SIGTTIN);
sigprocmask(SIG_BLOCK, &block_ttou, NULL);
while (true)
{
if (!kbhit())
break;
int nLen;
char ch = 0;
int numRead = read(STDIN_FILENO, &ch, 1);
if (!numRead)
break;
switch (ch)
{
case '\n': // Enter
es = ESCAPE_CLEAR;
nLen = ReceiveNewline();
if (nLen)
{
sigprocmask(SIG_UNBLOCK, &block_ttou, NULL);
return m_szConsoleText;
}
break;
case 127: // Backspace
case '\b': // Backspace
es = ESCAPE_CLEAR;
ReceiveBackspace();
break;
case '\t': // TAB
es = ESCAPE_CLEAR;
ReceiveTab();
break;
case 27: // Escape character
es = ESCAPE_RECEIVED;
break;
case '[': // 2nd part of escape sequence
case 'O':
case 'o':
switch (es)
{
case ESCAPE_CLEAR:
case ESCAPE_BRACKET_RECEIVED:
es = ESCAPE_CLEAR;
ReceiveStandardChar(ch);
break;
case ESCAPE_RECEIVED:
es = ESCAPE_BRACKET_RECEIVED;
break;
}
break;
case 'A':
if (es == ESCAPE_BRACKET_RECEIVED)
{
es = ESCAPE_CLEAR;
ReceiveUpArrow();
}
else
{
es = ESCAPE_CLEAR;
ReceiveStandardChar(ch);
}
break;
case 'B':
if (es == ESCAPE_BRACKET_RECEIVED)
{
es = ESCAPE_CLEAR;
ReceiveDownArrow();
}
else
{
es = ESCAPE_CLEAR;
ReceiveStandardChar(ch);
}
break;
case 'C':
if (es == ESCAPE_BRACKET_RECEIVED)
{
es = ESCAPE_CLEAR;
ReceiveRightArrow();
}
else
{
es = ESCAPE_CLEAR;
ReceiveStandardChar(ch);
}
break;
case 'D':
if (es == ESCAPE_BRACKET_RECEIVED)
{
es = ESCAPE_CLEAR;
ReceiveLeftArrow();
}
else
{
es = ESCAPE_CLEAR;
ReceiveStandardChar(ch);
}
break;
default:
// Just eat this char if it's an unsupported escape
if (es != ESCAPE_BRACKET_RECEIVED)
{
// dont' accept nonprintable chars
if ((ch >= ' ') && (ch <= '~'))
{
es = ESCAPE_CLEAR;
ReceiveStandardChar(ch);
}
}
break;
}
fflush(stdout);
}
sigprocmask(SIG_UNBLOCK, &block_ttou, NULL);
return NULL;
}
void CTextConsoleUnix::PrintRaw(char *pszMsg, int nChars)
{
if (nChars == 0)
{
printf("%s", pszMsg);
}
else
{
for (int nCount = 0; nCount < nChars; nCount++)
{
putchar(pszMsg[ nCount ]);
}
}
}
void CTextConsoleUnix::Echo(char *pszMsg, int nChars)
{
if (nChars == 0)
{
fputs(pszMsg, tty);
}
else
{
for (int nCount = 0; nCount < nChars; nCount++)
{
fputc(pszMsg[ nCount ], tty);
}
}
}
int CTextConsoleUnix::GetWidth()
{
struct winsize ws;
int nWidth = 0;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0)
{
nWidth = (int)ws.ws_col;
}
if (nWidth <= 1)
{
nWidth = 80;
}
return nWidth;
}
#endif // !defined(_WIN32)

59
common/TextConsoleUnix.h Normal file
View File

@ -0,0 +1,59 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
#include <termios.h>
#include "textconsole.h"
enum escape_sequence_t
{
ESCAPE_CLEAR,
ESCAPE_RECEIVED,
ESCAPE_BRACKET_RECEIVED
};
class CTextConsoleUnix: public CTextConsole {
public:
virtual ~CTextConsoleUnix();
bool Init(IBaseSystem *system = nullptr);
void ShutDown();
void PrintRaw(char *pszMsg, int nChars = 0);
void Echo(char *pszMsg, int nChars = 0);
char *GetLine();
int GetWidth();
private:
int kbhit();
struct termios termStored;
FILE *tty;
};
extern CTextConsoleUnix console;

280
common/TextConsoleWin32.cpp Normal file
View File

@ -0,0 +1,280 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#include "precompiled.h"
#if defined(_WIN32)
CTextConsoleWin32 console;
#pragma comment(lib, "user32.lib")
BOOL WINAPI ConsoleHandlerRoutine(DWORD CtrlType)
{
// TODO ?
/*if (CtrlType != CTRL_C_EVENT && CtrlType != CTRL_BREAK_EVENT)
{
// don't quit on break or ctrl+c
m_System->Stop();
}*/
return TRUE;
}
// GetConsoleHwnd() helper function from MSDN Knowledge Base Article Q124103
// needed, because HWND GetConsoleWindow(VOID) is not avaliable under Win95/98/ME
HWND GetConsoleHwnd()
{
HWND hwndFound; // This is what is returned to the caller.
char pszNewWindowTitle[1024]; // Contains fabricated WindowTitle
char pszOldWindowTitle[1024]; // Contains original WindowTitle
// Fetch current window title.
GetConsoleTitle(pszOldWindowTitle, sizeof(pszOldWindowTitle));
// Format a "unique" NewWindowTitle.
wsprintf(pszNewWindowTitle, "%d/%d", GetTickCount(), GetCurrentProcessId());
// Change current window title.
SetConsoleTitle(pszNewWindowTitle);
// Ensure window title has been updated.
Sleep(40);
// Look for NewWindowTitle.
hwndFound = FindWindow(nullptr, pszNewWindowTitle);
// Restore original window title.
SetConsoleTitle(pszOldWindowTitle);
return hwndFound;
}
CTextConsoleWin32::~CTextConsoleWin32()
{
CTextConsoleWin32::ShutDown();
}
bool CTextConsoleWin32::Init(IBaseSystem *system)
{
if (!AllocConsole())
m_System = system;
SetTitle(m_System ? m_System->GetName() : "Console");
hinput = GetStdHandle(STD_INPUT_HANDLE);
houtput = GetStdHandle(STD_OUTPUT_HANDLE);
if (!SetConsoleCtrlHandler(&ConsoleHandlerRoutine, TRUE))
{
Print("WARNING! TextConsole::Init: Could not attach console hook.\n");
}
Attrib = FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
SetWindowPos(GetConsoleHwnd(), HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOREPOSITION | SWP_SHOWWINDOW);
return CTextConsole::Init(system);
}
void CTextConsoleWin32::ShutDown()
{
FreeConsole();
CTextConsole::ShutDown();
}
void CTextConsoleWin32::SetVisible(bool visible)
{
ShowWindow(GetConsoleHwnd(), visible ? SW_SHOW : SW_HIDE);
m_ConsoleVisible = visible;
}
char *CTextConsoleWin32::GetLine()
{
while (true)
{
INPUT_RECORD recs[1024];
unsigned long numread;
unsigned long numevents;
if (!GetNumberOfConsoleInputEvents(hinput, &numevents))
{
if (m_System)
m_System->Errorf("CTextConsoleWin32::GetLine: !GetNumberOfConsoleInputEvents");
return nullptr;
}
if (numevents <= 0)
break;
if (!ReadConsoleInput(hinput, recs, ARRAYSIZE(recs), &numread))
{
if (m_System)
m_System->Errorf("CTextConsoleWin32::GetLine: !ReadConsoleInput");
return nullptr;
}
if (numread == 0)
return nullptr;
for (int i = 0; i < (int)numread; i++)
{
INPUT_RECORD *pRec = &recs[i];
if (pRec->EventType != KEY_EVENT)
continue;
if (pRec->Event.KeyEvent.bKeyDown)
{
// check for cursor keys
if (pRec->Event.KeyEvent.wVirtualKeyCode == VK_UP)
{
ReceiveUpArrow();
}
else if (pRec->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)
{
ReceiveDownArrow();
}
else if (pRec->Event.KeyEvent.wVirtualKeyCode == VK_LEFT)
{
ReceiveLeftArrow();
}
else if (pRec->Event.KeyEvent.wVirtualKeyCode == VK_RIGHT)
{
ReceiveRightArrow();
}
else
{
int nLen;
char ch = pRec->Event.KeyEvent.uChar.AsciiChar;
switch (ch)
{
case '\r': // Enter
nLen = ReceiveNewline();
if (nLen)
{
return m_szConsoleText;
}
break;
case '\b': // Backspace
ReceiveBackspace();
break;
case '\t': // TAB
ReceiveTab();
break;
default:
// dont' accept nonprintable chars
if ((ch >= ' ') && (ch <= '~'))
{
ReceiveStandardChar(ch);
}
break;
}
}
}
}
}
return nullptr;
}
void CTextConsoleWin32::PrintRaw(char *pszMsg, int nChars)
{
#ifdef LAUNCHER_FIXES
char outputStr[2048];
WCHAR unicodeStr[1024];
DWORD nSize = MultiByteToWideChar(CP_UTF8, 0, pszMsg, -1, NULL, 0);
if (nSize > sizeof(unicodeStr))
return;
MultiByteToWideChar(CP_UTF8, 0, pszMsg, -1, unicodeStr, nSize);
DWORD nLength = WideCharToMultiByte(CP_OEMCP, 0, unicodeStr, -1, 0, 0, NULL, NULL);
if (nLength > sizeof(outputStr))
return;
WideCharToMultiByte(CP_OEMCP, 0, unicodeStr, -1, outputStr, nLength, NULL, NULL);
WriteFile(houtput, outputStr, nChars ? nChars : strlen(outputStr), NULL, NULL);
#else
WriteFile(houtput, pszMsg, nChars ? nChars : strlen(pszMsg), NULL, NULL);
#endif
}
void CTextConsoleWin32::Echo(char *pszMsg, int nChars)
{
PrintRaw(pszMsg, nChars);
}
int CTextConsoleWin32::GetWidth()
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
int nWidth = 0;
if (GetConsoleScreenBufferInfo(houtput, &csbi)) {
nWidth = csbi.dwSize.X;
}
if (nWidth <= 1)
nWidth = 80;
return nWidth;
}
void CTextConsoleWin32::SetStatusLine(char *pszStatus)
{
strncpy(statusline, pszStatus, sizeof(statusline) - 1);
statusline[sizeof(statusline) - 2] = '\0';
UpdateStatus();
}
void CTextConsoleWin32::UpdateStatus()
{
COORD coord;
DWORD dwWritten = 0;
WORD wAttrib[ 80 ];
for (int i = 0; i < 80; i++)
{
wAttrib[i] = Attrib; // FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
}
coord.X = coord.Y = 0;
WriteConsoleOutputAttribute(houtput, wAttrib, 80, coord, &dwWritten);
WriteConsoleOutputCharacter(houtput, statusline, 80, coord, &dwWritten);
}
void CTextConsoleWin32::SetTitle(char *pszTitle)
{
SetConsoleTitle(pszTitle);
}
void CTextConsoleWin32::SetColor(WORD attrib)
{
Attrib = attrib;
}
#endif // defined(_WIN32)

61
common/TextConsoleWin32.h Normal file
View File

@ -0,0 +1,61 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
#include <windows.h>
#include "TextConsole.h"
class CTextConsoleWin32: public CTextConsole {
public:
virtual ~CTextConsoleWin32();
bool Init(IBaseSystem *system = nullptr);
void ShutDown();
void SetTitle(char *pszTitle);
void SetStatusLine(char *pszStatus);
void UpdateStatus();
void PrintRaw(char * pszMsz, int nChars = 0);
void Echo(char * pszMsz, int nChars = 0);
char *GetLine();
int GetWidth();
void SetVisible(bool visible);
void SetColor(WORD);
private:
HANDLE hinput; // standard input handle
HANDLE houtput; // standard output handle
WORD Attrib; // attrib colours for status bar
char statusline[81]; // first line in console is status line
};
extern CTextConsoleWin32 console;

132
common/TokenLine.cpp Normal file
View File

@ -0,0 +1,132 @@
#include "precompiled.h"
TokenLine::TokenLine()
{
memset(m_token, 0, sizeof(m_token));
memset(m_fullLine, 0, sizeof(m_fullLine));
memset(m_tokenBuffer, 0, sizeof(m_tokenBuffer));
m_tokenNumber = 0;
}
TokenLine::TokenLine(char *string)
{
SetLine(string);
}
TokenLine::~TokenLine()
{
}
bool TokenLine::SetLine(const char *newLine)
{
m_tokenNumber = 0;
if (!newLine || (strlen(newLine) >= (MAX_LINE_CHARS - 1)))
{
memset(m_fullLine, 0, sizeof(m_fullLine));
memset(m_tokenBuffer, 0, sizeof(m_tokenBuffer));
return false;
}
strcopy(m_fullLine, newLine);
strcopy(m_tokenBuffer, newLine);
// parse tokens
char *charPointer = m_tokenBuffer;
while (*charPointer && (m_tokenNumber < MAX_LINE_TOKENS))
{
// skip nonprintable chars
while (*charPointer && ((*charPointer <= ' ') || (*charPointer > '~')))
charPointer++;
if (*charPointer)
{
m_token[m_tokenNumber] = charPointer;
// special treatment for quotes
if (*charPointer == '\"')
{
charPointer++;
m_token[m_tokenNumber] = charPointer;
while (*charPointer && (*charPointer != '\"'))
charPointer++;
}
else
{
m_token[m_tokenNumber] = charPointer;
while (*charPointer && ((*charPointer > 32) && (*charPointer <= 126)))
charPointer++;
}
m_tokenNumber++;
if (*charPointer)
{
*charPointer = '\0';
charPointer++;
}
}
}
return (m_tokenNumber != MAX_LINE_TOKENS);
}
char *TokenLine::GetLine()
{
return m_fullLine;
}
char *TokenLine::GetToken(int i)
{
if (i >= m_tokenNumber)
return NULL;
return m_token[i];
}
// if the given parm is not present return NULL
// otherwise return the address of the following token, or an empty string
char *TokenLine::CheckToken(char *parm)
{
for (int i = 0; i < m_tokenNumber; i++)
{
if (!m_token[i])
continue;
if (!strcmp(parm, m_token[i]))
{
char *ret = m_token[i + 1];
// if this token doesn't exist, since index i was the last
// return an empty string
if (m_tokenNumber == (i + 1))
ret = "";
return ret;
}
}
return NULL;
}
int TokenLine::CountToken()
{
int c = 0;
for (int i = 0; i < m_tokenNumber; i++)
{
if (m_token[i])
c++;
}
return c;
}
char *TokenLine::GetRestOfLine(int i)
{
if (i >= m_tokenNumber)
return NULL;
return m_fullLine + (m_token[i] - m_tokenBuffer);
}

51
common/TokenLine.h Normal file
View File

@ -0,0 +1,51 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
class TokenLine {
public:
TokenLine();
TokenLine(char *string);
virtual ~TokenLine();
char *GetRestOfLine(int i); // returns all chars after token i
int CountToken(); // returns number of token
char *CheckToken(char *parm); // returns token after token parm or ""
char *GetToken(int i); // returns token i
char *GetLine(); // returns full line
bool SetLine(const char *newLine); // set new token line and parses it
private:
enum { MAX_LINE_CHARS = 2048, MAX_LINE_TOKENS = 128 };
char m_tokenBuffer[MAX_LINE_CHARS];
char m_fullLine[MAX_LINE_CHARS];
char *m_token[MAX_LINE_TOKENS];
int m_tokenNumber;
};

354
common/commandline.cpp Normal file
View File

@ -0,0 +1,354 @@
#include "precompiled.h"
class CCommandLine: public ICommandLine {
public:
CCommandLine();
virtual ~CCommandLine();
void CreateCmdLine(const char *commandline);
void CreateCmdLine(int argc, const char *argv[]);
const char *GetCmdLine() const;
// Check whether a particular parameter exists
const char *CheckParm(const char *psz, char **ppszValue = nullptr) const;
void RemoveParm(const char *pszParm);
void AppendParm(const char *pszParm, const char *pszValues);
void SetParm(const char *pszParm, const char *pszValues);
void SetParm(const char *pszParm, int iValue);
// When the commandline contains @name, it reads the parameters from that file
void LoadParametersFromFile(const char *&pSrc, char *&pDst, int maxDestLen);
private:
// Copy of actual command line
char *m_pszCmdLine;
};
CCommandLine g_CmdLine;
ICommandLine *cmdline = &g_CmdLine;
ICommandLine *CommandLine()
{
return &g_CmdLine;
}
CCommandLine::CCommandLine()
{
m_pszCmdLine = nullptr;
}
CCommandLine::~CCommandLine()
{
if (m_pszCmdLine)
{
delete [] m_pszCmdLine;
m_pszCmdLine = nullptr;
}
}
char *CopyString(const char *src)
{
if (!src)
return nullptr;
char *out = (char *)new char[strlen(src) + 1];
strcpy(out, src);
return out;
}
// Creates a command line from the arguments passed in
void CCommandLine::CreateCmdLine(int argc, const char *argv[])
{
char cmdline[4096] = "";
const int MAX_CHARS = sizeof(cmdline) - 1;
for (int i = 0; i < argc; ++i)
{
if (strchr(argv[i], ' '))
{
strncat(cmdline, "\"", MAX_CHARS);
strncat(cmdline, argv[i], MAX_CHARS);
strncat(cmdline, "\"", MAX_CHARS);
}
else
{
strncat(cmdline, argv[i], MAX_CHARS);
}
strncat(cmdline, " ", MAX_CHARS);
}
cmdline[strlen(cmdline)] = '\0';
CreateCmdLine(cmdline);
}
void CCommandLine::LoadParametersFromFile(const char *&pSrc, char *&pDst, int maxDestLen)
{
// Suck out the file name
char szFileName[ MAX_PATH ];
char *pOut;
char *pDestStart = pDst;
// Skip the @ sign
pSrc++;
pOut = szFileName;
while (*pSrc && *pSrc != ' ')
{
*pOut++ = *pSrc++;
#if 0
if ((pOut - szFileName) >= (MAX_PATH - 1))
break;
#endif
}
*pOut = '\0';
// Skip the space after the file name
if (*pSrc)
pSrc++;
// Now read in parameters from file
FILE *fp = fopen(szFileName, "r");
if (fp)
{
char c;
c = (char)fgetc(fp);
while (c != EOF)
{
// Turn return characters into spaces
if (c == '\n')
c = ' ';
*pDst++ = c;
#if 0
// Don't go past the end, and allow for our terminating space character AND a terminating null character.
if ((pDst - pDestStart) >= (maxDestLen - 2))
break;
#endif
// Get the next character, if there are more
c = (char)fgetc(fp);
}
// Add a terminating space character
*pDst++ = ' ';
fclose(fp);
}
else
{
printf("Parameter file '%s' not found, skipping...", szFileName);
}
}
// Purpose: Create a command line from the passed in string
// Note that if you pass in a @filename, then the routine will read settings from a file instead of the command line
void CCommandLine::CreateCmdLine(const char *commandline)
{
if (m_pszCmdLine)
{
delete[] m_pszCmdLine;
m_pszCmdLine = nullptr;
}
char szFull[4096];
char *pDst = szFull;
const char *pSrc = commandline;
bool allowAtSign = true;
while (*pSrc)
{
if (*pSrc == '@')
{
if (allowAtSign)
{
LoadParametersFromFile(pSrc, pDst, sizeof(szFull) - (pDst - szFull));
continue;
}
}
allowAtSign = isspace(*pSrc) != 0;
#if 0
// Don't go past the end.
if ((pDst - szFull) >= (sizeof(szFull) - 1))
break;
#endif
*pDst++ = *pSrc++;
}
*pDst = '\0';
int len = strlen(szFull) + 1;
m_pszCmdLine = new char[len];
memcpy(m_pszCmdLine, szFull, len);
}
// Purpose: Remove specified string ( and any args attached to it ) from command line
void CCommandLine::RemoveParm(const char *pszParm)
{
if (!m_pszCmdLine)
return;
if (!pszParm || *pszParm == '\0')
return;
// Search for first occurrence of pszParm
char *p, *found;
char *pnextparam;
int n;
int curlen;
p = m_pszCmdLine;
while (*p)
{
curlen = strlen(p);
found = strstr(p, pszParm);
if (!found)
break;
pnextparam = found + 1;
while (pnextparam && *pnextparam && (*pnextparam != '-') && (*pnextparam != '+'))
pnextparam++;
if (pnextparam && *pnextparam)
{
// We are either at the end of the string, or at the next param. Just chop out the current param.
// # of characters after this param.
n = curlen - (pnextparam - p);
memcpy(found, pnextparam, n);
found[n] = '\0';
}
else
{
// Clear out rest of string.
n = pnextparam - found;
memset(found, 0, n);
}
}
// Strip and trailing ' ' characters left over.
while (1)
{
int curpos = strlen(m_pszCmdLine);
if (curpos == 0 || m_pszCmdLine[ curpos - 1 ] != ' ')
break;
m_pszCmdLine[curpos - 1] = '\0';
}
}
// Purpose: Append parameter and argument values to command line
void CCommandLine::AppendParm(const char *pszParm, const char *pszValues)
{
int nNewLength = 0;
char *pCmdString;
// Parameter.
nNewLength = strlen(pszParm);
// Values + leading space character.
if (pszValues)
nNewLength += strlen(pszValues) + 1;
// Terminal 0;
nNewLength++;
if (!m_pszCmdLine)
{
m_pszCmdLine = new char[ nNewLength ];
strcpy(m_pszCmdLine, pszParm);
if (pszValues)
{
strcat(m_pszCmdLine, " ");
strcat(m_pszCmdLine, pszValues);
}
return;
}
// Remove any remnants from the current Cmd Line.
RemoveParm(pszParm);
nNewLength += strlen(m_pszCmdLine) + 1 + 1;
pCmdString = new char[ nNewLength ];
memset(pCmdString, 0, nNewLength);
strcpy(pCmdString, m_pszCmdLine); // Copy old command line.
strcat(pCmdString, " "); // Put in a space
strcat(pCmdString, pszParm);
if (pszValues)
{
strcat(pCmdString, " ");
strcat(pCmdString, pszValues);
}
// Kill off the old one
delete[] m_pszCmdLine;
// Point at the new command line.
m_pszCmdLine = pCmdString;
}
void CCommandLine::SetParm(const char *pszParm, const char *pszValues)
{
RemoveParm(pszParm);
AppendParm(pszParm, pszValues);
}
void CCommandLine::SetParm(const char *pszParm, int iValue)
{
char buf[64];
_snprintf(buf, sizeof(buf), "%d", iValue);
SetParm(pszParm, buf);
}
// Purpose: Search for the parameter in the current commandline
const char *CCommandLine::CheckParm(const char *psz, char **ppszValue) const
{
static char sz[128] = "";
if (!m_pszCmdLine)
return nullptr;
char *pret = strstr(m_pszCmdLine, psz);
if (!pret || !ppszValue)
return pret;
*ppszValue = nullptr;
// find the next whitespace
char *p1 = pret;
do {
++p1;
} while (*p1 != ' ' && *p1);
int i = 0;
char *p2 = p1 + 1;
do {
if (p2[i] == '\0' || p2[i] == ' ')
break;
sz[i++] = p2[i];
} while (i < sizeof(sz));
sz[i] = '\0';
*ppszValue = sz;
return pret;
}
const char *CCommandLine::GetCmdLine() const
{
return m_pszCmdLine;
}

View File

@ -17,17 +17,8 @@
#include "quakedef.h"
// MD5 Hash
typedef struct
{
unsigned int buf[4];
unsigned int bits[2];
unsigned char in[64];
} MD5Context_t;
typedef unsigned int CRC32_t;
#ifdef __cplusplus
extern "C"
{
@ -45,11 +36,3 @@ BOOL CRC_File(CRC32_t *crcvalue, char *pszFileName);
byte COM_BlockSequenceCRCByte(byte *base, int length, int sequence);
int CRC_MapFile(CRC32_t *crcvalue, char *pszFileName);
void MD5Init(MD5Context_t *ctx);
void MD5Update(MD5Context_t *ctx, const unsigned char *buf, unsigned int len);
void MD5Final(unsigned char digest[16], MD5Context_t *ctx);
void MD5Transform(unsigned int buf[4], const unsigned int in[16]);
BOOL MD5_Hash_File(unsigned char digest[16], char *pszFileName, BOOL bUsefopen, BOOL bSeed, unsigned int seed[4]);
char *MD5_Print(unsigned char hash[16]);

View File

@ -23,8 +23,9 @@
// For entityType below
#define ENTITY_NORMAL (1<<0)
#define ENTITY_BEAM (1<<1)
#define ENTITY_NORMAL (1<<0)
#define ENTITY_BEAM (1<<1)
#define ENTITY_UNINITIALIZED (1<<30)
// Entity state is used for the baseline and for delta compression of a packet of
// entities that is sent to a client.

View File

@ -16,12 +16,13 @@
#ifndef ENUMS_H
#define ENUMS_H
// Used as array indexer
typedef enum netsrc_s
{
NS_CLIENT,
NS_CLIENT = 0,
NS_SERVER,
NS_MULTICAST // xxxMO
NS_MULTICAST, // xxxMO
NS_MAX
} netsrc_t;
#endif

View File

@ -1,6 +1,6 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
// Purpose:
//
// $NoKeywords: $
//=============================================================================
@ -13,12 +13,13 @@
#define TYPE_CLIENT 0 // client is a normal HL client (default)
#define TYPE_PROXY 1 // client is another proxy
#define TYPE_DIRECTOR 2
#define TYPE_COMMENTATOR 3 // client is a commentator
#define TYPE_DEMO 4 // client is a demo file
// sub commands of svc_hltv:
#define HLTV_ACTIVE 0 // tells client that he's an spectator and will get director commands
#define HLTV_STATUS 1 // send status infos about proxy
#define HLTV_STATUS 1 // send status infos about proxy
#define HLTV_LISTEN 2 // tell client to listen to a multicast stream
// director command types:
@ -41,10 +42,9 @@
#define DRC_CMD_LAST 15
// DRC_CMD_EVENT event flags
#define DRC_FLAG_PRIO_MASK 0x0F // priorities between 0 and 15 (15 most important)
#define DRC_FLAG_SIDE (1<<4) //
#define DRC_FLAG_SIDE (1<<4) //
#define DRC_FLAG_DRAMATIC (1<<5) // is a dramatic scene
#define DRC_FLAG_SLOWMOTION (1<<6) // would look good in SloMo
#define DRC_FLAG_FACEPLAYER (1<<7) // player is doning something (reload/defuse bomb etc)
@ -52,7 +52,6 @@
#define DRC_FLAG_FINAL (1<<9) // is a final scene
#define DRC_FLAG_NO_RANDOM (1<<10) // don't randomize event data
// DRC_CMD_WAYPOINT flags
#define DRC_FLAG_STARTPATH 1 // end with speed 0.0
#define DRC_FLAG_SLOWSTART 2 // start with speed 0.0

25
common/icommandline.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef ICOMMANDLINE_H
#define ICOMMANDLINE_H
#ifdef _WIN32
#pragma once
#endif
// Interface to engine command line
class ICommandLine {
public:
virtual void CreateCmdLine(const char *commandline) = 0;
virtual void CreateCmdLine(int argc, const char **argv) = 0;
virtual const char *GetCmdLine() const = 0;
// Check whether a particular parameter exists
virtual const char *CheckParm(const char *psz, char **ppszValue = nullptr) const = 0;
virtual void RemoveParm(const char *pszParm) = 0;
virtual void AppendParm(const char *pszParm, const char *pszValues) = 0;
virtual void SetParm(const char *pszParm, const char *pszValues) = 0;
virtual void SetParm(const char *pszParm, int iValue) = 0;
};
ICommandLine *CommandLine();
#endif // ICOMMANDLINE_H

View File

@ -32,13 +32,10 @@
#pragma once
#endif
/* <31b2a> ../common/kbutton.h:7 */
typedef struct kbutton_s
{
int down[2];
int state;
} kbutton_t;
#endif // KBUTTON_H

View File

@ -1,37 +1,47 @@
/***
/*
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
* 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 2 of the License, or (at
* your option) any later version.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
* 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#ifndef MATHLIB_H
#define MATHLIB_H
#ifdef _WIN32
#pragma once
#endif
/* <42b7f> ../common/mathlib.h:3 */
typedef float vec_t;
/* <42b91> ../common/mathlib.h:6 */
#if !defined DID_VEC3_T_DEFINE && !defined vec3_t
#define DID_VEC3_T_DEFINE
typedef vec_t vec3_t[3];
#endif
/* <80013> ../common/mathlib.h:8 */
typedef vec_t vec4_t[4];
typedef int fixed16_t;
/* <42bac> ../common/mathlib.h:18 */
typedef int fixed16_t; /* size: 4 */
/* <42bb7> ../common/mathlib.h:60 */
typedef union DLONG_u
{
int i[2];
@ -55,32 +65,31 @@ typedef union DLONG_u
#endif
template <typename T>
inline T min(T a, T b) {
inline T min(T a, T b)
{
return (a < b) ? a : b;
}
template <typename T>
inline T max(T a, T b) {
inline T max(T a, T b)
{
return (a < b) ? b : a;
}
template <typename T>
inline T clamp(T a, T min, T max) {
inline T clamp(T a, T min, T max)
{
return (a > max) ? max : (a < min) ? min : a;
}
template <typename T>
inline T bswap(T s) {
switch (sizeof(T)) {
#ifdef _WIN32
case 2: {auto res = _byteswap_ushort(*(uint16 *)&s); return *(T *)&res;}
case 4: {auto res = _byteswap_ulong(*(uint32 *)(&s)); return *(T *)&res;}
case 8: {auto res = _byteswap_uint64(*(uint64 *)&s); return *(T *)&res;}
#else
case 2: {auto res = _bswap16(*(uint16 *)&s); return *(T *)&res;}
case 4: {auto res = _bswap(*(uint32 *)&s); return *(T *)&res;}
case 8: {auto res = _bswap64(*(uint64 *)&s); return *(T *)&res;}
#endif
inline T bswap(T s)
{
switch (sizeof(T))
{
case 2: {auto res = __builtin_bswap16(*(uint16 *)&s); return *(T *)&res; }
case 4: {auto res = __builtin_bswap32(*(uint32 *)&s); return *(T *)&res; }
case 8: {auto res = __builtin_bswap64(*(uint64 *)&s); return *(T *)&res; }
default: return s;
}
}

34
common/md5.h Normal file
View File

@ -0,0 +1,34 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#pragma once
#include <quakedef.h>
// MD5 Hash
typedef struct
{
unsigned int buf[4];
unsigned int bits[2];
unsigned char in[64];
} MD5Context_t;
void MD5Init(MD5Context_t *ctx);
void MD5Update(MD5Context_t *ctx, const unsigned char *buf, unsigned int len);
void MD5Final(unsigned char digest[16], MD5Context_t *ctx);
void MD5Transform(unsigned int buf[4], const unsigned int in[16]);
BOOL MD5_Hash_File(unsigned char digest[16], char *pszFileName, BOOL bUsefopen, BOOL bSeed, unsigned int seed[4]);
char *MD5_Print(unsigned char hash[16]);

View File

@ -12,7 +12,7 @@
* without written permission from Valve LLC.
*
****/
// netadr.h
#ifndef NETADR_H
#define NETADR_H
#ifdef _WIN32
@ -31,10 +31,10 @@ typedef enum
typedef struct netadr_s
{
netadrtype_t type;
unsigned char ip[4];
unsigned char ipx[10];
unsigned short port;
netadrtype_t type;
unsigned char ip[4];
unsigned char ipx[10];
unsigned short port;
} netadr_t;
#endif // NETADR_H

208
common/netapi.cpp Normal file
View File

@ -0,0 +1,208 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include "winsock.h"
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#endif // _WIN32
#include "netapi.h"
class CNetAPI: public INetAPI {
public:
virtual void NetAdrToSockAddr(netadr_t *a, struct sockaddr *s);
virtual void SockAddrToNetAdr(struct sockaddr *s, netadr_t *a);
virtual char *AdrToString(netadr_t *a);
virtual bool StringToAdr(const char *s, netadr_t *a);
virtual void GetSocketAddress(int socket, netadr_t *a);
virtual bool CompareAdr(netadr_t *a, netadr_t *b);
virtual void GetLocalIP(netadr_t *a);
};
// Expose interface
CNetAPI g_NetAPI;
INetAPI *net = (INetAPI *)&g_NetAPI;
void CNetAPI::NetAdrToSockAddr(netadr_t *a, struct sockaddr *s)
{
memset(s, 0, sizeof(*s));
if (a->type == NA_BROADCAST)
{
((struct sockaddr_in *)s)->sin_family = AF_INET;
((struct sockaddr_in *)s)->sin_port = a->port;
((struct sockaddr_in *)s)->sin_addr.s_addr = INADDR_BROADCAST;
}
else if (a->type == NA_IP)
{
((struct sockaddr_in *)s)->sin_family = AF_INET;
((struct sockaddr_in *)s)->sin_addr.s_addr = *(int *)&a->ip;
((struct sockaddr_in *)s)->sin_port = a->port;
}
}
void CNetAPI::SockAddrToNetAdr(struct sockaddr *s, netadr_t *a)
{
if (s->sa_family == AF_INET)
{
a->type = NA_IP;
*(int *)&a->ip = ((struct sockaddr_in *)s)->sin_addr.s_addr;
a->port = ((struct sockaddr_in *)s)->sin_port;
}
}
char *CNetAPI::AdrToString(netadr_t *a)
{
static char s[64];
memset(s, 0, sizeof(s));
if (a)
{
if (a->type == NA_LOOPBACK)
{
sprintf(s, "loopback");
}
else if (a->type == NA_IP)
{
sprintf(s, "%i.%i.%i.%i:%i", a->ip[0], a->ip[1], a->ip[2], a->ip[3], ntohs(a->port));
}
}
return s;
}
bool StringToSockaddr(const char *s, struct sockaddr *sadr)
{
struct hostent *h;
char *colon;
char copy[128];
struct sockaddr_in *p;
memset(sadr, 0, sizeof(*sadr));
p = (struct sockaddr_in *)sadr;
p->sin_family = AF_INET;
p->sin_port = 0;
strcpy(copy, s);
// strip off a trailing :port if present
for (colon = copy ; *colon ; colon++)
{
if (*colon == ':')
{
// terminate
*colon = '\0';
// Start at next character
p->sin_port = htons((short)atoi(colon + 1));
}
}
// Numeric IP, no DNS
if (copy[0] >= '0' && copy[0] <= '9' && strstr(copy, "."))
{
*(int *)&p->sin_addr = inet_addr(copy);
}
else
{
// DNS it
if (!(h = gethostbyname(copy)))
{
return false;
}
// Use first result
*(int *)&p->sin_addr = *(int *)h->h_addr_list[0];
}
return true;
}
bool CNetAPI::StringToAdr(const char *s, netadr_t *a)
{
struct sockaddr sadr;
if (!strcmp(s, "localhost"))
{
memset(a, 0, sizeof(*a));
a->type = NA_LOOPBACK;
return true;
}
if (!StringToSockaddr(s, &sadr))
{
return false;
}
SockAddrToNetAdr(&sadr, a);
return true;
}
// Lookup the IP address for the specified IP socket
void CNetAPI::GetSocketAddress(int socket, netadr_t *a)
{
char buff[512];
struct sockaddr_in address;
int namelen;
memset(a, 0, sizeof(*a));
gethostname(buff, sizeof(buff));
// Ensure that it doesn't overrun the buffer
buff[sizeof buff - 1] = '\0';
StringToAdr(buff, a);
namelen = sizeof(address);
if (getsockname(socket, (struct sockaddr *)&address, (int *)&namelen) == 0)
{
a->port = address.sin_port;
}
}
bool CNetAPI::CompareAdr(netadr_t *a, netadr_t *b)
{
if (a->type != b->type)
{
return false;
}
if (a->type == NA_LOOPBACK)
{
return true;
}
if (a->type == NA_IP &&
a->ip[0] == b->ip[0] &&
a->ip[1] == b->ip[1] &&
a->ip[2] == b->ip[2] &&
a->ip[3] == b->ip[3] &&
a->port == b->port)
{
return true;
}
return false;
}
void CNetAPI::GetLocalIP(netadr_t *a)
{
char s[64];
if(!::gethostname(s, 64))
{
struct hostent *localip = ::gethostbyname(s);
if(localip)
{
a->type = NA_IP;
a->port = 0;
memcpy(a->ip, localip->h_addr_list[0], 4);
}
}
}

25
common/netapi.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef NETAPI_H
#define NETAPI_H
#ifdef _WIN32
#pragma once
#endif
#include "netadr.h"
class INetAPI {
public:
virtual void NetAdrToSockAddr(netadr_t *a, struct sockaddr *s) = 0; // Convert a netadr_t to sockaddr
virtual void SockAddrToNetAdr(struct sockaddr *s, netadr_t *a) = 0; // Convert a sockaddr to netadr_t
virtual char *AdrToString(netadr_t *a) = 0; // Convert a netadr_t to a string
virtual bool StringToAdr(const char *s, netadr_t *a) = 0; // Convert a string address to a netadr_t, doing DNS if needed
virtual void GetSocketAddress(int socket, netadr_t *a) = 0; // Look up IP address for socket
virtual bool CompareAdr(netadr_t *a, netadr_t *b) = 0;
// return the IP of the local host
virtual void GetLocalIP(netadr_t *a) = 0;
};
extern INetAPI *net;
#endif // NETAPI_H

View File

@ -25,15 +25,19 @@
#define MAX_LIGHTSTYLE_INDEX_BITS 6
#define MAX_LIGHTSTYLES (1<<MAX_LIGHTSTYLE_INDEX_BITS)
// Resource counts;
// Resource counts
#define MAX_MODEL_INDEX_BITS 9 // sent as a short
#define MAX_MODELS (1<<MAX_MODEL_INDEX_BITS)
#define MAX_SOUND_INDEX_BITS 9
#define MAX_SOUNDS (1<<MAX_SOUND_INDEX_BITS)
#define MAX_SOUNDS_HASHLOOKUP_SIZE (MAX_SOUNDS * 2 - 1)
#define MAX_GENERIC_INDEX_BITS 9
#define MAX_GENERIC (1<<MAX_GENERIC_INDEX_BITS)
#define MAX_DECAL_INDEX_BITS 9
#define MAX_BASE_DECALS (1<<MAX_DECAL_INDEX_BITS)
#define MAX_EVENTS 256
#define MAX_PACKET_ENTITIES 256 // 256 visible entities per frame
#endif // QLIMITS_H

View File

@ -27,18 +27,15 @@
*/
#pragma once
/* <19039> ../common/quakedef.h:29 */
typedef int BOOL; /* size: 4 */
typedef int BOOL;
// user message
#define MAX_USER_MSG_DATA 192
/* <627f> ../common/quakedef.h:137 */
//moved to com_model.h
//typedef struct cache_user_s
//{
// void *data;
//} cache_user_t;
/* <4313b> ../common/quakedef.h:162 */
typedef int (*pfnUserMsgHook)(const char *, int, void *);

33
common/stdc++compat.cpp Normal file
View File

@ -0,0 +1,33 @@
#include <stdio.h>
#if !defined(_WIN32)
void NORETURN Sys_Error(const char *error, ...);
// This file adds the necessary compatibility tricks to avoid symbols with
// version GLIBCXX_3.4.16 and bigger, keeping binary compatibility with libstdc++ 4.6.1.
namespace std
{
// We shouldn't be throwing exceptions at all, but it sadly turns out we call STL (inline) functions that do.
void __throw_out_of_range_fmt(const char *fmt, ...)
{
va_list ap;
char buf[1024]; // That should be big enough.
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
buf[sizeof(buf) - 1] = '\0';
va_end(ap);
Sys_Error(buf);
}
}; // namespace std
// Technically, this symbol is not in GLIBCXX_3.4.20, but in CXXABI_1.3.8,
// but that's equivalent, version-wise. Those calls are added by the compiler
// itself on `new Class[n]` calls.
extern "C"
void __cxa_throw_bad_array_new_length()
{
Sys_Error("Bad array new length.");
}
#endif // !defined(_WIN32)

394
common/textconsole.cpp Normal file
View File

@ -0,0 +1,394 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#include "precompiled.h"
bool CTextConsole::Init(IBaseSystem *system)
{
// NULL or a valid base system interface
m_System = system;
memset(m_szConsoleText, 0, sizeof(m_szConsoleText));
m_nConsoleTextLen = 0;
m_nCursorPosition = 0;
memset(m_szSavedConsoleText, 0, sizeof(m_szSavedConsoleText));
m_nSavedConsoleTextLen = 0;
memset(m_aszLineBuffer, 0, sizeof(m_aszLineBuffer));
m_nTotalLines = 0;
m_nInputLine = 0;
m_nBrowseLine = 0;
// these are log messages, not related to console
Sys_Printf("\n");
Sys_Printf("Console initialized.\n");
m_ConsoleVisible = true;
return true;
}
void CTextConsole::SetVisible(bool visible)
{
m_ConsoleVisible = visible;
}
bool CTextConsole::IsVisible()
{
return m_ConsoleVisible;
}
void CTextConsole::ShutDown()
{
;
}
void CTextConsole::Print(char *pszMsg)
{
if (m_nConsoleTextLen)
{
int nLen = m_nConsoleTextLen;
while (nLen--)
{
PrintRaw("\b \b");
}
}
PrintRaw(pszMsg);
if (m_nConsoleTextLen)
{
PrintRaw(m_szConsoleText, m_nConsoleTextLen);
}
UpdateStatus();
}
int CTextConsole::ReceiveNewline()
{
int nLen = 0;
Echo("\n");
if (m_nConsoleTextLen)
{
nLen = m_nConsoleTextLen;
m_szConsoleText[ m_nConsoleTextLen ] = '\0';
m_nConsoleTextLen = 0;
m_nCursorPosition = 0;
// cache line in buffer, but only if it's not a duplicate of the previous line
if ((m_nInputLine == 0) || (strcmp(m_aszLineBuffer[ m_nInputLine - 1 ], m_szConsoleText)))
{
strncpy(m_aszLineBuffer[ m_nInputLine ], m_szConsoleText, MAX_CONSOLE_TEXTLEN);
m_nInputLine++;
if (m_nInputLine > m_nTotalLines)
m_nTotalLines = m_nInputLine;
if (m_nInputLine >= MAX_BUFFER_LINES)
m_nInputLine = 0;
}
m_nBrowseLine = m_nInputLine;
}
return nLen;
}
void CTextConsole::ReceiveBackspace()
{
int nCount;
if (m_nCursorPosition == 0)
{
return;
}
m_nConsoleTextLen--;
m_nCursorPosition--;
Echo("\b");
for (nCount = m_nCursorPosition; nCount < m_nConsoleTextLen; ++nCount)
{
m_szConsoleText[ nCount ] = m_szConsoleText[ nCount + 1 ];
Echo(m_szConsoleText + nCount, 1);
}
Echo(" ");
nCount = m_nConsoleTextLen;
while (nCount >= m_nCursorPosition)
{
Echo("\b");
nCount--;
}
m_nBrowseLine = m_nInputLine;
}
void CTextConsole::ReceiveTab()
{
#ifndef LAUNCHER_FIXES
if (!m_System)
return;
#else
if (!rehldsFuncs || !m_nConsoleTextLen)
{
return;
}
#endif
ObjectList matches;
m_szConsoleText[ m_nConsoleTextLen ] = '\0';
#ifndef LAUNCHER_FIXES
m_System->GetCommandMatches(m_szConsoleText, &matches);
#else
rehldsFuncs->GetCommandMatches(m_szConsoleText, &matches);
#endif
if (matches.IsEmpty())
return;
if (matches.CountElements() == 1)
{
char *pszCmdName = (char *)matches.GetFirst();
char *pszRest = pszCmdName + strlen(m_szConsoleText);
if (pszRest)
{
Echo(pszRest);
strcat(m_szConsoleText, pszRest);
m_nConsoleTextLen += strlen(pszRest);
Echo(" ");
strcat(m_szConsoleText, " ");
m_nConsoleTextLen++;
}
}
else
{
int nLongestCmd = 0;
int nSmallestCmd = 0;
int nCurrentColumn;
int nTotalColumns;
char szCommonCmd[256];//Should be enough.
char szFormatCmd[256];
char *pszSmallestCmd;
char *pszCurrentCmd = (char *)matches.GetFirst();
nSmallestCmd = strlen(pszCurrentCmd);
pszSmallestCmd = pszCurrentCmd;
while (pszCurrentCmd)
{
if ((int)strlen(pszCurrentCmd) > nLongestCmd)
{
nLongestCmd = strlen(pszCurrentCmd);
}
if ((int)strlen(pszCurrentCmd) < nSmallestCmd)
{
nSmallestCmd = strlen(pszCurrentCmd);
pszSmallestCmd = pszCurrentCmd;
}
pszCurrentCmd = (char *)matches.GetNext();
}
nTotalColumns = (GetWidth() - 1) / (nLongestCmd + 1);
nCurrentColumn = 0;
Echo("\n");
Q_strcpy(szCommonCmd, pszSmallestCmd);
// Would be nice if these were sorted, but not that big a deal
pszCurrentCmd = (char *)matches.GetFirst();
while (pszCurrentCmd)
{
if (++nCurrentColumn > nTotalColumns)
{
Echo("\n");
nCurrentColumn = 1;
}
_snprintf(szFormatCmd, sizeof(szFormatCmd), "%-*s ", nLongestCmd, pszCurrentCmd);
Echo(szFormatCmd);
for (char *pCur = pszCurrentCmd, *pCommon = szCommonCmd; (*pCur&&*pCommon); pCur++, pCommon++)
{
if (*pCur != *pCommon)
{
*pCommon = 0;
break;
}
}
pszCurrentCmd = (char *)matches.GetNext();
}
Echo("\n");
if (Q_strcmp(szCommonCmd, m_szConsoleText))
{
Q_strcpy(m_szConsoleText, szCommonCmd);
m_nConsoleTextLen = Q_strlen(szCommonCmd);
}
Echo(m_szConsoleText);
}
m_nCursorPosition = m_nConsoleTextLen;
m_nBrowseLine = m_nInputLine;
}
void CTextConsole::ReceiveStandardChar(const char ch)
{
int nCount;
// If the line buffer is maxed out, ignore this char
if (m_nConsoleTextLen >= (sizeof(m_szConsoleText) - 2))
{
return;
}
nCount = m_nConsoleTextLen;
while (nCount > m_nCursorPosition)
{
m_szConsoleText[ nCount ] = m_szConsoleText[ nCount - 1 ];
nCount--;
}
m_szConsoleText[ m_nCursorPosition ] = ch;
Echo(m_szConsoleText + m_nCursorPosition, m_nConsoleTextLen - m_nCursorPosition + 1);
m_nConsoleTextLen++;
m_nCursorPosition++;
nCount = m_nConsoleTextLen;
while (nCount > m_nCursorPosition)
{
Echo("\b");
nCount--;
}
m_nBrowseLine = m_nInputLine;
}
void CTextConsole::ReceiveUpArrow()
{
int nLastCommandInHistory = m_nInputLine + 1;
if (nLastCommandInHistory > m_nTotalLines)
nLastCommandInHistory = 0;
if (m_nBrowseLine == nLastCommandInHistory)
return;
if (m_nBrowseLine == m_nInputLine)
{
if (m_nConsoleTextLen > 0)
{
// Save off current text
strncpy(m_szSavedConsoleText, m_szConsoleText, m_nConsoleTextLen);
// No terminator, it's a raw buffer we always know the length of
}
m_nSavedConsoleTextLen = m_nConsoleTextLen;
}
m_nBrowseLine--;
if (m_nBrowseLine < 0)
{
m_nBrowseLine = m_nTotalLines - 1;
}
// delete old line
while (m_nConsoleTextLen--)
{
Echo("\b \b");
}
// copy buffered line
Echo(m_aszLineBuffer[ m_nBrowseLine ]);
strncpy(m_szConsoleText, m_aszLineBuffer[ m_nBrowseLine ], MAX_CONSOLE_TEXTLEN);
m_nConsoleTextLen = strlen(m_aszLineBuffer[ m_nBrowseLine ]);
m_nCursorPosition = m_nConsoleTextLen;
}
void CTextConsole::ReceiveDownArrow()
{
if (m_nBrowseLine == m_nInputLine)
return;
if (++m_nBrowseLine > m_nTotalLines)
m_nBrowseLine = 0;
// delete old line
while (m_nConsoleTextLen--)
{
Echo("\b \b");
}
if (m_nBrowseLine == m_nInputLine)
{
if (m_nSavedConsoleTextLen > 0)
{
// Restore current text
strncpy(m_szConsoleText, m_szSavedConsoleText, m_nSavedConsoleTextLen);
// No terminator, it's a raw buffer we always know the length of
Echo(m_szConsoleText, m_nSavedConsoleTextLen);
}
m_nConsoleTextLen = m_nSavedConsoleTextLen;
}
else
{
// copy buffered line
Echo(m_aszLineBuffer[ m_nBrowseLine ]);
strncpy(m_szConsoleText, m_aszLineBuffer[ m_nBrowseLine ], MAX_CONSOLE_TEXTLEN);
m_nConsoleTextLen = strlen(m_aszLineBuffer[ m_nBrowseLine ]);
}
m_nCursorPosition = m_nConsoleTextLen;
}
void CTextConsole::ReceiveLeftArrow()
{
if (m_nCursorPosition == 0)
return;
Echo("\b");
m_nCursorPosition--;
}
void CTextConsole::ReceiveRightArrow()
{
if (m_nCursorPosition == m_nConsoleTextLen)
return;
Echo(m_szConsoleText + m_nCursorPosition, 1);
m_nCursorPosition++;
}

93
common/textconsole.h Normal file
View File

@ -0,0 +1,93 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
#include "IBaseSystem.h"
#define MAX_CONSOLE_TEXTLEN 256
#define MAX_BUFFER_LINES 30
class CTextConsole {
public:
virtual ~CTextConsole() {}
virtual bool Init(IBaseSystem *system = nullptr);
virtual void ShutDown();
virtual void Print(char *pszMsg);
virtual void SetTitle(char *pszTitle) {}
virtual void SetStatusLine(char *pszStatus) {}
virtual void UpdateStatus() {}
// Must be provided by children
virtual void PrintRaw(char *pszMsg, int nChars = 0) = 0;
virtual void Echo(char *pszMsg, int nChars = 0) = 0;
virtual char *GetLine() = 0;
virtual int GetWidth() = 0;
virtual void SetVisible(bool visible);
virtual bool IsVisible();
protected:
char m_szConsoleText[MAX_CONSOLE_TEXTLEN]; // console text buffer
int m_nConsoleTextLen; // console textbuffer length
int m_nCursorPosition; // position in the current input line
// Saved input data when scrolling back through command history
char m_szSavedConsoleText[MAX_CONSOLE_TEXTLEN]; // console text buffer
int m_nSavedConsoleTextLen; // console textbuffer length
char m_aszLineBuffer[MAX_BUFFER_LINES][MAX_CONSOLE_TEXTLEN]; // command buffer last MAX_BUFFER_LINES commands
int m_nInputLine; // Current line being entered
int m_nBrowseLine; // current buffer line for up/down arrow
int m_nTotalLines; // # of nonempty lines in the buffer
bool m_ConsoleVisible;
IBaseSystem *m_System;
int ReceiveNewline();
void ReceiveBackspace();
void ReceiveTab();
void ReceiveStandardChar(const char ch);
void ReceiveUpArrow();
void ReceiveDownArrow();
void ReceiveLeftArrow();
void ReceiveRightArrow();
};
#include "SteamAppStartUp.h"
#if defined(_WIN32)
#include "TextConsoleWin32.h"
#else
#include "TextConsoleUnix.h"
#endif // defined(_WIN32)
void Sys_Printf(char *fmt, ...);

View File

@ -27,8 +27,6 @@
*/
#pragma once
/* <430ee> ../common/vmodes.h:40 */
typedef struct rect_s
{
int left, right, top, bottom;

View File

@ -33,7 +33,7 @@ typedef void(*xcommand_t)(void);
typedef struct cmd_function_s
{
struct cmd_function_s *next;
char *name;
const char *name;
xcommand_t function;
int flags;
} cmd_function_t;

View File

@ -26,18 +26,13 @@
*
*/
#ifndef CONSISTENCY_H
#define CONSISTENCY_H
#ifdef _WIN32
#pragma once
#endif
#define MAX_CONSISTENCY_LIST 512
const int MAX_CONSISTENCY_LIST = 512;
/* <7508> ../engine/consistency.h:9 */
typedef struct consistency_s
{
char * filename;
char *filename;
int issound;
int orig_index;
int value;
@ -45,5 +40,3 @@ typedef struct consistency_s
float mins[3];
float maxs[3];
} consistency_t;
#endif // CONSISTENCY_H

View File

@ -1,9 +1,9 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
@ -63,7 +63,14 @@ typedef struct resourceinfo_s
typedef struct resource_s
{
#ifdef HOOK_HLTV
// NOTE HLTV: array szFileName declared on 260 cell,
// this changes necessary for compatibility hookers.
char szFileName[MAX_PATH];
#else
char szFileName[MAX_QPATH]; // File name to download/precache.
#endif // HOOK_HLTV
resourcetype_t type; // t_sound, t_skin, t_model, t_decal.
int nIndex; // For t_decals
int nDownloadSize; // Size in Bytes if this must be downloaded.
@ -75,14 +82,19 @@ typedef struct resource_s
unsigned char rguc_reserved[ 32 ]; // For future expansion
struct resource_s *pNext; // Next in chain.
#if !defined(HLTV)
struct resource_s *pPrev;
#else
unsigned char *data;
#endif // !defined(HLTV)
} resource_t;
typedef struct customization_s
{
qboolean bInUse; // Is this customization in use;
resource_t resource; // The resource_t for this customization
qboolean bTranslated; // Has the raw data been translated into a useable format?
qboolean bTranslated; // Has the raw data been translated into a useable format?
// (e.g., raw decal .wad make into texture_t *)
int nUserData1; // Customization specific data
int nUserData2; // Customization specific data

View File

@ -144,11 +144,11 @@ typedef struct enginefuncs_s
const char *(*pfnTraceTexture) (edict_t *pTextureEntity, const float *v1, const float *v2 );
void (*pfnTraceSphere) (const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr);
void (*pfnGetAimVector) (edict_t* ent, float speed, float *rgflReturn);
void (*pfnServerCommand) (char* str);
void (*pfnServerCommand) (const char* str);
void (*pfnServerExecute) (void);
void (*pfnClientCommand) (edict_t* pEdict, char* szFmt, ...);
void (*pfnClientCommand) (edict_t* pEdict, const char* szFmt, ...);
void (*pfnParticleEffect) (const float *org, const float *dir, float color, float count);
void (*pfnLightStyle) (int style, char* val);
void (*pfnLightStyle) (int style, const char* val);
int (*pfnDecalIndex) (const char *name);
int (*pfnPointContents) (const float *rgflVector);
void (*pfnMessageBegin) (int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
@ -200,7 +200,7 @@ typedef struct enginefuncs_s
void (*pfnSetView) (const edict_t *pClient, const edict_t *pViewent );
float (*pfnTime) ( void );
void (*pfnCrosshairAngle) (const edict_t *pClient, float pitch, float yaw);
byte * (*pfnLoadFileForMe) (char *filename, int *pLength);
byte * (*pfnLoadFileForMe) (const char *filename, int *pLength);
void (*pfnFreeFile) (void *buffer);
void (*pfnEndSection) (const char *pszSectionName); // trigger_endsection
int (*pfnCompareFileTime) (char *filename1, char *filename2, int *iCompare);
@ -215,9 +215,9 @@ typedef struct enginefuncs_s
char* (*pfnInfoKeyValue) (char *infobuffer, const char *key);
void (*pfnSetKeyValue) (char *infobuffer, const char *key, const char *value);
void (*pfnSetClientKeyValue) (int clientIndex, char *infobuffer, const char *key, const char *value);
int (*pfnIsMapValid) (char *filename);
int (*pfnIsMapValid) (const char *filename);
void (*pfnStaticDecal) ( const float *origin, int decalIndex, int entityIndex, int modelIndex );
int (*pfnPrecacheGeneric) (char* s);
int (*pfnPrecacheGeneric) (const char* s);
int (*pfnGetPlayerUserId) (edict_t *e ); // returns the server assigned userid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients
void (*pfnBuildSoundMsg) (edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
int (*pfnIsDedicatedServer) (void);// is this a dedicated server?
@ -239,7 +239,7 @@ typedef struct enginefuncs_s
void (*pfnDeltaSetField) ( struct delta_s *pFields, const char *fieldname );
void (*pfnDeltaUnsetField) ( struct delta_s *pFields, const char *fieldname );
void (*pfnDeltaAddEncoder) ( char *name, void (*conditionalencode)( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) );
void (*pfnDeltaAddEncoder) ( const char *name, void (*conditionalencode)( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) );
int (*pfnGetCurrentPlayer) ( void );
int (*pfnCanSkipPlayer) ( const edict_t *player );
int (*pfnDeltaFindField) ( struct delta_s *pFields, const char *fieldname );
@ -258,7 +258,7 @@ typedef struct enginefuncs_s
void (*pfnGetPlayerStats) ( const edict_t *pClient, int *ping, int *packet_loss );
void (*pfnAddServerCommand) ( char *cmd_name, void (*function) (void) );
void (*pfnAddServerCommand) ( const char *cmd_name, void (*function) (void) );
// For voice communications, set which clients hear eachother.
// NOTE: these functions take player entity indices (starting at 1).
@ -274,7 +274,7 @@ typedef struct enginefuncs_s
sentenceEntry_s* (*pfnSequencePickSentence) ( const char* groupName, int pickMethod, int *picked );
// LH: Give access to filesize via filesystem
int (*pfnGetFileSize) ( char *filename );
int (*pfnGetFileSize) ( const char *filename );
unsigned int (*pfnGetApproxWavePlayLen) (const char *filepath);
// MDC: Added for CZ career-mode

View File

@ -32,11 +32,9 @@
#pragma once
#endif
#include "osconfig.h"
#include "mathlib.h"
// Has no references on server side.
#define NOXREF
// Function body is not implemented.
@ -44,9 +42,29 @@
// Function is not tested at all.
#define UNTESTED
#define CONST_INTEGER_AS_STRING(x) #x //Wraps the integer in quotes, allowing us to form constant strings with it
#define __HACK_LINE_AS_STRING__(x) CONST_INTEGER_AS_STRING(x) //__LINE__ can only be converted to an actual number by going through this, otherwise the output is literally "__LINE__"
#define __LINE__AS_STRING __HACK_LINE_AS_STRING__(__LINE__) //Gives you the line number in constant string form
#if defined _MSC_VER || defined __INTEL_COMPILER
#define NOXREFCHECK int __retAddr; __asm { __asm mov eax, [ebp + 4] __asm mov __retAddr, eax }; Sys_Error("[NOXREFCHECK]: %s: (" __FILE__ ":" __LINE__AS_STRING ") NOXREF, but called from 0x%.08x", __func__, __retAddr)
#else
// For EBP based stack (older gcc) (uncomment version apropriate for your compiler)
//#define NOXREFCHECK int __retAddr; __asm__ __volatile__("movl 4(%%ebp), %%eax;" "movl %%eax, %0":"=r"(__retAddr)::"%eax"); Sys_Error("[NOXREFCHECK]: %s: (" __FILE__ ":" __LINE__AS_STRING ") NOXREF, but called from 0x%.08x", __func__, __retAddr);
// For ESP based stack (newer gcc) (uncomment version apropriate for your compiler)
#define NOXREFCHECK int __retAddr; __asm__ __volatile__("movl 16(%%esp), %%eax;" "movl %%eax, %0":"=r"(__retAddr)::"%eax"); Sys_Error("[NOXREFCHECK]: %s: (" __FILE__ ":" __LINE__AS_STRING ") NOXREF, but called from 0x%.08x", __func__, __retAddr);
#endif
#define BIT(n) (1<<(n))
// From engine/pr_comp.h;
typedef unsigned int string_t;
typedef unsigned int string_t; // from engine's pr_comp.h;
// From engine/server.h
typedef enum sv_delta_s
{
sv_packet_nodelta,
sv_packet_delta,
} sv_delta_t;
#endif // MAINTYPES_H

View File

@ -74,7 +74,7 @@ typedef struct texture_s
char name[16];
unsigned width, height;
#ifndef SWDS
#if !defined(SWDS) && !defined(HLTV)
int gl_texturenum;
struct msurface_s * texturechain;
#endif
@ -85,7 +85,7 @@ typedef struct texture_s
struct texture_s *alternate_anims; // bmodels in frame 1 use these
unsigned offsets[MIPLEVELS]; // four mip maps stored
#ifdef SWDS
#if defined(SWDS) || defined(HLTV)
unsigned paloffset;
#else
byte *pPal;

View File

@ -79,9 +79,6 @@
#include <sys/types.h>
#include <sys/sysinfo.h>
#include <unistd.h>
// Deail with stupid macro in kernel.h
#undef __FUNCTION__
#endif // _WIN32
#include <string>
@ -92,7 +89,13 @@
#include <smmintrin.h>
#include <xmmintrin.h>
#ifdef _WIN32 // WINDOWS
// Define __func__ on VS less than 2015
#if _MSC_VER < 1900
#define __func__ __FUNCTION__
#endif
#define _CRT_SECURE_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
@ -103,8 +106,13 @@
#define HIDDEN
#define NOINLINE __declspec(noinline)
#define ALIGN16 __declspec(align(16))
#define NORETURN __declspec(noreturn)
#define FORCE_STACK_ALIGN
#define __builtin_bswap16 _byteswap_ushort
#define __builtin_bswap32 _byteswap_ulong
#define __builtin_bswap64 _byteswap_uint64
//inline bool SOCKET_FIONBIO(SOCKET s, int m) { return (ioctlsocket(s, FIONBIO, (u_long*)&m) == 0); }
//inline int SOCKET_MSGLEN(SOCKET s, u_long& r) { return ioctlsocket(s, FIONREAD, (u_long*)&r); }
typedef int socklen_t;
@ -123,11 +131,6 @@
VirtualFree(ptr, 0, MEM_RELEASE);
}
#else // _WIN32
#ifdef __FUNCTION__
#undef __FUNCTION__
#endif
#define __FUNCTION__ __func__
#ifndef PAGESIZE
#define PAGESIZE 4096
#endif
@ -135,10 +138,7 @@
#define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0]))
#define _MAX_FNAME NAME_MAX
#ifndef MAX_PATH
#define MAX_PATH 260
#endif // MAX_PATH
#define MAX_PATH 260
typedef void *HWND;
@ -151,8 +151,15 @@
#define HIDDEN __attribute__((visibility("hidden")))
#define NOINLINE __attribute__((noinline))
#define ALIGN16 __attribute__((aligned(16)))
#define NORETURN __attribute__((noreturn))
#define FORCE_STACK_ALIGN __attribute__((force_align_arg_pointer))
#if defined __INTEL_COMPILER
#define __builtin_bswap16 _bswap16
#define __builtin_bswap32 _bswap
#define __builtin_bswap64 _bswap64
#endif // __INTEL_COMPILER
//inline bool SOCKET_FIONBIO(SOCKET s, int m) { return (ioctl(s, FIONBIO, (int*)&m) == 0); }
//inline int SOCKET_MSGLEN(SOCKET s, u_long& r) { return ioctl(s, FIONREAD, (int*)&r); }
typedef int SOCKET;
@ -165,6 +172,10 @@
#define SOCKET_AGAIN() (errno == EAGAIN)
#define SOCKET_ERROR -1
inline int ioctlsocket(int fd, int cmd, unsigned int *argp) { return ioctl(fd, cmd, argp); }
inline int closesocket(int fd) { return close(fd); }
inline int WSAGetLastError() { return errno; }
inline void* sys_allocmem(unsigned int size) {
return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
}
@ -192,4 +203,8 @@
#define EXT_FUNC FORCE_STACK_ALIGN
// Used to obtain the string name of a variable.
#define nameof_variable(name) template_nameof_variable(name, #name)
template <typename T> const char* template_nameof_variable(const T& /*validate_type*/, const char* name) { return name; }
#endif // _OSCONFIG_H

View File

@ -267,7 +267,7 @@ struct RehldsFuncs_t {
cvar_t*(*GetCvarVars)();
int (*SV_GetChallenge)(const netadr_t& adr);
void (*SV_AddResource)(resourcetype_t type, const char *name, int size, unsigned char flags, int index);
int(*MSG_ReadShort)(void);
int(*MSG_ReadShort)();
int(*MSG_ReadBuf)(int iSize, void *pbuf);
void(*MSG_WriteBuf)(sizebuf_t *sb, int iSize, void *buf);
void(*MSG_WriteByte)(sizebuf_t *sb, int c);
@ -297,4 +297,4 @@ public:
virtual IRehldsFlightRecorder* GetFlightRecorder() = 0;
};
#define VREHLDS_HLDS_API_VERSION "VREHLDS_HLDS_API_VERSION001"
#define VREHLDS_HLDS_API_VERSION "VREHLDS_HLDS_API_VERSION001"

View File

@ -44,7 +44,7 @@ private:
// this was a root node
unsigned int rootId = GetRoodNodeId(node->key);
if (m_RootNodes[rootId] != node) {
Sys_Error(__FUNCTION__ ": invalid root node");
Sys_Error("%s: invalid root node", __func__);
return;
}

View File

@ -29,6 +29,8 @@
#if defined(__GNUC__)
#include <cpuid.h>
#elif _MSC_VER >= 1400 && !defined(ASMLIB_H)
#include <intrin.h> // __cpuidex
#endif
#define SSE3_FLAG (1<<0)
@ -69,4 +71,4 @@ void Sys_CheckCpuInstructionsSupport(void)
#endif
cpuinfo.avx2 = (cpuid_data[1] & AVX2_FLAG) ? 1 : 0; // ebx
}
}

View File

@ -162,7 +162,6 @@
<ClInclude Include="..\pm_shared\pm_movevars.h" />
<ClInclude Include="..\pm_shared\pm_shared.h" />
<ClInclude Include="..\public\FileSystem.h" />
<ClInclude Include="..\public\interface.h" />
<ClInclude Include="..\public\rechecker_api.h" />
<ClInclude Include="..\public\rechecker_interfaces.h" />
<ClInclude Include="..\src\cmdexec.h" />
@ -178,11 +177,9 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\public\interface.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\src\cmdexec.cpp" />
<ClCompile Include="..\src\hookchains_impl.cpp" />
<ClCompile Include="..\src\public_amalgamation.cpp" />
<ClCompile Include="..\src\rechecker_api_impl.cpp" />
<ClCompile Include="..\src\resource.cpp" />
<ClCompile Include="..\src\dllapi.cpp" />
@ -260,7 +257,8 @@
<ModuleDefinitionFile>rechecker.def</ModuleDefinitionFile>
</Link>
<PostBuildEvent>
<Command>IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")</Command>
<Command>IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")
IF EXIST "$(ProjectDir)ServerStart_cs_6153.bat" (CALL "$(ProjectDir)ServerStart_cs_6153.bat")</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Automatic deployment script</Message>

View File

@ -454,9 +454,6 @@
<ClInclude Include="..\public\FileSystem.h">
<Filter>sdk\public</Filter>
</ClInclude>
<ClInclude Include="..\public\interface.h">
<Filter>sdk\public</Filter>
</ClInclude>
<ClInclude Include="..\src\main.h" />
<ClInclude Include="..\src\precompiled.h" />
<ClInclude Include="..\src\engine_rehlds.h" />
@ -475,9 +472,6 @@
<ClCompile Include="..\common\parsemsg.cpp">
<Filter>sdk\common</Filter>
</ClCompile>
<ClCompile Include="..\public\interface.cpp">
<Filter>sdk\public</Filter>
</ClCompile>
<ClCompile Include="..\src\dllapi.cpp" />
<ClCompile Include="..\src\engine_api.cpp" />
<ClCompile Include="..\src\engine_rehlds.cpp" />
@ -490,6 +484,7 @@
<ClCompile Include="..\src\resource.cpp" />
<ClCompile Include="..\src\hookchains_impl.cpp" />
<ClCompile Include="..\src\rechecker_api_impl.cpp" />
<ClCompile Include="..\src\public_amalgamation.cpp" />
</ItemGroup>
<ItemGroup>
<Filter Include="sdk">

View File

@ -208,7 +208,7 @@ typedef struct playermove_s
void (*PM_GetModelBounds)( struct model_s *mod, float *mins, float *maxs );
void *(*PM_HullForBsp)( physent_t *pe, float *offset );
float (*PM_TraceModel)( physent_t *pEnt, float *start, float *end, trace_t *trace );
int (*COM_FileSize)(char *filename);
int (*COM_FileSize)(const char *filename);
byte *(*COM_LoadFile) (const char *path, int usehunk, int *pLength);
void (*COM_FreeFile) ( void *buffer );
char *(*memfgets)( byte *pMemFile, int fileSize, int *pFilePos, char *pBuffer, int bufferSize );

View File

@ -1,32 +1,54 @@
//========= Copyright <20> 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#ifndef FILESYSTEM_H
#define FILESYSTEM_H
#ifdef _WIN32
#pragma once
#endif
#include "interface.h"
#include <stdio.h>
#include <stdlib.h>
// There is only one instance of the IFileSystem interface,
// located in the filesystem_stdio library (filesystem_steam is obsolete).
#ifdef _WIN32
#define STDIO_FILESYSTEM_LIB "filesystem_stdio.dll"
#define STEAM_FILESYSTEM_LIB "filesystem_steam.dll"
#else
#define STDIO_FILESYSTEM_LIB "filesystem_stdio.so"
#define STEAM_FILESYSTEM_LIB "filesystem_steam.so"
#endif // _WIN32
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
typedef FILE * FileHandle_t;
typedef FILE *FileHandle_t;
typedef int FileFindHandle_t;
typedef int WaitForResourcesHandle_t;
typedef void (*WarningFunc_t)(const char *fmt, ...);
//-----------------------------------------------------------------------------
// Enums used by the interface
//-----------------------------------------------------------------------------
#ifndef FILESYSTEM_INTERNAL_H
typedef enum
{
@ -42,148 +64,138 @@ enum
typedef enum
{
// Don't print anything
FILESYSTEM_WARNING_QUIET = 0,
// On shutdown, report names of files left unclosed
FILESYSTEM_WARNING_REPORTUNCLOSED,
// Report number of times a file was opened, closed
FILESYSTEM_WARNING_REPORTUSAGE,
// Report all open/close events to console ( !slow! )
FILESYSTEM_WARNING_REPORTALLACCESSES
FILESYSTEM_WARNING_QUIET = 0, // Don't print anything
FILESYSTEM_WARNING_REPORTUNCLOSED, // On shutdown, report names of files left unclosed
FILESYSTEM_WARNING_REPORTUSAGE, // Report number of times a file was opened, closed
FILESYSTEM_WARNING_REPORTALLACCESSES // Report all open/close events to console (!slow!)
} FileWarningLevel_t;
#define FILESYSTEM_INVALID_HANDLE ( FileHandle_t )0
#endif
#define FILESYSTEM_INVALID_HANDLE (FileHandle_t)0
#endif // FILESYSTEM_INTERNAL_H
// turn off any windows defines
#undef GetCurrentDirectory
//-----------------------------------------------------------------------------
// Purpose: Main file system interface
//-----------------------------------------------------------------------------
class IFileSystem : public IBaseInterface
{
public:
// Mount and unmount the filesystem
virtual void Mount( void ) = 0;
virtual void Unmount( void ) = 0;
virtual void Mount() = 0;
virtual void Unmount() = 0;
// Remove all search paths (including write path?)
virtual void RemoveAllSearchPaths( void ) = 0;
virtual void RemoveAllSearchPaths() = 0;
// Add paths in priority order (mod dir, game dir, ....)
// If one or more .pak files are in the specified directory, then they are
// added after the file system path
// If the path is the relative path to a .bsp file, then any previous .bsp file
// If the path is the relative path to a .bsp file, then any previous .bsp file
// override is cleared and the current .bsp is searched for an embedded PAK file
// and this file becomes the highest priority search path ( i.e., it's looked at first
// even before the mod's file system path ).
virtual void AddSearchPath( const char *pPath, const char *pathID ) = 0;
virtual bool RemoveSearchPath( const char *pPath ) = 0;
// and this file becomes the highest priority search path (i.e., it's looked at first
// even before the mod's file system path).
virtual void AddSearchPath(const char *pPath, const char *pathID) = 0;
virtual bool RemoveSearchPath(const char *pPath) = 0;
// Deletes a file
virtual void RemoveFile( const char *pRelativePath, const char *pathID ) = 0;
virtual void RemoveFile(const char *pRelativePath, const char *pathID) = 0;
// this isn't implementable on STEAM as is.
virtual void CreateDirHierarchy( const char *path, const char *pathID ) = 0;
virtual void CreateDirHierarchy(const char *path, const char *pathID) = 0;
// File I/O and info
virtual bool FileExists( const char *pFileName ) = 0;
virtual bool IsDirectory( const char *pFileName ) = 0;
virtual bool FileExists(const char *pFileName) = 0;
virtual bool IsDirectory(const char *pFileName) = 0;
// opens a file
// if pathID is NULL, all paths will be searched for the file
virtual FileHandle_t Open( const char *pFileName, const char *pOptions, const char *pathID = 0L ) = 0;
virtual FileHandle_t Open(const char *pFileName, const char *pOptions, const char *pathID = 0L) = 0;
virtual void Close( FileHandle_t file ) = 0;
virtual void Close(FileHandle_t file) = 0;
virtual void Seek( FileHandle_t file, int pos, FileSystemSeek_t seekType ) = 0;
virtual unsigned int Tell( FileHandle_t file ) = 0;
virtual void Seek(FileHandle_t file, int pos, FileSystemSeek_t seekType) = 0;
virtual unsigned int Tell(FileHandle_t file) = 0;
virtual unsigned int Size( FileHandle_t file ) = 0;
virtual unsigned int Size( const char *pFileName ) = 0;
virtual unsigned int Size(FileHandle_t file) = 0;
virtual unsigned int Size(const char *pFileName) = 0;
virtual long GetFileTime( const char *pFileName ) = 0;
virtual void FileTimeToString( char* pStrip, int maxCharsIncludingTerminator, long fileTime ) = 0;
virtual long GetFileTime(const char *pFileName) = 0;
virtual void FileTimeToString(char *pStrip, int maxCharsIncludingTerminator, long fileTime) = 0;
virtual bool IsOk( FileHandle_t file ) = 0;
virtual bool IsOk(FileHandle_t file) = 0;
virtual void Flush( FileHandle_t file ) = 0;
virtual bool EndOfFile( FileHandle_t file ) = 0;
virtual void Flush(FileHandle_t file) = 0;
virtual bool EndOfFile(FileHandle_t file) = 0;
virtual int Read( void* pOutput, int size, FileHandle_t file ) = 0;
virtual int Write( void const* pInput, int size, FileHandle_t file ) = 0;
virtual char *ReadLine( char *pOutput, int maxChars, FileHandle_t file ) = 0;
virtual int FPrintf( FileHandle_t file, char *pFormat, ... ) = 0;
virtual int Read(void *pOutput, int size, FileHandle_t file) = 0;
virtual int Write(void const *pInput, int size, FileHandle_t file) = 0;
virtual char *ReadLine(char *pOutput, int maxChars, FileHandle_t file) = 0;
virtual int FPrintf(FileHandle_t file, char *pFormat, ...) = 0;
// direct filesystem buffer access
// returns a handle to a buffer containing the file data
// this is the optimal way to access the complete data for a file,
// this is the optimal way to access the complete data for a file,
// since the file preloader has probably already got it in memory
virtual void *GetReadBuffer( FileHandle_t file, int *outBufferSize, bool failIfNotInCache ) = 0;
virtual void ReleaseReadBuffer( FileHandle_t file, void *readBuffer ) = 0;
virtual void *GetReadBuffer(FileHandle_t file, int *outBufferSize, bool failIfNotInCache) = 0;
virtual void ReleaseReadBuffer(FileHandle_t file, void *readBuffer) = 0;
// FindFirst/FindNext
virtual const char *FindFirst( const char *pWildCard, FileFindHandle_t *pHandle, const char *pathID = 0L ) = 0;
virtual const char *FindNext( FileFindHandle_t handle ) = 0;
virtual bool FindIsDirectory( FileFindHandle_t handle ) = 0;
virtual void FindClose( FileFindHandle_t handle ) = 0;
virtual const char *FindFirst(const char *pWildCard, FileFindHandle_t *pHandle, const char *pathID = 0L) = 0;
virtual const char *FindNext(FileFindHandle_t handle) = 0;
virtual bool FindIsDirectory(FileFindHandle_t handle) = 0;
virtual void FindClose(FileFindHandle_t handle) = 0;
virtual void GetLocalCopy( const char *pFileName ) = 0;
virtual void GetLocalCopy(const char *pFileName) = 0;
virtual const char *GetLocalPath( const char *pFileName, char *pLocalPath, int localPathBufferSize ) = 0;
virtual const char *GetLocalPath(const char *pFileName, char *pLocalPath, int localPathBufferSize) = 0;
// Note: This is sort of a secondary feature; but it's really useful to have it here
virtual char *ParseFile( char* pFileBytes, char* pToken, bool* pWasQuoted ) = 0;
virtual char *ParseFile(char *pFileBytes, char *pToken, bool *pWasQuoted) = 0;
// Returns true on success ( based on current list of search paths, otherwise false if it can't be resolved )
virtual bool FullPathToRelativePath( const char *pFullpath, char *pRelative ) = 0;
// Returns true on success (based on current list of search paths, otherwise false if it can't be resolved)
virtual bool FullPathToRelativePath(const char *pFullpath, char *pRelative) = 0;
// Gets the current working directory
virtual bool GetCurrentDirectory( char* pDirectory, int maxlen ) = 0;
virtual bool GetCurrentDirectory(char *pDirectory, int maxlen) = 0;
// Dump to printf/OutputDebugString the list of files that have not been closed
virtual void PrintOpenedFiles( void ) = 0;
virtual void PrintOpenedFiles() = 0;
virtual void SetWarningFunc( void (*pfnWarning)( const char *fmt, ... ) ) = 0;
virtual void SetWarningLevel( FileWarningLevel_t level ) = 0;
virtual void SetWarningFunc(WarningFunc_t pfnWarning) = 0;
virtual void SetWarningLevel(FileWarningLevel_t level) = 0;
virtual void LogLevelLoadStarted( const char *name ) = 0;
virtual void LogLevelLoadFinished( const char *name ) = 0;
virtual int HintResourceNeed( const char *hintlist, int forgetEverything ) = 0;
virtual int PauseResourcePreloading( void ) = 0;
virtual int ResumeResourcePreloading( void ) = 0;
virtual int SetVBuf( FileHandle_t stream, char *buffer, int mode, long size ) = 0;
virtual void GetInterfaceVersion( char *p, int maxlen ) = 0;
virtual void LogLevelLoadStarted(const char *name) = 0;
virtual void LogLevelLoadFinished(const char *name) = 0;
virtual int HintResourceNeed(const char *hintlist, int forgetEverything) = 0;
virtual int PauseResourcePreloading() = 0;
virtual int ResumeResourcePreloading() = 0;
virtual int SetVBuf(FileHandle_t stream, char *buffer, int mode, long size) = 0;
virtual void GetInterfaceVersion(char *p, int maxlen) = 0;
virtual bool IsFileImmediatelyAvailable(const char *pFileName) = 0;
// starts waiting for resources to be available
// returns FILESYSTEM_INVALID_HANDLE if there is nothing to wait on
virtual WaitForResourcesHandle_t WaitForResources( const char *resourcelist ) = 0;
virtual WaitForResourcesHandle_t WaitForResources(const char *resourcelist) = 0;
// get progress on waiting for resources; progress is a float [0, 1], complete is true on the waiting being done
// returns false if no progress is available
// any calls after complete is true or on an invalid handle will return false, 0.0f, true
virtual bool GetWaitForResourcesProgress( WaitForResourcesHandle_t handle, float *progress /* out */ , bool *complete /* out */ ) = 0;
virtual bool GetWaitForResourcesProgress(WaitForResourcesHandle_t handle, float *progress /* out */ , bool *complete /* out */) = 0;
// cancels a progress call
virtual void CancelWaitForResources( WaitForResourcesHandle_t handle ) = 0;
virtual void CancelWaitForResources(WaitForResourcesHandle_t handle) = 0;
// returns true if the appID has all its caches fully preloaded
virtual bool IsAppReadyForOfflinePlay( int appID ) = 0;
virtual bool IsAppReadyForOfflinePlay(int appID) = 0;
// interface for custom pack files > 4Gb
virtual bool AddPackFile( const char *fullpath, const char *pathID ) = 0;
// open a file but force the data to come from the steam cache, NOT from disk
virtual FileHandle_t OpenFromCacheForRead( const char *pFileName, const char *pOptions, const char *pathID = 0L ) = 0;
virtual bool AddPackFile(const char *fullpath, const char *pathID) = 0;
virtual void AddSearchPathNoWrite( const char *pPath, const char *pathID ) = 0;
// open a file but force the data to come from the steam cache, NOT from disk
virtual FileHandle_t OpenFromCacheForRead(const char *pFileName, const char *pOptions, const char *pathID = 0L) = 0;
virtual void AddSearchPathNoWrite(const char *pPath, const char *pathID) = 0;
};
// Steam3/Src compat
#define IBaseFileSystem IFileSystem
#define FILESYSTEM_INTERFACE_VERSION "VFileSystem009"
#endif // FILESYSTEM_H

View File

@ -28,16 +28,20 @@
#pragma once
#include "maintypes.h"
#include "interface.h"
#ifdef _WIN32
#define ENGINE_LIB "swds.dll"
#else
#define ENGINE_LIB "engine_i486.so"
#endif // _WIN32
class IDedicatedServerAPI : public IBaseInterface
{
public:
virtual bool Init(char *basedir, char *cmdline, CreateInterfaceFn launcherFactory, CreateInterfaceFn filesystemFactory) = 0;
virtual int Shutdown(void) = 0;
virtual bool RunFrame(void) = 0;
virtual int Shutdown() = 0;
virtual bool RunFrame() = 0;
virtual void AddConsoleText(char *text) = 0;
virtual void UpdateStatus(float *fps, int *nActive, int *nMaxPlayers, char *pszMap) = 0;
};

View File

@ -26,19 +26,21 @@
*
*/
#ifndef ENGINE_LAUNCHER_API_H
#define ENGINE_LAUNCHER_API_H
#ifdef _WIN32
#pragma once
#endif
#include "maintypes.h"
#include "interface.h"
#ifdef _WIN32
#define ENGINE_CLIENT_LIB "hw.dll" // OpenGL/D3D video mode
#define ENGINE_CLIENT_SOFT_LIB "sw.dll" // Software video mode
#else
#define ENGINE_CLIENT_LIB "hw.so"
#endif // _WIN32
class IEngineAPI : public IBaseInterface
{
public:
virtual int Run(void *instance, char *basedir, char *cmdline, char *postRestartCmdLineArgs, CreateInterfaceFn launcherFactory, CreateInterfaceFn filesystemFactory) = 0;
};
#endif // ENGINE_LAUNCHER_API_H
#define VENGINE_LAUNCHER_API_VERSION "VENGINE_LAUNCHER_API_VERSION002"

47
public/icommandline.h Normal file
View File

@ -0,0 +1,47 @@
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
// Interface to engine command line
class ICommandLine {
public:
virtual void CreateCmdLine(const char *commandline) = 0;
virtual void CreateCmdLine(int argc, const char **argv) = 0;
virtual const char *GetCmdLine() const = 0;
// Check whether a particular parameter exists
virtual const char *CheckParm(const char *psz, char **ppszValue = nullptr) const = 0;
virtual void RemoveParm(const char *pszParm) = 0;
virtual void AppendParm(const char *pszParm, const char *pszValues) = 0;
virtual void SetParm(const char *pszParm, const char *pszValues) = 0;
virtual void SetParm(const char *pszParm, int iValue) = 0;
};
ICommandLine *CommandLine();

View File

@ -1,25 +1,40 @@
//========= Copyright 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#ifndef IDEDICATEDEXPORTS_H
#define IDEDICATEDEXPORTS_H
#ifdef _WIN32
#pragma once
#endif
#include "interface.h"
class IDedicatedExports : IBaseInterface
class IDedicatedExports : public IBaseInterface
{
public:
virtual ~IDedicatedExports() { };
virtual ~IDedicatedExports() {};
virtual void Sys_Printf(char *text) = 0;
};
#define VENGINE_DEDICATEDEXPORTS_API_VERSION "VENGINE_DEDICATEDEXPORTS_API_VERSION001"
#endif // IDEDICATEDEXPORTS_H

View File

@ -1,25 +1,98 @@
#include "precompiled.h"
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#if !defined ( _WIN32 )
#include "interface.h"
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif // _WIN32
// InterfaceReg
InterfaceReg *InterfaceReg::s_pInterfaceRegs = nullptr;
InterfaceReg::InterfaceReg(InstantiateInterfaceFn fn, const char *pName) : m_pName(pName)
{
m_CreateFn = fn;
m_pNext = s_pInterfaceRegs;
s_pInterfaceRegs = this;
}
// This is the primary exported function by a dll, referenced by name via dynamic binding
// that exposes an opqaue function pointer to the interface.
//
// We have the Internal variant so Sys_GetFactoryThis() returns the correct internal
// symbol under GCC/Linux/Mac as CreateInterface is DLL_EXPORT so its global so the loaders
// on those OS's pick exactly 1 of the CreateInterface symbols to be the one that is process wide and
// all Sys_GetFactoryThis() calls find that one, which doesn't work. Using the internal walkthrough here
// makes sure Sys_GetFactoryThis() has the dll specific symbol and GetProcAddress() returns the module specific
// function for CreateInterface again getting the dll specific symbol we need.
EXPORT_FUNCTION IBaseInterface *CreateInterface(const char *pName, int *pReturnCode)
{
InterfaceReg *pCur;
for (pCur = InterfaceReg::s_pInterfaceRegs; pCur; pCur = pCur->m_pNext)
{
if (strcmp(pCur->m_pName, pName) == 0)
{
if (pReturnCode)
{
*pReturnCode = IFACE_OK;
}
return pCur->m_CreateFn();
}
}
if (pReturnCode)
{
*pReturnCode = IFACE_FAILED;
}
return nullptr;
}
#ifndef _WIN32
// Linux doesn't have this function so this emulates its functionality
//
//
void *GetModuleHandle(const char *name)
{
void *handle;
if (name == NULL)
if (name == nullptr)
{
// hmm, how can this be handled under linux....
// is it even needed?
return NULL;
return nullptr;
}
if ((handle=dlopen(name, RTLD_NOW)) == NULL)
if ((handle = dlopen(name, RTLD_NOW)) == nullptr)
{
//printf("Error:%s\n",dlerror());
// couldn't open this file
return NULL;
return nullptr;
}
// read "man dlopen" for details
@ -28,151 +101,67 @@ void *GetModuleHandle(const char *name)
dlclose(handle);
return handle;
}
#endif
#endif // _WIN32
// ------------------------------------------------------------------------------------ //
// InterfaceReg.
// ------------------------------------------------------------------------------------ //
InterfaceReg *InterfaceReg::s_pInterfaceRegs = NULL;
InterfaceReg::InterfaceReg( InstantiateInterfaceFn fn, const char *pName ) : m_pName(pName)
{
m_CreateFn = fn;
m_pNext = s_pInterfaceRegs;
s_pInterfaceRegs = this;
}
// ------------------------------------------------------------------------------------ //
// CreateInterface.
// ------------------------------------------------------------------------------------ //
EXPORT_FUNCTION IBaseInterface *CreateInterface( const char *pName, int *pReturnCode )
{
InterfaceReg *pCur;
for(pCur=InterfaceReg::s_pInterfaceRegs; pCur; pCur=pCur->m_pNext)
{
if(strcmp(pCur->m_pName, pName) == 0)
{
if ( pReturnCode )
{
*pReturnCode = IFACE_OK;
}
return pCur->m_CreateFn();
}
}
if ( pReturnCode )
{
*pReturnCode = IFACE_FAILED;
}
return NULL;
}
#ifdef LINUX
static IBaseInterface *CreateInterfaceLocal( const char *pName, int *pReturnCode )
{
InterfaceReg *pCur;
for(pCur=InterfaceReg::s_pInterfaceRegs; pCur; pCur=pCur->m_pNext)
{
if(strcmp(pCur->m_pName, pName) == 0)
{
if ( pReturnCode )
{
*pReturnCode = IFACE_OK;
}
return pCur->m_CreateFn();
}
}
if ( pReturnCode )
{
*pReturnCode = IFACE_FAILED;
}
return NULL;
}
#endif
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif
//-----------------------------------------------------------------------------
// Purpose: returns a pointer to a function, given a module
// Input : pModuleName - module name
// *pName - proc name
//-----------------------------------------------------------------------------
//static hlds_run wants to use this function
void *Sys_GetProcAddress( const char *pModuleName, const char *pName )
//static hlds_run wants to use this function
void *Sys_GetProcAddress(const char *pModuleName, const char *pName)
{
return GetProcAddress( GetModuleHandle(pModuleName), pName );
return GetProcAddress(GetModuleHandle(pModuleName), pName);
}
//-----------------------------------------------------------------------------
// Purpose: returns a pointer to a function, given a module
// Input : pModuleName - module name
// *pName - proc name
//-----------------------------------------------------------------------------
// hlds_run wants to use this function
void *Sys_GetProcAddress( void *pModuleHandle, const char *pName )
// hlds_run wants to use this function
void *Sys_GetProcAddress(void *pModuleHandle, const char *pName)
{
#if defined ( _WIN32 )
return GetProcAddress( (HINSTANCE)pModuleHandle, pName );
#else
return GetProcAddress( pModuleHandle, pName );
#endif
return GetProcAddress((HMODULE)pModuleHandle, pName);
}
//-----------------------------------------------------------------------------
// Purpose: Loads a DLL/component from disk and returns a handle to it
// Input : *pModuleName - filename of the component
// Output : opaque handle to the module (hides system dependency)
//-----------------------------------------------------------------------------
CSysModule *Sys_LoadModule( const char *pModuleName )
CSysModule *Sys_LoadModule(const char *pModuleName)
{
#if defined ( _WIN32 )
HMODULE hDLL = LoadLibrary( pModuleName );
#ifdef _WIN32
HMODULE hDLL = LoadLibrary(pModuleName);
#else
HMODULE hDLL = NULL;
HMODULE hDLL = nullptr;
char szAbsoluteModuleName[1024];
szAbsoluteModuleName[0] = 0;
if ( pModuleName[0] != '/' )
if (pModuleName[0] != '/')
{
char szCwd[1024];
char szAbsoluteModuleName[1024];
getcwd(szCwd, sizeof(szCwd));
if (szCwd[strlen(szCwd) - 1] == '/')
szCwd[strlen(szCwd) - 1] = '\0';
getcwd( szCwd, sizeof( szCwd ) );
if ( szCwd[ strlen( szCwd ) - 1 ] == '/' )
szCwd[ strlen( szCwd ) - 1 ] = 0;
_snprintf( szAbsoluteModuleName, sizeof(szAbsoluteModuleName), "%s/%s", szCwd, pModuleName );
hDLL = dlopen( szAbsoluteModuleName, RTLD_NOW );
_snprintf(szAbsoluteModuleName, sizeof(szAbsoluteModuleName), "%s/%s", szCwd, pModuleName);
hDLL = dlopen(szAbsoluteModuleName, RTLD_NOW);
}
else
{
_snprintf( szAbsoluteModuleName, sizeof(szAbsoluteModuleName), "%s", pModuleName );
hDLL = dlopen( pModuleName, RTLD_NOW );
_snprintf(szAbsoluteModuleName, sizeof(szAbsoluteModuleName), "%s", pModuleName);
hDLL = dlopen(pModuleName, RTLD_NOW);
}
#endif
#endif // _WIN32
if( !hDLL )
if (!hDLL)
{
char str[512];
#if defined ( _WIN32 )
_snprintf( str, sizeof(str), "%s.dll", pModuleName );
hDLL = LoadLibrary( str );
#if defined(_WIN32)
_snprintf(str, sizeof(str), "%s.dll", pModuleName);
hDLL = LoadLibrary(str);
#elif defined(OSX)
printf("Error:%s\n",dlerror());
_snprintf( str, sizeof(str), "%s.dylib", szAbsoluteModuleName );
hDLL = dlopen(str, RTLD_NOW);
printf("Error: %s\n", dlerror());
_snprintf(str, sizeof(str), "%s.dylib", szAbsoluteModuleName);
hDLL = dlopen(str, RTLD_NOW);
#else
printf("Error:%s\n",dlerror());
_snprintf( str, sizeof(str), "%s.so", szAbsoluteModuleName );
printf("Error: %s\n", dlerror());
_snprintf(str, sizeof(str), "%s.so", szAbsoluteModuleName);
hDLL = dlopen(str, RTLD_NOW);
#endif
}
@ -180,83 +169,68 @@ CSysModule *Sys_LoadModule( const char *pModuleName )
return reinterpret_cast<CSysModule *>(hDLL);
}
//-----------------------------------------------------------------------------
// Purpose: Unloads a DLL/component from
// Input : *pModuleName - filename of the component
// Output : opaque handle to the module (hides system dependency)
//-----------------------------------------------------------------------------
void Sys_UnloadModule( CSysModule *pModule )
void Sys_UnloadModule(CSysModule *pModule)
{
if ( !pModule )
if (!pModule)
return;
HMODULE hDLL = reinterpret_cast<HMODULE>(pModule);
#if defined ( _WIN32 )
FreeLibrary( hDLL );
#else
dlclose((void *)hDLL);
#endif
#ifdef _WIN32
FreeLibrary(hDLL);
#else
dlclose(hDLL);
#endif // _WIN32
}
//-----------------------------------------------------------------------------
// Purpose: returns a pointer to a function, given a module
// Input : module - windows HMODULE from Sys_LoadModule()
// Input : module - windows HMODULE from Sys_LoadModule()
// *pName - proc name
// Output : factory for this module
//-----------------------------------------------------------------------------
CreateInterfaceFn Sys_GetFactory( CSysModule *pModule )
CreateInterfaceFn Sys_GetFactory(CSysModule *pModule)
{
if ( !pModule )
return NULL;
if (!pModule)
return nullptr;
HMODULE hDLL = reinterpret_cast<HMODULE>(pModule);
#if defined ( _WIN32 )
return reinterpret_cast<CreateInterfaceFn>(GetProcAddress( hDLL, CREATEINTERFACE_PROCNAME ));
#else
// Linux gives this error:
//../public/interface.cpp: In function `IBaseInterface *(*Sys_GetFactory
//(CSysModule *)) (const char *, int *)':
//../public/interface.cpp:154: ISO C++ forbids casting between
//pointer-to-function and pointer-to-object
//
// so lets get around it :)
return (CreateInterfaceFn)(GetProcAddress( hDLL, CREATEINTERFACE_PROCNAME ));
#endif
return reinterpret_cast<CreateInterfaceFn>(Sys_GetProcAddress(pModule, CREATEINTERFACE_PROCNAME));
}
//-----------------------------------------------------------------------------
// Purpose: returns the instance of this module
// Output : interface_instance_t
//-----------------------------------------------------------------------------
CreateInterfaceFn Sys_GetFactoryThis( void )
// Output : CreateInterfaceFn
CreateInterfaceFn Sys_GetFactoryThis()
{
#ifdef LINUX
return CreateInterfaceLocal;
#else
return CreateInterface;
#endif
}
//-----------------------------------------------------------------------------
// Purpose: returns the instance of the named module
// Input : *pModuleName - name of the module
// Output : interface_instance_t - instance of that module
//-----------------------------------------------------------------------------
CreateInterfaceFn Sys_GetFactory( const char *pModuleName )
// Output : CreateInterfaceFn - instance of that module
CreateInterfaceFn Sys_GetFactory(const char *pModuleName)
{
#if defined ( _WIN32 )
return static_cast<CreateInterfaceFn>( Sys_GetProcAddress( pModuleName, CREATEINTERFACE_PROCNAME ) );
#else
// Linux gives this error:
//../public/interface.cpp: In function `IBaseInterface *(*Sys_GetFactory
//(const char *)) (const char *, int *)':
//../public/interface.cpp:186: invalid static_cast from type `void *' to
//type `IBaseInterface *(*) (const char *, int *)'
//
// so lets use the old style cast.
return (CreateInterfaceFn)( Sys_GetProcAddress( pModuleName, CREATEINTERFACE_PROCNAME ) );
#endif
return reinterpret_cast<CreateInterfaceFn>(Sys_GetProcAddress(pModuleName, CREATEINTERFACE_PROCNAME));
}
// Purpose: finds a particular interface in the factory set
void *InitializeInterface(char const *interfaceName, CreateInterfaceFn *factoryList, int numFactories)
{
void *retval;
for (int i = 0; i < numFactories; i++)
{
CreateInterfaceFn factory = factoryList[ i ];
if (!factory)
continue;
retval = factory(interfaceName, nullptr);
if (retval)
return retval;
}
// No provider for requested interface!!!
// assert(!"No provider for requested interface!!!");
return nullptr;
}

View File

@ -1,4 +1,3 @@
// This header defines the interface convention used in the valve engine.
// To make an interface and expose it:
// 1. Derive from IBaseInterface.
@ -8,22 +7,17 @@
// Versioning
// There are two versioning cases that are handled by this:
// 1. You add functions to the end of an interface, so it is binary compatible with the previous interface. In this case,
// 1. You add functions to the end of an interface, so it is binary compatible with the previous interface. In this case,
// you need two EXPOSE_INTERFACEs: one to expose your class as the old interface and one to expose it as the new interface.
// 2. You update an interface so it's not compatible anymore (but you still want to be able to expose the old interface
// for legacy code). In this case, you need to make a new version name for your new interface, and make a wrapper interface and
// 2. You update an interface so it's not compatible anymore (but you still want to be able to expose the old interface
// for legacy code). In this case, you need to make a new version name for your new interface, and make a wrapper interface and
// expose it for the old interface.
//#if _MSC_VER >= 1300 // VC7
//#include "tier1/interface.h"
//#else
#pragma once
#ifndef INTERFACE_H
#define INTERFACE_H
#ifndef _WIN32
#if !defined ( _WIN32 )
#include <dlfcn.h> // dlopen,dlclose, et al
#include <dlfcn.h> // dlopen, dlclose, et al
#include <unistd.h>
#define HMODULE void *
@ -31,7 +25,7 @@
#define _snprintf snprintf
#endif
#endif // _WIN32
void *Sys_GetProcAddress(const char *pModuleName, const char *pName);
void *Sys_GetProcAddress(void *pModuleHandle, const char *pName);
@ -40,17 +34,13 @@ void *Sys_GetProcAddress(void *pModuleHandle, const char *pName);
class IBaseInterface
{
public:
virtual ~IBaseInterface() {}
virtual ~IBaseInterface() {}
};
#define CREATEINTERFACE_PROCNAME "CreateInterface"
#define CREATEINTERFACE_PROCNAME "CreateInterface"
typedef IBaseInterface* (*CreateInterfaceFn)(const char *pName, int *pReturnCode);
typedef IBaseInterface* (*InstantiateInterfaceFn)();
typedef IBaseInterface *(*CreateInterfaceFn)(const char *pName, int *pReturnCode);
typedef IBaseInterface *(*InstantiateInterfaceFn)();
// Used internally to register classes.
class InterfaceReg
@ -60,19 +50,18 @@ public:
public:
InstantiateInterfaceFn m_CreateFn;
const char *m_pName;
InstantiateInterfaceFn m_CreateFn;
const char *m_pName;
InterfaceReg *m_pNext; // For the global list.
static InterfaceReg *s_pInterfaceRegs;
InterfaceReg *m_pNext; // For the global list.
static InterfaceReg *s_pInterfaceRegs;
};
// Use this to expose an interface that can have multiple instances.
// e.g.:
// EXPOSE_INTERFACE( CInterfaceImp, IInterface, "MyInterface001" )
// EXPOSE_INTERFACE(CInterfaceImp, IInterface, "MyInterface001")
// This will expose a class called CInterfaceImp that implements IInterface (a pure class)
// clients can receive a pointer to this class by calling CreateInterface( "MyInterface001" )
// clients can receive a pointer to this class by calling CreateInterface("MyInterface001")
//
// In practice, the shared header file defines the interface (IInterface) and version name ("MyInterface001")
// so that each component can use these names/vtables to communicate
@ -80,71 +69,55 @@ public:
// A single class can support multiple interfaces through multiple inheritance
//
// Use this if you want to write the factory function.
#define EXPOSE_INTERFACE_FN(functionName, interfaceName, versionName) \
#define EXPOSE_INTERFACE_FN(functionName, interfaceName, versionName)\
static InterfaceReg __g_Create##className##_reg(functionName, versionName);
#define EXPOSE_INTERFACE(className, interfaceName, versionName) \
static IBaseInterface* __Create##className##_interface() {return (interfaceName *)new className;}\
static InterfaceReg __g_Create##className##_reg(__Create##className##_interface, versionName );
#define EXPOSE_INTERFACE(className, interfaceName, versionName)\
static IBaseInterface *__Create##className##_interface() {return (interfaceName *)new className;}\
static InterfaceReg __g_Create##className##_reg(__Create##className##_interface, versionName);
// Use this to expose a singleton interface with a global variable you've created.
#define EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, globalVarName) \
static IBaseInterface* __Create##className##interfaceName##_interface() {return (IBaseInterface *)&globalVarName;}\
#define EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, globalVarName)\
static IBaseInterface *__Create##className##interfaceName##_interface() {return (IBaseInterface *)&globalVarName;}\
static InterfaceReg __g_Create##className##interfaceName##_reg(__Create##className##interfaceName##_interface, versionName);
// Use this to expose a singleton interface. This creates the global variable for you automatically.
#define EXPOSE_SINGLE_INTERFACE(className, interfaceName, versionName) \
#define EXPOSE_SINGLE_INTERFACE(className, interfaceName, versionName)\
static className __g_##className##_singleton;\
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, __g_##className##_singleton)
#ifdef _WIN32
#define EXPORT_FUNCTION __declspec(dllexport)
#else
#define EXPORT_FUNCTION __attribute__ ((visibility("default")))
#endif
#define EXPORT_FUNCTION __attribute__((visibility("default")))
#endif // _WIN32
// This function is automatically exported and allows you to access any interfaces exposed with the above macros.
// if pReturnCode is set, it will return one of the following values
// extend this for other error conditions/code
enum
enum
{
IFACE_OK = 0,
IFACE_FAILED
};
extern "C"
{
EXPORT_FUNCTION IBaseInterface* CreateInterface(const char *pName, int *pReturnCode);
EXPORT_FUNCTION IBaseInterface *CreateInterface(const char *pName, int *pReturnCode);
};
extern CreateInterfaceFn Sys_GetFactoryThis();
extern CreateInterfaceFn Sys_GetFactoryThis( void );
//-----------------------------------------------------------------------------
// UNDONE: This is obsolete, use the module load/unload/get instead!!!
//-----------------------------------------------------------------------------
extern CreateInterfaceFn Sys_GetFactory( const char *pModuleName );
extern CreateInterfaceFn Sys_GetFactory(const char *pModuleName);
// load/unload components
class CSysModule;
//-----------------------------------------------------------------------------
// Load & Unload should be called in exactly one place for each module
// The factory for that module should be passed on to dependent components for
// proper versioning.
//-----------------------------------------------------------------------------
extern CSysModule *Sys_LoadModule( const char *pModuleName );
extern void Sys_UnloadModule( CSysModule *pModule );
extern CreateInterfaceFn Sys_GetFactory( CSysModule *pModule );
#endif
//#endif // MSVC 6.0
extern CSysModule *Sys_LoadModule(const char *pModuleName);
extern void Sys_UnloadModule(CSysModule *pModule);
extern CreateInterfaceFn Sys_GetFactory(CSysModule *pModule);
extern void *InitializeInterface(char const *interfaceName, CreateInterfaceFn *factoryList, int numFactories);

View File

@ -121,4 +121,4 @@
#define K_MOUSE4 244
#define K_MOUSE5 245
#endif // KEYDEFS_H
#endif // KEYDEFS_H

View File

@ -194,4 +194,4 @@ public:
};
#endif//PARTICLEMEM_H__
#endif//PARTICLEMEM_H__

View File

@ -1,20 +1,35 @@
//========= Copyright 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
/*
*
* 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 2 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#if !defined( SAVEGAME_VERSION_H )
#define SAVEGAME_VERSION_H
#ifdef _WIN32
#pragma once
#endif
#include "commonmacros.h"
#define SAVEFILE_HEADER MAKEID('V','A','L','V') // little-endian "VALV"
#define SAVEGAME_HEADER MAKEID('J','S','A','V') // little-endian "JSAV"
#define SAVEGAME_VERSION 0x0071 // Version 0.71
#endif // SAVEGAME_VERSION_H
#define SAVEGAME_VERSION 0x0071 // Version 0.71

435
public/tier0/dbg.cpp Normal file
View File

@ -0,0 +1,435 @@
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// The main debug library implementation
//=============================================================================
#include "precompiled.h"
//-----------------------------------------------------------------------------
// internal structures
//-----------------------------------------------------------------------------
enum
{
MAX_GROUP_NAME_LENGTH = 48
};
struct SpewGroup_t
{
char m_GroupName[MAX_GROUP_NAME_LENGTH];
int m_Level;
};
//-----------------------------------------------------------------------------
// Templates to assist in validating pointers:
void _AssertValidReadPtr(void* ptr, int count/* = 1*/)
{
#ifdef _WIN32
Assert(!IsBadReadPtr(ptr, count));
#else
Assert(ptr);
#endif
}
void _AssertValidWritePtr(void* ptr, int count/* = 1*/)
{
#ifdef _WIN32
Assert(!IsBadWritePtr(ptr, count));
#else
Assert(ptr);
#endif
}
void _AssertValidReadWritePtr(void* ptr, int count/* = 1*/)
{
#ifdef _WIN32
Assert(!(IsBadWritePtr(ptr, count) || IsBadReadPtr(ptr, count)));
#else
Assert(ptr);
#endif
}
void AssertValidStringPtr(const char* ptr, int maxchar/* = 0xFFFFFF */)
{
#ifdef _WIN32
Assert(!IsBadStringPtr(ptr, maxchar));
#else
Assert(ptr);
#endif
}
//-----------------------------------------------------------------------------
// globals
//-----------------------------------------------------------------------------
SpewRetval_t DefaultSpewFunc(SpewType_t type, char const *pMsg)
{
printf("%s", pMsg);
if (type == SPEW_ASSERT)
return SPEW_DEBUGGER;
else if (type == SPEW_ERROR)
return SPEW_ABORT;
else
return SPEW_CONTINUE;
}
static SpewOutputFunc_t s_SpewOutputFunc = DefaultSpewFunc;
static char const* s_pFileName;
static int s_Line;
static SpewType_t s_SpewType;
static SpewGroup_t* s_pSpewGroups = 0;
static int s_GroupCount = 0;
static int s_DefaultLevel = 0;
//-----------------------------------------------------------------------------
// Spew output management.
//-----------------------------------------------------------------------------
void SpewOutputFunc(SpewOutputFunc_t func)
{
s_SpewOutputFunc = func ? func : DefaultSpewFunc;
}
SpewOutputFunc_t GetSpewOutputFunc(void)
{
if (s_SpewOutputFunc)
{
return s_SpewOutputFunc;
}
else
{
return DefaultSpewFunc;
}
}
//-----------------------------------------------------------------------------
// Spew functions
//-----------------------------------------------------------------------------
void _SpewInfo(SpewType_t type, char const* pFile, int line)
{
// Only grab the file name. Ignore the path.
char const* pSlash = strrchr(pFile, '\\');
char const* pSlash2 = strrchr(pFile, '/');
if (pSlash < pSlash2) pSlash = pSlash2;
s_pFileName = pSlash ? pSlash + 1 : pFile;
s_Line = line;
s_SpewType = type;
}
SpewRetval_t _SpewMessage(SpewType_t spewType, char const* pMsgFormat, va_list args)
{
char pTempBuffer[1024];
/* Printf the file and line for warning + assert only... */
int len = 0;
if ((spewType == SPEW_ASSERT))
{
len = sprintf(pTempBuffer, "%s (%d) : ", s_pFileName, s_Line);
}
/* Create the message.... */
len += vsprintf(&pTempBuffer[len], pMsgFormat, args);
// Add \n for warning and assert
if ((spewType == SPEW_ASSERT))
{
len += sprintf(&pTempBuffer[len], "\n");
}
assert(len < 1024); /* use normal assert here; to avoid recursion. */
assert(s_SpewOutputFunc);
/* direct it to the appropriate target(s) */
SpewRetval_t ret = s_SpewOutputFunc(spewType, pTempBuffer);
switch (ret)
{
// Put the break into the macro so it would occur in the right place
// case SPEW_DEBUGGER:
// DebuggerBreak();
// break;
case SPEW_ABORT:
// MessageBox(NULL,"Error in _SpewMessage","Error",MB_OK);
exit(0);
default:
break;
}
return ret;
}
SpewRetval_t _SpewMessage(char const* pMsgFormat, ...)
{
va_list args;
va_start(args, pMsgFormat);
SpewRetval_t ret = _SpewMessage(s_SpewType, pMsgFormat, args);
va_end(args);
return ret;
}
SpewRetval_t _DSpewMessage(char const *pGroupName, int level, char const* pMsgFormat, ...)
{
if (!IsSpewActive(pGroupName, level))
return SPEW_CONTINUE;
va_list args;
va_start(args, pMsgFormat);
SpewRetval_t ret = _SpewMessage(s_SpewType, pMsgFormat, args);
va_end(args);
return ret;
}
void Msg(char const* pMsgFormat, ...)
{
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_MESSAGE, pMsgFormat, args);
va_end(args);
}
void DMsg(char const *pGroupName, int level, char const *pMsgFormat, ...)
{
if (!IsSpewActive(pGroupName, level))
return;
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_MESSAGE, pMsgFormat, args);
va_end(args);
}
void Warning(char const *pMsgFormat, ...)
{
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_WARNING, pMsgFormat, args);
va_end(args);
}
void DWarning(char const *pGroupName, int level, char const *pMsgFormat, ...)
{
if (!IsSpewActive(pGroupName, level))
return;
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_WARNING, pMsgFormat, args);
va_end(args);
}
void Log(char const *pMsgFormat, ...)
{
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_LOG, pMsgFormat, args);
va_end(args);
}
void DLog(char const *pGroupName, int level, char const *pMsgFormat, ...)
{
if (!IsSpewActive(pGroupName, level))
return;
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_LOG, pMsgFormat, args);
va_end(args);
}
void Error(char const *pMsgFormat, ...)
{
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_ERROR, pMsgFormat, args);
va_end(args);
}
//-----------------------------------------------------------------------------
// A couple of super-common dynamic spew messages, here for convenience
// These looked at the "developer" group, print if it's level 1 or higher
//-----------------------------------------------------------------------------
void DevMsg(int level, char const* pMsgFormat, ...)
{
if (!IsSpewActive("developer", level))
return;
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_MESSAGE, pMsgFormat, args);
va_end(args);
}
void DevWarning(int level, char const *pMsgFormat, ...)
{
if (!IsSpewActive("developer", level))
return;
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_WARNING, pMsgFormat, args);
va_end(args);
}
void DevLog(int level, char const *pMsgFormat, ...)
{
if (!IsSpewActive("developer", level))
return;
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_LOG, pMsgFormat, args);
va_end(args);
}
void DevMsg(char const *pMsgFormat, ...)
{
if (!IsSpewActive("developer", 1))
return;
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_MESSAGE, pMsgFormat, args);
va_end(args);
}
void DevWarning(char const *pMsgFormat, ...)
{
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_WARNING, pMsgFormat, args);
va_end(args);
}
void DevLog(char const *pMsgFormat, ...)
{
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_LOG, pMsgFormat, args);
va_end(args);
}
//-----------------------------------------------------------------------------
// Find a group, return true if found, false if not. Return in ind the
// index of the found group, or the index of the group right before where the
// group should be inserted into the list to maintain sorted order.
//-----------------------------------------------------------------------------
bool FindSpewGroup(char const* pGroupName, int* pInd)
{
int s = 0;
if (s_GroupCount)
{
int e = (int)(s_GroupCount - 1);
while (s <= e)
{
int m = (s + e) >> 1;
int cmp = Q_stricmp(pGroupName, s_pSpewGroups[m].m_GroupName);
if (!cmp)
{
*pInd = m;
return true;
}
if (cmp < 0)
e = m - 1;
else
s = m + 1;
}
}
*pInd = s;
return false;
}
//-----------------------------------------------------------------------------
// Sets the priority level for a spew group
//-----------------------------------------------------------------------------
void SpewActivate(char const* pGroupName, int level)
{
Assert(pGroupName);
// check for the default group first...
if ((pGroupName[0] == '*') && (pGroupName[1] == '\0'))
{
s_DefaultLevel = level;
return;
}
// Normal case, search in group list using binary search.
// If not found, grow the list of groups and insert it into the
// right place to maintain sorted order. Then set the level.
int ind;
if (!FindSpewGroup(pGroupName, &ind))
{
// not defined yet, insert an entry.
++s_GroupCount;
if (s_pSpewGroups)
{
s_pSpewGroups = (SpewGroup_t*)realloc(s_pSpewGroups,
s_GroupCount * sizeof(SpewGroup_t));
// shift elements down to preserve order
int numToMove = s_GroupCount - ind - 1;
memmove(&s_pSpewGroups[ind + 1], &s_pSpewGroups[ind],
numToMove * sizeof(SpewGroup_t));
}
else
s_pSpewGroups = (SpewGroup_t*)malloc(s_GroupCount * sizeof(SpewGroup_t));
Assert(strlen(pGroupName) < MAX_GROUP_NAME_LENGTH);
strcpy(s_pSpewGroups[ind].m_GroupName, pGroupName);
}
s_pSpewGroups[ind].m_Level = level;
}
//-----------------------------------------------------------------------------
// Tests to see if a particular spew is active
//-----------------------------------------------------------------------------
bool IsSpewActive(char const* pGroupName, int level)
{
// If we don't find the spew group, use the default level.
int ind;
if (FindSpewGroup(pGroupName, &ind))
return s_pSpewGroups[ind].m_Level >= level;
else
return s_DefaultLevel >= level;
}
// If we don't have a function from math.h, then it doesn't link certain floating-point
// functions in and printfs with %f cause runtime errors in the C libraries.
float CrackSmokingCompiler(float a)
{
return fabs(a);
}
void* Plat_SimpleLog(const char* file, int line)
{
FILE* f = fopen("simple.log", "at+");
fprintf(f, "%s:%i\n", file, line);
fclose(f);
return NULL;
}

453
public/tier0/dbg.h Normal file
View File

@ -0,0 +1,453 @@
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// The main debug library interfaces
//=============================================================================
#ifndef DBG_H
#define DBG_H
#ifdef _WIN32
#pragma once
#endif
#include "osconfig.h"
#include "basetypes.h"
#include "tier0/platform.h"
#include <math.h>
#include <stdio.h>
#include <stdarg.h>
//-----------------------------------------------------------------------------
// dll export stuff
//-----------------------------------------------------------------------------
#ifdef TIER0_DLL_EXPORT
#define DBG_INTERFACE DLL_EXPORT
#define DBG_OVERLOAD DLL_GLOBAL_EXPORT
#define DBG_CLASS DLL_CLASS_EXPORT
#else
#define DBG_INTERFACE DLL_IMPORT
#define DBG_OVERLOAD DLL_GLOBAL_IMPORT
#define DBG_CLASS DLL_CLASS_IMPORT
#endif
//-----------------------------------------------------------------------------
// Usage model for the Dbg library
//
// 1. Spew.
//
// Spew can be used in a static and a dynamic mode. The static
// mode allows us to display assertions and other messages either only
// in debug builds, or in non-release builds. The dynamic mode allows us to
// turn on and off certain spew messages while the application is running.
//
// Static Spew messages:
//
// Assertions are used to detect and warn about invalid states
// Spews are used to display a particular status/warning message.
//
// To use an assertion, use
//
// Assert( (f == 5) );
// AssertMsg( (f == 5), ("F needs to be %d here!\n", 5) );
// AssertFunc( (f == 5), BadFunc() );
// AssertEquals( f, 5 );
// AssertFloatEquals( f, 5.0f, 1e-3 );
//
// The first will simply report that an assertion failed on a particular
// code file and line. The second version will display a print-f formatted message
// along with the file and line, the third will display a generic message and
// will also cause the function BadFunc to be executed, and the last two
// will report an error if f is not equal to 5 (the last one asserts within
// a particular tolerance).
//
// To use a warning, use
//
// Warning("Oh I feel so %s all over\n", "yummy");
//
// Warning will do its magic in only Debug builds. To perform spew in *all*
// builds, use RelWarning.
//
// Three other spew types, Msg, Log, and Error, are compiled into all builds.
// These error types do *not* need two sets of parenthesis.
//
// Msg( "Isn't this exciting %d?", 5 );
// Error( "I'm just thrilled" );
//
// Dynamic Spew messages
//
// It is possible to dynamically turn spew on and off. Dynamic spew is
// identified by a spew group and priority level. To turn spew on for a
// particular spew group, use SpewActivate( "group", level ). This will
// cause all spew in that particular group with priority levels <= the
// level specified in the SpewActivate function to be printed. Use DSpew
// to perform the spew:
//
// DWarning( "group", level, "Oh I feel even yummier!\n" );
//
// Priority level 0 means that the spew will *always* be printed, and group
// '*' is the default spew group. If a DWarning is encountered using a group
// whose priority has not been set, it will use the priority of the default
// group. The priority of the default group is initially set to 0.
//
// Spew output
//
// The output of the spew system can be redirected to an externally-supplied
// function which is responsible for outputting the spew. By default, the
// spew is simply printed using printf.
//
// To redirect spew output, call SpewOutput.
//
// SpewOutputFunc( OutputFunc );
//
// This will cause OutputFunc to be called every time a spew message is
// generated. OutputFunc will be passed a spew type and a message to print.
// It must return a value indicating whether the debugger should be invoked,
// whether the program should continue running, or whether the program
// should abort.
//
// 2. Code activation
//
// To cause code to be run only in debug builds, use DBG_CODE:
// An example is below.
//
// DBG_CODE(
// {
// int x = 5;
// ++x;
// }
// );
//
// Code can be activated based on the dynamic spew groups also. Use
//
// DBG_DCODE( "group", level,
// { int x = 5; ++x; }
// );
//
// 3. Breaking into the debugger.
//
// To cause an unconditional break into the debugger in debug builds only, use DBG_BREAK
//
// DBG_BREAK();
//
// You can force a break in any build (release or debug) using
//
// DebuggerBreak();
//-----------------------------------------------------------------------------
/* Various types of spew messages */
// I'm sure you're asking yourself why SPEW_ instead of DBG_ ?
// It's because DBG_ is used all over the place in windows.h
// For example, DBG_CONTINUE is defined. Feh.
enum SpewType_t
{
SPEW_MESSAGE = 0,
SPEW_WARNING,
SPEW_ASSERT,
SPEW_ERROR,
SPEW_LOG,
SPEW_TYPE_COUNT
};
enum SpewRetval_t
{
SPEW_DEBUGGER = 0,
SPEW_CONTINUE,
SPEW_ABORT
};
/* type of externally defined function used to display debug spew */
typedef SpewRetval_t(*SpewOutputFunc_t)(SpewType_t spewType, char const *pMsg);
/* Used to redirect spew output */
void SpewOutputFunc(SpewOutputFunc_t func);
/* Used ot get the current spew output function */
SpewOutputFunc_t GetSpewOutputFunc(void);
/* Used to manage spew groups and subgroups */
void SpewActivate(char const* pGroupName, int level);
bool IsSpewActive(char const* pGroupName, int level);
/* Used to display messages, should never be called directly. */
void _SpewInfo(SpewType_t type, char const* pFile, int line);
SpewRetval_t _SpewMessage(char const* pMsg, ...);
SpewRetval_t _DSpewMessage(char const *pGroupName, int level, char const* pMsg, ...);
/* Used to define macros, never use these directly. */
#define _Assert( _exp ) do { \
if (!(_exp)) \
{ \
_SpewInfo( SPEW_ASSERT, __FILE__, __LINE__ ); \
if (_SpewMessage("Assertion Failed: " #_exp) == SPEW_DEBUGGER) \
{ \
DebuggerBreak(); \
} \
} \
} while (0)
#define _AssertMsg( _exp, _msg ) do { \
if (!(_exp)) \
{ \
_SpewInfo( SPEW_ASSERT, __FILE__, __LINE__ ); \
if (_SpewMessage(_msg) == SPEW_DEBUGGER) \
{ \
DebuggerBreak(); \
} \
} \
} while (0)
#define _AssertFunc( _exp, _f ) do { \
if (!(_exp)) \
{ \
_SpewInfo( SPEW_ASSERT, __FILE__, __LINE__ ); \
SpewRetval_t ret = _SpewMessage("Assertion Failed!" #_exp); \
_f; \
if (ret == SPEW_DEBUGGER) \
{ \
DebuggerBreak(); \
} \
} \
} while (0)
#define _AssertEquals( _exp, _expectedValue ) \
do { \
if ((_exp) != (_expectedValue)) \
{ \
_SpewInfo( SPEW_ASSERT, __FILE__, __LINE__ ); \
SpewRetval_t ret = _SpewMessage("Expected %d but got %d!", (_expectedValue), (_exp)); \
if (ret == SPEW_DEBUGGER) \
{ \
DebuggerBreak(); \
} \
} \
} while (0)
#define _AssertFloatEquals( _exp, _expectedValue, _tol ) \
do { \
if (fabs((_exp) - (_expectedValue)) > (_tol)) \
{ \
_SpewInfo( SPEW_ASSERT, __FILE__, __LINE__ ); \
SpewRetval_t ret = _SpewMessage("Expected %f but got %f!", (_expectedValue), (_exp)); \
if (ret == SPEW_DEBUGGER) \
{ \
DebuggerBreak(); \
} \
} \
} while (0)
/* Spew macros... */
#ifdef _DEBUG
#define Assert( _exp ) _Assert( _exp )
#define AssertMsg( _exp, _msg ) _AssertMsg( _exp, _msg )
#define AssertFunc( _exp, _f ) _AssertFunc( _exp, _f )
#define AssertEquals( _exp, _expectedValue ) _AssertEquals( _exp, _expectedValue )
#define AssertFloatEquals( _exp, _expectedValue, _tol ) _AssertFloatEquals( _exp, _expectedValue, _tol )
#define Verify( _exp ) _Assert( _exp )
#define AssertMsg1( _exp, _msg, a1 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1 ) )
#define AssertMsg2( _exp, _msg, a1, a2 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2 ) )
#define AssertMsg3( _exp, _msg, a1, a2, a3 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3 ) )
#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3, a4 ) )
#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3, a4, a5 ) )
#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 ) )
#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 ) )
#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7 ) )
#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) )
#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) )
#else /* Not _DEBUG */
#define Assert( _exp ) ((void)0)
#define AssertMsg( _exp, _msg ) ((void)0)
#define AssertFunc( _exp, _f ) ((void)0)
#define AssertEquals( _exp, _expectedValue ) ((void)0)
#define AssertFloatEquals( _exp, _expectedValue, _tol ) ((void)0)
#define Verify( _exp ) (_exp)
#define AssertMsg1( _exp, _msg, a1 ) ((void)0)
#define AssertMsg2( _exp, _msg, a1, a2 ) ((void)0)
#define AssertMsg3( _exp, _msg, a1, a2, a3 ) ((void)0)
#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) ((void)0)
#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) ((void)0)
#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0)
#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0)
#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) ((void)0)
#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) ((void)0)
#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) ((void)0)
#endif /* _DEBUG */
/* These are always compiled in */
void Msg(char const* pMsg, ...);
void DMsg(char const *pGroupName, int level, char const *pMsg, ...);
void Warning(char const *pMsg, ...);
void DWarning(char const *pGroupName, int level, char const *pMsg, ...);
void Log(char const *pMsg, ...);
void DLog(char const *pGroupName, int level, char const *pMsg, ...);
void Error(char const *pMsg, ...);
// You can use this macro like a runtime assert macro.
// If the condition fails, then Error is called with the message. This macro is called
// like AssertMsg, where msg must be enclosed in parenthesis:
//
// ErrorIfNot( bCondition, ("a b c %d %d %d", 1, 2, 3) );
#define ErrorIfNot( condition, msg ) \
if ( (condition) ) \
; \
else \
{ \
Error msg; \
}
/* A couple of super-common dynamic spew messages, here for convenience */
/* These looked at the "developer" group */
void DevMsg(int level, char const* pMsg, ...);
void DevWarning(int level, char const *pMsg, ...);
void DevLog(int level, char const *pMsg, ...);
/* default level versions (level 1) */
void DevMsg(char const* pMsg, ...);
void DevWarning(char const *pMsg, ...);
void DevLog(char const *pMsg, ...);
/* Code macros, debugger interface */
#ifdef _DEBUG
#define DBG_CODE( _code ) if (0) ; else { _code }
#define DBG_DCODE( _g, _l, _code ) if (IsSpewActive( _g, _l )) { _code } else {}
#define DBG_BREAK() DebuggerBreak() /* defined in platform.h */
#else /* not _DEBUG */
#define DBG_CODE( _code ) ((void)0)
#define DBG_DCODE( _g, _l, _code ) ((void)0)
#define DBG_BREAK() ((void)0)
#endif /* _DEBUG */
//-----------------------------------------------------------------------------
// Macro to assist in asserting constant invariants during compilation
#define UID_PREFIX generated_id_
#define UID_CAT1(a,c) a ## c
#define UID_CAT2(a,c) UID_CAT1(a,c)
#define UNIQUE_ID UID_CAT2(UID_PREFIX,__LINE__)
#ifdef _DEBUG
#define COMPILE_TIME_ASSERT( pred ) switch(0){case 0:case pred:;}
#define ASSERT_INVARIANT( pred ) static void UNIQUE_ID() { COMPILE_TIME_ASSERT( pred ) }
#else
#define COMPILE_TIME_ASSERT( pred )
#define ASSERT_INVARIANT( pred )
#endif
//-----------------------------------------------------------------------------
// Templates to assist in validating pointers:
// Have to use these stubs so we don't have to include windows.h here.
void _AssertValidReadPtr(void* ptr, int count = 1);
void _AssertValidWritePtr(void* ptr, int count = 1);
void _AssertValidReadWritePtr(void* ptr, int count = 1);
void AssertValidStringPtr(const char* ptr, int maxchar = 0xFFFFFF);
template<class T> inline void AssertValidReadPtr(T* ptr, int count = 1) { _AssertValidReadPtr((void*)ptr, count); }
template<class T> inline void AssertValidWritePtr(T* ptr, int count = 1) { _AssertValidWritePtr((void*)ptr, count); }
template<class T> inline void AssertValidReadWritePtr(T* ptr, int count = 1) { _AssertValidReadWritePtr((void*)ptr, count); }
#define AssertValidThis() AssertValidReadWritePtr(this,sizeof(*this))
//-----------------------------------------------------------------------------
// Macro to protect functions that are not reentrant
#ifdef _DEBUG
class CReentryGuard
{
public:
CReentryGuard(int *pSemaphore)
: m_pSemaphore(pSemaphore)
{
++(*m_pSemaphore);
}
~CReentryGuard()
{
--(*m_pSemaphore);
}
private:
int *m_pSemaphore;
};
#define ASSERT_NO_REENTRY() \
static int fSemaphore##__LINE__; \
Assert( !fSemaphore##__LINE__ ); \
CReentryGuard ReentryGuard##__LINE__( &fSemaphore##__LINE__ )
#else
#define ASSERT_NO_REENTRY()
#endif
//-----------------------------------------------------------------------------
//
// Purpose: Inline string formatter
//
class CDbgFmtMsg
{
public:
CDbgFmtMsg(const char *pszFormat, ...)
{
va_list arg_ptr;
va_start(arg_ptr, pszFormat);
_vsnprintf(m_szBuf, sizeof(m_szBuf) - 1, pszFormat, arg_ptr);
va_end(arg_ptr);
m_szBuf[sizeof(m_szBuf) - 1] = 0;
}
operator const char *() const
{
return m_szBuf;
}
private:
char m_szBuf[256];
};
//-----------------------------------------------------------------------------
//
// Purpose: Embed debug info in each file.
//
//#ifdef _WIN32
//#ifdef _DEBUG
//#pragma comment(compiler)
//#pragma comment(exestr,"*** DEBUG file detected, Last Compile: " __DATE__ ", " __TIME__ " ***")
//#endif
//#endif
#endif /* DBG_H */

37
public/tier0/mem.h Normal file
View File

@ -0,0 +1,37 @@
//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose: Memory allocation!
//
// $NoKeywords: $
//=============================================================================
#ifndef TIER0_MEM_H
#define TIER0_MEM_H
#ifdef _WIN32
#pragma once
#endif
#include "osconfig.h"
#include <stddef.h>
#include "tier0/platform.h"
#ifdef TIER0_DLL_EXPORT
# define MEM_INTERFACE DLL_EXPORT
#else
# define MEM_INTERFACE DLL_IMPORT
#endif
//-----------------------------------------------------------------------------
// DLL-exported methods for particular kinds of memory
//-----------------------------------------------------------------------------
MEM_INTERFACE void *MemAllocScratch(int nMemSize);
MEM_INTERFACE void MemFreeScratch();
#ifdef __linux__
MEM_INTERFACE void ZeroMemory(void *mem, size_t length);
#endif
#endif /* TIER0_MEM_H */

77
public/tier0/memalloc.h Normal file
View File

@ -0,0 +1,77 @@
//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose: This header should never be used directly from leaf code!!!
// Instead, just add the file memoverride.cpp into your project and all this
// will automagically be used
//
// $NoKeywords: $
//=============================================================================
#ifndef TIER0_MEMALLOC_H
#define TIER0_MEMALLOC_H
#ifdef _WIN32
#pragma once
#endif
#include "osconfig.h"
#include <stddef.h>
#include "tier0/mem.h"
struct _CrtMemState;
//-----------------------------------------------------------------------------
// NOTE! This should never be called directly from leaf code
// Just use new,delete,malloc,free etc. They will call into this eventually
//-----------------------------------------------------------------------------
class IMemAlloc
{
public:
// Release versions
virtual void *Alloc(size_t nSize) = 0;
virtual void *Realloc(void *pMem, size_t nSize) = 0;
virtual void Free(void *pMem) = 0;
virtual void *Expand(void *pMem, size_t nSize) = 0;
// Debug versions
virtual void *Alloc(size_t nSize, const char *pFileName, int nLine) = 0;
virtual void *Realloc(void *pMem, size_t nSize, const char *pFileName, int nLine) = 0;
virtual void Free(void *pMem, const char *pFileName, int nLine) = 0;
virtual void *Expand(void *pMem, size_t nSize, const char *pFileName, int nLine) = 0;
// Returns size of a particular allocation
virtual size_t GetSize(void *pMem) = 0;
// Force file + line information for an allocation
virtual void PushAllocDbgInfo(const char *pFileName, int nLine) = 0;
virtual void PopAllocDbgInfo() = 0;
// FIXME: Remove when we have our own allocator
// these methods of the Crt debug code is used in our codebase currently
virtual long CrtSetBreakAlloc(long lNewBreakAlloc) = 0;
virtual int CrtSetReportMode(int nReportType, int nReportMode) = 0;
virtual int CrtIsValidHeapPointer(const void *pMem) = 0;
virtual int CrtCheckMemory(void) = 0;
virtual int CrtSetDbgFlag(int nNewFlag) = 0;
virtual void CrtMemCheckpoint(_CrtMemState *pState) = 0;
// FIXME: Make a better stats interface
virtual void DumpStats() = 0;
// FIXME: Remove when we have our own allocator
virtual void* CrtSetReportFile(int nRptType, void* hFile) = 0;
virtual void* CrtSetReportHook(void* pfnNewHook) = 0;
virtual int CrtDbgReport(int nRptType, const char * szFile,
int nLine, const char * szModule, const char * pMsg) = 0;
virtual int heapchk() = 0;
};
//-----------------------------------------------------------------------------
// Singleton interface
//-----------------------------------------------------------------------------
IMemAlloc *g_pMemAlloc;
#endif /* TIER0_MEMALLOC_H */

21
public/tier0/memdbgoff.h Normal file
View File

@ -0,0 +1,21 @@
//========= Copyright © 1996-2003, Valve LLC, All rights reserved. ============
//
// Purpose: This header, which must be the final line of a .h file,
// causes all crt methods to stop using debugging versions of the memory allocators.
// NOTE: Use memdbgon.h to re-enable memory debugging.
//
// $NoKeywords: $
//=============================================================================
#ifdef MEM_DEBUG_ON
#undef malloc
#undef realloc
#undef calloc
#undef free
#undef _expand
#undef _msize
#undef new
#undef MEM_DEBUG_ON
#endif

93
public/tier0/memdbgon.h Normal file
View File

@ -0,0 +1,93 @@
//========= Copyright © 1996-2003, Valve LLC, All rights reserved. ============
//
// Purpose: This header, which must be the final include in a .cpp (or .h) file,
// causes all crt methods to use debugging versions of the memory allocators.
// NOTE: Use memdbgoff.h to disable memory debugging.
//
// $NoKeywords: $
//=============================================================================
// SPECIAL NOTE! This file must *not* use include guards; we need to be able
// to include this potentially multiple times (since we can deactivate debugging
// by including memdbgoff.h)
// SPECIAL NOTE #2: This must be the final include in a .cpp or .h file!!!
#include "osconfig.h"
#ifdef _DEBUG
#include <tchar.h>
#include <string.h>
#include <malloc.h>
#include <crtdbg.h>
#include "tier0/memdbgoff.h"
#define MEM_DEBUG_ON 1
#undef malloc
#undef realloc
#undef calloc
#undef _expand
#undef free
#undef _msize
#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
#define calloc(c, s) _calloc_dbg(c, s, _NORMAL_BLOCK, __FILE__, __LINE__)
#define realloc(p, s) _realloc_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__)
#define free(p) _free_dbg(p, _NORMAL_BLOCK)
#define _msize(p) _msize_dbg(p, _NORMAL_BLOCK)
#define _expand(p, s) _expand_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__)
#if defined(__AFX_H__) && defined(DEBUG_NEW)
#define new DEBUG_NEW
#else
#undef new
#define MEMALL_DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new MEMALL_DEBUG_NEW
#endif
#undef _strdup
#undef strdup
#undef _wcsdup
#undef wcsup
#define _strdup(s) strdup_dbg(s, __FILE__, __LINE__)
#define strdup(s) strdup_dbg(s, __FILE__, __LINE__)
#define _wcsdup(s) wcsdup_dbg(s, __FILE__, __LINE__)
#define wcsdup(s) wcsdup_dbg(s, __FILE__, __LINE__)
// Make sure we don't define strdup twice
#ifndef MEM_DBG_DEFINED_STRDUP
#define MEM_DBG_DEFINED_STRDUP 1
inline char *strdup_dbg(const char *pString, const char *pFileName, unsigned nLine)
{
char *pMemory;
if (!pString)
return NULL;
if ((pMemory = (char *)_malloc_dbg(strlen(pString) + 1, _NORMAL_BLOCK, pFileName, nLine)) != NULL)
return strcpy(pMemory, pString);
return NULL;
}
inline wchar_t *wcsdup_dbg(const wchar_t *pString, const char *pFileName, unsigned nLine)
{
wchar_t *pMemory;
if (!pString)
return NULL;
if ((pMemory = (wchar_t *)_malloc_dbg((wcslen(pString) + 1) * sizeof(wchar_t), _NORMAL_BLOCK, pFileName, nLine)) != NULL)
return wcscpy(pMemory, pString);
return NULL;
}
#endif // DBMEM_DEFINED_STRDUP
#endif // _DEBUG

630
public/tier0/platform.h Normal file
View File

@ -0,0 +1,630 @@
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// Extremely low-level platform-specific stuff
//=============================================================================
#ifndef PLATFORM_H
#define PLATFORM_H
#ifdef _WIN32
#pragma once
#endif
#include "osconfig.h"
// need this for _alloca
#include <malloc.h>
// need this for memset
#include <string.h>
#include "archtypes.h"
typedef float float32;
typedef double float64;
// for when we don't care about how many bits we use
typedef unsigned int uint;
// This can be used to ensure the size of pointers to members when declaring
// a pointer type for a class that has only been forward declared
#ifdef _MSC_VER
#define SINGLE_INHERITANCE __single_inheritance
#define MULTIPLE_INHERITANCE __multiple_inheritance
#else
#define SINGLE_INHERITANCE
#define MULTIPLE_INHERITANCE
#endif
/*
FIXME: Enable this when we no longer fear change =)
// need these for the limits
#include <limits.h>
#include <float.h>
// Maximum and minimum representable values
#define INT8_MAX SCHAR_MAX
#define INT16_MAX SHRT_MAX
#define INT32_MAX LONG_MAX
#define INT64_MAX (((int64)~0) >> 1)
#define INT8_MIN SCHAR_MIN
#define INT16_MIN SHRT_MIN
#define INT32_MIN LONG_MIN
#define INT64_MIN (((int64)1) << 63)
#define UINT8_MAX ((uint8)~0)
#define UINT16_MAX ((uint16)~0)
#define UINT32_MAX ((uint32)~0)
#define UINT64_MAX ((uint64)~0)
#define UINT8_MIN 0
#define UINT16_MIN 0
#define UINT32_MIN 0
#define UINT64_MIN 0
#ifndef UINT_MIN
#define UINT_MIN UINT32_MIN
#endif
#define FLOAT32_MAX FLT_MAX
#define FLOAT64_MAX DBL_MAX
#define FLOAT32_MIN FLT_MIN
#define FLOAT64_MIN DBL_MIN
*/
// portability / compiler settings
#if defined(_WIN32) && !defined(WINDED)
#if defined(_M_IX86)
#define __i386__ 1
#endif
#elif __linux__
typedef void * HINSTANCE;
#define _MAX_PATH PATH_MAX
#endif // defined(_WIN32) && !defined(WINDED)
// Defines MAX_PATH
#ifndef MAX_PATH
#define MAX_PATH 260
#endif
// Used to step into the debugger
#define DebuggerBreak() __asm { int 3 }
// C functions for external declarations that call the appropriate C++ methods
#ifndef EXPORT
#ifdef _WIN32
#define EXPORT _declspec( dllexport )
#else
#define EXPORT /* */
#endif
#endif
#if defined __i386__ && !defined __linux__
#define id386 1
#else
#define id386 0
#endif // __i386__
#ifdef _WIN32
// Used for dll exporting and importing
#define DLL_EXPORT extern "C" __declspec( dllexport )
#define DLL_IMPORT extern "C" __declspec( dllimport )
// Can't use extern "C" when DLL exporting a class
#define DLL_CLASS_EXPORT __declspec( dllexport )
#define DLL_CLASS_IMPORT __declspec( dllimport )
// Can't use extern "C" when DLL exporting a global
#define DLL_GLOBAL_EXPORT extern __declspec( dllexport )
#define DLL_GLOBAL_IMPORT extern __declspec( dllimport )
#elif defined __linux__
// Used for dll exporting and importing
#define DLL_EXPORT extern "C"
#define DLL_IMPORT extern "C"
// Can't use extern "C" when DLL exporting a class
#define DLL_CLASS_EXPORT
#define DLL_CLASS_IMPORT
// Can't use extern "C" when DLL exporting a global
#define DLL_GLOBAL_EXPORT extern
#define DLL_GLOBAL_IMPORT extern
#else
#error "Unsupported Platform."
#endif
// Used for standard calling conventions
#ifdef _WIN32
#define FASTCALL __fastcall
#define FORCEINLINE __forceinline
#else
#define FASTCALL
#define FORCEINLINE inline
#endif
// Force a function call site -not- to inlined. (useful for profiling)
#define DONT_INLINE(a) (((int)(a)+1)?(a):(a))
// Pass hints to the compiler to prevent it from generating unnessecary / stupid code
// in certain situations. Several compilers other than MSVC also have an equivilent
// construct.
//
// Essentially the 'Hint' is that the condition specified is assumed to be true at
// that point in the compilation. If '0' is passed, then the compiler assumes that
// any subsequent code in the same 'basic block' is unreachable, and thus usually
// removed.
#ifdef _MSC_VER
#define HINT(THE_HINT) __assume((THE_HINT))
#else
#define HINT(THE_HINT) 0
#endif
// Marks the codepath from here until the next branch entry point as unreachable,
// and asserts if any attempt is made to execute it.
#define UNREACHABLE() { Assert(0); HINT(0); }
// In cases where no default is present or appropriate, this causes MSVC to generate
// as little code as possible, and throw an assertion in debug.
#define NO_DEFAULT default: UNREACHABLE();
#ifdef _WIN32
// Alloca defined for this platform
#define stackalloc( _size ) _alloca( _size )
#define stackfree( _p ) 0
#elif __linux__
// Alloca defined for this platform
#define stackalloc( _size ) alloca( _size )
#define stackfree( _p ) 0
#endif
#ifdef _WIN32
// Remove warnings from warning level 4.
#pragma warning(disable : 4514) // warning C4514: 'acosl' : unreferenced inline function has been removed
#pragma warning(disable : 4100) // warning C4100: 'hwnd' : unreferenced formal parameter
#pragma warning(disable : 4127) // warning C4127: conditional expression is constant
#pragma warning(disable : 4512) // warning C4512: 'InFileRIFF' : assignment operator could not be generated
#pragma warning(disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable
#pragma warning(disable : 4706) // warning C4706: assignment within conditional expression
#pragma warning(disable : 4710) // warning C4710: function 'x' not inlined
#pragma warning(disable : 4702) // warning C4702: unreachable code
#pragma warning(disable : 4505) // unreferenced local function has been removed
#pragma warning(disable : 4239) // nonstandard extension used : 'argument' ( conversion from class Vector to class Vector& )
#pragma warning(disable : 4097) // typedef-name 'BaseClass' used as synonym for class-name 'CFlexCycler::CBaseFlex'
#pragma warning(disable : 4324) // Padding was added at the end of a structure
#pragma warning(disable : 4244) // type conversion warning.
#pragma warning(disable : 4305) // truncation from 'const double ' to 'float '
#pragma warning(disable : 4786) // Disable warnings about long symbol names
#if _MSC_VER >= 1300
#pragma warning(disable : 4511) // Disable warnings about private copy constructors
#endif
#endif
//-----------------------------------------------------------------------------
// Purpose: Standard functions for handling endian-ness
//-----------------------------------------------------------------------------
//-------------------------------------
// Basic swaps
//-------------------------------------
template <typename T>
inline T WordSwapC(T w)
{
uint16 temp;
temp = ((*((uint16 *)&w) & 0xff00) >> 8);
temp |= ((*((uint16 *)&w) & 0x00ff) << 8);
return *((T*)&temp);
}
template <typename T>
inline T DWordSwapC(T dw)
{
uint32 temp;
temp = *((uint32 *)&dw) >> 24;
temp |= ((*((uint32 *)&dw) & 0x00FF0000) >> 8);
temp |= ((*((uint32 *)&dw) & 0x0000FF00) << 8);
temp |= ((*((uint32 *)&dw) & 0x000000FF) << 24);
return *((T*)&temp);
}
//-------------------------------------
// Fast swaps
//-------------------------------------
#ifdef _MSC_VER
#define WordSwap WordSwapAsm
#define DWordSwap DWordSwapAsm
#pragma warning(push)
#pragma warning (disable:4035) // no return value
template <typename T>
inline T WordSwapAsm(T w)
{
__asm
{
mov ax, w
xchg al, ah
}
}
template <typename T>
inline T DWordSwapAsm(T dw)
{
__asm
{
mov eax, dw
bswap eax
}
}
#pragma warning(pop)
// The assembly implementation is not compatible with floats
template <>
inline float DWordSwapAsm<float>(float f)
{
return DWordSwapC(f);
}
#else
#define WordSwap WordSwapC
#define DWordSwap DWordSwapC
#endif
//-------------------------------------
// The typically used methods.
//-------------------------------------
#if defined(__i386__)
#define VALVE_LITTLE_ENDIAN 1
#endif
#ifdef _SGI_SOURCE
#define VALVE_BIG_ENDIAN 1
#endif
#if defined(VALVE_LITTLE_ENDIAN)
#define Valve_BigShort( val ) WordSwap( val )
#define Valve_BigWord( val ) WordSwap( val )
#define Valve_BigLong( val ) DWordSwap( val )
#define Valve_BigDWord( val ) DWordSwap( val )
#define Valve_BigFloat( val ) DWordSwap( val )
#define Valve_LittleShort( val ) ( val )
#define Valve_LittleWord( val ) ( val )
#define Valve_LittleLong( val ) ( val )
#define Valve_LittleDWord( val ) ( val )
#define Valve_LittleFloat( val ) ( val )
#elif defined(BIG_ENDIAN)
#define Valve_BigShort( val ) ( val )
#define Valve_BigWord( val ) ( val )
#define Valve_BigLong( val ) ( val )
#define Valve_BigDWord( val ) ( val )
#define Valve_BigFloat( val ) ( val )
#define Valve_LittleShort( val ) WordSwap( val )
#define Valve_LittleWord( val ) WordSwap( val )
#define Valve_LittleLong( val ) DWordSwap( val )
#define Valve_LittleDWord( val ) DWordSwap( val )
#define Valve_LittleFloat( val ) DWordSwap( val )
#else
// @Note (toml 05-02-02): this technique expects the compiler to
// optimize the expression and eliminate the other path. On any new
// platform/compiler this should be tested.
inline short BigShort(short val) { int test = 1; return (*(char *)&test == 1) ? WordSwap(val) : val; }
inline uint16 BigWord(uint16 val) { int test = 1; return (*(char *)&test == 1) ? WordSwap(val) : val; }
inline long BigLong(long val) { int test = 1; return (*(char *)&test == 1) ? DWordSwap(val) : val; }
inline uint32 BigDWord(uint32 val) { int test = 1; return (*(char *)&test == 1) ? DWordSwap(val) : val; }
inline float BigFloat(float val) { int test = 1; return (*(char *)&test == 1) ? DWordSwap(val) : val; }
inline short LittleShort(short val) { int test = 1; return (*(char *)&test == 1) ? val : WordSwap(val); }
inline uint16 LittleWord(uint16 val) { int test = 1; return (*(char *)&test == 1) ? val : WordSwap(val); }
inline long LittleLong(long val) { int test = 1; return (*(char *)&test == 1) ? val : DWordSwap(val); }
inline uint32 LittleDWord(uint32 val) { int test = 1; return (*(char *)&test == 1) ? val : DWordSwap(val); }
inline float LittleFloat(float val) { int test = 1; return (*(char *)&test == 1) ? val : DWordSwap(val); }
#endif
#ifdef TIER0_DLL_EXPORT
#define PLATFORM_INTERFACE DLL_EXPORT
#define PLATFORM_OVERLOAD DLL_GLOBAL_EXPORT
#else
#define PLATFORM_INTERFACE DLL_IMPORT
#define PLATFORM_OVERLOAD DLL_GLOBAL_IMPORT
#endif
/*
PLATFORM_INTERFACE double Plat_FloatTime(); // Returns time in seconds since the module was loaded.
PLATFORM_INTERFACE unsigned long Plat_MSTime(); // Time in milliseconds.
// b/w compatibility
#define Sys_FloatTime Plat_FloatTime
*/
// Processor Information:
struct CPUInformation
{
int m_Size; // Size of this structure, for forward compatability.
bool m_bRDTSC : 1, // Is RDTSC supported?
m_bCMOV : 1, // Is CMOV supported?
m_bFCMOV : 1, // Is FCMOV supported?
m_bSSE : 1, // Is SSE supported?
m_bSSE2 : 1, // Is SSE2 Supported?
m_b3DNow : 1, // Is 3DNow! Supported?
m_bMMX : 1, // Is MMX supported?
m_bHT : 1; // Is HyperThreading supported?
unsigned char m_nLogicalProcessors, // Number op logical processors.
m_nPhysicalProcessors; // Number of physical processors
int64 m_Speed; // In cycles per second.
char* m_szProcessorID; // Processor vendor Identification.
};
PLATFORM_INTERFACE const CPUInformation& GetCPUInformation();
//-----------------------------------------------------------------------------
// Thread related functions
//-----------------------------------------------------------------------------
// Registers the current thread with Tier0's thread management system.
// This should be called on every thread created in the game.
PLATFORM_INTERFACE unsigned long Plat_RegisterThread(const char *pName = "Source Thread");
// Registers the current thread as the primary thread.
PLATFORM_INTERFACE unsigned long Plat_RegisterPrimaryThread();
// VC-specific. Sets the thread's name so it has a friendly name in the debugger.
// This should generally only be handled by Plat_RegisterThread and Plat_RegisterPrimaryThread
PLATFORM_INTERFACE void Plat_SetThreadName(unsigned long dwThreadID, const char *pName);
// These would be private if it were possible to export private variables from a .DLL.
// They need to be variables because they are checked by inline functions at performance
// critical places.
PLATFORM_INTERFACE unsigned long Plat_PrimaryThreadID;
// Returns the ID of the currently executing thread.
PLATFORM_INTERFACE unsigned long Plat_GetCurrentThreadID();
// Returns the ID of the primary thread.
inline unsigned long Plat_GetPrimaryThreadID()
{
return Plat_PrimaryThreadID;
}
// Returns true if the current thread is the primary thread.
inline bool Plat_IsPrimaryThread()
{
//return true;
return (Plat_GetPrimaryThreadID() == Plat_GetCurrentThreadID());
}
//-----------------------------------------------------------------------------
// Security related functions
//-----------------------------------------------------------------------------
// Ensure that the hardware key's drivers have been installed.
PLATFORM_INTERFACE bool Plat_VerifyHardwareKeyDriver();
// Ok, so this isn't a very secure way to verify the hardware key for now. It
// is primarially depending on the fact that all the binaries have been wrapped
// with the secure wrapper provided by the hardware keys vendor.
PLATFORM_INTERFACE bool Plat_VerifyHardwareKey();
// The same as above, but notifies user with a message box when the key isn't in
// and gives him an opportunity to correct the situation.
PLATFORM_INTERFACE bool Plat_VerifyHardwareKeyPrompt();
// Can be called in real time, doesn't perform the verify every frame. Mainly just
// here to allow the game to drop out quickly when the key is removed, rather than
// allowing the wrapper to pop up it's own blocking dialog, which the engine doesn't
// like much.
PLATFORM_INTERFACE bool Plat_FastVerifyHardwareKey();
//-----------------------------------------------------------------------------
// Include additional dependant header components.
//-----------------------------------------------------------------------------
//#include "tier0/fasttimer.h"
//-----------------------------------------------------------------------------
// Just logs file and line to simple.log
//-----------------------------------------------------------------------------
void* Plat_SimpleLog(const char* file, int line);
//#define Plat_dynamic_cast Plat_SimpleLog(__FILE__,__LINE__),dynamic_cast
//-----------------------------------------------------------------------------
// Methods to invoke the constructor, copy constructor, and destructor
//-----------------------------------------------------------------------------
template <class T>
inline void Construct(T* pMemory)
{
new(pMemory)T;
}
template <class T>
inline void CopyConstruct(T* pMemory, T const& src)
{
new(pMemory)T(src);
}
template <class T>
inline void Destruct(T* pMemory)
{
pMemory->~T();
#ifdef _DEBUG
memset(pMemory, 0xDD, sizeof(T));
#endif
}
//
// GET_OUTER()
//
// A platform-independent way for a contained class to get a pointer to its
// owner. If you know a class is exclusively used in the context of some
// "outer" class, this is a much more space efficient way to get at the outer
// class than having the inner class store a pointer to it.
//
// class COuter
// {
// class CInner // Note: this does not need to be a nested class to work
// {
// void PrintAddressOfOuter()
// {
// printf( "Outer is at 0x%x\n", GET_OUTER( COuter, m_Inner ) );
// }
// };
//
// CInner m_Inner;
// friend class CInner;
// };
#define GET_OUTER( OuterType, OuterMember ) \
( ( OuterType * ) ( (char *)this - offsetof( OuterType, OuterMember ) ) )
/* TEMPLATE_FUNCTION_TABLE()
(Note added to platform.h so platforms that correctly support templated
functions can handle portions as templated functions rather than wrapped
functions)
Helps automate the process of creating an array of function
templates that are all specialized by a single integer.
This sort of thing is often useful in optimization work.
For example, using TEMPLATE_FUNCTION_TABLE, this:
TEMPLATE_FUNCTION_TABLE(int, Function, ( int blah, int blah ), 10)
{
return argument * argument;
}
is equivilent to the following:
(NOTE: the function has to be wrapped in a class due to code
generation bugs involved with directly specializing a function
based on a constant.)
template<int argument>
class FunctionWrapper
{
public:
int Function( int blah, int blah )
{
return argument*argument;
}
}
typedef int (*FunctionType)( int blah, int blah );
class FunctionName
{
public:
enum { count = 10 };
FunctionType functions[10];
};
FunctionType FunctionName::functions[] =
{
FunctionWrapper<0>::Function,
FunctionWrapper<1>::Function,
FunctionWrapper<2>::Function,
FunctionWrapper<3>::Function,
FunctionWrapper<4>::Function,
FunctionWrapper<5>::Function,
FunctionWrapper<6>::Function,
FunctionWrapper<7>::Function,
FunctionWrapper<8>::Function,
FunctionWrapper<9>::Function
};
*/
bool vtune(bool resume);
#define TEMPLATE_FUNCTION_TABLE(RETURN_TYPE, NAME, ARGS, COUNT) \
\
typedef RETURN_TYPE (FASTCALL *__Type_##NAME) ARGS; \
\
template<const int nArgument> \
struct __Function_##NAME \
{ \
static RETURN_TYPE FASTCALL Run ARGS; \
}; \
\
template <int i> \
struct __MetaLooper_##NAME : __MetaLooper_##NAME<i-1> \
{ \
__Type_##NAME func; \
inline __MetaLooper_##NAME() { func = __Function_##NAME<i>::Run; } \
}; \
\
template<> \
struct __MetaLooper_##NAME<0> \
{ \
__Type_##NAME func; \
inline __MetaLooper_##NAME() { func = __Function_##NAME<0>::Run; } \
}; \
\
class NAME \
{ \
private: \
static const __MetaLooper_##NAME<COUNT> m; \
public: \
enum { count = COUNT }; \
static const __Type_##NAME* functions; \
}; \
const __MetaLooper_##NAME<COUNT> NAME::m; \
const __Type_##NAME* NAME::functions = (__Type_##NAME*)&m; \
template<int nArgument> \
RETURN_TYPE FASTCALL __Function_##NAME<nArgument>::Run ARGS
#define LOOP_INTERCHANGE(BOOLEAN, CODE)\
if( (BOOLEAN) )\
{\
CODE;\
} else\
{\
CODE;\
}
#endif /* PLATFORM_H */

View File

@ -0,0 +1,59 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "precompiled.h"
double Plat_FloatTime()
{
struct timeval tp;
static int secbase = 0;
gettimeofday(&tp, NULL);
if (!secbase)
{
secbase = tp.tv_sec;
return (tp.tv_usec / 1000000.0);
}
return ((tp.tv_sec - secbase) + tp.tv_usec / 1000000.0);
}
unsigned long Plat_MSTime()
{
struct timeval tp;
static int secbase = 0;
gettimeofday(&tp, NULL);
if (!secbase)
{
secbase = tp.tv_sec;
return (tp.tv_usec / 1000000.0);
}
return (unsigned long)((tp.tv_sec - secbase) + tp.tv_usec / 1000000.0);
}
bool vtune(bool resume)
{
return true;
}
// -------------------------------------------------------------------------------------------------- //
// Memory stuff.
// -------------------------------------------------------------------------------------------------- //
void Plat_SetThreadName(unsigned long dwThreadID, const char *pName)
{
Assert("Plat_SetThreadName not implemented");
}

View File

@ -0,0 +1,95 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "precompiled.h"
static LARGE_INTEGER g_PerformanceFrequency;
static LARGE_INTEGER g_MSPerformanceFrequency;
static LARGE_INTEGER g_ClockStart;
static HINSTANCE g_pVTuneDLL;
static void InitTime()
{
if (!g_PerformanceFrequency.QuadPart)
{
QueryPerformanceFrequency(&g_PerformanceFrequency);
g_MSPerformanceFrequency.QuadPart = g_PerformanceFrequency.QuadPart / 1000;
QueryPerformanceCounter(&g_ClockStart);
}
}
double Plat_FloatTime()
{
InitTime();
LARGE_INTEGER CurrentTime;
QueryPerformanceCounter(&CurrentTime);
double fRawSeconds = (double)(CurrentTime.QuadPart - g_ClockStart.QuadPart) / (double)(g_PerformanceFrequency.QuadPart);
return fRawSeconds;
}
unsigned long Plat_MSTime()
{
InitTime();
LARGE_INTEGER CurrentTime;
QueryPerformanceCounter(&CurrentTime);
return (unsigned long)((CurrentTime.QuadPart - g_ClockStart.QuadPart) / g_MSPerformanceFrequency.QuadPart);
}
void free_vtune()
{
FreeLibrary(g_pVTuneDLL);
}
bool vtune(bool resume)
{
static bool bInitialized = false;
static void(__cdecl *VTResume)(void) = NULL;
static void(__cdecl *VTPause) (void) = NULL;
// Grab the Pause and Resume function pointers from the VTune DLL the first time through:
if (!bInitialized)
{
bInitialized = true;
g_pVTuneDLL = LoadLibrary("vtuneapi.dll");
if (g_pVTuneDLL)
{
VTResume = (void(__cdecl *)())GetProcAddress(g_pVTuneDLL, "VTResume");
VTPause = (void(__cdecl *)())GetProcAddress(g_pVTuneDLL, "VTPause");
atexit(free_vtune);
}
}
// Call the appropriate function, as indicated by the argument:
if (resume && VTResume)
{
VTResume();
return true;
}
else if (!resume && VTPause)
{
VTPause();
return true;
}
return false;
}
// -------------------------------------------------------------------------------------------------- //
// Memory stuff.
// -------------------------------------------------------------------------------------------------- //

View File

@ -416,4 +416,4 @@ void CUtlBuffer::SeekPut(SeekType_t type, int offset)
m_Put = m_Memory.NumAllocated() - offset;
break;
}
}
}

View File

@ -320,4 +320,4 @@ void CUtlMemory<T>::Purge()
}
#endif // UTLSTORAGE_H
#endif // UTLSTORAGE_H

View File

@ -1119,7 +1119,7 @@ int CUtlRBTree<T, I>::Depth( I node ) const
int depthright = Depth( RightChild(node) );
int depthleft = Depth( LeftChild(node) );
return max(depthright, depthleft) + 1;
return Q_max(depthright, depthleft) + 1;
}

View File

@ -15,7 +15,7 @@ CExecMngr::CBufExec::~CBufExec()
;
}
void CExecMngr::AddElement(IGameClient *pClient, CResourceBuffer *pResource, uint32 responseHash)
void CExecMngr::Add(IGameClient *pClient, CResourceBuffer *pResource, uint32 responseHash)
{
m_execList.push_back(new CBufExec(pClient, pResource, responseHash));
}
@ -86,7 +86,7 @@ void EXT_FUNC CmdExec_hook(IGameClient *pClient, IResourceBuffer *pRes, char *cm
SERVER_COMMAND(cmdExec);
}
void CExecMngr::CommandExecute(IGameClient *pClient)
void CExecMngr::ExecuteCommand(IGameClient *pClient)
{
bool bBreak = false;
auto iter = m_execList.begin();
@ -133,6 +133,10 @@ void CExecMngr::Clear(IGameClient *pClient)
{
if (!pClient)
{
for (auto exec : m_execList) {
delete exec;
}
m_execList.clear();
return;
}

View File

@ -3,8 +3,8 @@
class CExecMngr
{
public:
void AddElement(IGameClient *pClient, CResourceBuffer *pResource, uint32 responseHash);
void CommandExecute(IGameClient *pClient);
void Add(IGameClient *pClient, CResourceBuffer *pResource, uint32 responseHash);
void ExecuteCommand(IGameClient *pClient);
void Clear(IGameClient *pClient = NULL);
private:

View File

@ -9,7 +9,7 @@ CConfig Config;
void CConfig::Init()
{
char *pos;
char path[MAX_PATH_LENGTH];
char path[MAX_PATH];
strncpy(path, GET_PLUGIN_PATH(PLID), sizeof(path) - 1);
path[sizeof(path) - 1] = '\0';
@ -73,7 +73,7 @@ void CConfig::Load()
if (fp == NULL)
{
UTIL_Printf(__FUNCTION__ ": can't find path to " FILE_INI_CONFIG "\n");
UTIL_Printf("%s: can't find path to " FILE_INI_CONFIG "\n", __func__);
return;
}

View File

@ -14,7 +14,7 @@ private:
void ResetValues();
private:
char m_PathDir[MAX_PATH_LENGTH];
char m_PathDir[MAX_PATH];
// settings
float m_DelayExec;

View File

@ -3,7 +3,6 @@
DLL_FUNCTIONS *g_pFunctionTable;
extern void ServerDeactivate_Post();
extern void ClientPutInServer_Post(edict_t *pEntity);
static DLL_FUNCTIONS gFunctionTable =
{
@ -92,7 +91,7 @@ static DLL_FUNCTIONS gFunctionTable_Post =
NULL, // pfnClientConnect
NULL, // pfnClientDisconnect
NULL, // pfnClientKill
&ClientPutInServer_Post, // pfnClientPutInServer
NULL, // pfnClientPutInServer
NULL, // pfnClientCommand
NULL, // pfnClientUserInfoChanged
NULL, // pfnServerActivate
@ -137,12 +136,12 @@ C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersi
{
if (!pFunctionTable)
{
ALERT(at_logged, __FUNCTION__ " called with null pFunctionTable");
ALERT(at_logged, "%s called with null pFunctionTable", __func__);
return FALSE;
}
else if (*interfaceVersion != INTERFACE_VERSION)
{
ALERT(at_logged, __FUNCTION__ " version mismatch; requested=%d ours=%d", *interfaceVersion, INTERFACE_VERSION);
ALERT(at_logged, "%s version mismatch; requested=%d ours=%d", __func__, *interfaceVersion, INTERFACE_VERSION);
//! Tell metamod what version we had, so it can figure out who is out of date.
*interfaceVersion = INTERFACE_VERSION;
@ -159,12 +158,12 @@ C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interface
{
if (!pFunctionTable)
{
ALERT(at_logged, __FUNCTION__ " called with null pFunctionTable");
ALERT(at_logged, "%s called with null pFunctionTable", __func__);
return FALSE;
}
else if (*interfaceVersion != INTERFACE_VERSION)
{
ALERT(at_logged, __FUNCTION__ " version mismatch; requested=%d ours=%d", *interfaceVersion, INTERFACE_VERSION);
ALERT(at_logged, "%s version mismatch; requested=%d ours=%d", __func__, *interfaceVersion, INTERFACE_VERSION);
//! Tell metamod what version we had, so it can figure out who is out of date.
*interfaceVersion = INTERFACE_VERSION;

View File

@ -1,6 +1,6 @@
#include "precompiled.h"
enginefuncs_t meta_engfuncs_post =
enginefuncs_t meta_engfuncs_post =
{
NULL, // pfnPrecacheModel()
NULL, // pfnPrecacheSound()
@ -216,12 +216,12 @@ C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int
{
if (!pengfuncsFromEngine)
{
ALERT(at_logged, __FUNCTION__ " called with null pengfuncsFromEngine");
ALERT(at_logged, "%s called with null pengfuncsFromEngine", __func__);
return FALSE;
}
else if (*interfaceVersion != ENGINE_INTERFACE_VERSION)
{
ALERT(at_logged, __FUNCTION__ " version mismatch; requested=%d ours=%d", *interfaceVersion, ENGINE_INTERFACE_VERSION);
ALERT(at_logged, "%s version mismatch; requested=%d ours=%d", __func__, *interfaceVersion, ENGINE_INTERFACE_VERSION);
// Tell metamod what version we had, so it can figure out who is out of date.
*interfaceVersion = ENGINE_INTERFACE_VERSION;
return FALSE;

View File

@ -8,11 +8,7 @@ IRehldsServerData *g_RehldsServerData;
rehlds_ret RehldsApi_Init()
{
#ifdef WIN32
CSysModule *engineModule = Sys_LoadModule("swds.dll");
#else
CSysModule *engineModule = Sys_LoadModule("engine_i486.so");
#endif // WIN32
CSysModule *engineModule = Sys_LoadModule(ENGINE_LIB);
if (!engineModule)
return RETURN_NOT_FOUND;
@ -26,7 +22,7 @@ rehlds_ret RehldsApi_Init()
if (!g_RehldsApi)
{
UTIL_LogPrintf(__FUNCTION__ " : REHLDS can't find Interface API\n");
UTIL_LogPrintf("%s : REHLDS can't find Interface API\n", __func__);
return RETURN_NOT_FOUND;
}
@ -35,13 +31,13 @@ rehlds_ret RehldsApi_Init()
if (majorVersion != REHLDS_API_VERSION_MAJOR)
{
UTIL_LogPrintf(__FUNCTION__ " : REHLDS Api major version mismatch; expected %d, real %d\n", REHLDS_API_VERSION_MAJOR, majorVersion);
UTIL_LogPrintf("%s : REHLDS Api major version mismatch; expected %d, real %d\n", __func__, REHLDS_API_VERSION_MAJOR, majorVersion);
return RETURN_MAJOR_MISMATCH;
}
if (minorVersion < REHLDS_API_VERSION_MINOR)
{
UTIL_LogPrintf(__FUNCTION__ " : REHLDS Api minor version mismatch; expected at least %d, real %d\n", REHLDS_API_VERSION_MINOR, minorVersion);
UTIL_LogPrintf("%s : REHLDS Api minor version mismatch; expected at least %d, real %d\n", __func__, REHLDS_API_VERSION_MINOR, minorVersion);
return RETURN_MINOR_MISMATCH;
}

View File

@ -21,13 +21,13 @@
AbstractHookChainRegistry::AbstractHookChainRegistry()
{
memset(m_Hooks, 0, sizeof(m_Hooks));
memset(m_Priorities, 0, sizeof(m_Priorities));
Q_memset(m_Hooks, 0, sizeof(m_Hooks));
Q_memset(m_Priorities, 0, sizeof(m_Priorities));
m_NumHooks = 0;
}
bool AbstractHookChainRegistry::findHook(void* hookFunc) const
bool AbstractHookChainRegistry::findHook(void *hookFunc) const
{
for (auto i = 0; i < m_NumHooks; i++) {
if (m_Hooks[i] == hookFunc)
@ -37,14 +37,14 @@ bool AbstractHookChainRegistry::findHook(void* hookFunc) const
return false;
}
void AbstractHookChainRegistry::addHook(void* hookFunc, int priority)
void AbstractHookChainRegistry::addHook(void *hookFunc, int priority)
{
if (!hookFunc) {
Sys_Error(__FUNCTION__ " Parameter hookFunc can't be a nullptr");
Sys_Error("%s: Parameter hookFunc can't be a nullptr", __func__);
}
if (findHook(hookFunc)) {
Sys_Error(__FUNCTION__ " The same handler can't be used twice on the hookchain.");
Sys_Error("%s: The same handler can't be used twice on the hookchain.", __func__);
}
for (auto i = 0; i < MAX_HOOKS_IN_CHAIN; i++)
@ -63,13 +63,13 @@ void AbstractHookChainRegistry::addHook(void* hookFunc, int priority)
}
if (m_NumHooks >= MAX_HOOKS_IN_CHAIN) {
Sys_Error(__FUNCTION__ " MAX_HOOKS_IN_CHAIN limit hit");
Sys_Error("%s: MAX_HOOKS_IN_CHAIN limit hit", __func__);
}
m_NumHooks++;
}
void AbstractHookChainRegistry::removeHook(void* hookFunc) {
void AbstractHookChainRegistry::removeHook(void *hookFunc) {
// erase hook
for (auto i = 0; i < m_NumHooks; i++)
@ -79,8 +79,8 @@ void AbstractHookChainRegistry::removeHook(void* hookFunc) {
--m_NumHooks;
if (m_NumHooks != i)
{
memmove(&m_Hooks[i], &m_Hooks[i + 1], (m_NumHooks - i) * sizeof(m_Hooks[0]));
memmove(&m_Priorities[i], &m_Priorities[i + 1], (m_NumHooks - i) * sizeof(m_Priorities[0]));
Q_memmove(&m_Hooks[i], &m_Hooks[i + 1], (m_NumHooks - i) * sizeof(m_Hooks[0]));
Q_memmove(&m_Priorities[i], &m_Priorities[i + 1], (m_NumHooks - i) * sizeof(m_Priorities[0]));
m_Hooks[m_NumHooks] = NULL;
}
else

View File

@ -28,19 +28,19 @@
#pragma once
#include "hookchains.h"
#define MAX_HOOKS_IN_CHAIN 19
const int MAX_HOOKS_IN_CHAIN = 19;
// Implementation for chains in modules
template<typename t_ret, typename ...t_args>
class IHookChainImpl : public IHookChain<t_ret, t_args...> {
class IHookChainImpl: public IHookChain<t_ret, t_args...> {
public:
typedef t_ret(*hookfunc_t)(IHookChain<t_ret, t_args...>*, t_args...);
typedef t_ret(*origfunc_t)(t_args...);
typedef t_ret (*hookfunc_t)(IHookChain<t_ret, t_args...> *, t_args...);
typedef t_ret (*origfunc_t)(t_args...);
IHookChainImpl(void** hooks, origfunc_t orig) : m_Hooks(hooks), m_OriginalFunc(orig)
IHookChainImpl(void **hooks, origfunc_t orig) : m_Hooks(hooks), m_OriginalFunc(orig)
{
if (orig == NULL)
Sys_Error(__FUNCTION__ ": Non-void HookChain without original function.");
Sys_Error("%s: Non-void HookChain without original function.", __func__);
}
virtual ~IHookChainImpl() {}
@ -62,18 +62,18 @@ public:
}
private:
void** m_Hooks;
void **m_Hooks;
origfunc_t m_OriginalFunc;
};
// Implementation for void chains in modules
template<typename ...t_args>
class IVoidHookChainImpl : public IVoidHookChain<t_args...> {
class IVoidHookChainImpl: public IVoidHookChain<t_args...> {
public:
typedef void(*hookfunc_t)(IVoidHookChain<t_args...>*, t_args...);
typedef void(*origfunc_t)(t_args...);
typedef void (*hookfunc_t)(IVoidHookChain<t_args...> *, t_args...);
typedef void (*origfunc_t)(t_args...);
IVoidHookChainImpl(void** hooks, origfunc_t orig) : m_Hooks(hooks), m_OriginalFunc(orig) {}
IVoidHookChainImpl(void **hooks, origfunc_t orig) : m_Hooks(hooks), m_OriginalFunc(orig) {}
virtual ~IVoidHookChainImpl() {}
virtual void callNext(t_args... args) {
@ -97,20 +97,20 @@ public:
}
private:
void** m_Hooks;
void **m_Hooks;
origfunc_t m_OriginalFunc;
};
class AbstractHookChainRegistry {
protected:
void* m_Hooks[MAX_HOOKS_IN_CHAIN + 1]; // +1 for null
void *m_Hooks[MAX_HOOKS_IN_CHAIN + 1]; // +1 for null
int m_Priorities[MAX_HOOKS_IN_CHAIN + 1];
int m_NumHooks;
protected:
void addHook(void* hookFunc, int priority);
bool findHook(void* hookFunc) const;
void removeHook(void* hookFunc);
void addHook(void *hookFunc, int priority);
bool findHook(void *hookFunc) const;
void removeHook(void *hookFunc);
public:
AbstractHookChainRegistry();
@ -119,8 +119,8 @@ public:
template<typename t_ret, typename ...t_args>
class IHookChainRegistryImpl : public IHookChainRegistry < t_ret, t_args...>, public AbstractHookChainRegistry {
public:
typedef t_ret(*hookfunc_t)(IHookChain<t_ret, t_args...>*, t_args...);
typedef t_ret(*origfunc_t)(t_args...);
typedef t_ret (*hookfunc_t)(IHookChain<t_ret, t_args...> *, t_args...);
typedef t_ret (*origfunc_t)(t_args...);
virtual ~IHookChainRegistryImpl() { }
@ -130,18 +130,18 @@ public:
}
virtual void registerHook(hookfunc_t hook, int priority) {
addHook((void*)hook, priority);
addHook((void *)hook, priority);
}
virtual void unregisterHook(hookfunc_t hook) {
removeHook((void*)hook);
removeHook((void *)hook);
}
};
template<typename ...t_args>
class IVoidHookChainRegistryImpl : public IVoidHookChainRegistry <t_args...>, public AbstractHookChainRegistry {
class IVoidHookChainRegistryImpl: public IVoidHookChainRegistry <t_args...>, public AbstractHookChainRegistry {
public:
typedef void(*hookfunc_t)(IVoidHookChain<t_args...>*, t_args...);
typedef void(*origfunc_t)(t_args...);
typedef void (*hookfunc_t)(IVoidHookChain<t_args...> *, t_args...);
typedef void (*origfunc_t)(t_args...);
virtual ~IVoidHookChainRegistryImpl() { }
@ -151,10 +151,10 @@ public:
}
virtual void registerHook(hookfunc_t hook, int priority) {
addHook((void*)hook, priority);
addHook((void *)hook, priority);
}
virtual void unregisterHook(hookfunc_t hook) {
removeHook((void*)hook);
removeHook((void *)hook);
}
};

View File

@ -68,6 +68,8 @@ bool OnMetaAttach()
g_RehldsHookchains->SV_DropClient()->registerHook(&SV_DropClient);
g_RehldsHookchains->SV_CheckConsistencyResponse()->registerHook(&SV_CheckConsistencyResponse);
g_RehldsHookchains->SV_TransferConsistencyInfo()->registerHook(&SV_TransferConsistencyInfo);
g_RehldsHookchains->SV_Spawn_f()->registerHook(&SV_Spawn_f);
g_RehldsHookchains->HandleNetCommand()->registerHook(&HandleNetCommand);
SV_AddResource = g_RehldsFuncs->SV_AddResource;
SV_FileInConsistencyList = g_RehldsFuncs->SV_FileInConsistencyList;
@ -107,6 +109,10 @@ void OnMetaDetach()
g_RehldsHookchains->SV_DropClient()->unregisterHook(&SV_DropClient);
g_RehldsHookchains->SV_CheckConsistencyResponse()->unregisterHook(&SV_CheckConsistencyResponse);
g_RehldsHookchains->SV_TransferConsistencyInfo()->unregisterHook(&SV_TransferConsistencyInfo);
g_RehldsHookchains->SV_Spawn_f()->unregisterHook(&SV_Spawn_f);
g_RehldsHookchains->HandleNetCommand()->unregisterHook(&HandleNetCommand);
ClearQueryFiles_api();
}
void ServerDeactivate_Post()
@ -141,24 +147,6 @@ int SV_TransferConsistencyInfo(IRehldsHook_SV_TransferConsistencyInfo *chain)
return chain->callNext() + nConsistency;
}
void ClientPutInServer_Post(edict_t *pEntity)
{
int nIndex = ENTINDEX(pEntity) - 1;
if (nIndex < 0 || nIndex >= gpGlobals->maxClients)
RETURN_META(MRES_IGNORED);
IGameClient *pClient = g_RehldsApi->GetServerStatic()->GetClient(nIndex);
// client is connected to putinserver, go execute cmd out buffer
Exec.CommandExecute(pClient);
// clear temporary files of response
g_pResource->Clear(pClient);
SET_META_RESULT(MRES_IGNORED);
}
bool SV_CheckConsistencyResponse(IRehldsHook_SV_CheckConsistencyResponse *chain, IGameClient *pSenderClient, resource_t *resource, uint32 hash)
{
if (!g_pResource->FileConsistencyResponse(pSenderClient, resource, hash))
@ -167,3 +155,33 @@ bool SV_CheckConsistencyResponse(IRehldsHook_SV_CheckConsistencyResponse *chain,
// call next hook and take return of values from original func
return chain->callNext(pSenderClient, resource, hash);
}
void SV_Spawn_f(IRehldsHook_SV_Spawn_f *chain)
{
chain->callNext();
auto pClient = g_RehldsFuncs->GetHostClient();
if (!pClient->IsConnected()) {
return;
}
bool haveAtLeastOne;
g_pResource->GetResponseFile(pClient, nullptr, &haveAtLeastOne);
if (haveAtLeastOne) {
g_RecheckerHookchains.m_FileConsistencyFinal.callChain(nullptr, pClient);
}
// client is connected to putinserver, go execute cmd out buffer
Exec.ExecuteCommand(pClient);
}
const int clc_fileconsistency = 7;
void HandleNetCommand(IRehldsHook_HandleNetCommand *chain, IGameClient *cl, int8 opcode)
{
if (opcode == clc_fileconsistency) {
// clear temporary files of response
g_pResource->Clear(cl);
}
chain->callNext(cl, opcode);
}

View File

@ -3,6 +3,8 @@
void SV_DropClient(IRehldsHook_SV_DropClient *chain, IGameClient *pClient, bool crash, const char *string);
bool SV_CheckConsistencyResponse(IRehldsHook_SV_CheckConsistencyResponse *chain, IGameClient *pSenderClient, resource_t *resource, uint32 hash);
int SV_TransferConsistencyInfo(IRehldsHook_SV_TransferConsistencyInfo *chain);
void SV_Spawn_f(IRehldsHook_SV_Spawn_f *chain);
void HandleNetCommand(IRehldsHook_HandleNetCommand *chain, IGameClient *cl, int8 opcode);
extern void (*SV_AddResource)(resourcetype_t type, const char *name, int size, unsigned char flags, int index);
extern qboolean (*SV_FileInConsistencyList)(const char *filename, consistency_t **ppconsist);

View File

@ -1,17 +1,7 @@
#pragma once
#ifdef _WIN32 // WINDOWS
#pragma warning(disable : 4005)
#else
#define _stricmp strcasecmp
#define _mkdir mkdir
#ifdef __FUNCTION__
#undef __FUNCTION__
#endif
#define __FUNCTION__ __func__
#endif // _WIN32
#define MAX_PATH_LENGTH 260
#include "basetypes.h"
#include "archtypes.h"
#include <list>
#include <vector>
@ -29,16 +19,15 @@
#include "engine_rehlds.h"
#include "consistency.h"
#include "engine_hlds_api.h"
#include "hookchains_impl.h"
#include "rechecker_api.h"
#include "rechecker_api_impl.h"
#include "main.h"
#include "task.h"
//#include "config.h"
#include "resource.h"
#include "cmdexec.h"
//#include "sdk_util.h" // UTIL_LogPrintf, etc
#undef DLLEXPORT

View File

@ -0,0 +1,3 @@
#include "precompiled.h"
#include "interface.cpp"

View File

@ -30,73 +30,103 @@
#include "hookchains.h"
#include "interface.h"
#define RECHECKER_API_VERSION_MAJOR 1
#define RECHECKER_API_VERSION_MINOR 0
#define RECHECKER_API_VERSION_MAJOR 2
#define RECHECKER_API_VERSION_MINOR 1
enum flag_type_resources
enum ResourceType_e
{
FLAG_TYPE_NONE = 0,
FLAG_TYPE_EXISTS, // to comparison with the specified hash value
FLAG_TYPE_MISSING, // check it missing file on client
FLAG_TYPE_IGNORE, // ignore the specified hash value
FLAG_TYPE_HASH_ANY, // any file with any the hash value
RES_TYPE_NONE = 0,
RES_TYPE_EXISTS, // to comparison with the specified hash value
RES_TYPE_MISSING, // check it missing file on client
RES_TYPE_IGNORE, // ignore the specified hash value
RES_TYPE_HASH_ANY, // any file with any the hash value
};
class IResourceBuffer;
// FileConsistencyProcess hook
typedef IVoidHookChain<IGameClient *, IResourceBuffer *, flag_type_resources, uint32> IRecheckerHook_FileConsistencyProcess;
typedef IVoidHookChainRegistry<IGameClient *, IResourceBuffer *, flag_type_resources, uint32> IRecheckerHookRegistry_FileConsistencyProcess;
typedef IVoidHookChain<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> IRecheckerHook_FileConsistencyProcess;
typedef IVoidHookChainRegistry<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> IRecheckerHookRegistry_FileConsistencyProcess;
// CmdExec hook
typedef IVoidHookChain<IGameClient *, IResourceBuffer *, char *, uint32> IRecheckerHook_CmdExec;
typedef IVoidHookChainRegistry<IGameClient *, IResourceBuffer *, char *, uint32> IRecheckerHookRegistry_CmdExec;
// FileConsistencyFinal hook
typedef IVoidHookChain<IGameClient *> IRecheckerHook_FileConsistencyFinal;
typedef IVoidHookChainRegistry<IGameClient *> IRecheckerHookRegistry_FileConsistencyFinal;
class IRecheckerHookchains {
public:
protected:
virtual ~IRecheckerHookchains() {}
public:
virtual IRecheckerHookRegistry_FileConsistencyProcess *FileConsistencyProcess() = 0;
virtual IRecheckerHookRegistry_CmdExec *CmdExec() = 0;
virtual IRecheckerHookRegistry_FileConsistencyFinal *FileConsistencyFinal() = 0;
};
class IResourceBuffer {
public:
protected:
virtual ~IResourceBuffer() {}
public:
virtual uint32 GetFileHash() const = 0;
virtual flag_type_resources GetFileFlag() const = 0;
virtual ResourceType_e GetFileFlag() const = 0;
virtual const char *GetFileName() const = 0;
virtual const char *GetCmdExec() const = 0;
virtual int GetLine() const = 0;
virtual bool IsBreak() const = 0; // is have do not check a next files
virtual bool IsDuplicate() const = 0; // it is already have in resourcelist
virtual bool IsDuplicate() const = 0; // it is already have in resourcelist
virtual bool IsAddEx() const = 0; // if it added via API
};
class IResourceFile {
class IResponseBuffer {
protected:
virtual ~IResponseBuffer() {}
public:
virtual int GetUserID() const = 0;
virtual IGameClient *GetGameClient() const = 0;
virtual const char *GetFileName() const = 0;
virtual uint32 GetClientHash() const = 0;
virtual uint32 GetPrevHash() const = 0;
};
class IResourceFile {
protected:
virtual ~IResourceFile() {}
public:
virtual const char *FindFilenameOfHash(uint32 hash) = 0;
virtual int GetConsistencyNum() const = 0;
virtual uint32 GetPrevHash() const = 0;
};
#undef FindResource
using query_func_t = void (*)(IGameClient *pClient, uint32 hash, int uniqueId);
struct RecheckerFuncs_t {
IResourceBuffer *(*AddElement)(char *filename, char *cmdExec, flag_type_resources flag, uint32 hash, bool bBreak);
IResourceBuffer*(*FindElement)(char *filename);
IResourceFile*(*GetResourceFile)();
IResourceBuffer *(*AddResource)(const char *filename, char *cmdExec, ResourceType_e flag, uint32 hash, bool bBreak);
IResourceBuffer *(*AddQueryFile)(const char *filename, ResourceType_e flag, uint32 hash, query_func_t callback, int uniqueId);
void (*RemoveQueryFile)(int uniqueId);
void (*ClearQueryFiles)();
IResourceBuffer *(*FindResource)(const char *filename);
IResourceFile *(*GetResource)();
IResponseBuffer *(*GetResponseFile)(IGameClient *pClient, const char *filename);
bool (*IsResourceExists)(IGameClient *pClient, const char *filename, uint32 &hash);
};
class IRecheckerApi {
public:
protected:
virtual ~IRecheckerApi() { }
public:
virtual int GetMajorVersion() = 0;
virtual int GetMinorVersion() = 0;
virtual const RecheckerFuncs_t* GetFuncs() = 0;
virtual IRecheckerHookchains* GetHookchains() = 0;
virtual const RecheckerFuncs_t *GetFuncs() = 0;
virtual IRecheckerHookchains *GetHookchains() = 0;
};

View File

@ -29,52 +29,108 @@
CRecheckerApi g_RecheckerApi;
CRecheckerHookchains g_RecheckerHookchains;
RecheckerFuncs_t g_RecheckerApiFuncs =
RecheckerFuncs_t g_RecheckerApiFuncs =
{
&AddElement_api,
&FindElement_api,
&GetResourceFile_api
&AddResource_api,
&AddQueryFile_api,
&RemoveQueryFile_api,
&ClearQueryFiles_api,
&FindResource_api,
&GetResource_api,
&GetResponseFile_api,
&IsResourceExists_api,
};
IResourceBuffer *EXT_FUNC AddElement_api(char *filename, char *cmdExec, flag_type_resources flag, uint32 hash, bool bBreak)
IResourceBuffer *EXT_FUNC AddResource_api(const char *filename, char *cmdExec, ResourceType_e flag, uint32 hash, bool bBreak)
{
auto nRes = g_pResource->AddElement(filename, cmdExec, flag, hash, 0, bBreak);
if (!nRes->IsDuplicate()) {
// resource was added via the API
nRes->SetAddEx();
}
auto nRes = g_pResource->Add(filename, cmdExec, flag, hash, 0, bBreak);
// resource was added via the API
nRes->SetAddEx();
return nRes;
}
IResourceBuffer *EXT_FUNC FindElement_api(char *filename)
{
// to mark files which are not required to add to the resource again
for (auto res : (*g_pResource->GetResourceList()))
{
if (_stricmp(res->GetFileName(), filename) == 0)
{
// resource name already have, return its;
return res;
}
}
std::vector<query_file_t *> g_QueryFiles;
return nullptr;
IResourceBuffer *EXT_FUNC AddQueryFile_api(const char *filename, ResourceType_e flag, uint32 hash, query_func_t callback, int uniqueId)
{
g_QueryFiles.push_back(new query_file_t(filename, flag, hash, callback, uniqueId));
auto nRes = g_pResource->Add(filename, "", flag, hash, -1, false);
// resource was added via the API
nRes->SetAddEx();
return nRes;
}
IResourceFile *EXT_FUNC GetResourceFile_api()
void EXT_FUNC ClearQueryFiles_api()
{
for (auto query : g_QueryFiles) {
delete query;
}
g_QueryFiles.clear();
}
void EXT_FUNC RemoveQueryFile_api(int uniqueId)
{
auto iter = g_QueryFiles.begin();
while (iter != g_QueryFiles.end())
{
if ((*iter)->uniqueId != uniqueId) {
iter++;
continue;
}
delete (*iter);
iter = g_QueryFiles.erase(iter);
}
if (g_QueryFiles.size() <= 0) {
g_QueryFiles.clear();
}
}
IResourceBuffer *EXT_FUNC FindResource_api(const char *filename) {
return g_pResource->GetResourceFile(filename);
}
IResponseBuffer *EXT_FUNC GetResponseFile_api(IGameClient *pClient, const char *filename) {
return g_pResource->GetResponseFile(pClient, filename);
}
bool EXT_FUNC IsResourceExists_api(IGameClient *pClient, const char *filename, uint32 &hash)
{
auto res = g_pResource->GetResponseFile(pClient, filename);
if (res->GetClientHash() == res->GetPrevHash()) {
// file is missing?
return false;
}
if (hash && res->GetClientHash() == hash) {
return true;
}
hash = res->GetClientHash();
return true;
}
IResourceFile *EXT_FUNC GetResource_api() {
return g_pResource;
}
IRecheckerHookRegistry_FileConsistencyProcess* CRecheckerHookchains::FileConsistencyProcess() {
IRecheckerHookRegistry_FileConsistencyProcess *CRecheckerHookchains::FileConsistencyProcess() {
return &m_FileConsistencyProcess;
}
IRecheckerHookRegistry_CmdExec* CRecheckerHookchains::CmdExec() {
IRecheckerHookRegistry_CmdExec *CRecheckerHookchains::CmdExec() {
return &m_CmdExec;
}
IRecheckerHookRegistry_FileConsistencyFinal *CRecheckerHookchains::FileConsistencyFinal() {
return &m_FileConsistencyFinal;
}
int EXT_FUNC CRecheckerApi::GetMajorVersion()
{
return RECHECKER_API_VERSION_MAJOR;
@ -85,12 +141,12 @@ int EXT_FUNC CRecheckerApi::GetMinorVersion()
return RECHECKER_API_VERSION_MINOR;
}
const RecheckerFuncs_t* EXT_FUNC CRecheckerApi::GetFuncs()
const RecheckerFuncs_t *EXT_FUNC CRecheckerApi::GetFuncs()
{
return &g_RecheckerApiFuncs;
}
IRecheckerHookchains* EXT_FUNC CRecheckerApi::GetHookchains()
IRecheckerHookchains *EXT_FUNC CRecheckerApi::GetHookchains()
{
return &g_RecheckerHookchains;
}

View File

@ -28,21 +28,27 @@
#pragma once
// FileConsistencyProcess hook
typedef IVoidHookChainImpl<IGameClient *, IResourceBuffer *, flag_type_resources, uint32> CRecheckerHook_FileConsistencyProcess;
typedef IVoidHookChainRegistryImpl<IGameClient *, IResourceBuffer *, flag_type_resources, uint32> CRecheckerHookRegistry_FileConsistencyProcess;
typedef IVoidHookChainImpl<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> CRecheckerHook_FileConsistencyProcess;
typedef IVoidHookChainRegistryImpl<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> CRecheckerHookRegistry_FileConsistencyProcess;
// CmdExec hook
typedef IVoidHookChainImpl<IGameClient *, IResourceBuffer *, char *, uint32> CRecheckerHook_CmdExec;
typedef IVoidHookChainRegistryImpl<IGameClient *, IResourceBuffer *, char *, uint32> CRecheckerHookRegistry_CmdExec;
// FileConsistencyFinal hook
typedef IVoidHookChainImpl<IGameClient *> CRecheckerHook_FileConsistencyFinal;
typedef IVoidHookChainRegistryImpl<IGameClient *> CRecheckerHookRegistry_FileConsistencyFinal;
class CRecheckerHookchains: public IRecheckerHookchains {
public:
CRecheckerHookRegistry_FileConsistencyProcess m_FileConsistencyProcess;
CRecheckerHookRegistry_CmdExec m_CmdExec;
CRecheckerHookRegistry_FileConsistencyFinal m_FileConsistencyFinal;
public:
virtual IRecheckerHookRegistry_FileConsistencyProcess *FileConsistencyProcess();
virtual IRecheckerHookRegistry_CmdExec *CmdExec();
virtual IRecheckerHookRegistry_FileConsistencyFinal *FileConsistencyFinal();
};
extern CRecheckerHookchains g_RecheckerHookchains;
@ -53,11 +59,45 @@ public:
virtual int GetMajorVersion();
virtual int GetMinorVersion();
virtual const RecheckerFuncs_t* GetFuncs();
virtual IRecheckerHookchains* GetHookchains();
virtual const RecheckerFuncs_t *GetFuncs();
virtual IRecheckerHookchains *GetHookchains();
};
void Rechecker_Api_Init();
IResourceBuffer *AddElement_api(char *filename, char *cmdExec, flag_type_resources flag, uint32 hash, bool bBreak);
IResourceBuffer *FindElement_api(char *filename);
IResourceFile *GetResourceFile_api();
IResourceBuffer *AddResource_api(const char *filename, char *cmdExec, ResourceType_e flag, uint32 hash, bool bBreak);
IResourceBuffer *AddQueryFile_api(const char *filename, ResourceType_e flag, uint32 hash, query_func_t callback, int uniqueId);
IResourceBuffer *FindResource_api(const char *filename);
IResourceFile *GetResource_api();
IResponseBuffer *GetResponseFile_api(IGameClient *pClient, const char *filename);
bool IsResourceExists_api(IGameClient *pClient, const char *filename, uint32 &hash);
void ClearQueryFiles_api();
void RemoveQueryFile_api(int uniqueId);
struct query_file_t
{
query_file_t(const char *filename, const ResourceType_e flag, uint32 hash, query_func_t func, int uniqueId);
~query_file_t()
{
delete[] this->filename;
this->filename = nullptr;
}
uint32 hash;
int uniqueId;
char *filename;
ResourceType_e flag;
query_func_t func;
};
inline query_file_t::query_file_t(const char *filename, const ResourceType_e flag, uint32 hash, query_func_t func, int uniqueId)
{
this->filename = new char [strlen(filename) + 1];
strcpy(this->filename, filename);
this->flag = flag;
this->hash = hash;
this->func = func;
this->uniqueId = uniqueId;
}
extern std::vector<query_file_t *> g_QueryFiles;

View File

@ -41,7 +41,12 @@ int CResourceFile::CreateResourceList()
// check limit resource
if (g_RehldsServerData->GetResourcesNum() >= RESOURCE_MAX_COUNT)
{
UTIL_Printf(__FUNCTION__ ": can't add resource \"%s\" on line %d; exceeded the limit of resources max '%d'\n", res->GetFileName(), res->GetLine(), RESOURCE_MAX_COUNT);
if (res->IsAddEx()) {
UTIL_Printf("%s: can't add resource \"%s\"; exceeded the limit of resources max '%d'\n", __func__, res->GetFileName(), RESOURCE_MAX_COUNT);
} else {
UTIL_Printf("%s: can't add resource \"%s\" on line %d; exceeded the limit of resources max '%d'\n", __func__, res->GetFileName(), res->GetLine(), RESOURCE_MAX_COUNT);
}
break;
}
@ -49,18 +54,23 @@ int CResourceFile::CreateResourceList()
// https://github.com/dreamstalker/rehlds/blob/beaeb65/rehlds/engine/sv_user.cpp#L374
if (nCustomConsistency + m_ConsistencyNum >= MAX_RANGE_CONSISTENCY)
{
UTIL_Printf(__FUNCTION__ ": can't add consistency \"%s\" on line %d; index out of bounds '%d'\n", res->GetFileName(), res->GetLine(), MAX_RANGE_CONSISTENCY);
if (res->IsAddEx()) {
UTIL_Printf("%s: can't add consistency \"%s\"; index out of bounds '%d'\n", __func__, res->GetFileName(), MAX_RANGE_CONSISTENCY);
} else {
UTIL_Printf("%s: can't add consistency \"%s\" on line %d; index out of bounds '%d'\n", __func__, res->GetFileName(), res->GetLine(), MAX_RANGE_CONSISTENCY);
}
break;
}
Log(LOG_DETAILED, __FUNCTION__ " -> file: (%s), cmdexec: (%s), hash: (%x), typeFind: (%s)", res->GetFileName(), res->GetCmdExec(), res->GetFileHash(), szTypeNames[ res->GetFileFlag() ]);
Log(LOG_DETAILED, "%s -> file: (%s), cmdexec: (%s), hash: (%x), typeFind: (%s), ex: (%d)", __func__, res->GetFileName(), res->GetCmdExec(), res->GetFileHash(), szTypeNames[ res->GetFileFlag() ], res->IsAddEx());
SV_AddResource(t_decal, res->GetFileName(), 0, RES_CHECKFILE, startIndex++);
++nCustomConsistency;
nCustomConsistency++;
}
}
std::vector<resource_t> sortList;
for (int i = 0; i < g_RehldsServerData->GetResourcesNum(); ++i)
for (int i = 0; i < g_RehldsServerData->GetResourcesNum(); i++)
{
sortList.push_back(*g_RehldsServerData->GetResource(i));
}
@ -83,7 +93,7 @@ int CResourceFile::CreateResourceList()
return a.nIndex < b.nIndex;
});
for (auto res : sortList)
for (auto& res : sortList)
{
// Add new resource in the own order
SV_AddResource(res.type, res.szFileName, res.nDownloadSize, res.ucFlags, res.nIndex);
@ -114,15 +124,20 @@ void CResourceFile::Clear(IGameClient *pClient)
{
// remove each entries by pClient
auto nUserID = g_engfuncs.pfnGetPlayerUserId(pClient->GetEdict());
m_responseList.erase(
std::remove_if(
m_responseList.begin(),
m_responseList.end(),
[nUserID](const CResponseBuffer *pFiles) -> bool {
return (pFiles->GetUserID() == nUserID);
}
), m_responseList.end()
);
auto iter = m_responseList.begin();
while (iter != m_responseList.end())
{
CResponseBuffer *pFiles = (*iter);
// erase cmdexec
if (pFiles->GetUserID() == nUserID)
{
delete pFiles;
iter = m_responseList.erase(iter);
}
else
iter++;
}
m_PrevHash = 0;
return;
@ -133,6 +148,12 @@ void CResourceFile::Clear(IGameClient *pClient)
m_ConsistencyNum = 0;
// clear resources
for (auto it : m_resourceList)
delete it;
for (auto it : m_responseList)
delete it;
m_resourceList.clear();
m_responseList.clear();
@ -216,7 +237,7 @@ void CreateDirectory(const char *path)
void CResourceFile::Init()
{
char *pos;
char path[MAX_PATH_LENGTH];
char path[MAX_PATH];
strncpy(path, GET_PLUGIN_PATH(PLID), sizeof(path) - 1);
path[sizeof(path) - 1] = '\0';
@ -315,9 +336,9 @@ void CResourceFile::LoadResources()
FILE *fp;
int argc;
int len;
flag_type_resources flag;
char filename[MAX_PATH_LENGTH];
char cmdBufExec[MAX_PATH_LENGTH];
ResourceType_e flag;
char filename[MAX_PATH];
char cmdBufExec[MAX_PATH];
int cline = 0;
bool bBreak;
@ -325,7 +346,7 @@ void CResourceFile::LoadResources()
if (!fp)
{
UTIL_Printf(__FUNCTION__ ": can't find path to " FILE_INI_RESOURCES "\n");
//UTIL_Printf("%s: can't find path to " FILE_INI_RESOURCES "\n", __func__);
return;
}
@ -346,7 +367,7 @@ void CResourceFile::LoadResources()
argc = 0;
bBreak = false;
flag = FLAG_TYPE_NONE;
flag = RES_TYPE_NONE;
memset(hash, 0, sizeof(hash));
@ -371,18 +392,18 @@ void CResourceFile::LoadResources()
if (_stricmp((const char *)pbuf, "UNKNOWN") == 0)
{
flag = FLAG_TYPE_HASH_ANY;
flag = RES_TYPE_HASH_ANY;
}
else if (_stricmp((const char *)pbuf, "MISSING") == 0)
{
flag = FLAG_TYPE_MISSING;
flag = RES_TYPE_MISSING;
}
else
{
for (int i = 0; i < sizeof(pbuf) / 2; ++i)
hash[i] = hexbyte(&pbuf[i * 2]);
flag = FLAG_TYPE_EXISTS;
flag = RES_TYPE_EXISTS;
}
break;
}
@ -393,7 +414,7 @@ void CResourceFile::LoadResources()
if (_stricmp(cmdBufExec, "IGNORE") == 0)
{
flag = FLAG_TYPE_IGNORE;
flag = RES_TYPE_IGNORE;
cmdBufExec[0] = '\0';
}
else if (_stricmp(cmdBufExec, "BREAK") == 0)
@ -412,7 +433,7 @@ void CResourceFile::LoadResources()
{
if (_stricmp(pToken, "IGNORE") == 0)
{
flag = FLAG_TYPE_IGNORE;
flag = RES_TYPE_IGNORE;
}
else if (_stricmp(pToken, "BREAK") == 0)
{
@ -434,7 +455,7 @@ void CResourceFile::LoadResources()
}
#define LOG_PRINT_FAILED(str, ...)\
UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; " str, __VA_ARGS__);\
UTIL_Printf("%s: Failed to load \"" FILE_INI_RESOURCES "\"; %s", __func__, str, __VA_ARGS__);\
continue;
if (argc >= MAX_PARSE_ARGUMENT)
@ -444,24 +465,24 @@ void CResourceFile::LoadResources()
{
LOG_PRINT_FAILED("path to filename is empty on line %d\n", cline);
}
else if (!IsFileHasExtension(filename))
{
LOG_PRINT_FAILED("filename has no extension on line %d\n", cline);
}
//else if (!IsFileHasExtension(filename))
//{
// LOG_PRINT_FAILED("filename has no extension on line %d\n", cline);
//}
else if (!IsValidFilename(filename, pchar))
{
LOG_PRINT_FAILED("filename has invalid character '%c' on line %d\n", pchar, cline);
}
else if (flag == FLAG_TYPE_NONE)
else if (flag == RES_TYPE_NONE)
{
LOG_PRINT_FAILED("parsing hash failed on line %d\n", cline);
}
else if (strlen(cmdBufExec) <= 0 && (flag != FLAG_TYPE_IGNORE && !bBreak))
else if (strlen(cmdBufExec) <= 0 && (flag != RES_TYPE_IGNORE && !bBreak))
{
LOG_PRINT_FAILED("parsing command line is empty on line %d\n", cline);
}
AddElement(filename, cmdBufExec, flag, *(uint32 *)&hash[0], cline, bBreak);
Add(filename, cmdBufExec, flag, *(uint32 *)&hash[0], cline, bBreak);
}
else if (pToken || argc > ARG_TYPE_FILE_NAME)
{
@ -538,7 +559,7 @@ const char *CResourceFile::GetNextToken(char **pbuf)
return res;
}
CResourceBuffer *CResourceFile::AddElement(char *filename, char *cmdExec, flag_type_resources flag, uint32 hash, int line, bool bBreak)
CResourceBuffer *CResourceFile::Add(const char *filename, char *cmdExec, ResourceType_e flag, uint32 hash, int line, bool bBreak)
{
auto nRes = new CResourceBuffer(filename, cmdExec, flag, hash, line, bBreak);
@ -559,38 +580,93 @@ CResourceBuffer *CResourceFile::AddElement(char *filename, char *cmdExec, flag_t
void CResourceFile::AddFileResponse(IGameClient *pSenderClient, char *filename, uint32 hash)
{
m_responseList.push_back(new CResponseBuffer(pSenderClient, filename, hash));
m_responseList.push_back(new CResponseBuffer(pSenderClient, filename, hash, m_PrevHash));
}
void EXT_FUNC FileConsistencyProcess_hook(IGameClient *pSenderClient, IResourceBuffer *res, flag_type_resources typeFind, uint32 hash)
void EXT_FUNC FileConsistencyProcess_hook(IGameClient *pSenderClient, IResourceBuffer *res, ResourceType_e typeFind, uint32 hash)
{
if (typeFind == FLAG_TYPE_NONE)
if (typeFind == RES_TYPE_NONE)
return;
auto nRes = static_cast<CResourceBuffer *>(res);
auto pRes = static_cast<CResourceBuffer *>(res);
// Fire query to callback's
for (auto query : g_QueryFiles)
{
if (!res->IsAddEx() || strcmp(query->filename, pRes->GetFileName()) != 0)
continue;
if (query->flag == typeFind) {
query->func(pSenderClient, hash, query->uniqueId);
}
}
// push exec cmd
Exec.AddElement(pSenderClient, nRes, hash);
g_pResource->PrintLog(pSenderClient, nRes, typeFind, hash);
Exec.Add(pSenderClient, pRes, hash);
g_pResource->PrintLog(pSenderClient, pRes, typeFind, hash);
}
void CResourceFile::PrintLog(IGameClient *pSenderClient, CResourceBuffer *res, flag_type_resources typeFind, uint32 hash)
void CResourceFile::PrintLog(IGameClient *pSenderClient, CResourceBuffer *res, ResourceType_e typeFind, uint32 hash)
{
flag_type_log type = (typeFind == FLAG_TYPE_IGNORE) ? LOG_DETAILED : LOG_NORMAL;
Log(type, " -> file: (%s), exphash: (%x), got: (%x), typeFind: (%s), prevhash: (%x), (#%u)(%s), prevfile: (%s), findathash: (%s), md5hex: (%x)",
flag_type_log type = (typeFind == RES_TYPE_IGNORE) ? LOG_DETAILED : LOG_NORMAL;
Log(type, " -> file: (%s), exphash: (%x), got: (%x), typeFind: (%s), prevhash: (%x), (#%u)(%s), prevfile: (%s), findathash: (%s), md5hex: (%x), ex: (%d)",
res->GetFileName(), res->GetFileHash(), hash, szTypeNames[ typeFind ], m_PrevHash, g_engfuncs.pfnGetPlayerUserId(pSenderClient->GetEdict()),
pSenderClient->GetName(), FindFilenameOfHash(m_PrevHash), FindFilenameOfHash(hash), _byteswap_ulong(hash));
pSenderClient->GetName(), FindFilenameOfHash(m_PrevHash), FindFilenameOfHash(hash), _byteswap_ulong(hash), res->IsAddEx());
}
IResourceBuffer *CResourceFile::GetResourceFile(const char *filename)
{
// to mark files which are not required to add to the resource again
for (auto res : m_resourceList)
{
if (_stricmp(res->GetFileName(), filename) == 0)
{
// resource name already have, return its;
return res;
}
}
return nullptr;
}
IResponseBuffer *CResourceFile::GetResponseFile(IGameClient *pClient, const char *filename, bool *firstFound)
{
if (firstFound) {
*firstFound = false;
}
int nUserID = g_engfuncs.pfnGetPlayerUserId(pClient->GetEdict());
for (auto res : m_responseList)
{
if (res->GetUserID() != nUserID) {
continue;
}
if (firstFound) {
*firstFound = true;
}
if (!filename) {
break;
}
if (_stricmp(res->GetFileName(), filename) == 0) {
return res;
}
}
return nullptr;
}
bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource_t *resource, uint32 hash)
{
bool bHandled = false;
flag_type_resources typeFind;
ResourceType_e typeFind;
std::vector<CResourceBuffer *> tempResourceList;
if (resource->type != t_decal
|| resource->nIndex < 4095) // if by some miracle the decals will have the flag RES_CHECKFILE
// to be sure not bypass the decals
// to be sure not bypass the decals
{
AddFileResponse(pSenderClient, resource->szFileName, hash);
m_PrevHash = hash;
@ -611,21 +687,21 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource
typeFind = res->GetFileFlag();
if (m_PrevHash == hash && typeFind != FLAG_TYPE_MISSING)
typeFind = FLAG_TYPE_NONE;
if (m_PrevHash == hash && typeFind != RES_TYPE_MISSING)
typeFind = RES_TYPE_NONE;
switch (typeFind)
{
case FLAG_TYPE_IGNORE:
case RES_TYPE_IGNORE:
tempResourceList.push_back(res);
break;
case FLAG_TYPE_EXISTS:
case RES_TYPE_EXISTS:
if (res->GetFileHash() != hash)
{
typeFind = FLAG_TYPE_NONE;
typeFind = RES_TYPE_NONE;
}
break;
case FLAG_TYPE_HASH_ANY:
case RES_TYPE_HASH_ANY:
for (auto temp : tempResourceList)
{
if (_stricmp(temp->GetFileName(), res->GetFileName()) != 0)
@ -633,19 +709,19 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource
if (temp->GetFileHash() == hash)
{
typeFind = FLAG_TYPE_NONE;
typeFind = RES_TYPE_NONE;
break;
}
}
break;
case FLAG_TYPE_MISSING:
case RES_TYPE_MISSING:
if (m_PrevHash != hash)
{
typeFind = FLAG_TYPE_NONE;
typeFind = RES_TYPE_NONE;
}
break;
default:
typeFind = FLAG_TYPE_NONE;
typeFind = RES_TYPE_NONE;
break;
}
@ -653,8 +729,8 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource
bHandled = true;
}
m_PrevHash = hash;
AddFileResponse(pSenderClient, resource->szFileName, hash);
m_PrevHash = hash;
return !bHandled;
}
@ -679,7 +755,7 @@ void CResourceFile::ClearStringsCache()
m_StringsCache.clear();
}
CResourceBuffer::CResourceBuffer(char *filename, char *cmdExec, flag_type_resources flag, uint32 hash, int line, bool bBreak)
CResourceBuffer::CResourceBuffer(const char *filename, char *cmdExec, ResourceType_e flag, uint32 hash, int line, bool bBreak)
{
m_FileName = CResourceFile::DuplicateString(filename);
m_CmdExec = (cmdExec[0] != '\0') ? CResourceFile::DuplicateString(cmdExec) : nullptr;
@ -693,12 +769,13 @@ CResourceBuffer::CResourceBuffer(char *filename, char *cmdExec, flag_type_resour
m_AddEx = false;
}
CResourceFile::CResponseBuffer::CResponseBuffer(IGameClient *pSenderClient, char *filename, uint32 hash)
CResourceFile::CResponseBuffer::CResponseBuffer(IGameClient *pSenderClient, char *filename, uint32 hash, uint32 prevHash)
{
m_pClient = pSenderClient;
m_FileName = DuplicateString(filename);
m_ClientHash = hash;
m_UserID = g_engfuncs.pfnGetPlayerUserId(pSenderClient->GetEdict());
m_PrevHash = prevHash;
}
const char *CResourceFile::FindFilenameOfHash(uint32 hash)

View File

@ -1,11 +1,11 @@
#pragma once
#define FILE_INI_RESOURCES "resources.ini"
#define MAX_CMD_LENGTH 128
#define FILE_INI_RESOURCES "resources.ini"
#define MAX_CMD_LENGTH 128
#define MAX_RANGE_CONSISTENCY 1024
#define RESOURCE_INDEX_BITS 12
#define RESOURCE_MAX_COUNT (1 << RESOURCE_INDEX_BITS)
#define RESOURCE_INDEX_BITS 12
#define RESOURCE_MAX_COUNT (1 << RESOURCE_INDEX_BITS)
enum flag_type_log
{
@ -28,13 +28,13 @@ enum arg_type_e
class CResourceBuffer: public IResourceBuffer
{
public:
CResourceBuffer(char *filename, char *cmdExec, flag_type_resources flag, uint32 hash, int line, bool bBreak);
CResourceBuffer(const char *filename, char *cmdExec, ResourceType_e flag, uint32 hash, int line, bool bBreak);
uint32 GetFileHash() const { return m_FileHash; };
flag_type_resources GetFileFlag() const { return m_Flag; };
ResourceType_e GetFileFlag() const { return m_Flag; };
const char *GetFileName() const { return m_FileName; };
const char *GetCmdExec() const { return m_CmdExec; };
const char *GetCmdExec() const { return (m_CmdExec == nullptr) ? "" : m_CmdExec; };
int GetLine() const { return m_Line; };
bool IsBreak() const { return m_Break; };
@ -47,7 +47,7 @@ public:
private:
uint32 m_FileHash;
flag_type_resources m_Flag;
ResourceType_e m_Flag;
int m_Line;
const char *m_FileName;
@ -69,7 +69,7 @@ public:
void LoadResources();
int CreateResourceList();
void Log(flag_type_log type, const char *fmt, ...);
void PrintLog(IGameClient *pSenderClient, CResourceBuffer *res, flag_type_resources typeFind, uint32 hash);
void PrintLog(IGameClient *pSenderClient, CResourceBuffer *res, ResourceType_e typeFind, uint32 hash);
bool FileConsistencyResponse(IGameClient *pSenderClient, resource_t *resource, uint32 hash);
static const char *DuplicateString(const char *str);
@ -77,21 +77,23 @@ public:
private:
// buffer for response list
class CResponseBuffer
class CResponseBuffer: public IResponseBuffer
{
public:
CResponseBuffer(IGameClient *pSenderClient, char *filename, uint32 hash);
CResponseBuffer(IGameClient *pSenderClient, char *filename, uint32 hash, uint32 prevHash);
int GetUserID() const { return m_UserID; };
IGameClient *GetGameClient() const { return m_pClient; };
const char *GetFileName() const { return m_FileName; };
uint32 GetClientHash() const { return m_ClientHash; };
uint32 GetPrevHash() const { return m_PrevHash; };
private:
int m_UserID;
IGameClient *m_pClient;
const char *m_FileName;
uint32 m_ClientHash;
uint32 m_PrevHash;
};
private:
@ -115,18 +117,20 @@ private:
int m_ConsistencyNum;
uint32 m_PrevHash;
char m_PathDir[MAX_PATH_LENGTH];
char m_LogFilePath[MAX_PATH_LENGTH]; // log data
char m_PathDir[MAX_PATH];
char m_LogFilePath[MAX_PATH]; // log data
typedef std::vector<const char *> StringList;
static StringList m_StringsCache;
public:
IResourceBuffer *GetResourceFile(const char *filename);
IResponseBuffer *GetResponseFile(IGameClient *pClient, const char *filename, bool *firstFound = nullptr);
const char *FindFilenameOfHash(uint32 hash);
int GetConsistencyNum() const { return m_ConsistencyNum; }
uint32 GetPrevHash() const { return m_PrevHash; }
CResourceBuffer *AddElement(char *filename, char *cmdExec, flag_type_resources flag, uint32 hash, int line, bool bBreak);
const ResourceList *GetResourceList() const { return &m_resourceList; }
CResourceBuffer *Add(const char *filename, char *cmdExec, ResourceType_e flag, uint32 hash, int line, bool bBreak);
};
extern CResourceFile *g_pResource;