mirror of
https://github.com/rehlds/rechecker.git
synced 2024-12-25 03:45:29 +03:00
Enhanced rechecker api
This commit is contained in:
parent
4727659db0
commit
bb2bb4453f
15
Makefile
15
Makefile
@ -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
154
common/BaseSystemModule.cpp
Normal 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
75
common/BaseSystemModule.h
Normal 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
54
common/IAdminServer.h
Normal 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
91
common/IBaseSystem.h
Normal 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
93
common/IDemoPlayer.h
Normal 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
71
common/IEngineWrapper.h
Normal 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
47
common/IObjectContainer.h
Normal 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
57
common/ISystemModule.h
Normal 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
76
common/IVGuiModule.h
Normal 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
515
common/ObjectDictionary.cpp
Normal 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
94
common/ObjectDictionary.h
Normal 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
259
common/ObjectList.cpp
Normal 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
65
common/ObjectList.h
Normal 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
211
common/SteamAppStartUp.cpp
Normal 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
37
common/SteamAppStartUp.h
Normal 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
324
common/TextConsoleUnix.cpp
Normal 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
59
common/TextConsoleUnix.h
Normal 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
280
common/TextConsoleWin32.cpp
Normal 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
61
common/TextConsoleWin32.h
Normal 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
132
common/TokenLine.cpp
Normal 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
51
common/TokenLine.h
Normal 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
354
common/commandline.cpp
Normal 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;
|
||||
}
|
17
common/crc.h
17
common/crc.h
@ -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]);
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
25
common/icommandline.h
Normal 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
|
@ -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
|
||||
|
@ -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
34
common/md5.h
Normal 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]);
|
@ -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
208
common/netapi.cpp
Normal 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
25
common/netapi.h
Normal 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
|
@ -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
|
||||
|
@ -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
33
common/stdc++compat.cpp
Normal 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
394
common/textconsole.cpp
Normal 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
93
common/textconsole.h
Normal 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, ...);
|
@ -27,8 +27,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
/* <430ee> ../common/vmodes.h:40 */
|
||||
typedef struct rect_s
|
||||
{
|
||||
int left, right, top, bottom;
|
||||
|
@ -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;
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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">
|
||||
|
@ -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 );
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
47
public/icommandline.h
Normal 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();
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -121,4 +121,4 @@
|
||||
#define K_MOUSE4 244
|
||||
#define K_MOUSE5 245
|
||||
|
||||
#endif // KEYDEFS_H
|
||||
#endif // KEYDEFS_H
|
||||
|
@ -194,4 +194,4 @@ public:
|
||||
};
|
||||
|
||||
|
||||
#endif//PARTICLEMEM_H__
|
||||
#endif//PARTICLEMEM_H__
|
||||
|
@ -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
435
public/tier0/dbg.cpp
Normal 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
453
public/tier0/dbg.h
Normal 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
37
public/tier0/mem.h
Normal 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
77
public/tier0/memalloc.h
Normal 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
21
public/tier0/memdbgoff.h
Normal 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
93
public/tier0/memdbgon.h
Normal 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
630
public/tier0/platform.h
Normal 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 */
|
59
public/tier0/platform_linux.cpp
Normal file
59
public/tier0/platform_linux.cpp
Normal 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");
|
||||
}
|
95
public/tier0/platform_win32.cpp
Normal file
95
public/tier0/platform_win32.cpp
Normal 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.
|
||||
// -------------------------------------------------------------------------------------------------- //
|
@ -416,4 +416,4 @@ void CUtlBuffer::SeekPut(SeekType_t type, int offset)
|
||||
m_Put = m_Memory.NumAllocated() - offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -320,4 +320,4 @@ void CUtlMemory<T>::Purge()
|
||||
}
|
||||
|
||||
|
||||
#endif // UTLSTORAGE_H
|
||||
#endif // UTLSTORAGE_H
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ private:
|
||||
void ResetValues();
|
||||
|
||||
private:
|
||||
char m_PathDir[MAX_PATH_LENGTH];
|
||||
char m_PathDir[MAX_PATH];
|
||||
|
||||
// settings
|
||||
float m_DelayExec;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
54
src/main.cpp
54
src/main.cpp
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
3
src/public_amalgamation.cpp
Normal file
3
src/public_amalgamation.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "interface.cpp"
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
197
src/resource.cpp
197
src/resource.cpp
@ -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)
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user