2
0
mirror of https://github.com/rehlds/metamod-r.git synced 2024-12-27 07:05:34 +03:00

Implemented JIT callbacks

This commit is contained in:
asmodai 2016-07-30 02:03:01 +03:00
parent 2e4a5b7c9e
commit 2cf145e2a0
39 changed files with 10477 additions and 3296 deletions

View File

@ -67,7 +67,7 @@ extern enginefuncs_t g_engfuncs;
#define TRACE_MODEL (*g_engfuncs.pfnTraceModel)
#define GET_AIM_VECTOR (*g_engfuncs.pfnGetAimVector)
#define SERVER_COMMAND (*g_engfuncs.pfnServerCommand)
#define SERVER_EXECUTE (*g_engfuncs.pfnServerExecute)
//#define SERVER_EXECUTE (*g_engfuncs.pfnServerExecute)
#define CLIENT_COMMAND (*g_engfuncs.pfnClientCommand)
#define PARTICLE_EFFECT (*g_engfuncs.pfnParticleEffect)
#define LIGHT_STYLE (*g_engfuncs.pfnLightStyle)

View File

@ -48,7 +48,7 @@
<TargetName>$(ProjectName)_mm</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetName>$(ProjectName)_mm</TargetName>
<TargetName>$(ProjectName)</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@ -130,6 +130,7 @@
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>Default</CompileAs>
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
<PreprocessToFile>false</PreprocessToFile>
</ClCompile>
<Link>
<OutputFile>.\release/metamod.dll</OutputFile>
@ -175,6 +176,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\api_info.cpp" />
<ClCompile Include="..\src\callback_jit.cpp" />
<ClCompile Include="..\src\commands_meta.cpp" />
<ClCompile Include="..\src\conf_meta.cpp" />
<ClCompile Include="..\src\dllapi.cpp" />
@ -204,6 +206,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\api_info.h" />
<ClInclude Include="..\src\callback_jit.h" />
<ClInclude Include="..\src\commands_meta.h" />
<ClInclude Include="..\src\conf_meta.h" />
<ClInclude Include="..\src\dllapi.h" />
@ -211,18 +214,16 @@
<ClInclude Include="..\src\engine_t.h" />
<ClInclude Include="..\src\enginecallbacks.h" />
<ClInclude Include="..\src\game_support.h" />
<ClInclude Include="..\src\games.h" />
<ClInclude Include="..\src\h_export.h" />
<ClInclude Include="..\src\jitasm.h" />
<ClInclude Include="..\src\linkent.h" />
<ClInclude Include="..\src\log_meta.h" />
<ClInclude Include="..\src\meta_api.h" />
<ClInclude Include="..\src\meta_eiface.h" />
<ClInclude Include="..\src\metamod.h" />
<ClInclude Include="..\src\mhook.h" />
<ClInclude Include="..\src\mlist.h" />
<ClInclude Include="..\src\mplayer.h" />
<ClInclude Include="..\src\mplugin.h" />
<ClInclude Include="..\src\mqueue.h" />
<ClInclude Include="..\src\mreg.h" />
<ClInclude Include="..\src\mutil.h" />
<ClInclude Include="..\src\osdep.h" />

View File

@ -83,6 +83,9 @@
<ClCompile Include="..\src\utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\callback_jit.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\api_info.h">
@ -109,9 +112,6 @@
<ClInclude Include="..\src\game_support.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\games.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\h_export.h">
<Filter>Source Files</Filter>
</ClInclude>
@ -130,9 +130,6 @@
<ClInclude Include="..\src\metamod.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\mhook.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\mlist.h">
<Filter>Source Files</Filter>
</ClInclude>
@ -142,9 +139,6 @@
<ClInclude Include="..\src\mplugin.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\mqueue.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\mreg.h">
<Filter>Source Files</Filter>
</ClInclude>
@ -178,6 +172,12 @@
<ClInclude Include="..\src\utils.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\callback_jit.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\jitasm.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="metamod.def">

View File

@ -1,234 +1,239 @@
#include "precompiled.h"
#define API_ENTRY(table, name, loglevel) { offsetof(table, pfn##name), #table "::" #name, loglevel }
#define DLLAPI_ENTRY(name, loglevel) API_ENTRY(DLL_FUNCTIONS, name, loglevel)
#define NEWAPI_ENTRY(name, loglevel) API_ENTRY(NEW_DLL_FUNCTIONS, name, loglevel)
#define ENGAPI_ENTRY(name, loglevel) API_ENTRY(enginefuncs_t, name, loglevel)
// trace flag, loglevel, name
dllapi_info_t dllapi_info = {
{ mFALSE, 3, "GameDLLInit" }, // pfnGameInit
{ mFALSE, 10, "DispatchSpawn" }, // pfnSpawn
{ mFALSE, 16, "DispatchThink" }, // pfnThink
{ mFALSE, 9, "DispatchUse" }, // pfnUse
{ mFALSE, 11, "DispatchTouch" }, // pfnTouch
{ mFALSE, 9, "DispatchBlocked" }, // pfnBlocked
{ mFALSE, 10, "DispatchKeyValue" }, // pfnKeyValue
{ mFALSE, 9, "DispatchSave" }, // pfnSave
{ mFALSE, 9, "DispatchRestore" }, // pfnRestore
{ mFALSE, 20, "DispatchObjectCollsionBox" }, // pfnSetAbsBox
{ mFALSE, 9, "SaveWriteFields" }, // pfnSaveWriteFields
{ mFALSE, 9, "SaveReadFields" }, // pfnSaveReadFields
{ mFALSE, 9, "SaveGlobalState" }, // pfnSaveGlobalState
{ mFALSE, 9, "RestoreGlobalState" }, // pfnRestoreGlobalState
{ mFALSE, 9, "ResetGlobalState" }, // pfnResetGlobalState
{ mFALSE, 3, "ClientConnect" }, // pfnClientConnect
{ mFALSE, 3, "ClientDisconnect" }, // pfnClientDisconnect
{ mFALSE, 3, "ClientKill" }, // pfnClientKill
{ mFALSE, 3, "ClientPutInServer" }, // pfnClientPutInServer
{ mFALSE, 9, "ClientCommand" }, // pfnClientCommand
{ mFALSE, 11, "ClientUserInfoChanged" }, // pfnClientUserInfoChanged
{ mFALSE, 3, "ServerActivate" }, // pfnServerActivate
{ mFALSE, 3, "ServerDeactivate" }, // pfnServerDeactivate
{ mFALSE, 14, "PlayerPreThink" }, // pfnPlayerPreThink
{ mFALSE, 14, "PlayerPostThink" }, // pfnPlayerPostThink
{ mFALSE, 18, "StartFrame" }, // pfnStartFrame
{ mFALSE, 9, "ParmsNewLevel" }, // pfnParmsNewLevel
{ mFALSE, 9, "ParmsChangeLevel" }, // pfnParmsChangeLevel
{ mFALSE, 9, "GetGameDescription" }, // pfnGetGameDescription
{ mFALSE, 9, "PlayerCustomization" }, // pfnPlayerCustomization
{ mFALSE, 9, "SpectatorConnect" }, // pfnSpectatorConnect
{ mFALSE, 9, "SpectatorDisconnect" }, // pfnSpectatorDisconnect
{ mFALSE, 9, "SpectatorThink" }, // pfnSpectatorThink
{ mFALSE, 3, "Sys_Error" }, // pfnSys_Error
{ mFALSE, 13, "PM_Move" }, // pfnPM_Move
{ mFALSE, 9, "PM_Init" }, // pfnPM_Init
{ mFALSE, 9, "PM_FindTextureType" }, // pfnPM_FindTextureType
{ mFALSE, 12, "SetupVisibility" }, // pfnSetupVisibility
{ mFALSE, 12, "UpdateClientData" }, // pfnUpdateClientData
{ mFALSE, 16, "AddToFullPack" }, // pfnAddToFullPack
{ mFALSE, 9, "CreateBaseline" }, // pfnCreateBaseline
{ mFALSE, 9, "RegisterEncoders" }, // pfnRegisterEncoders
{ mFALSE, 9, "GetWeaponData" }, // pfnGetWeaponData
{ mFALSE, 15, "CmdStart" }, // pfnCmdStart
{ mFALSE, 15, "CmdEnd" }, // pfnCmdEnd
{ mFALSE, 9, "ConnectionlessPacket" }, // pfnConnectionlessPacket
{ mFALSE, 9, "GetHullBounds" }, // pfnGetHullBounds
{ mFALSE, 9, "CreateInstancedBaselines" }, // pfnCreateInstancedBaselines
{ mFALSE, 3, "InconsistentFile" }, // pfnInconsistentFile
{ mFALSE, 20, "AllowLagCompensation" }, // pfnAllowLagCompensation
DLLAPI_ENTRY(GameInit, 1), // pfnGameInit
DLLAPI_ENTRY(Spawn, 2), // pfnSpawn
DLLAPI_ENTRY(Think, 2), // pfnThink
DLLAPI_ENTRY(Use, 2), // pfnUse
DLLAPI_ENTRY(Touch, 2), // pfnTouch
DLLAPI_ENTRY(Blocked, 2), // pfnBlocked
DLLAPI_ENTRY(KeyValue, 4), // pfnKeyValue
DLLAPI_ENTRY(Save, 4), // pfnSave
DLLAPI_ENTRY(Restore, 4), // pfnRestore
DLLAPI_ENTRY(SetAbsBox, 2), // pfnSetAbsBox
DLLAPI_ENTRY(SaveWriteFields, 4), // pfnSaveWriteFields
DLLAPI_ENTRY(SaveReadFields, 4), // pfnSaveReadFields
DLLAPI_ENTRY(SaveGlobalState, 4), // pfnSaveGlobalState
DLLAPI_ENTRY(RestoreGlobalState, 4), // pfnRestoreGlobalState
DLLAPI_ENTRY(ResetGlobalState, 4), // pfnResetGlobalState
DLLAPI_ENTRY(ClientConnect, 1), // pfnClientConnect
DLLAPI_ENTRY(ClientDisconnect, 1), // pfnClientDisconnect
DLLAPI_ENTRY(ClientKill, 2), // pfnClientKill
DLLAPI_ENTRY(ClientPutInServer, 1), // pfnClientPutInServer
DLLAPI_ENTRY(ClientCommand, 2), // pfnClientCommand
DLLAPI_ENTRY(ClientUserInfoChanged, 2), // pfnClientUserInfoChanged
DLLAPI_ENTRY(ServerActivate, 1), // pfnServerActivate
DLLAPI_ENTRY(ServerDeactivate, 1), // pfnServerDeactivate
DLLAPI_ENTRY(PlayerPreThink, 3), // pfnPlayerPreThink
DLLAPI_ENTRY(PlayerPostThink, 3), // pfnPlayerPostThink
DLLAPI_ENTRY(StartFrame, 4), // pfnStartFrame
DLLAPI_ENTRY(ParmsNewLevel, 4), // pfnParmsNewLevel
DLLAPI_ENTRY(ParmsChangeLevel, 4), // pfnParmsChangeLevel
DLLAPI_ENTRY(GetGameDescription, 3), // pfnGetGameDescription
DLLAPI_ENTRY(PlayerCustomization, 4), // pfnPlayerCustomization
DLLAPI_ENTRY(SpectatorConnect, 3), // pfnSpectatorConnect
DLLAPI_ENTRY(SpectatorDisconnect, 3), // pfnSpectatorDisconnect
DLLAPI_ENTRY(SpectatorThink, 3), // pfnSpectatorThink
DLLAPI_ENTRY(Sys_Error, 4), // pfnSys_Error
DLLAPI_ENTRY(PM_Move, 3), // pfnPM_Move
DLLAPI_ENTRY(PM_Init, 1), // pfnPM_Init
DLLAPI_ENTRY(PM_FindTextureType, 3), // pfnPM_FindTextureType
DLLAPI_ENTRY(SetupVisibility, 3), // pfnSetupVisibility
DLLAPI_ENTRY(UpdateClientData, 3), // pfnUpdateClientData
DLLAPI_ENTRY(AddToFullPack, 3), // pfnAddToFullPack
DLLAPI_ENTRY(CreateBaseline, 4), // pfnCreateBaseline
DLLAPI_ENTRY(RegisterEncoders, 4), // pfnRegisterEncoders
DLLAPI_ENTRY(GetWeaponData, 3), // pfnGetWeaponData
DLLAPI_ENTRY(CmdStart, 3), // pfnCmdStart
DLLAPI_ENTRY(CmdEnd, 3), // pfnCmdEnd
DLLAPI_ENTRY(ConnectionlessPacket, 4), // pfnConnectionlessPacket
DLLAPI_ENTRY(GetHullBounds, 3), // pfnGetHullBounds
DLLAPI_ENTRY(CreateInstancedBaselines, 4), // pfnCreateInstancedBaselines
DLLAPI_ENTRY(InconsistentFile, 3), // pfnInconsistentFile
DLLAPI_ENTRY(AllowLagCompensation, 4), // pfnAllowLagCompensation
{ mFALSE, 0, nullptr },
{ 0, "", 0 },
};
newapi_info_t newapi_info = {
{ mFALSE, 16, "OnFreeEntPrivateData" }, // pfnOnFreeEntPrivateData
{ mFALSE, 3, "GameShutdown" }, // pfnGameShutdown
{ mFALSE, 14, "ShouldCollide" }, // pfnShouldCollide
{ mFALSE, 3, "CvarValue" }, // pfnCvarValue
{ mFALSE, 3, "CvarValue2" }, // pfnCvarValue2
NEWAPI_ENTRY(OnFreeEntPrivateData, 3), // pfnOnFreeEntPrivateData
NEWAPI_ENTRY(GameShutdown, 3), // pfnGameShutdown
NEWAPI_ENTRY(ShouldCollide, 3), // pfnShouldCollide
NEWAPI_ENTRY(CvarValue, 2), // pfnCvarValue
NEWAPI_ENTRY(CvarValue2, 2), // pfnCvarValue2
{ mFALSE, 0, nullptr },
{ 0, "", 0 },
};
engine_info_t engine_info = {
{ mFALSE, 13, "PrecacheModel" }, // pfnPrecacheModel
{ mFALSE, 13, "PrecacheSound" }, // pfnPrecacheSound
{ mFALSE, 18, "SetModel" }, // pfnSetModel
{ mFALSE, 34, "ModelIndex" }, // pfnModelIndex
{ mFALSE, 10, "ModelFrames" }, // pfnModelFrames
{ mFALSE, 14, "SetSize" }, // pfnSetSize
{ mFALSE, 9, "ChangeLevel" }, // pfnChangeLevel
{ mFALSE, 9, "GetSpawnParms" }, // pfnGetSpawnParms
{ mFALSE, 9, "SaveSpawnParms" }, // pfnSaveSpawnParms
{ mFALSE, 9, "VecToYaw" }, // pfnVecToYaw
{ mFALSE, 14, "VecToAngles" }, // pfnVecToAngles
{ mFALSE, 9, "MoveToOrigin" }, // pfnMoveToOrigin
{ mFALSE, 9, "ChangeYaw" }, // pfnChangeYaw
{ mFALSE, 9, "ChangePitch" }, // pfnChangePitch
{ mFALSE, 32, "FindEntityByString" }, // pfnFindEntityByString
{ mFALSE, 9, "GetEntityIllum" }, // pfnGetEntityIllum
{ mFALSE, 9, "FindEntityInSphere" }, // pfnFindEntityInSphere
{ mFALSE, 19, "FindClientInPVS" }, // pfnFindClientInPVS
{ mFALSE, 9, "EntitiesInPVS" }, // pfnEntitiesInPVS
{ mFALSE, 40, "MakeVectors" }, // pfnMakeVectors
{ mFALSE, 9, "AngleVectors" }, // pfnAngleVectors
{ mFALSE, 13, "CreateEntity" }, // pfnCreateEntity
{ mFALSE, 13, "RemoveEntity" }, // pfnRemoveEntity
{ mFALSE, 13, "CreateNamedEntity" }, // pfnCreateNamedEntity
{ mFALSE, 9, "MakeStatic" }, // pfnMakeStatic
{ mFALSE, 9, "EntIsOnFloor" }, // pfnEntIsOnFloor
{ mFALSE, 9, "DropToFloor" }, // pfnDropToFloor
{ mFALSE, 9, "WalkMove" }, // pfnWalkMove
{ mFALSE, 14, "SetOrigin" }, // pfnSetOrigin
{ mFALSE, 12, "EmitSound" }, // pfnEmitSound
{ mFALSE, 12, "EmitAmbientSound" }, // pfnEmitAmbientSound
{ mFALSE, 20, "TraceLine" }, // pfnTraceLine
{ mFALSE, 9, "TraceToss" }, // pfnTraceToss
{ mFALSE, 9, "TraceMonsterHull" }, // pfnTraceMonsterHull
{ mFALSE, 9, "TraceHull" }, // pfnTraceHull
{ mFALSE, 9, "TraceModel" }, // pfnTraceModel
{ mFALSE, 15, "TraceTexture" }, // pfnTraceTexture // CS: when moving
{ mFALSE, 9, "TraceSphere" }, // pfnTraceSphere
{ mFALSE, 9, "GetAimVector" }, // pfnGetAimVector
{ mFALSE, 9, "ServerCommand" }, // pfnServerCommand
{ mFALSE, 9, "ServerExecute" }, // pfnServerExecute
{ mFALSE, 11, "engClientCommand" }, // pfnClientCommand // d'oh, ClientCommand in dllapi too
{ mFALSE, 9, "ParticleEffect" }, // pfnParticleEffect
{ mFALSE, 9, "LightStyle" }, // pfnLightStyle
{ mFALSE, 9, "DecalIndex" }, // pfnDecalIndex
{ mFALSE, 15, "PointContents" }, // pfnPointContents // CS: when moving
{ mFALSE, 22, "MessageBegin" }, // pfnMessageBegin
{ mFALSE, 22, "MessageEnd" }, // pfnMessageEnd
{ mFALSE, 30, "WriteByte" }, // pfnWriteByte
{ mFALSE, 23, "WriteChar" }, // pfnWriteChar
{ mFALSE, 24, "WriteShort" }, // pfnWriteShort
{ mFALSE, 23, "WriteLong" }, // pfnWriteLong
{ mFALSE, 23, "WriteAngle" }, // pfnWriteAngle
{ mFALSE, 23, "WriteCoord" }, // pfnWriteCoord
{ mFALSE, 25, "WriteString" }, // pfnWriteString
{ mFALSE, 23, "WriteEntity" }, // pfnWriteEntity
{ mFALSE, 9, "CVarRegister" }, // pfnCVarRegister
{ mFALSE, 21, "CVarGetFloat" }, // pfnCVarGetFloat
{ mFALSE, 9, "CVarGetString" }, // pfnCVarGetString
{ mFALSE, 10, "CVarSetFloat" }, // pfnCVarSetFloat
{ mFALSE, 9, "CVarSetString" }, // pfnCVarSetString
{ mFALSE, 15, "AlertMessage" }, // pfnAlertMessage
{ mFALSE, 17, "EngineFprintf" }, // pfnEngineFprintf
{ mFALSE, 14, "PvAllocEntPrivateData" }, // pfnPvAllocEntPrivateData
{ mFALSE, 9, "PvEntPrivateData" }, // pfnPvEntPrivateData
{ mFALSE, 9, "FreeEntPrivateData" }, // pfnFreeEntPrivateData
{ mFALSE, 9, "SzFromIndex" }, // pfnSzFromIndex
{ mFALSE, 10, "AllocString" }, // pfnAllocString
{ mFALSE, 9, "GetVarsOfEnt" }, // pfnGetVarsOfEnt
{ mFALSE, 14, "PEntityOfEntOffset" }, // pfnPEntityOfEntOffset
{ mFALSE, 19, "EntOffsetOfPEntity" }, // pfnEntOffsetOfPEntity
{ mFALSE, 14, "IndexOfEdict" }, // pfnIndexOfEdict
{ mFALSE, 17, "PEntityOfEntIndex" }, // pfnPEntityOfEntIndex
{ mFALSE, 9, "FindEntityByVars" }, // pfnFindEntityByVars
{ mFALSE, 14, "GetModelPtr" }, // pfnGetModelPtr
{ mFALSE, 9, "RegUserMsg" }, // pfnRegUserMsg
{ mFALSE, 9, "AnimationAutomove" }, // pfnAnimationAutomove
{ mFALSE, 9, "GetBonePosition" }, // pfnGetBonePosition
{ mFALSE, 9, "FunctionFromName" }, // pfnFunctionFromName
{ mFALSE, 9, "NameForFunction" }, // pfnNameForFunction
{ mFALSE, 9, "ClientPrintf" }, // pfnClientPrintf
{ mFALSE, 9, "ServerPrint" }, // pfnServerPrint
{ mFALSE, 13, "Cmd_Args" }, // pfnCmd_Args
{ mFALSE, 13, "Cmd_Argv" }, // pfnCmd_Argv
{ mFALSE, 13, "Cmd_Argc" }, // pfnCmd_Argc
{ mFALSE, 9, "GetAttachment" }, // pfnGetAttachment
{ mFALSE, 9, "CRC32_Init" }, // pfnCRC32_Init
{ mFALSE, 9, "CRC32_ProcessBuffer" }, // pfnCRC32_ProcessBuffer
{ mFALSE, 9, "CRC32_ProcessByte" }, // pfnCRC32_ProcessByte
{ mFALSE, 9, "CRC32_Final" }, // pfnCRC32_Final
{ mFALSE, 16, "RandomLong" }, // pfnRandomLong
{ mFALSE, 14, "RandomFloat" }, // pfnRandomFloat // CS: when firing
{ mFALSE, 14, "SetView" }, // pfnSetView
{ mFALSE, 9, "Time" }, // pfnTime
{ mFALSE, 9, "CrosshairAngle" }, // pfnCrosshairAngle
{ mFALSE, 10, "LoadFileForMe" }, // pfnLoadFileForMe
{ mFALSE, 10, "FreeFile" }, // pfnFreeFile
{ mFALSE, 9, "EndSection" }, // pfnEndSection
{ mFALSE, 9, "CompareFileTime" }, // pfnCompareFileTime
{ mFALSE, 9, "GetGameDir" }, // pfnGetGameDir
{ mFALSE, 9, "Cvar_RegisterVariable" }, // pfnCvar_RegisterVariable
{ mFALSE, 9, "FadeClientVolume" }, // pfnFadeClientVolume
{ mFALSE, 14, "SetClientMaxspeed" }, // pfnSetClientMaxspeed
{ mFALSE, 9, "CreateFakeClient" }, // pfnCreateFakeClient
{ mFALSE, 9, "RunPlayerMove" }, // pfnRunPlayerMove
{ mFALSE, 9, "NumberOfEntities" }, // pfnNumberOfEntities
{ mFALSE, 17, "GetInfoKeyBuffer" }, // pfnGetInfoKeyBuffer
{ mFALSE, 13, "InfoKeyValue" }, // pfnInfoKeyValue
{ mFALSE, 9, "SetKeyValue" }, // pfnSetKeyValue
{ mFALSE, 12, "SetClientKeyValue" }, // pfnSetClientKeyValue
{ mFALSE, 9, "IsMapValid" }, // pfnIsMapValid
{ mFALSE, 9, "StaticDecal" }, // pfnStaticDecal
{ mFALSE, 9, "PrecacheGeneric" }, // pfnPrecacheGeneric
{ mFALSE, 10, "GetPlayerUserId" }, // pfnGetPlayerUserId
{ mFALSE, 9, "BuildSoundMsg" }, // pfnBuildSoundMsg
{ mFALSE, 9, "IsDedicatedServer" }, // pfnIsDedicatedServer
{ mFALSE, 9, "CVarGetPointer" }, // pfnCVarGetPointer
{ mFALSE, 9, "GetPlayerWONId" }, // pfnGetPlayerWONId
{ mFALSE, 9, "Info_RemoveKey" }, // pfnInfo_RemoveKey
{ mFALSE, 15, "GetPhysicsKeyValue" }, // pfnGetPhysicsKeyValue
{ mFALSE, 14, "SetPhysicsKeyValue" }, // pfnSetPhysicsKeyValue
{ mFALSE, 15, "GetPhysicsInfoString" }, // pfnGetPhysicsInfoString
{ mFALSE, 13, "PrecacheEvent" }, // pfnPrecacheEvent
{ mFALSE, 9, "PlaybackEvent" }, // pfnPlaybackEvent
{ mFALSE, 31, "SetFatPVS" }, // pfnSetFatPVS
{ mFALSE, 31, "SetFatPAS" }, // pfnSetFatPAS
{ mFALSE, 50, "CheckVisibility" }, // pfnCheckVisibility
{ mFALSE, 37, "DeltaSetField" }, // pfnDeltaSetField
{ mFALSE, 38, "DeltaUnsetField" }, // pfnDeltaUnsetField
{ mFALSE, 9, "DeltaAddEncoder" }, // pfnDeltaAddEncoder
{ mFALSE, 45, "GetCurrentPlayer" }, // pfnGetCurrentPlayer
{ mFALSE, 14, "CanSkipPlayer" }, // pfnCanSkipPlayer
{ mFALSE, 9, "DeltaFindField" }, // pfnDeltaFindField
{ mFALSE, 37, "DeltaSetFieldByIndex" }, // pfnDeltaSetFieldByIndex
{ mFALSE, 38, "DeltaUnsetFieldByIndex" }, // pfnDeltaUnsetFieldByIndex
{ mFALSE, 9, "SetGroupMask" }, // pfnSetGroupMask
{ mFALSE, 9, "engCreateInstancedBaseline" }, // pfnCreateInstancedBaseline // d'oh, CreateInstancedBaseline in dllapi too
{ mFALSE, 9, "Cvar_DirectSet" }, // pfnCvar_DirectSet
{ mFALSE, 9, "ForceUnmodified" }, // pfnForceUnmodified
{ mFALSE, 9, "GetPlayerStats" }, // pfnGetPlayerStats
{ mFALSE, 3, "AddServerCommand" }, // pfnAddServerCommand
ENGAPI_ENTRY(PrecacheModel, 2), // pfnPrecacheModel
ENGAPI_ENTRY(PrecacheSound, 2), // pfnPrecacheSound
ENGAPI_ENTRY(SetModel, 2), // pfnSetModel
ENGAPI_ENTRY(ModelIndex, 2), // pfnModelIndex
ENGAPI_ENTRY(ModelFrames, 3), // pfnModelFrames
ENGAPI_ENTRY(SetSize, 2), // pfnSetSize
ENGAPI_ENTRY(ChangeLevel, 2), // pfnChangeLevel
ENGAPI_ENTRY(GetSpawnParms, 4), // pfnGetSpawnParms
ENGAPI_ENTRY(SaveSpawnParms, 4), // pfnSaveSpawnParms
ENGAPI_ENTRY(VecToYaw, 3), // pfnVecToYaw
ENGAPI_ENTRY(VecToAngles, 3), // pfnVecToAngles
ENGAPI_ENTRY(MoveToOrigin, 3), // pfnMoveToOrigin
ENGAPI_ENTRY(ChangeYaw, 3), // pfnChangeYaw
ENGAPI_ENTRY(ChangePitch, 3), // pfnChangePitch
ENGAPI_ENTRY(FindEntityByString, 2), // pfnFindEntityByString
ENGAPI_ENTRY(GetEntityIllum, 4), // pfnGetEntityIllum
ENGAPI_ENTRY(FindEntityInSphere, 2), // pfnFindEntityInSphere
ENGAPI_ENTRY(FindClientInPVS, 2), // pfnFindClientInPVS
ENGAPI_ENTRY(EntitiesInPVS, 2), // pfnEntitiesInPVS
ENGAPI_ENTRY(MakeVectors, 3), // pfnMakeVectors
ENGAPI_ENTRY(AngleVectors, 3), // pfnAngleVectors
ENGAPI_ENTRY(CreateEntity, 2), // pfnCreateEntity
ENGAPI_ENTRY(RemoveEntity, 2), // pfnRemoveEntity
ENGAPI_ENTRY(CreateNamedEntity, 2), // pfnCreateNamedEntity
ENGAPI_ENTRY(MakeStatic, 2), // pfnMakeStatic
ENGAPI_ENTRY(EntIsOnFloor, 2), // pfnEntIsOnFloor
ENGAPI_ENTRY(DropToFloor, 2), // pfnDropToFloor
ENGAPI_ENTRY(WalkMove, 2), // pfnWalkMove
ENGAPI_ENTRY(SetOrigin, 2), // pfnSetOrigin
ENGAPI_ENTRY(EmitSound, 2), // pfnEmitSound
ENGAPI_ENTRY(EmitAmbientSound, 2), // pfnEmitAmbientSound
ENGAPI_ENTRY(TraceLine, 2), // pfnTraceLine
ENGAPI_ENTRY(TraceToss, 2), // pfnTraceToss
ENGAPI_ENTRY(TraceMonsterHull, 2), // pfnTraceMonsterHull
ENGAPI_ENTRY(TraceHull, 2), // pfnTraceHull
ENGAPI_ENTRY(TraceModel, 2), // pfnTraceModel
ENGAPI_ENTRY(TraceTexture, 2), // pfnTraceTexture // CS: when moving
ENGAPI_ENTRY(TraceSphere, 2), // pfnTraceSphere
ENGAPI_ENTRY(GetAimVector, 2), // pfnGetAimVector
ENGAPI_ENTRY(ServerCommand, 3), // pfnServerCommand
ENGAPI_ENTRY(ServerExecute, 3), // pfnServerExecute
ENGAPI_ENTRY(ClientCommand, 3), // pfnClientCommand // d'oh, ClientCommand in dllapi too
ENGAPI_ENTRY(ParticleEffect, 4), // pfnParticleEffect
ENGAPI_ENTRY(LightStyle, 2), // pfnLightStyle
ENGAPI_ENTRY(DecalIndex, 2), // pfnDecalIndex
ENGAPI_ENTRY(PointContents, 2), // pfnPointContents // CS: when moving
ENGAPI_ENTRY(MessageBegin, 3), // pfnMessageBegin
ENGAPI_ENTRY(MessageEnd, 3), // pfnMessageEnd
ENGAPI_ENTRY(WriteByte, 3), // pfnWriteByte
ENGAPI_ENTRY(WriteChar, 3), // pfnWriteChar
ENGAPI_ENTRY(WriteShort, 3), // pfnWriteShort
ENGAPI_ENTRY(WriteLong, 3), // pfnWriteLong
ENGAPI_ENTRY(WriteAngle, 3), // pfnWriteAngle
ENGAPI_ENTRY(WriteCoord, 3), // pfnWriteCoord
ENGAPI_ENTRY(WriteString, 3), // pfnWriteString
ENGAPI_ENTRY(WriteEntity, 3), // pfnWriteEntity
ENGAPI_ENTRY(CVarRegister, 2), // pfnCVarRegister
ENGAPI_ENTRY(CVarGetFloat, 2), // pfnCVarGetFloat
ENGAPI_ENTRY(CVarGetString, 2), // pfnCVarGetString
ENGAPI_ENTRY(CVarSetFloat, 2), // pfnCVarSetFloat
ENGAPI_ENTRY(CVarSetString, 2), // pfnCVarSetString
ENGAPI_ENTRY(AlertMessage, 3), // pfnAlertMessage
ENGAPI_ENTRY(EngineFprintf, 3), // pfnEngineFprintf
ENGAPI_ENTRY(PvAllocEntPrivateData, 2), // pfnPvAllocEntPrivateData
ENGAPI_ENTRY(PvEntPrivateData, 2), // pfnPvEntPrivateData
ENGAPI_ENTRY(FreeEntPrivateData, 2), // pfnFreeEntPrivateData
ENGAPI_ENTRY(SzFromIndex, 3), // pfnSzFromIndex
ENGAPI_ENTRY(AllocString, 3), // pfnAllocString
ENGAPI_ENTRY(GetVarsOfEnt, 2), // pfnGetVarsOfEnt
ENGAPI_ENTRY(PEntityOfEntOffset, 3), // pfnPEntityOfEntOffset
ENGAPI_ENTRY(EntOffsetOfPEntity, 3), // pfnEntOffsetOfPEntity
ENGAPI_ENTRY(IndexOfEdict, 3), // pfnIndexOfEdict
ENGAPI_ENTRY(PEntityOfEntIndex, 3), // pfnPEntityOfEntIndex
ENGAPI_ENTRY(FindEntityByVars, 3), // pfnFindEntityByVars
ENGAPI_ENTRY(GetModelPtr, 3), // pfnGetModelPtr
ENGAPI_ENTRY(RegUserMsg, 3), // pfnRegUserMsg
ENGAPI_ENTRY(AnimationAutomove, 2), // pfnAnimationAutomove
ENGAPI_ENTRY(GetBonePosition, 2), // pfnGetBonePosition
ENGAPI_ENTRY(FunctionFromName, 4), // pfnFunctionFromName
ENGAPI_ENTRY(NameForFunction, 4), // pfnNameForFunction
ENGAPI_ENTRY(ClientPrintf, 3), // pfnClientPrintf
ENGAPI_ENTRY(ServerPrint, 3), // pfnServerPrint
ENGAPI_ENTRY(Cmd_Args, 3), // pfnCmd_Args
ENGAPI_ENTRY(Cmd_Argv, 3), // pfnCmd_Argv
ENGAPI_ENTRY(Cmd_Argc, 3), // pfnCmd_Argc
ENGAPI_ENTRY(GetAttachment, 2), // pfnGetAttachment
ENGAPI_ENTRY(CRC32_Init, 4), // pfnCRC32_Init
ENGAPI_ENTRY(CRC32_ProcessBuffer, 4), // pfnCRC32_ProcessBuffer
ENGAPI_ENTRY(CRC32_ProcessByte, 4), // pfnCRC32_ProcessByte
ENGAPI_ENTRY(CRC32_Final, 4), // pfnCRC32_Final
ENGAPI_ENTRY(RandomLong, 3), // pfnRandomLong
ENGAPI_ENTRY(RandomFloat, 3), // pfnRandomFloat // CS: when firing
ENGAPI_ENTRY(SetView, 2), // pfnSetView
ENGAPI_ENTRY(Time, 2), // pfnTime
ENGAPI_ENTRY(CrosshairAngle, 2), // pfnCrosshairAngle
ENGAPI_ENTRY(LoadFileForMe, 4), // pfnLoadFileForMe
ENGAPI_ENTRY(FreeFile, 4), // pfnFreeFile
ENGAPI_ENTRY(EndSection, 4), // pfnEndSection
ENGAPI_ENTRY(CompareFileTime, 4), // pfnCompareFileTime
ENGAPI_ENTRY(GetGameDir, 3), // pfnGetGameDir
ENGAPI_ENTRY(Cvar_RegisterVariable, 2), // pfnCvar_RegisterVariable
ENGAPI_ENTRY(FadeClientVolume, 2), // pfnFadeClientVolume
ENGAPI_ENTRY(SetClientMaxspeed, 3), // pfnSetClientMaxspeed
ENGAPI_ENTRY(CreateFakeClient, 2), // pfnCreateFakeClient
ENGAPI_ENTRY(RunPlayerMove, 3), // pfnRunPlayerMove
ENGAPI_ENTRY(NumberOfEntities, 2), // pfnNumberOfEntities
ENGAPI_ENTRY(GetInfoKeyBuffer, 2), // pfnGetInfoKeyBuffer
ENGAPI_ENTRY(InfoKeyValue, 2), // pfnInfoKeyValue
ENGAPI_ENTRY(SetKeyValue, 2), // pfnSetKeyValue
ENGAPI_ENTRY(SetClientKeyValue, 2), // pfnSetClientKeyValue
ENGAPI_ENTRY(IsMapValid, 2), // pfnIsMapValid
ENGAPI_ENTRY(StaticDecal, 2), // pfnStaticDecal
ENGAPI_ENTRY(PrecacheGeneric, 2), // pfnPrecacheGeneric
ENGAPI_ENTRY(GetPlayerUserId, 2), // pfnGetPlayerUserId
ENGAPI_ENTRY(BuildSoundMsg, 2), // pfnBuildSoundMsg
ENGAPI_ENTRY(IsDedicatedServer, 2), // pfnIsDedicatedServer
ENGAPI_ENTRY(CVarGetPointer, 3), // pfnCVarGetPointer
ENGAPI_ENTRY(GetPlayerWONId, 4), // pfnGetPlayerWONId
ENGAPI_ENTRY(Info_RemoveKey, 2), // pfnInfo_RemoveKey
ENGAPI_ENTRY(GetPhysicsKeyValue, 2), // pfnGetPhysicsKeyValue
ENGAPI_ENTRY(SetPhysicsKeyValue, 2), // pfnSetPhysicsKeyValue
ENGAPI_ENTRY(GetPhysicsInfoString, 2), // pfnGetPhysicsInfoString
ENGAPI_ENTRY(PrecacheEvent, 2), // pfnPrecacheEvent
ENGAPI_ENTRY(PlaybackEvent, 2), // pfnPlaybackEvent
ENGAPI_ENTRY(SetFatPVS, 2), // pfnSetFatPVS
ENGAPI_ENTRY(SetFatPAS, 2), // pfnSetFatPAS
ENGAPI_ENTRY(CheckVisibility, 2), // pfnCheckVisibility
ENGAPI_ENTRY(DeltaSetField, 3), // pfnDeltaSetField
ENGAPI_ENTRY(DeltaUnsetField, 3), // pfnDeltaUnsetField
ENGAPI_ENTRY(DeltaAddEncoder, 3), // pfnDeltaAddEncoder
ENGAPI_ENTRY(GetCurrentPlayer, 2), // pfnGetCurrentPlayer
ENGAPI_ENTRY(CanSkipPlayer, 2), // pfnCanSkipPlayer
ENGAPI_ENTRY(DeltaFindField, 3), // pfnDeltaFindField
ENGAPI_ENTRY(DeltaSetFieldByIndex, 3), // pfnDeltaSetFieldByIndex
ENGAPI_ENTRY(DeltaUnsetFieldByIndex, 3), // pfnDeltaUnsetFieldByIndex
ENGAPI_ENTRY(SetGroupMask, 2), // pfnSetGroupMask
ENGAPI_ENTRY(CreateInstancedBaseline, 3), // pfnCreateInstancedBaseline // d'oh, CreateInstancedBaseline in dllapi too
ENGAPI_ENTRY(Cvar_DirectSet, 2), // pfnCvar_DirectSet
ENGAPI_ENTRY(ForceUnmodified, 2), // pfnForceUnmodified
ENGAPI_ENTRY(GetPlayerStats, 2), // pfnGetPlayerStats
ENGAPI_ENTRY(AddServerCommand, 2), // pfnAddServerCommand
{ mFALSE, 9, "Voice_GetClientListening" }, // Voice_GetClientListening
{ mFALSE, 9, "Voice_SetClientListening" }, // Voice_SetClientListening
{ mFALSE, 9, "GetPlayerAuthId" }, // pfnGetPlayerAuthId
{ mFALSE, 30, "SequenceGet" }, // pfnSequenceGet
ENGAPI_ENTRY(Voice_GetClientListening, 2), // Voice_GetClientListening
ENGAPI_ENTRY(Voice_SetClientListening, 2), // Voice_SetClientListening
ENGAPI_ENTRY(GetPlayerAuthId, 2), // pfnGetPlayerAuthId
ENGAPI_ENTRY(SequenceGet, 2), // pfnSequenceGet
{ mFALSE, 30, "SequencePickSentence" }, // pfnSequencePickSentence
{ mFALSE, 30, "GetFileSize" }, // pfnGetFileSize
{ mFALSE, 30, "GetApproxWavePlayLen" }, // pfnGetApproxWavePlayLen
{ mFALSE, 30, "IsCareerMatch" }, // pfnIsCareerMatch
{ mFALSE, 30, "GetLocalizedStringLength" }, // pfnGetLocalizedStringLength
{ mFALSE, 30, "RegisterTutorMessageShown" }, // pfnRegisterTutorMessageShown
{ mFALSE, 30, "GetTimesTutorMessageShown" }, // pfnGetTimesTutorMessageShown
{ mFALSE, 30, "ProcessTutorMessageDecayBuffer" }, // pfnProcessTutorMessageDecayBuffer
{ mFALSE, 30, "ConstructTutorMessageDecayBuffer" }, // pfnConstructTutorMessageDecayBuffer
{ mFALSE, 9, "ResetTutorMessageDecayData" }, // pfnResetTutorMessageDecayData
ENGAPI_ENTRY(SequencePickSentence, 2), // pfnSequencePickSentence
ENGAPI_ENTRY(GetFileSize, 4), // pfnGetFileSize
ENGAPI_ENTRY(GetApproxWavePlayLen, 4), // pfnGetApproxWavePlayLen
ENGAPI_ENTRY(IsCareerMatch, 4), // pfnIsCareerMatch
ENGAPI_ENTRY(GetLocalizedStringLength, 4), // pfnGetLocalizedStringLength
ENGAPI_ENTRY(RegisterTutorMessageShown, 4), // pfnRegisterTutorMessageShown
ENGAPI_ENTRY(GetTimesTutorMessageShown, 4), // pfnGetTimesTutorMessageShown
ENGAPI_ENTRY(ProcessTutorMessageDecayBuffer, 4), // pfnProcessTutorMessageDecayBuffer
ENGAPI_ENTRY(ConstructTutorMessageDecayBuffer, 4), // pfnConstructTutorMessageDecayBuffer
ENGAPI_ENTRY(ResetTutorMessageDecayData, 4), // pfnResetTutorMessageDecayData
{ mFALSE, 3, "QueryClientCvarValue" }, //pfnQueryClientCvarValue
{ mFALSE, 3, "QueryClientCvarValue2" }, //pfnQueryClientCvarValue2
{ mFALSE, 8, "CheckParm" }, //pfnCheckParm
ENGAPI_ENTRY(QueryClientCvarValue, 2), //pfnQueryClientCvarValue
ENGAPI_ENTRY(QueryClientCvarValue2, 2), //pfnQueryClientCvarValue2
ENGAPI_ENTRY(EngCheckParm, 2), //pfnCheckParm
// end
{ mFALSE, 0, NULL },
{ 0, "", 0 },
};

View File

@ -7,9 +7,9 @@
struct api_info_t
{
mBOOL trace; // if true, log info about this function
int loglevel; // level at which to log info about this function
const char *name; // string representation of function name
size_t offset;
const char *name;
size_t loglevel;
};
// DLL api functions

View File

@ -0,0 +1,369 @@
#include "precompiled.h"
CJit g_jit;
class CUniqueLabel
{
public:
CUniqueLabel(const char* name) : m_name(name)
{
m_name += m_unique_index++;
}
operator std::string&()
{
return m_name;
}
private:
std::string m_name;
static size_t m_unique_index;
};
size_t CUniqueLabel::m_unique_index;
class CForwardCallbackJIT : public jitasm::function<int, CForwardCallbackJIT, int>
{
public:
CForwardCallbackJIT(jitdata_t *jitdata);
void naked_main();
void call_func(jitasm::Frontend::Reg32 addr);
private:
jitdata_t* m_jitdata;
enum
{
mg_mres = 0,
mg_prev_mres = 4,
mg_status = 8,
mg_orig_ret = 12,
mg_over_ret = 16,
};
};
CForwardCallbackJIT::CForwardCallbackJIT(jitdata_t* jitdata) : m_jitdata(jitdata)
{
}
void CForwardCallbackJIT::naked_main()
{
// prologue
push(ebp);
mov(ebp, esp);
push(ebx);
enum // stack map
{
orig_ret = 0,
over_ret = 4
};
auto globals = ebx;
auto mg_backup = m_jitdata->has_ret ? 8 : 0;
auto framesize = mg_backup + sizeof(meta_globals_t);
if (m_jitdata->has_varargs) {
sub(esp, framesize += MAX_STRBUF_LEN);
// format varargs
lea(edx, dword_ptr[ebp + 8 + m_jitdata->args_count * 4]); // varargs ptr
lea(eax, dword_ptr[esp + mg_backup + sizeof(meta_globals_t)]); // buf ptr
mov(ecx, size_t(vsnprintf));
push(edx);
push(dword_ptr[ebp + 8 + (m_jitdata->args_count - 1) * 4]); // last arg of pfn (format)
push(MAX_STRBUF_LEN);
push(eax);
call(ecx);
add(esp, 4 * sizeof(int));
}
else
sub(esp, framesize);
// setup globals ptr
mov(globals, size_t(&g_metaGlobals));
movups(xmm0, xmmword_ptr[globals]);
mov(eax, dword_ptr[globals + 16]);
movups(xmmword_ptr[esp + mg_backup], xmm0);
mov(dword_ptr[esp + mg_backup + 16], eax);
// call metamod's pre hook if present
if (m_jitdata->mm_hook && m_jitdata->mm_hook_time == P_PRE) {
mov(ecx, m_jitdata->mm_hook);
call_func(ecx);
}
// setup meta globals
mov(dword_ptr[globals + mg_mres], MRES_UNSET);
// setup retval pointers
if (m_jitdata->has_ret) {
lea(eax, dword_ptr[esp + over_ret]);
mov(dword_ptr[globals + mg_orig_ret], esp);
mov(dword_ptr[globals + mg_over_ret], eax);
}
// call pre
for (int i = 0, hookid = 0; i < m_jitdata->plugins_count; i++) {
auto plug = &m_jitdata->plugins[i];
size_t fn_table = *(size_t *)(size_t(plug) + m_jitdata->table_offset);
// plugin don't want any hooks from that table
if (!fn_table)
continue;
CUniqueLabel go_next_plugin("go_next_plugin");
// check status and handler set
cmp(byte_ptr[size_t(&plug->status)], PL_RUNNING);
mov(ecx, dword_ptr[fn_table + m_jitdata->pfn_offset]);
jnz(go_next_plugin);
jecxz(go_next_plugin);
if (hookid++) {
mov(eax, dword_ptr[globals + mg_mres]);
mov(dword_ptr[globals + mg_mres], MRES_IGNORED);
mov(dword_ptr[globals + mg_prev_mres], eax);
}
else { // init
xor_(eax, eax);
mov(dword_ptr[globals + mg_mres], MRES_IGNORED);
mov(dword_ptr[globals + mg_prev_mres], eax); // MRES_UNSET
mov(dword_ptr[globals + mg_status], eax); // NULL
}
call_func(ecx);
mov(edx, dword_ptr[globals + mg_mres]);
mov(ecx, dword_ptr[globals + mg_status]);
cmp(edx, ecx);
cmovg(ecx, edx);
mov(dword_ptr[globals + mg_status], ecx);
if (m_jitdata->has_ret) {
mov(ecx, dword_ptr[esp + over_ret]);
cmp(edx, MRES_SUPERCEDE);
cmovz(ecx, eax);
mov(dword_ptr[esp + over_ret], ecx);
}
L(go_next_plugin);
}
// call original if need
cmp(dword_ptr[globals + mg_status], MRES_SUPERCEDE);
jz("skip_original");
{
if (m_jitdata->pfn_original) {
mov(ecx, m_jitdata->pfn_original);
call_func(ecx);
}
if (m_jitdata->has_ret) {
if (m_jitdata->pfn_original)
mov(dword_ptr[esp + orig_ret], eax);
else
mov(dword_ptr[esp + orig_ret], TRUE); // for should collide :/
jmp("skip_supercede");
}
}
L("skip_original");
{
if (m_jitdata->has_ret) {
// if supercede
mov(eax, dword_ptr[esp + over_ret]);
mov(dword_ptr[esp + orig_ret], eax);
L("skip_supercede");
}
}
L("skip_all");
// call post
for (int i = 0, hookid = 0; i < m_jitdata->plugins_count; i++) {
auto plug = &m_jitdata->plugins[i];
size_t fn_table = *(size_t *)(size_t(plug) + m_jitdata->post_table_offset);
// plugin don't want any hooks from that table
if (!fn_table)
continue;
CUniqueLabel go_next_plugin("go_next_plugin");
// check status and handler set
cmp(byte_ptr[size_t(&plug->status)], PL_RUNNING);
mov(ecx, dword_ptr[fn_table + m_jitdata->pfn_offset]);
jnz(go_next_plugin);
jecxz(go_next_plugin);
if (hookid++) {
mov(eax, dword_ptr[globals + mg_mres]);
mov(dword_ptr[globals + mg_mres], MRES_IGNORED);
mov(dword_ptr[globals + mg_prev_mres], eax);
}
else { // init
xor_(eax, eax);
mov(dword_ptr[globals + mg_mres], MRES_IGNORED);
mov(dword_ptr[globals + mg_prev_mres], eax); // MRES_UNSET
mov(dword_ptr[globals + mg_status], eax); // NULL
}
call_func(ecx);
mov(edx, dword_ptr[globals + mg_mres]);
mov(ecx, dword_ptr[globals + mg_status]);
cmp(ecx, edx);
cmovl(ecx, edx);
mov(dword_ptr[globals + mg_status], ecx);
if (m_jitdata->has_ret) {
cmp(edx, MRES_SUPERCEDE);
mov(ecx, dword_ptr[esp + over_ret]);
cmovz(ecx, eax);
mov(dword_ptr[esp + over_ret], ecx);
}
L(go_next_plugin);
}
// call metamod's post hook if present
if (m_jitdata->mm_hook && m_jitdata->mm_hook_time == P_POST) {
mov(ecx, m_jitdata->mm_hook);
call_func(ecx);
}
movups(xmm0, xmmword_ptr[esp + mg_backup]);
mov(eax, dword_ptr[esp + mg_backup + 16]);
movups(xmmword_ptr[globals], xmm0);
mov(dword_ptr[globals + 16], eax);
if (m_jitdata->has_ret) {
mov(eax, dword_ptr[esp + orig_ret]);
cmp(dword_ptr[globals + mg_status], MRES_OVERRIDE);
cmovz(eax, dword_ptr[esp + over_ret]);
}
if (framesize) {
add(esp, framesize);
}
// epilogue
pop(ebx);
pop(ebp);
ret();
}
void CForwardCallbackJIT::call_func(jitasm::Frontend::Reg32 addr)
{
const size_t normal_args_count = m_jitdata->args_count - (m_jitdata->has_varargs ? 1u : 0u);
const size_t strbuf_stack_offset = (m_jitdata->has_ret ? 8u : 0u) + sizeof(meta_globals_t);
// push formatted buf
if (m_jitdata->has_varargs) {
lea(eax, dword_ptr[esp + strbuf_stack_offset]);
push(eax);
}
// push normal args
for (size_t j = normal_args_count; j > 0; j--)
push(dword_ptr[ebp + 8 + (j - 1) * 4]);
// call
call(addr);
// pop stack
if (m_jitdata->args_count)
add(esp, m_jitdata->args_count * 4);
}
class CSimpleJmp : public jitasm::function<void, CSimpleJmp>
{
public:
CSimpleJmp(size_t addr/*, size_t hook, size_t hook_time, size_t ret_backup*/);
void naked_main();
private:
size_t m_addr;
/*size_t m_hook;
size_t m_hook_time;
size_t m_ret_backup;*/
};
CSimpleJmp::CSimpleJmp(size_t addr/*, size_t hook, size_t hook_time, size_t ret_backup*/) : m_addr(addr)/*, m_hook(hook), m_hook_time(hook_time), m_ret_backup(ret_backup)*/
{
}
void CSimpleJmp::naked_main()
{
/*if (m_hook && m_hook_time == P_PRE) {
mov(ecx, m_hook);
pop(dword_ptr[m_ret_backup]);
call(ecx);
push(dword_ptr[m_ret_backup]);
}*/
jmp(dword_ptr[m_addr]);
/*if (m_hook && m_hook_time == P_POST) {
mov(ecx, m_hook);
pop(dword_ptr[m_ret_backup]);
call(ecx);
push(dword_ptr[m_ret_backup]);
}*/
}
size_t CJit::compile_callback(jitdata_t* jitdata)
{
if (!is_hook_needed(jitdata)) {
return jitdata->pfn_original;
}
CForwardCallbackJIT callback(jitdata);
callback.Assemble();
auto code = callback.GetCode();
auto codeSize = callback.GetCodeSize();
auto ptr = m_allocator.allocate(codeSize);
return (size_t)memcpy(ptr, code, codeSize);
}
size_t CJit::compile_tramp(size_t ptr_to_func/*, size_t hook, size_t hook_time*/)
{
CSimpleJmp jmp(ptr_to_func/*, hook, hook_time, size_t(m_static_allocator.allocate(sizeof(int)))*/);
jmp.Assemble();
auto code = jmp.GetCode();
auto codeSize = jmp.GetCodeSize();
auto ptr = m_static_allocator.allocate(codeSize);
return (size_t)memcpy(ptr, code, codeSize);
}
void CJit::clear_callbacks()
{
m_allocator.deallocate_all();
}
bool CJit::is_hook_needed(jitdata_t* jitdata)
{
if (jitdata->mm_hook)
return true;
if (!jitdata->plugins)
return false;
for (int i = 0, hookid = 0; i < jitdata->plugins_count; i++) {
auto plug = &jitdata->plugins[i];
const size_t fn_table = *(size_t *)(size_t(plug) + jitdata->table_offset);
const size_t fn_table_post = *(size_t *)(size_t(plug) + jitdata->post_table_offset);
if (fn_table || fn_table_post) {
return true;
}
}
return false;
}

View File

@ -0,0 +1,95 @@
#pragma once
#define CDATA_ENTRY(s, x, p, h) {#x, offsetof(s, x), getArgsCount(decltype(s##::##x)()), !is_void(decltype(s##::##x)()), is_varargs(decltype(s##::##x)()), p, h}
struct jitdata_t
{
size_t pfn_original;
uint8 args_count;
bool has_ret;
bool has_varargs;
uint8 mm_hook_time;
size_t pfn_offset; // from fn table
size_t mm_hook;
MPlugin* plugins;
int plugins_count;
size_t table_offset; // from MPlugin
size_t post_table_offset; // from MPlugin
};
struct compile_data_t
{
const char* name;
size_t offset;
uint8 args_count;
bool has_ret;
bool has_varargs;
uint8 mm_hook_time;
size_t mm_hook;
};
template<typename ret_t, typename ...t_args>
size_t getArgsCount(ret_t (*)(t_args...))
{
return sizeof...(t_args);
}
template<typename ret_t, typename ...t_args>
size_t getArgsCount(ret_t (*)(t_args..., ...))
{
return sizeof...(t_args);
}
template<typename ...t_args>
bool is_void(void (*)(t_args...))
{
return true;
}
template<typename ...t_args>
bool is_void(void (*)(t_args..., ...))
{
return true;
}
template<typename ret_t, typename ...t_args>
bool is_void(ret_t (*)(t_args..., ...))
{
return false;
}
template<typename ret_t, typename ...t_args>
bool is_void(ret_t (*)(t_args...))
{
return false;
}
template<typename ret_t, typename ...t_args>
bool is_varargs(ret_t (*)(t_args...))
{
return false;
}
template<typename ret_t, typename ...t_args>
bool is_varargs(ret_t (*)(t_args..., ...))
{
return true;
}
class CJit
{
public:
size_t compile_callback(jitdata_t* jitdata);
size_t compile_tramp(size_t ptr_to_func/*, size_t hook, size_t hook_time*/);
void clear_callbacks();
private:
static bool is_hook_needed(jitdata_t* jitdata);
private:
execmem_allocator m_allocator;
execmem_allocator m_static_allocator;
};
extern CJit g_jit;

View File

@ -201,7 +201,7 @@ void cmd_meta_refresh()
}
META_LOG("Refreshing the plugins on demand...");
if (g_plugins->refresh(PT_ANYTIME) != mTRUE)
if (g_plugins->refresh(PT_ANYTIME) != true)
{
META_LOG("Refresh failed.");
}

View File

@ -1,8 +1,6 @@
#include "precompiled.h"
MConfig::MConfig()
: list(nullptr), filename(nullptr), debuglevel(0),
plugins_file(nullptr), exec_cfg(nullptr)
MConfig::MConfig() : debuglevel(0), plugins_file(nullptr), exec_cfg(nullptr), list(nullptr), filename(nullptr)
{
}
@ -19,7 +17,7 @@ option_t *MConfig::find(const char* lookup) const
{
for (auto optp = list; optp->name; optp++)
{
if (!Q_strcmp(optp->name, lookup)) {
if (!strcmp(optp->name, lookup)) {
return optp;
}
}
@ -27,16 +25,16 @@ option_t *MConfig::find(const char* lookup) const
RETURN_ERRNO(NULL, ME_NOTFOUND);
}
mBOOL MConfig::set(const char* key, const char* value)
bool MConfig::set(const char* key, const char* value) const
{
option_t* optp = find(key);
if (optp)
return set(optp, value);
RETURN_ERRNO(mFALSE, ME_NOTFOUND);
RETURN_ERRNO(false, ME_NOTFOUND);
}
mBOOL MConfig::set(option_t* setp, const char* setstr)
bool MConfig::set(option_t* setp, const char* setstr)
{
char pathbuf[PATH_MAX ];
int* optval = (int *) setp->dest;
@ -45,7 +43,7 @@ mBOOL MConfig::set(option_t* setp, const char* setstr)
// SETOPT_FN optcmd = (SETOPT_FN) setp->dest;
if (!setstr)
return mTRUE;
return true;
switch (setp->type)
{
@ -53,7 +51,7 @@ mBOOL MConfig::set(option_t* setp, const char* setstr)
if (!isdigit(setstr[0]))
{
META_ERROR("option '%s' invalid format '%s'", setp->name, setstr);
RETURN_ERRNO(mFALSE, ME_FORMAT);
RETURN_ERRNO(false, ME_FORMAT);
}
*optval = Q_atoi(setstr);
META_DEBUG(3, ("set config int: %s = %d", setp->name, *optval));
@ -71,7 +69,7 @@ mBOOL MConfig::set(option_t* setp, const char* setstr)
{
META_ERROR("option '%s' invalid format '%s'", setp->name,
setstr);
RETURN_ERRNO(mFALSE, ME_FORMAT);
RETURN_ERRNO(false, ME_FORMAT);
}
META_DEBUG(3, ("set config bool: %s = %s", setp->name, *optval ? "true" : "false"));
break;
@ -90,13 +88,13 @@ mBOOL MConfig::set(option_t* setp, const char* setstr)
break;
default:
META_ERROR("unrecognized config type '%d'", setp->type);
RETURN_ERRNO(mFALSE, ME_ARGUMENT);
RETURN_ERRNO(false, ME_ARGUMENT);
}
return mTRUE;
return true;
}
mBOOL MConfig::load(const char* fn)
bool MConfig::load(const char* fn)
{
FILE* fp;
char loadfile[PATH_MAX ];
@ -113,7 +111,7 @@ mBOOL MConfig::load(const char* fn)
if (!fp)
{
META_ERROR("unable to open config file '%s': %s", loadfile, strerror(errno));
RETURN_ERRNO(mFALSE, ME_NOFILE);
RETURN_ERRNO(false, ME_NOFILE);
}
META_DEBUG(2, ("Loading from config file: %s", loadfile));
@ -149,7 +147,7 @@ mBOOL MConfig::load(const char* fn)
filename = Q_strdup(loadfile);
fclose(fp);
return mTRUE;
return true;
}
void MConfig::show() const

View File

@ -32,8 +32,8 @@ public:
char *exec_cfg; // ie metaexec.cfg, exec.cfg
void init(option_t *global_options);
mBOOL load(const char *filename);
mBOOL set(const char *key, const char *value);
bool load(const char *filename);
bool set(const char *key, const char *value) const;
void show() const;
private:
@ -41,7 +41,7 @@ private:
char *filename;
option_t *find(const char *lookup) const;
static mBOOL set(option_t *setp, const char *value);
static bool set(option_t *setp, const char *value);
// Private; to satisfy -Weffc++ "has pointer data members but does
// not override" copy/assignment constructor.
void operator=(const MConfig &src);

View File

@ -1,178 +1,38 @@
#include "precompiled.h"
// Original DLL routines, functions returning "void".
#define META_DLLAPI_HANDLE_void(FN_TYPE, pfnName, pfn_args) \
SETUP_API_CALLS_void(FN_TYPE, pfnName, dllapi_info); \
CALL_PLUGIN_API_void(P_PRE, pfnName, pfn_args, dllapi_table); \
CALL_GAME_API_void(pfnName, pfn_args, dllapi_table); \
CALL_PLUGIN_API_void(P_POST, pfnName, pfn_args, dllapi_post_table);
#define CDATA_DLL_H(x, p, h) CDATA_ENTRY(DLL_FUNCTIONS, x, p, size_t(h))
#define CDATA_DLL(x) CDATA_ENTRY(DLL_FUNCTIONS, x, P_PRE, 0u)
#define CDATA_NEWDLL_H(x, p, h) CDATA_ENTRY(NEW_DLL_FUNCTIONS, x, p, size_t(h))
#define CDATA_NEWDLL(x) CDATA_ENTRY(NEW_DLL_FUNCTIONS, x, P_PRE, 0u)
// Original DLL routines, functions returning an actual value.
#define META_DLLAPI_HANDLE(ret_t, ret_init, FN_TYPE, pfnName, pfn_args) \
SETUP_API_CALLS(ret_t, ret_init, FN_TYPE, pfnName, dllapi_info); \
CALL_PLUGIN_API(P_PRE, ret_init, pfnName, pfn_args, MRES_SUPERCEDE, dllapi_table); \
CALL_GAME_API(pfnName, pfn_args, dllapi_table); \
CALL_PLUGIN_API(P_POST, ret_init, pfnName, pfn_args, MRES_OVERRIDE, dllapi_post_table);
DLL_FUNCTIONS sFunctionTable;
DLL_FUNCTIONS sFunctionTable_jit;
DLL_FUNCTIONS *pHookedDllFunctions = &sFunctionTable;
NEW_DLL_FUNCTIONS sNewFunctionTable;
NEW_DLL_FUNCTIONS sNewFunctionTable_jit;
NEW_DLL_FUNCTIONS *pHookedNewDllFunctions = &sNewFunctionTable;
// The "new" api routines (just 3 right now), functions returning "void".
#define META_NEWAPI_HANDLE_void(FN_TYPE, pfnName, pfn_args) \
SETUP_API_CALLS_void(FN_TYPE, pfnName, newapi_info); \
CALL_PLUGIN_API_void(P_PRE, pfnName, pfn_args, newapi_table); \
CALL_GAME_API_void(pfnName, pfn_args, newapi_table); \
CALL_PLUGIN_API_void(P_POST, pfnName, pfn_args, newapi_post_table);
// The "new" api routines (just 3 right now), functions returning an actual value.
#define META_NEWAPI_HANDLE(ret_t, ret_init, FN_TYPE, pfnName, pfn_args) \
SETUP_API_CALLS(ret_t, ret_init, FN_TYPE, pfnName, newapi_info); \
CALL_PLUGIN_API(P_PRE, ret_init, pfnName, pfn_args, MRES_SUPERCEDE, newapi_table); \
CALL_GAME_API(pfnName, pfn_args, newapi_table); \
CALL_PLUGIN_API(P_POST, ret_init, pfnName, pfn_args, MRES_OVERRIDE, newapi_post_table);
void mm_GameDLLInit(void)
void mm_ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] )
{
META_DLLAPI_HANDLE_void(FN_GAMEINIT, pfnGameInit, ());
RETURN_API_void();
}
int mm_DispatchSpawn(edict_t *pent)
{
// Success == 0, Failure == -1 ?
META_DLLAPI_HANDLE(int, 0, FN_DISPATCHSPAWN, pfnSpawn, (pent));
RETURN_API();
}
void mm_DispatchThink(edict_t *pent)
{
META_DLLAPI_HANDLE_void(FN_DISPATCHTHINK, pfnThink, (pent));
RETURN_API_void();
}
void mm_DispatchUse(edict_t *pentUsed, edict_t *pentOther)
{
META_DLLAPI_HANDLE_void(FN_DISPATCHUSE, pfnUse, (pentUsed, pentOther));
RETURN_API_void();
}
void mm_DispatchTouch(edict_t *pentTouched, edict_t *pentOther)
{
META_DLLAPI_HANDLE_void(FN_DISPATCHTOUCH, pfnTouch, (pentTouched, pentOther));
RETURN_API_void();
}
void mm_DispatchBlocked(edict_t *pentBlocked, edict_t *pentOther)
{
META_DLLAPI_HANDLE_void(FN_DISPATCHBLOCKED, pfnBlocked, (pentBlocked, pentOther));
RETURN_API_void();
}
void mm_DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd)
{
META_DLLAPI_HANDLE_void(FN_DISPATCHKEYVALUE, pfnKeyValue, (pentKeyvalue, pkvd));
RETURN_API_void();
}
void mm_DispatchSave(edict_t *pent, SAVERESTOREDATA *pSaveData)
{
META_DLLAPI_HANDLE_void(FN_DISPATCHSAVE, pfnSave, (pent, pSaveData));
RETURN_API_void();
}
int mm_DispatchRestore(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity)
{
// Success == 0, Failure == -1 ?
META_DLLAPI_HANDLE(int, 0, FN_DISPATCHRESTORE, pfnRestore, (pent, pSaveData, globalEntity));
RETURN_API();
}
void mm_DispatchObjectCollsionBox(edict_t *pent)
{
META_DLLAPI_HANDLE_void(FN_DISPATCHOBJECTCOLLISIONBOX, pfnSetAbsBox, (pent));
RETURN_API_void();
}
void mm_SaveWriteFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount)
{
META_DLLAPI_HANDLE_void(FN_SAVEWRITEFIELDS, pfnSaveWriteFields, (pSaveData, pname, pBaseData, pFields, fieldCount));
RETURN_API_void();
}
void mm_SaveReadFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount)
{
META_DLLAPI_HANDLE_void(FN_SAVEREADFIELDS, pfnSaveReadFields, (pSaveData, pname, pBaseData, pFields, fieldCount));
RETURN_API_void();
}
void mm_SaveGlobalState(SAVERESTOREDATA *pSaveData)
{
META_DLLAPI_HANDLE_void(FN_SAVEGLOBALSTATE, pfnSaveGlobalState, (pSaveData));
RETURN_API_void();
}
void mm_RestoreGlobalState(SAVERESTOREDATA *pSaveData)
{
META_DLLAPI_HANDLE_void(FN_RESTOREGLOBALSTATE, pfnRestoreGlobalState, (pSaveData));
RETURN_API_void();
}
void mm_ResetGlobalState(void)
{
META_DLLAPI_HANDLE_void(FN_RESETGLOBALSTATE, pfnResetGlobalState, ());
RETURN_API_void();
}
BOOL mm_ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] )
{
g_Players.clear_player_cvar_query(pEntity);
META_DLLAPI_HANDLE(BOOL, TRUE, FN_CLIENTCONNECT, pfnClientConnect, (pEntity, pszName, pszAddress, szRejectReason));
RETURN_API();
g_players.clear_player_cvar_query(pEntity);
}
void mm_ClientDisconnect(edict_t *pEntity)
{
g_Players.clear_player_cvar_query(pEntity);
META_DLLAPI_HANDLE_void(FN_CLIENTDISCONNECT, pfnClientDisconnect, (pEntity));
RETURN_API_void();
}
void mm_ClientKill(edict_t *pEntity)
{
META_DLLAPI_HANDLE_void(FN_CLIENTKILL, pfnClientKill, (pEntity));
RETURN_API_void();
}
void mm_ClientPutInServer(edict_t *pEntity)
{
META_DLLAPI_HANDLE_void(FN_CLIENTPUTINSERVER, pfnClientPutInServer, (pEntity));
RETURN_API_void();
g_players.clear_player_cvar_query(pEntity);
}
void mm_ClientCommand(edict_t *pEntity)
{
if (!Q_strcmp(CMD_ARGV(0), "meta"))
{
if (!strcmp(CMD_ARGV(0), "meta")) {
client_meta(pEntity);
}
META_DLLAPI_HANDLE_void(FN_CLIENTCOMMAND, pfnClientCommand, (pEntity));
RETURN_API_void();
}
void mm_ClientUserInfoChanged(edict_t *pEntity, char *infobuffer)
{
META_DLLAPI_HANDLE_void(FN_CLIENTUSERINFOCHANGED, pfnClientUserInfoChanged, (pEntity, infobuffer));
RETURN_API_void();
}
void mm_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
{
META_DLLAPI_HANDLE_void(FN_SERVERACTIVATE, pfnServerActivate, (pEdictList, edictCount, clientMax));
RETURN_API_void();
}
void mm_ServerDeactivate(void)
{
META_DLLAPI_HANDLE_void(FN_SERVERDEACTIVATE, pfnServerDeactivate, ());
sFunctionTable_jit.pfnServerDeactivate();
// Update loaded plugins. Look for new plugins in inifile, as well as
// any plugins waiting for a changelevel to load.
//
@ -189,270 +49,84 @@ void mm_ServerDeactivate(void)
g_plugins->refresh(PT_CHANGELEVEL);
g_plugins->unpause_all();
// g_plugins->retry_all(PT_CHANGELEVEL);
g_Players.clear_all_cvar_queries();
g_players.clear_all_cvar_queries();
requestid_counter = 0;
RETURN_API_void();
}
void mm_PlayerPreThink(edict_t *pEntity)
compile_data_t g_dllfunc_cdata[] =
{
META_DLLAPI_HANDLE_void(FN_PLAYERPRETHINK, pfnPlayerPreThink, (pEntity));
RETURN_API_void();
}
CDATA_DLL(pfnGameInit), // pfnGameInit() Initialize the game (one-time call after loading of game .dll)
CDATA_DLL(pfnSpawn), // pfnSpawn()
CDATA_DLL(pfnThink), // pfnThink()
CDATA_DLL(pfnUse), // pfnUse()
CDATA_DLL(pfnTouch), // pfnTouch()
CDATA_DLL(pfnBlocked), // pfnBlocked()
CDATA_DLL(pfnKeyValue), // pfnKeyValue()
CDATA_DLL(pfnSave), // pfnSave()
CDATA_DLL(pfnRestore), // pfnRestore()
CDATA_DLL(pfnSetAbsBox), // pfnSetAbsBox()
void mm_PlayerPostThink(edict_t *pEntity)
{
META_DLLAPI_HANDLE_void(FN_PLAYERPOSTTHINK, pfnPlayerPostThink, (pEntity));
RETURN_API_void();
}
CDATA_DLL(pfnSaveWriteFields), // pfnSaveWriteFields()
CDATA_DLL(pfnSaveReadFields), // pfnSaveReadFields()
void mm_StartFrame(void)
{
META_DLLAPI_HANDLE_void(FN_STARTFRAME, pfnStartFrame, ());
RETURN_API_void();
}
CDATA_DLL(pfnSaveGlobalState), // pfnSaveGlobalState()
CDATA_DLL(pfnRestoreGlobalState), // pfnRestoreGlobalState()
CDATA_DLL(pfnResetGlobalState), // pfnResetGlobalState()
void mm_ParmsNewLevel(void)
{
META_DLLAPI_HANDLE_void(FN_PARMSNEWLEVEL, pfnParmsNewLevel, ());
RETURN_API_void();
}
CDATA_DLL_H(pfnClientConnect, P_PRE, mm_ClientConnect), // pfnClientConnect() (wd) Client has connected
CDATA_DLL_H(pfnClientDisconnect, P_PRE, mm_ClientDisconnect), // pfnClientDisconnect() (wd) Player has left the game
CDATA_DLL(pfnClientKill), // pfnClientKill() (wd) Player has typed "kill"
CDATA_DLL(pfnClientPutInServer), // pfnClientPutInServer() (wd) Client is entering the game
CDATA_DLL_H(pfnClientCommand, P_PRE, mm_ClientCommand),
CDATA_DLL(pfnClientUserInfoChanged), // pfnClientUserInfoChanged() (wd) Client has updated their setinfo structure
CDATA_DLL(pfnServerActivate), // pfnServerActivate() (wd) Server is starting a new map
CDATA_DLL(pfnServerDeactivate), // pfnServerDeactivate() (wd) Server is leaving the map (shutdown), or changelevel); SDK2
void mm_ParmsChangeLevel(void)
{
META_DLLAPI_HANDLE_void(FN_PARMSCHANGELEVEL, pfnParmsChangeLevel, ());
RETURN_API_void();
}
CDATA_DLL(pfnPlayerPreThink), // pfnPlayerPreThink()
CDATA_DLL(pfnPlayerPostThink), // pfnPlayerPostThink()
const char *mm_GetGameDescription(void)
{
META_DLLAPI_HANDLE(const char *, NULL, FN_GETGAMEDESCRIPTION, pfnGetGameDescription, ());
RETURN_API();
}
CDATA_DLL(pfnStartFrame), // pfnStartFrame()
CDATA_DLL(pfnParmsNewLevel), // pfnParmsNewLevel()
CDATA_DLL(pfnParmsChangeLevel), // pfnParmsChangeLevel()
void mm_PlayerCustomization(edict_t *pEntity, customization_t *pCust)
{
META_DLLAPI_HANDLE_void(FN_PLAYERCUSTOMIZATION, pfnPlayerCustomization, (pEntity, pCust));
RETURN_API_void();
}
CDATA_DLL(pfnGetGameDescription), // pfnGetGameDescription() Returns string describing current .dll. E.g. "TeamFotrress 2"), "Half-Life"
CDATA_DLL(pfnPlayerCustomization), // pfnPlayerCustomization() Notifies .dll of new customization for player.
void mm_SpectatorConnect(edict_t *pEntity)
{
META_DLLAPI_HANDLE_void(FN_SPECTATORCONNECT, pfnSpectatorConnect, (pEntity));
RETURN_API_void();
}
CDATA_DLL(pfnSpectatorConnect), // pfnSpectatorConnect() Called when spectator joins server
CDATA_DLL(pfnSpectatorDisconnect), // pfnSpectatorDisconnect() Called when spectator leaves the server
CDATA_DLL(pfnSpectatorThink), // pfnSpectatorThink() Called when spectator sends a command packet (usercmd_t)
void mm_SpectatorDisconnect(edict_t *pEntity)
{
META_DLLAPI_HANDLE_void(FN_SPECTATORDISCONNECT, pfnSpectatorDisconnect, (pEntity));
RETURN_API_void();
}
CDATA_DLL(pfnSys_Error), // pfnSys_Error() Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint. SDK2
void mm_SpectatorThink(edict_t *pEntity)
{
META_DLLAPI_HANDLE_void(FN_SPECTATORTHINK, pfnSpectatorThink, (pEntity));
RETURN_API_void();
}
CDATA_DLL(pfnPM_Move), // pfnPM_Move() (wd) SDK2
CDATA_DLL(pfnPM_Init), // pfnPM_Init() Server version of player movement initialization; (wd) SDK2
CDATA_DLL(pfnPM_FindTextureType), // pfnPM_FindTextureType() (wd) SDK2
void mm_Sys_Error(const char *error_string)
{
META_DLLAPI_HANDLE_void(FN_SYS_ERROR, pfnSys_Error, (error_string));
RETURN_API_void();
}
void mm_PM_Move (struct playermove_s *ppmove, int server)
{
META_DLLAPI_HANDLE_void(FN_PM_MOVE, pfnPM_Move, (ppmove, server));
RETURN_API_void();
}
void mm_PM_Init(struct playermove_s *ppmove)
{
META_DLLAPI_HANDLE_void(FN_PM_INIT, pfnPM_Init, (ppmove));
RETURN_API_void();
}
char mm_PM_FindTextureType(char *name)
{
META_DLLAPI_HANDLE(char, '\0', FN_PM_FINDTEXTURETYPE, pfnPM_FindTextureType, (name));
RETURN_API();
}
void mm_SetupVisibility(edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas)
{
META_DLLAPI_HANDLE_void(FN_SETUPVISIBILITY, pfnSetupVisibility, (pViewEntity, pClient, pvs, pas));
RETURN_API_void();
}
void mm_UpdateClientData (const struct edict_s *ent, int sendweapons, struct clientdata_s *cd)
{
META_DLLAPI_HANDLE_void(FN_UPDATECLIENTDATA, pfnUpdateClientData, (ent, sendweapons, cd));
RETURN_API_void();
}
int mm_AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet)
{
META_DLLAPI_HANDLE(int, 0, FN_ADDTOFULLPACK, pfnAddToFullPack, (state, e, ent, host, hostflags, player, pSet));
RETURN_API();
}
void mm_CreateBaseline(int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs)
{
META_DLLAPI_HANDLE_void(FN_CREATEBASELINE, pfnCreateBaseline, (player, eindex, baseline, entity, playermodelindex, player_mins, player_maxs));
RETURN_API_void();
}
void mm_RegisterEncoders(void)
{
META_DLLAPI_HANDLE_void(FN_REGISTERENCODERS, pfnRegisterEncoders, ());
RETURN_API_void();
}
int mm_GetWeaponData(struct edict_s *player, struct weapon_data_s *info)
{
META_DLLAPI_HANDLE(int, 0, FN_GETWEAPONDATA, pfnGetWeaponData, (player, info));
RETURN_API();
}
void mm_CmdStart(const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed)
{
META_DLLAPI_HANDLE_void(FN_CMDSTART, pfnCmdStart, (player, cmd, random_seed));
RETURN_API_void();
}
void mm_CmdEnd (const edict_t *player)
{
META_DLLAPI_HANDLE_void(FN_CMDEND, pfnCmdEnd, (player));
RETURN_API_void();
}
int mm_ConnectionlessPacket(const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size)
{
META_DLLAPI_HANDLE(int, 0, FN_CONNECTIONLESSPACKET, pfnConnectionlessPacket, (net_from, args, response_buffer, response_buffer_size));
RETURN_API();
}
int mm_GetHullBounds(int hullnumber, float *mins, float *maxs)
{
META_DLLAPI_HANDLE(int, 0, FN_GETHULLBOUNDS, pfnGetHullBounds, (hullnumber, mins, maxs));
RETURN_API();
}
void mm_CreateInstancedBaselines (void)
{
META_DLLAPI_HANDLE_void(FN_CREATEINSTANCEDBASELINES, pfnCreateInstancedBaselines, ());
RETURN_API_void();
}
int mm_InconsistentFile(const edict_t *player, const char *filename, char *disconnect_message)
{
META_DLLAPI_HANDLE(int, 0, FN_INCONSISTENTFILE, pfnInconsistentFile, (player, filename, disconnect_message));
RETURN_API();
}
int mm_AllowLagCompensation(void)
{
META_DLLAPI_HANDLE(int, 0, FN_ALLOWLAGCOMPENSATION, pfnAllowLagCompensation, ());
RETURN_API();
}
void mm_OnFreeEntPrivateData(edict_t *pEnt)
{
META_NEWAPI_HANDLE_void(FN_ONFREEENTPRIVATEDATA, pfnOnFreeEntPrivateData, (pEnt));
RETURN_API_void();
}
void mm_GameShutdown(void)
{
META_NEWAPI_HANDLE_void(FN_GAMESHUTDOWN, pfnGameShutdown, ());
RETURN_API_void();
}
int mm_ShouldCollide(edict_t *pentTouched, edict_t *pentOther)
{
META_NEWAPI_HANDLE(int, 1, FN_SHOULDCOLLIDE, pfnShouldCollide, (pentTouched, pentOther));
RETURN_API();
}
void mm_CvarValue(const edict_t *pEdict, const char *value)
{
g_Players.clear_player_cvar_query(pEdict);
META_NEWAPI_HANDLE_void(FN_CVARVALUE, pfnCvarValue, (pEdict, value));
RETURN_API_void();
}
void mm_CvarValue2(const edict_t *pEdict, int requestID, const char *cvarName, const char *value)
{
META_NEWAPI_HANDLE_void(FN_CVARVALUE2, pfnCvarValue2, (pEdict, requestID, cvarName, value));
RETURN_API_void();
}
// "(wd)" indicates my comments on the functions
DLL_FUNCTIONS sFunctionTable =
{
mm_GameDLLInit, // pfnGameInit() Initialize the game (one-time call after loading of game .dll)
mm_DispatchSpawn, // pfnSpawn()
mm_DispatchThink, // pfnThink()
mm_DispatchUse, // pfnUse()
mm_DispatchTouch, // pfnTouch()
mm_DispatchBlocked, // pfnBlocked()
mm_DispatchKeyValue, // pfnKeyValue()
mm_DispatchSave, // pfnSave()
mm_DispatchRestore, // pfnRestore()
mm_DispatchObjectCollsionBox, // pfnSetAbsBox()
mm_SaveWriteFields, // pfnSaveWriteFields()
mm_SaveReadFields, // pfnSaveReadFields()
mm_SaveGlobalState, // pfnSaveGlobalState()
mm_RestoreGlobalState, // pfnRestoreGlobalState()
mm_ResetGlobalState, // pfnResetGlobalState()
mm_ClientConnect, // pfnClientConnect() (wd) Client has connected
mm_ClientDisconnect, // pfnClientDisconnect() (wd) Player has left the game
mm_ClientKill, // pfnClientKill() (wd) Player has typed "kill"
mm_ClientPutInServer, // pfnClientPutInServer() (wd) Client is entering the game
mm_ClientCommand, // pfnClientCommand() (wd) Player has sent a command (typed, or from a bind)
mm_ClientUserInfoChanged, // pfnClientUserInfoChanged() (wd) Client has updated their setinfo structure
mm_ServerActivate, // pfnServerActivate() (wd) Server is starting a new map
mm_ServerDeactivate, // pfnServerDeactivate() (wd) Server is leaving the map (shutdown, or changelevel); SDK2
mm_PlayerPreThink, // pfnPlayerPreThink()
mm_PlayerPostThink, // pfnPlayerPostThink()
mm_StartFrame, // pfnStartFrame()
mm_ParmsNewLevel, // pfnParmsNewLevel()
mm_ParmsChangeLevel, // pfnParmsChangeLevel()
mm_GetGameDescription, // pfnGetGameDescription() Returns string describing current .dll. E.g. "TeamFotrress 2", "Half-Life"
mm_PlayerCustomization, // pfnPlayerCustomization() Notifies .dll of new customization for player.
mm_SpectatorConnect, // pfnSpectatorConnect() Called when spectator joins server
mm_SpectatorDisconnect, // pfnSpectatorDisconnect() Called when spectator leaves the server
mm_SpectatorThink, // pfnSpectatorThink() Called when spectator sends a command packet (usercmd_t)
mm_Sys_Error, // pfnSys_Error() Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint. SDK2
mm_PM_Move, // pfnPM_Move() (wd) SDK2
mm_PM_Init, // pfnPM_Init() Server version of player movement initialization; (wd) SDK2
mm_PM_FindTextureType, // pfnPM_FindTextureType() (wd) SDK2
mm_SetupVisibility, // pfnSetupVisibility() Set up PVS and PAS for networking for this client; (wd) SDK2
mm_UpdateClientData, // pfnUpdateClientData() Set up data sent only to specific client; (wd) SDK2
mm_AddToFullPack, // pfnAddToFullPack() (wd) SDK2
mm_CreateBaseline, // pfnCreateBaseline() Tweak entity baseline for network encoding, allows setup of player baselines, too.; (wd) SDK2
mm_RegisterEncoders, // pfnRegisterEncoders() Callbacks for network encoding; (wd) SDK2
mm_GetWeaponData, // pfnGetWeaponData() (wd) SDK2
mm_CmdStart, // pfnCmdStart() (wd) SDK2
mm_CmdEnd, // pfnCmdEnd() (wd) SDK2
mm_ConnectionlessPacket, // pfnConnectionlessPacket() (wd) SDK2
mm_GetHullBounds, // pfnGetHullBounds() (wd) SDK2
mm_CreateInstancedBaselines, // pfnCreateInstancedBaselines() (wd) SDK2
mm_InconsistentFile, // pfnInconsistentFile() (wd) SDK2
mm_AllowLagCompensation, // pfnAllowLagCompensation() (wd) SDK2
CDATA_DLL(pfnSetupVisibility), // pfnSetupVisibility() Set up PVS and PAS for networking for this client; (wd) SDK2
CDATA_DLL(pfnUpdateClientData), // pfnUpdateClientData() Set up data sent only to specific client; (wd) SDK2
CDATA_DLL(pfnAddToFullPack), // pfnAddToFullPack() (wd) SDK2
CDATA_DLL(pfnCreateBaseline), // pfnCreateBaseline() Tweak entity baseline for network encoding), allows setup of player baselines), too.; (wd) SDK2
CDATA_DLL(pfnRegisterEncoders), // pfnRegisterEncoders() Callbacks for network encoding; (wd) SDK2
CDATA_DLL(pfnGetWeaponData), // pfnGetWeaponData() (wd) SDK2
CDATA_DLL(pfnCmdStart), // pfnCmdStart() (wd) SDK2
CDATA_DLL(pfnCmdEnd), // pfnCmdEnd() (wd) SDK2
CDATA_DLL(pfnConnectionlessPacket), // pfnConnectionlessPacket() (wd) SDK2
CDATA_DLL(pfnGetHullBounds), // pfnGetHullBounds() (wd) SDK2
CDATA_DLL(pfnCreateInstancedBaselines), // pfnCreateInstancedBaselines() (wd) SDK2
CDATA_DLL(pfnInconsistentFile), // pfnInconsistentFile() (wd) SDK2
CDATA_DLL(pfnAllowLagCompensation), // pfnAllowLagCompensation() (wd) SDK2
};
DLL_FUNCTIONS *pHookedDllFunctions = &sFunctionTable;
compile_data_t g_newdllfunc_cdata[] =
{
CDATA_NEWDLL(pfnOnFreeEntPrivateData), // pfnOnFreeEntPrivateData() Called right before the object's memory is freed. Calls its destructor.
CDATA_NEWDLL(pfnGameShutdown), // pfnGameShutdown()
CDATA_NEWDLL(pfnShouldCollide), // pfnShouldCollide()
CDATA_NEWDLL(pfnCvarValue), // pfnCvarValue() (fz) Use mm_CvarValue2 instead
CDATA_NEWDLL(pfnCvarValue2) // pfnCvarValue2() (fz) When pfnQueryClientCvarValue2() completes it will call
// pfnCvarValue2() with the request ID supplied earlier, the name of the cvar requested and the value of that cvar.
};
// It's not clear what the difference is between GetAPI and GetAPI2; they
// both appear to return the exact same function table.
@ -477,7 +151,7 @@ C_DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion
META_ERROR("GetEntityAPI called with null pFunctionTable");
return FALSE;
}
else if (interfaceVersion != INTERFACE_VERSION)
if (interfaceVersion != INTERFACE_VERSION)
{
META_ERROR("GetEntityAPI version mismatch; requested=%d ours=%d", interfaceVersion, INTERFACE_VERSION);
return FALSE;
@ -496,7 +170,7 @@ C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersi
META_ERROR("GetEntityAPI2 called with null pFunctionTable");
return FALSE;
}
else if (*interfaceVersion != INTERFACE_VERSION)
if (*interfaceVersion != INTERFACE_VERSION)
{
META_ERROR("GetEntityAPI2 version mismatch; requested=%d ours=%d", *interfaceVersion, INTERFACE_VERSION);
//! Tell engine what version we had, so it can figure out who is out of date.
@ -504,33 +178,10 @@ C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersi
return FALSE;
}
Q_memcpy(pFunctionTable, &sFunctionTable, sizeof(DLL_FUNCTIONS));
memcpy(pFunctionTable, &sFunctionTable, sizeof(DLL_FUNCTIONS));
return TRUE;
}
// I could find _no_ documentation or examples for the intended use of
// NEW_DLL_FUNCTIONS. I wouldn't have even _known_ about the
// GetNewDLLFunctions() function except for the reference in Adminmod.. It
// appears to be new with SDK 2.0.
//
// Obviously, it seems to provide additional functions to the engine, but
// it's unclear why a new table and interface were added, rather than
// appending new functions to the GetAPI table/interface.
//
// Interestingly, it appears to be called by the engine _before_ GetAPI.
meta_new_dll_functions_t sNewFunctionTable (
&mm_OnFreeEntPrivateData, // pfnOnFreeEntPrivateData() Called right before the object's memory is freed. Calls its destructor.
&mm_GameShutdown, // pfnGameShutdown()
&mm_ShouldCollide, // pfnShouldCollide()
&mm_CvarValue, // pfnCvarValue() (fz) Use mm_CvarValue2 instead
&mm_CvarValue2 // pfnCvarValue2() (fz) When pfnQueryClientCvarValue2() completes it will call
// pfnCvarValue2() with the request ID supplied earlier, the name of the cvar requested and the value of that cvar.
);
NEW_DLL_FUNCTIONS *pHookedNewDllFunctions = &sNewFunctionTable;
C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion)
{
META_DEBUG(6, ("called: GetNewDLLFunctions; version=%d", *interfaceVersion));
@ -547,7 +198,7 @@ C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *in
META_ERROR("GetNewDLLFunctions called with null pNewFunctionTable");
return FALSE;
}
else if (*interfaceVersion != NEW_DLL_FUNCTIONS_VERSION)
if (*interfaceVersion != NEW_DLL_FUNCTIONS_VERSION)
{
META_ERROR("GetNewDLLFunctions version mismatch; requested=%d ours=%d", *interfaceVersion, NEW_DLL_FUNCTIONS_VERSION);
//! Tell engine what version we had, so it can figure out who is out of date.
@ -555,6 +206,76 @@ C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *in
return FALSE;
}
sNewFunctionTable.copy_to(pNewFunctionTable);
memcpy(pNewFunctionTable, &sNewFunctionTable, sizeof(NEW_DLL_FUNCTIONS));
return TRUE;
}
void compile_dllfunc_callbacks()
{
jitdata_t jitdata;
jitdata.plugins = g_plugins ? g_plugins->plist : nullptr;
jitdata.plugins_count = g_plugins ? g_plugins->endlist : 0;
jitdata.table_offset = offsetof(MPlugin, dllapi_table);
jitdata.post_table_offset = offsetof(MPlugin, dllapi_post_table);
for (auto& cd : g_dllfunc_cdata) {
jitdata.pfn_original = *(size_t *)(size_t(GameDLL.funcs.dllapi_table) + cd.offset);
jitdata.args_count = cd.args_count;
jitdata.has_ret = cd.has_ret;
jitdata.has_varargs = cd.has_varargs;
jitdata.pfn_offset = cd.offset;
jitdata.mm_hook_time = cd.mm_hook_time;
jitdata.mm_hook = cd.mm_hook;
*(size_t *)(size_t(&sFunctionTable) + cd.offset) = g_jit.compile_callback(&jitdata);
}
}
void compile_newdllfunc_callbacks()
{
jitdata_t jitdata;
jitdata.plugins = g_plugins ? g_plugins->plist : nullptr;
jitdata.plugins_count = g_plugins ? g_plugins->endlist : 0;
jitdata.table_offset = offsetof(MPlugin, newapi_table);
jitdata.post_table_offset = offsetof(MPlugin, newapi_post_table);
for (auto& cd : g_newdllfunc_cdata) {
jitdata.pfn_original = *(size_t *)(size_t(GameDLL.funcs.newapi_table) + cd.offset);
jitdata.args_count = cd.args_count;
jitdata.has_ret = cd.has_ret;
jitdata.has_varargs = cd.has_varargs;
jitdata.pfn_offset = cd.offset;
jitdata.mm_hook_time = cd.mm_hook_time;
jitdata.mm_hook = cd.mm_hook;
*(size_t *)(size_t(&sNewFunctionTable) + cd.offset) = g_jit.compile_callback(&jitdata);
}
}
void compile_gamedll_tramps()
{
// we compile simple static functions that will call dynamic callbacks
for (auto& cd : g_dllfunc_cdata) {
*(size_t *)(size_t(&sFunctionTable) + cd.offset) = g_jit.compile_tramp(size_t(&sFunctionTable_jit) + cd.offset);
}
// use direct hook
sFunctionTable.pfnServerDeactivate = mm_ServerDeactivate;
for (auto& cd : g_newdllfunc_cdata) {
*(size_t *)(size_t(&sNewFunctionTable) + cd.offset) = g_jit.compile_tramp(size_t(&sNewFunctionTable_jit) + cd.offset);
}
}
void compile_gamedll_callbacks()
{
static bool initialized = false;
if (!initialized) {
compile_gamedll_tramps();
initialized = true;
}
compile_dllfunc_callbacks();
compile_newdllfunc_callbacks();
}

View File

@ -3,6 +3,8 @@
#include "sdk_util.h"
#include "osdep.h"
typedef void (*FN_GAMEINIT)();
// Typedefs for these are provided in SDK engine/eiface.h, but I didn't
// like the names (APIFUNCTION, APIFUNCTION2, NEW_DLL_FUNCTIONS_FN).
typedef int (*GETENTITYAPI_FN)(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion);
@ -13,114 +15,4 @@ C_DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion
C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion);
C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion);
extern void mm_GameDLLInit();
extern int mm_DispatchSpawn(edict_t *pent);
extern void mm_DispatchThink(edict_t *pent);
extern void mm_DispatchUse(edict_t *pentUsed, edict_t *pentOther);
extern void mm_DispatchTouch(edict_t *pentTouched, edict_t *pentOther);
extern void mm_DispatchBlocked(edict_t *pentBlocked, edict_t *pentOther);
extern void mm_DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd);
extern void mm_DispatchSave(edict_t *pent, SAVERESTOREDATA *pSaveData);
extern int mm_DispatchRestore(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity);
extern void mm_DispatchObjectCollisionBox(edict_t *pent);
extern void mm_SaveWriteFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount);
extern void mm_SaveReadFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount);
extern void mm_SaveGlobalState(SAVERESTOREDATA *pSaveData);
extern void mm_RestoreGlobalState(SAVERESTOREDATA *pSaveData);
extern void mm_ResetGlobalState();
extern BOOL mm_ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ]);
extern void mm_ClientDisconnect(edict_t *pEntity);
extern void mm_ClientKill(edict_t *pEntity);
extern void mm_ClientPutInServer(edict_t *pEntity);
extern void mm_ClientCommand(edict_t *pEntity);
extern void mm_ClientUserInfoChanged(edict_t *pEntity, char *infobuffer);
extern void mm_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax);
extern void mm_ServerDeactivate();
extern void mm_PlayerPreThink(edict_t *pEntity);
extern void mm_PlayerPostThink(edict_t *pEntity);
extern void mm_StartFrame();
extern void mm_ParmsNewLevel();
extern void mm_ParmsChangeLevel();
extern const char *mm_GetGameDescription();
extern void mm_PlayerCustomization(edict_t *pEntity, customization_t *pCust);
extern void mm_SpectatorConnect (edict_t *pEntity);
extern void mm_SpectatorDisconnect (edict_t *pEntity);
extern void mm_SpectatorThink (edict_t *pEntity);
extern void mm_Sys_Error(const char *error_string);
extern void mm_PM_Move(struct playermove_s *ppmove, int server);
extern void mm_PM_Init(struct playermove_s *ppmove);
extern char mm_PM_FindTextureType (const char *name);
extern void mm_SetupVisibility(edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas);
extern void mm_UpdateClientData (const struct edict_s *ent, int sendweapons, struct clientdata_s *cd);
extern int mm_AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet);
extern void mm_CreateBaseline(int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs);
extern void mm_RegisterEncoders();
extern int mm_GetWeaponData(struct edict_s *player, struct weapon_data_s *info);
extern void mm_CmdStart(const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed);
extern void mm_CmdEnd (const edict_t *player);
extern int mm_ConnectionlessPacket(const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size);
extern int mm_GetHullBounds(int hullnumber, float *mins, float *maxs);
extern void mm_CreateInstancedBaselines ();
extern int mm_InconsistentFile(const edict_t *player, const char *filename, char *disconnect_message);
extern int mm_AllowLagCompensation();
extern void mm_OnFreeEntPrivateData(edict_t pEnt);
extern void mm_GameShutdown();
extern int mm_ShouldCollide(edict_t *pentTouched, edict_t *pentOther);
extern void mm_CvarValue(const edict_t *pEnt, const char *value);
extern void mm_CvarValue2(const edict_t *pEnt, int requestID, const char *cvarName, const char *value);
typedef void (*FN_GAMEINIT)();
typedef int (*FN_DISPATCHSPAWN)(edict_t *pent);
typedef void (*FN_DISPATCHTHINK)(edict_t *pent);
typedef void (*FN_DISPATCHUSE)(edict_t *pentUsed, edict_t *pentOther);
typedef void (*FN_DISPATCHTOUCH)(edict_t *pentTouched, edict_t *pentOther);
typedef void (*FN_DISPATCHBLOCKED)(edict_t *pentBlocked, edict_t *pentOther);
typedef void (*FN_DISPATCHKEYVALUE)(edict_t *pentKeyvalue, KeyValueData *pkvd);
typedef void (*FN_DISPATCHSAVE)(edict_t *pent, SAVERESTOREDATA *pSaveData);
typedef int (*FN_DISPATCHRESTORE)(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity);
typedef void (*FN_DISPATCHOBJECTCOLLISIONBOX)(edict_t *pent);
typedef void (*FN_SAVEWRITEFIELDS)(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount);
typedef void (*FN_SAVEREADFIELDS)(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount);
typedef void (*FN_SAVEGLOBALSTATE)(SAVERESTOREDATA *pSaveData);
typedef void (*FN_RESTOREGLOBALSTATE)(SAVERESTOREDATA *pSaveData);
typedef void (*FN_RESETGLOBALSTATE)();
typedef BOOL (*FN_CLIENTCONNECT)(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ]);
typedef void (*FN_CLIENTDISCONNECT)(edict_t *pEntity);
typedef void (*FN_CLIENTKILL)(edict_t *pEntity);
typedef void (*FN_CLIENTPUTINSERVER)(edict_t *pEntity);
typedef void (*FN_CLIENTCOMMAND)(edict_t *pEntity);
typedef void (*FN_CLIENTUSERINFOCHANGED)(edict_t *pEntity, char *infobuffer);
typedef void (*FN_SERVERACTIVATE)(edict_t *pEdictList, int edictCount, int clientMax);
typedef void (*FN_SERVERDEACTIVATE)();
typedef void (*FN_PLAYERPRETHINK)(edict_t *pEntity);
typedef void (*FN_PLAYERPOSTTHINK)(edict_t *pEntity);
typedef void (*FN_STARTFRAME)();
typedef void (*FN_PARMSNEWLEVEL)();
typedef void (*FN_PARMSCHANGELEVEL)();
typedef const char *(*FN_GETGAMEDESCRIPTION)();
typedef void (*FN_PLAYERCUSTOMIZATION)(edict_t *pEntity, customization_t *pCust);
typedef void (*FN_SPECTATORCONNECT) (edict_t *pEntity);
typedef void (*FN_SPECTATORDISCONNECT) (edict_t *pEntity);
typedef void (*FN_SPECTATORTHINK) (edict_t *pEntity);
typedef void (*FN_SYS_ERROR)(const char *error_string);
typedef void (*FN_PM_MOVE)(struct playermove_s *ppmove, int server);
typedef void (*FN_PM_INIT)(struct playermove_s *ppmove);
typedef char (*FN_PM_FINDTEXTURETYPE)(char *name);
typedef void (*FN_SETUPVISIBILITY)(edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas);
typedef void (*FN_UPDATECLIENTDATA) (const struct edict_s *ent, int sendweapons, struct clientdata_s *cd);
typedef int (*FN_ADDTOFULLPACK)(struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet);
typedef void (*FN_CREATEBASELINE)(int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs);
typedef void (*FN_REGISTERENCODERS)();
typedef int (*FN_GETWEAPONDATA)(struct edict_s *player, struct weapon_data_s *info);
typedef void (*FN_CMDSTART)(const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed);
typedef void (*FN_CMDEND) (const edict_t *player);
typedef int (*FN_CONNECTIONLESSPACKET)(const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size);
typedef int (*FN_GETHULLBOUNDS)(int hullnumber, float *mins, float *maxs);
typedef void (*FN_CREATEINSTANCEDBASELINES) ();
typedef int (*FN_INCONSISTENTFILE)(const edict_t *player, const char *filename, char *disconnect_message);
typedef int (*FN_ALLOWLAGCOMPENSATION)();
typedef void (*FN_ONFREEENTPRIVATEDATA)(edict_t *pEnt);
typedef void (*FN_GAMESHUTDOWN)();
typedef int (*FN_SHOULDCOLLIDE)(edict_t *pentTouched, edict_t *pentOther);
typedef void (*FN_CVARVALUE)(const edict_t *pEnt, const char *value); //! Obsolete! Use FN_CVARVALUE2 instead
typedef void (*FN_CVARVALUE2)(const edict_t *pEnt, int requestID, const char *cvarName, const char *value);
void compile_gamedll_callbacks();

File diff suppressed because it is too large Load Diff

View File

@ -18,359 +18,4 @@ typedef int (*GET_ENGINE_FUNCTIONS_FN)(enginefuncs_t *pengfuncsFromEngine, int *
extern enginefuncs_t meta_engfuncs;
#endif
extern int mm_PrecacheModel(const char *s);
extern int mm_PrecacheSound(const char *s);
extern void mm_SetModel(edict_t *e, const char *m);
extern int mm_ModelIndex(const char *m);
extern int mm_ModelFrames(int modelIndex);
extern void mm_SetSize(edict_t *e, const float *rgflMin, const float *rgflMax);
extern void mm_ChangeLevel(const char *s1, const char *s2);
extern void mm_GetSpawnParms(edict_t *ent);
extern void mm_SaveSpawnParms(edict_t *ent);
extern float mm_VecToYaw(const float *rgflVector);
extern void mm_VecToAngles(const float *rgflVectorIn, float *rgflVectorOut);
extern void mm_MoveToOrigin(edict_t *ent, const float *pflGoal, float dist, int iMoveType);
extern void mm_ChangeYaw(edict_t *ent);
extern void mm_ChangePitch(edict_t *ent);
extern edict_t *mm_FindEntityByString(edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue);
extern int mm_GetEntityIllum(edict_t *pEnt);
extern edict_t *mm_FindEntityInSphere(edict_t *pEdictStartSearchAfter, const float *org, float rad);
extern edict_t *mm_FindClientInPVS(edict_t *pEdict);
extern edict_t *mm_EntitiesInPVS(edict_t *pplayer);
extern void mm_MakeVectors(const float *rgflVector);
extern void mm_AngleVectors(const float *rgflVector, float *forward, float *right, float *up);
extern edict_t *mm_CreateEntity();
extern void mm_RemoveEntity(edict_t *e);
extern edict_t *mm_CreateNamedEntity(int className);
extern void mm_MakeStatic(edict_t *ent);
extern int mm_EntIsOnFloor(edict_t *e);
extern int mm_DropToFloor(edict_t *e);
extern int mm_WalkMove(edict_t *ent, float yaw, float dist, int iMode);
extern void mm_SetOrigin(edict_t *e, const float *rgflOrigin);
extern void mm_EmitSound(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch);
extern void mm_EmitAmbientSound(edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch);
extern void mm_TraceLine(const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr);
extern void mm_TraceToss(edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr);
extern int mm_TraceMonsterHull(edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr);
extern void mm_TraceHull(const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr);
extern void mm_TraceModel(const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr);
extern const char *mm_TraceTexture(edict_t *pTextureEntity, const float *v1, const float *v2);
extern void mm_TraceSphere(const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr);
extern void mm_GetAimVector(edict_t *ent, float speed, float *rgflReturn);
extern void mm_ServerCommand(const char *str);
extern void mm_ServerExecute();
extern void ClientCommand(edict_t *pEdict, const char *szFmt, ...);
extern void mm_ParticleEffect(const float *org, const float *dir, float color, float count);
extern void mm_LightStyle(int style, const char *val);
extern int mm_DecalIndex(const char *name);
extern int mm_PointContents(const float *rgflVector);
extern void mm_MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
extern void mm_MessageEnd();
extern void mm_WriteByte(int iValue);
extern void mm_WriteChar(int iValue);
extern void mm_WriteShort(int iValue);
extern void mm_WriteLong(int iValue);
extern void mm_WriteAngle(float flValue);
extern void mm_WriteCoord(float flValue);
extern void mm_WriteString(const char *sz);
extern void mm_WriteEntity(int iValue);
extern void mm_CVarRegister(cvar_t *pCvar);
extern float mm_CVarGetFloat(const char *szVarName);
extern const char *mm_CVarGetString(const char *szVarName);
extern void mm_CVarSetFloat(const char *szVarName, float flValue);
extern void mm_CVarSetString(const char *szVarName, const char *szValue);
extern void mm_AlertMessage(ALERT_TYPE atype, const char *szFmt, ...);
extern void mm_EngineFprintf(void *pfile, const char *szFmt, ...);
extern void *mm_PvAllocEntPrivateData(edict_t *pEdict, int32 cb);
extern void *mm_PvEntPrivateData(edict_t *pEdict);
extern void mm_FreeEntPrivateData(edict_t *pEdict);
extern const char *mm_SzFromIndex(int iString);
extern int mm_AllocString(const char *szValue);
extern struct entvars_s *mm_GetVarsOfEnt(edict_t *pEdict);
extern edict_t *mm_PEntityOfEntOffset(int iEntOffset);
extern int mm_EntOffsetOfPEntity(const edict_t *pEdict);
extern int mm_IndexOfEdict(const edict_t *pEdict);
extern edict_t *mm_PEntityOfEntIndex(int iEntIndex);
extern edict_t *mm_FindEntityByVars(struct entvars_s *pvars);
extern void *mm_GetModelPtr(edict_t *pEdict);
extern int mm_RegUserMsg(const char *pszName, int iSize);
extern void mm_AnimationAutomove(const edict_t *pEdict, float flTime);
extern void mm_GetBonePosition(const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles);
extern uint32 mm_FunctionFromName(const char *pName);
extern const char *mm_NameForFunction(uint32 function);
extern void mm_ClientPrintf(edict_t *pEdict, PRINT_TYPE ptype, const char *szMsg); //! JOHN: engine callbacks so game DLL can print messages to individual clients
extern void mm_ServerPrint(const char *szMsg);
extern const char *mm_Cmd_Args(); //! these 3 added
extern const char *mm_Cmd_Argv(int argc); //! so game DLL can easily
extern int mm_Cmd_Argc(); //! access client 'cmd' strings
extern void mm_GetAttachment(const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles);
extern void mm_CRC32_Init(CRC32_t *pulCRC);
extern void mm_CRC32_ProcessBuffer(CRC32_t *pulCRC, void *p, int len);
extern void mm_CRC32_ProcessByte(CRC32_t *pulCRC, unsigned char ch);
extern CRC32_t mm_CRC32_Final(CRC32_t pulCRC);
extern int32 mm_RandomLong(int32 lLow, int32 lHigh);
extern float mm_RandomFloat(float flLow, float flHigh);
extern void mm_SetView(const edict_t *pClient, const edict_t *pViewent);
extern float mm_Time();
extern void mm_CrosshairAngle(const edict_t *pClient, float pitch, float yaw);
extern byte *mm_LoadFileForMe(const char *filename, int *pLength);
extern void mm_FreeFile(void *buffer);
extern void mm_EndSection(const char *pszSectionName); //! trigger_endsection
extern int mm_CompareFileTime(char *filename1, char *filename2, int *iCompare);
extern void mm_GetGameDir(char *szGetGameDir);
extern void mm_Cvar_RegisterVariable(cvar_t *variable);
extern void mm_FadeClientVolume(const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds);
extern void mm_SetClientMaxspeed(const edict_t *pEdict, float fNewMaxspeed);
extern edict_t *mm_CreateFakeClient(const char *netname); //! returns NULL if fake client can't be created
extern void mm_RunPlayerMove(edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec);
extern int mm_NumberOfEntities();
extern char *mm_GetInfoKeyBuffer(edict_t *e); //! passing in NULL gets the serverinfo
extern char *mm_InfoKeyValue(char *infobuffer, const char *key);
extern void mm_SetKeyValue(char *infobuffer, const char *key, const char *value);
extern void mm_SetClientKeyValue(int clientIndex, char *infobuffer, const char *key, const char *value);
extern int mm_IsMapValid(char *filename);
extern void mm_StaticDecal(const float *origin, int decalIndex, int entityIndex, int modelIndex);
extern int mm_PrecacheGeneric(const char *s);
extern int mm_GetPlayerUserId(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
extern void mm_BuildSoundMsg(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);
extern int mm_IsDedicatedServer();//! is this a dedicated server?
extern cvar_t *mm_CVarGetPointer(const char *szVarName);
extern unsigned int mm_GetPlayerWONId(edict_t *e); //! returns the server assigned WONid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients
// 8/1/99 TFF Physics additions
extern void mm_Info_RemoveKey(char *s, const char *key);
extern const char *mm_GetPhysicsKeyValue(const edict_t *pClient, const char *key);
extern void mm_SetPhysicsKeyValue(const edict_t *pClient, const char *key, const char *value);
extern const char *mm_GetPhysicsInfoString(const edict_t *pClient);
extern unsigned short mm_PrecacheEvent(int type, const char *psz);
extern void mm_PlaybackEvent(int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2);
extern unsigned char *mm_SetFatPVS(float *org);
extern unsigned char *mm_SetFatPAS(float *org);
extern int mm_CheckVisibility(edict_t *entity, unsigned char *pset);
extern void mm_DeltaSetField(struct delta_s *pFields, const char *fieldname);
extern void mm_DeltaUnsetField(struct delta_s *pFields, const char *fieldname);
extern void mm_DeltaAddEncoder(const char *name, void (*conditionalencode)(struct delta_s *pFields, const unsigned char *from, const unsigned char *to));
extern int mm_GetCurrentPlayer();
extern int mm_CanSkipPlayer(const edict_t *player);
extern int mm_DeltaFindField(struct delta_s *pFields, const char *fieldname);
extern void mm_DeltaSetFieldByIndex(struct delta_s *pFields, int fieldNumber);
extern void mm_DeltaUnsetFieldByIndex(struct delta_s *pFields, int fieldNumber);
extern void mm_SetGroupMask(int mask, int op);
extern int CreateInstancedBaseline(int classname, struct entity_state_s *baseline);
extern void mm_Cvar_DirectSet(struct cvar_s *var, const char *value);
// Forces the client and server to be running with the same version of the specified file e.g., a player model).
// Calling this has no effect in single player
extern void mm_ForceUnmodified(FORCE_TYPE type, float *mins, float *maxs, const char *filename);
extern void mm_GetPlayerStats(const edict_t *pClient, int *ping, int *packet_loss);
extern void mm_AddServerCommand(const char *cmd_name, void (*function)());
extern qboolean mm_Voice_GetClientListening(int iReceiver, int iSender);
extern qboolean mm_Voice_SetClientListening(int iReceiver, int iSender, qboolean bListen);
extern const char *mm_pfnGetPlayerAuthId(edict_t *e);
extern sequenceEntry_s *mm_SequenceGet(const char *fileName, const char *entryName);
extern sentenceEntry_s *mm_SequencePickSentence(const char *groupName, int pickMethod, int *picked);
extern int mm_GetFileSize(const char *filename);
extern unsigned int mm_GetApproxWavePlayLen(const char *filepath);
extern int mm_IsCareerMatch();
extern int mm_GetLocalizedStringLength(const char *label);
extern void mm_RegisterTutorMessageShown(int mid);
extern int mm_GetTimesTutorMessageShown(int mid);
extern void mm_ProcessTutorMessageDecayBuffer(int *buffer, int bufferLength);
extern void mm_ConstructTutorMessageDecayBuffer(int *buffer, int bufferLength);
extern void mm_ResetTutorMessageDecayData();
extern void mm_QueryClientCvarValue(const edict_t *pEdict, const char *cvarName); //! Obsolete! Use mm_QueryClientCvarValue2 instead
extern void mm_QueryClientCvarValue2(const edict_t *pEdict, const char *cvarName, int requestID);
extern int mm_EngCheckParm(const char *pchCmdLineToken, char **ppnext);
// Typedefs for the above functions:
typedef int (*FN_PRECACHEMODEL)(const char *s);
typedef int (*FN_PRECACHESOUND)(const char *s);
typedef void (*FN_SETMODEL)(edict_t *e, const char *m);
typedef int (*FN_MODELINDEX)(const char *m);
typedef int (*FN_MODELFRAMES)(int modelIndex);
typedef void (*FN_SETSIZE)(edict_t *e, const float *rgflMin, const float *rgflMax);
typedef void (*FN_CHANGELEVEL)(const char *s1, const char *s2);
typedef void (*FN_GETSPAWNPARMS)(edict_t *ent);
typedef void (*FN_SAVESPAWNPARMS)(edict_t *ent);
typedef float (*FN_VECTOYAW)(const float *rgflVector);
typedef void (*FN_VECTOANGLES)(const float *rgflVectorIn, float *rgflVectorOut);
typedef void (*FN_MOVETOORIGIN)(edict_t *ent, const float *pflGoal, float dist, int iMoveType);
typedef void (*FN_CHANGEYAW)(edict_t *ent);
typedef void (*FN_CHANGEPITCH)(edict_t *ent);
typedef edict_t *(*FN_FINDENTITYBYSTRING)(edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue);
typedef int (*FN_GETENTITYILLUM)(edict_t *pEnt);
typedef edict_t *(*FN_FINDENTITYINSPHERE)(edict_t *pEdictStartSearchAfter, const float *org, float rad);
typedef edict_t *(*FN_FINDCLIENTINPVS)(edict_t *pEdict);
typedef edict_t *(*FN_ENTITIESINPVS)(edict_t *pplayer);
typedef void (*FN_MAKEVECTORS)(const float *rgflVector);
typedef void (*FN_ANGLEVECTORS)(const float *rgflVector, float *forward, float *right, float *up);
typedef edict_t *(*FN_CREATEENTITY)();
typedef void (*FN_REMOVEENTITY)(edict_t *e);
typedef edict_t *(*FN_CREATENAMEDENTITY)(int className);
typedef void (*FN_MAKESTATIC)(edict_t *ent);
typedef int (*FN_ENTISONFLOOR)(edict_t *e);
typedef int (*FN_DROPTOFLOOR)(edict_t *e);
typedef int (*FN_WALKMOVE)(edict_t *ent, float yaw, float dist, int iMode);
typedef void (*FN_SETORIGIN)(edict_t *e, const float *rgflOrigin);
typedef void (*FN_EMITSOUND)(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch);
typedef void (*FN_EMITAMBIENTSOUND)(edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch);
typedef void (*FN_TRACELINE)(const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr);
typedef void (*FN_TRACETOSS)(edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr);
typedef int (*FN_TRACEMONSTERHULL)(edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr);
typedef void (*FN_TRACEHULL)(const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr);
typedef void (*FN_TRACEMODEL)(const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr);
typedef const char *(*FN_TRACETEXTURE)(edict_t *pTextureEntity, const float *v1, const float *v2);
typedef void (*FN_TRACESPHERE)(const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr);
typedef void (*FN_GETAIMVECTOR)(edict_t *ent, float speed, float *rgflReturn);
typedef void (*FN_SERVERCOMMAND)(char *str);
typedef void (*FN_SERVEREXECUTE)();
typedef void (*FN_CLIENTCOMMAND_ENG)(edict_t *pEdict, char *szFmt, ...);
typedef void (*FN_PARTICLEEFFECT)(const float *org, const float *dir, float color, float count);
typedef void (*FN_LIGHTSTYLE)(int style, char *val);
typedef int (*FN_DECALINDEX)(const char *name);
typedef int (*FN_POINTCONTENTS)(const float *rgflVector);
typedef void (*FN_MESSAGEBEGIN)(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
typedef void (*FN_MESSAGEEND)();
typedef void (*FN_WRITEBYTE)(int iValue);
typedef void (*FN_WRITECHAR)(int iValue);
typedef void (*FN_WRITESHORT)(int iValue);
typedef void (*FN_WRITELONG)(int iValue);
typedef void (*FN_WRITEANGLE)(float flValue);
typedef void (*FN_WRITECOORD)(float flValue);
typedef void (*FN_WRITESTRING)(const char *sz);
typedef void (*FN_WRITEENTITY)(int iValue);
typedef void (*FN_CVARREGISTER)(cvar_t *pCvar);
typedef float (*FN_CVARGETFLOAT)(const char *szVarName);
typedef const char *(*FN_CVARGETSTRING)(const char *szVarName);
typedef void (*FN_CVARSETFLOAT)(const char *szVarName, float flValue);
typedef void (*FN_CVARSETSTRING)(const char *szVarName, const char *szValue);
typedef void (*FN_ALERTMESSAGE)(ALERT_TYPE atype, const char *szFmt, ...);
typedef void (*FN_ENGINEFPRINTF)(void *pfile, const char *szFmt, ...);
typedef void *(*FN_PVALLOCENTPRIVATEDATA)(edict_t *pEdict, int32 cb);
typedef void *(*FN_PVENTPRIVATEDATA)(edict_t *pEdict);
typedef void (*FN_FREEENTPRIVATEDATA)(edict_t *pEdict);
typedef const char *(*FN_SZFROMINDEX)(int iString);
typedef int (*FN_ALLOCSTRING)(const char *szValue);
typedef struct entvars_s *(*FN_GETVARSOFENT)(edict_t *pEdict);
typedef edict_t *(*FN_PENTITYOFENTOFFSET)(int iEntOffset);
typedef int (*FN_ENTOFFSETOFPENTITY)(const edict_t *pEdict);
typedef int (*FN_INDEXOFEDICT)(const edict_t *pEdict);
typedef edict_t *(*FN_PENTITYOFENTINDEX)(int iEntIndex);
typedef edict_t *(*FN_FINDENTITYBYVARS)(struct entvars_s *pvars);
typedef void *(*FN_GETMODELPTR)(edict_t *pEdict);
typedef int (*FN_REGUSERMSG)(const char *pszName, int iSize);
typedef void (*FN_ANIMATIONAUTOMOVE)(const edict_t *pEdict, float flTime);
typedef void (*FN_GETBONEPOSITION)(const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles);
typedef uint32 (*FN_FUNCTIONFROMNAME)(const char *pName);
typedef const char *(*FN_NAMEFORFUNCTION)(uint32 function);
typedef void (*FN_CLIENTPRINTF)(edict_t *pEdict, PRINT_TYPE ptype, const char *szMsg);
typedef void (*FN_SERVERPRINT)(const char *szMsg);
typedef const char *(*FN_CMD_ARGS)();
typedef const char *(*FN_CMD_ARGV)(int argc);
typedef int (*FN_CMD_ARGC)();
typedef void (*FN_GETATTACHMENT)(const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles);
typedef void (*FN_CRC32_INIT)(CRC32_t *pulCRC);
typedef void (*FN_CRC32_PROCESSBUFFER)(CRC32_t *pulCRC, void *p, int len);
typedef void (*FN_CRC32_PROCESSBYTE)(CRC32_t *pulCRC, unsigned char ch);
typedef CRC32_t (*FN_CRC32_FINAL)(CRC32_t pulCRC);
typedef int32 (*FN_RANDOMLONG)(int32 lLow, int32 lHigh);
typedef float (*FN_RANDOMFLOAT)(float flLow, float flHigh);
typedef void (*FN_SETVIEW)(const edict_t *pClient, const edict_t *pViewent);
typedef float (*FN_TIME)();
typedef void (*FN_CROSSHAIRANGLE)(const edict_t *pClient, float pitch, float yaw);
typedef byte *(*FN_LOADFILEFORME)(char *filename, int *pLength);
typedef void (*FN_FREEFILE)(void *buffer);
typedef void (*FN_ENDSECTION)(const char *pszSectionName);
typedef int (*FN_COMPAREFILETIME)(char *filename1, char *filename2, int *iCompare);
typedef void (*FN_GETGAMEDIR)(char *szGetGameDir);
typedef void (*FN_CVAR_REGISTERVARIABLE)(cvar_t *variable);
typedef void (*FN_FADECLIENTVOLUME)(const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds);
typedef void (*FN_SETCLIENTMAXSPEED)(edict_t *pEdict, float fNewMaxspeed);
typedef edict_t *(*FN_CREATEFAKECLIENT)(const char *netname);
typedef void (*FN_RUNPLAYERMOVE)(edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec);
typedef int (*FN_NUMBEROFENTITIES)();
typedef char *(*FN_GETINFOKEYBUFFER)(edict_t *e);
typedef char *(*FN_INFOKEYVALUE)(char *infobuffer, const char *key);
typedef void (*FN_SETKEYVALUE)(char *infobuffer, const char *key, const char *value);
typedef void (*FN_SETCLIENTKEYVALUE)(int clientIndex, char *infobuffer, const char *key, const char *value);
typedef int (*FN_ISMAPVALID)(char *filename);
typedef void (*FN_STATICDECAL)(const float *origin, int decalIndex, int entityIndex, int modelIndex);
typedef int (*FN_PRECACHEGENERIC)(char *s);
typedef int (*FN_GETPLAYERUSERID)(edict_t *e);
typedef void (*FN_BUILDSOUNDMSG)(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);
typedef int (*FN_ISDEDICATEDSERVER)();
typedef cvar_t *(*FN_CVARGETPOINTER)(const char *szVarName);
typedef unsigned int (*FN_GETPLAYERWONID)(edict_t *e);
typedef void (*FN_INFO_REMOVEKEY)(char *s, const char *key);
typedef const char *(*FN_GETPHYSICSKEYVALUE)(const edict_t *pClient, const char *key);
typedef void (*FN_SETPHYSICSKEYVALUE)(const edict_t *pClient, const char *key, const char *value);
typedef const char *(*FN_GETPHYSICSINFOSTRING)(const edict_t *pClient);
typedef unsigned short (*FN_PRECACHEEVENT)(int type, const char *psz);
typedef void (*FN_PLAYBACKEVENT)(int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2);
typedef unsigned char *(*FN_SETFATPVS)(float *org);
typedef unsigned char *(*FN_SETFATPAS)(float *org);
typedef int (*FN_CHECKVISIBILITY)(edict_t *entity, unsigned char *pset);
typedef void (*FN_DELTASETFIELD)(struct delta_s *pFields, const char *fieldname);
typedef void (*FN_DELTAUNSETFIELD)(struct delta_s *pFields, const char *fieldname);
typedef void (*FN_DELTAADDENCODER)(char *name, void (*conditionalencode)(struct delta_s *pFields, const unsigned char *from, const unsigned char *to));
typedef int (*FN_GETCURRENTPLAYER)();
typedef int (*FN_CANSKIPPLAYER)(const edict_t *player);
typedef int (*FN_DELTAFINDFIELD)(struct delta_s *pFields, const char *fieldname);
typedef void (*FN_DELTASETFIELDBYINDEX)(struct delta_s *pFields, int fieldNumber);
typedef void (*FN_DELTAUNSETFIELDBYINDEX)(struct delta_s *pFields, int fieldNumber);
typedef void (*FN_SETGROUPMASK)(int mask, int op);
typedef int (*FN_CREATEINSTANCEDBASELINE)(int classname, struct entity_state_s *baseline);
typedef void (*FN_CVAR_DIRECTSET)(struct cvar_s *var, const char *value);
typedef void (*FN_FORCEUNMODIFIED)(FORCE_TYPE type, float *mins, float *maxs, const char *filename);
typedef void (*FN_GETPLAYERSTATS)(const edict_t *pClient, int *ping, int *packet_loss);
typedef void (*FN_ADDSERVERCOMMAND)(char *cmd_name, void (*function)());
typedef qboolean (*FN_VOICE_GETCLIENTLISTENING)(int iReceiver, int iSender);
typedef qboolean (*FN_VOICE_SETCLIENTLISTENING)(int iReceiver, int iSender, qboolean bListen);
typedef const char *(*FN_GETPLAYERAUTHID)(edict_t *e);
typedef sequenceEntry_s *(*FN_SEQUENCEGET)(const char *fileName, const char *entryName);
typedef sentenceEntry_s *(*FN_SEQUENCEPICKSENTENCE)(const char *groupName, int pickMethod, int *picked);
typedef int (*FN_GETFILESIZE)(char *filename);
typedef unsigned int (*FN_GETAPPROXWAVEPLAYLEN)(const char *filepath);
typedef int (*FN_ISCAREERMATCH)();
typedef int (*FN_GETLOCALIZEDSTRINGLENGTH)(const char *label);
typedef void (*FN_REGISTERTUTORMESSAGESHOWN)(int mid);
typedef int (*FN_GETTIMESTUTORMESSAGESHOWN)(int mid);
typedef void (*FN_PROCESSTUTORMESSAGEDECAYBUFFER)(int *buffer, int bufferLength);
typedef void (*FN_CONSTRUCTTUTORMESSAGEDECAYBUFFER)(int *buffer, int bufferLength);
typedef void (*FN_RESETTUTORMESSAGEDECAYDATA)();
typedef void (*FN_QUERYCLIENTCVARVALUE)(const edict_t *pEdict, const char *cvarName); // Use FN_QUERYCLIENTCVARVALUE2 instead
typedef void (*FN_QUERYCLIENTCVARVALUE2)(const edict_t *pEdict, const char *cvarName, int requestID);
typedef int (*FN_CHECKPARM)(const char *pchCmdLineToken, char **ppnext);
void compile_engine_callbacks();

View File

@ -10,7 +10,7 @@ const game_modinfo_t known_games[] = {
// Previously enumerated in this sourcefile, the list is now kept in a
// separate file, generated based on game information stored in a
// convenient db.
{ "cstrike", "cs.so", "mp.dll", "Counter-Strike" },
{ "cstrike", "cs.so", "mp.dll", "Counter-Strike" },
{ "czero", "cs.so", "mp.dll", "Counter-Strike:Condition Zero" },
// End of list terminator:
@ -22,7 +22,7 @@ inline const game_modinfo_t *lookup_game(const char *name)
{
for (auto& known : known_games)
{
if (known.name && Q_stricmp(known.name, name))
if (known.name && !Q_stricmp(known.name, name))
return &known;
}
@ -31,13 +31,13 @@ inline const game_modinfo_t *lookup_game(const char *name)
}
// Installs gamedll from Steam cache
mBOOL install_gamedll(char *from, const char *to)
bool install_gamedll(char *from, const char *to)
{
int length_in;
int length_out;
if (!from)
return mFALSE;
return false;
if (!to)
to = from;
@ -52,7 +52,7 @@ mBOOL install_gamedll(char *from, const char *to)
{
META_DEBUG(3, ("Installing gamedll from cache: Failed to create file %s: %s", to, strerror(errno)) );
FREE_FILE(cachefile);
return mFALSE;
return false;
}
length_out = Q_write(fd, cachefile, length_in);
@ -68,7 +68,7 @@ mBOOL install_gamedll(char *from, const char *to)
if (length_out >= 0)
_unlink(to);
return mFALSE;
return false;
}
META_LOG("Installed gamedll %s from cache.", to);
@ -76,10 +76,10 @@ mBOOL install_gamedll(char *from, const char *to)
else
{
META_DEBUG(3, ("Failed to install gamedll from cache: file %s not found in cache.", from));
return mFALSE;
return false;
}
return mTRUE;
return true;
}
// Set all the fields in the gamedll struct, - based either on an entry in
@ -88,7 +88,7 @@ mBOOL install_gamedll(char *from, const char *to)
//
// meta_errno values:
// - ME_NOTFOUND couldn't recognize game
mBOOL setup_gamedll(gamedll_t *gamedll)
bool setup_gamedll(gamedll_t *gamedll)
{
const game_modinfo_t *known;
const char *knownfn = nullptr;
@ -121,7 +121,7 @@ mBOOL setup_gamedll(gamedll_t *gamedll)
else
{
// Neither known-list found a gamedll.
RETURN_ERRNO(mFALSE, ME_NOTFOUND);
RETURN_ERRNO(false, ME_NOTFOUND);
}
Q_snprintf(gamedll->pathname, sizeof(gamedll->pathname), "%s/dlls/%s", gamedll->gamedir, knownfn);
@ -141,5 +141,5 @@ mBOOL setup_gamedll(gamedll_t *gamedll)
gamedll->desc = known->desc;
META_LOG("Recognized game '%s'; using dllfile '%s'", gamedll->name, gamedll->file);
return mTRUE;
return true;
}

View File

@ -13,4 +13,4 @@ struct game_modinfo_t
const char *desc; // our long-name description
};
mBOOL setup_gamedll(gamedll_t *gamedll);
bool setup_gamedll(gamedll_t *gamedll);

View File

@ -57,31 +57,3 @@ void WINAPI GiveFnptrsToDll(enginefuncs_t *pengfuncsFromEngine, globalvars_t *pG
// Load plugins, load game dll.
metamod_startup();
}
// Avoid linking to libstdc++
#if defined(linux)
extern "C" void __cxa_pure_virtual(void)
{
}
void *operator new(size_t size)
{
return Q_malloc(size);
}
void *operator new[](size_t size)
{
return Q_malloc(size);
}
void operator delete(void *ptr)
{
Q_free(ptr);
}
void operator delete[](void * ptr)
{
Q_free(ptr);
}
#endif

8968
metamod/src/jitasm.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -18,49 +18,3 @@ void do_link_ent(ENTITY_FN *pfnEntity, int *missing, const char *entStr, entvars
static int missing = 0; \
do_link_ent(&pfnEntity, &missing, STRINGIZE(entityName, 0), pev); \
}
// For now, we have to explicitly export functions for plugin entities,
// just as for gamedll entities. Ideally, this could be generalized in
// some manner, so that plugins can declare and use their own entities
// without having them explicitly supported by metamod, but I don't know
// yet if that is actually possible.
//
// LINK_ENTITY_TO_PLUGIN
// - if plugin not loaded & running, return
// - plugin has to be set loadable=startup only, else log error, return
// - (plugin loaded) if func missing, return
// - (plugin loaded) if func not found, dlsym
// - (plugin loaded) if func still not found, set missing, return
// - (plugin loaded, func found) call func
#define LINK_ENTITY_TO_PLUGIN(entityName, pluginName) \
C_DLLEXPORT void entityName(entvars_t *pev); \
void entityName(entvars_t *pev) { \
static ENTITY_FN pfnEntity = NULL; \
static int missing = 0; \
const char *entStr; \
MPlugin *findp; \
entStr = STRINGIZE(entityName, 0); \
if (missing) \
return; \
if (!pfnEntity) { \
if (!(findp = g_plugins->find_match(pluginName))) { \
META_ERROR("Couldn't find loaded plugin '%s' for plugin entity '%s'", pluginName, entStr); \
missing = 1; \
return; \
} \
if (findp->info && findp->info->loadable != PT_STARTUP) { \
META_ERROR("Can't link entity '%s' for plugin '%s'; loadable != startup: %s", entStr, pluginName, findp->str_loadable()); \
missing = 1; \
return; \
} \
META_DEBUG(9, ("Looking up plugin entity '%s'", entStr)); \
pfnEntity = (ENTITY_FN) DLSYM(findp->handle, entStr); \
} \
if (!pfnEntity) { \
META_ERROR("Couldn't find plugin entity '%s' in plugin DLL '%s'", entStr, findp->file); \
missing = 1; \
return; \
} \
META_DEBUG(8, ("Linking plugin entity '%s'", entStr)); \
(*pfnEntity)(pev); \
}

View File

@ -1,21 +1,11 @@
#include "precompiled.h"
meta_new_dll_functions_t::meta_new_dll_functions_t(
void (*_pfnOnFreeEntPrivateData)(edict_t*),
void (*_pfnGameShutdown)(void),
int (*_pfnShouldCollide)(edict_t*, edict_t*),
void (*_pfnCvarValue)(const edict_t*, const char*),
void (*_pfnCvarValue2)(const edict_t*, int, const char*, const char*)
)
void meta_new_dll_functions_t::set_from(NEW_DLL_FUNCTIONS* _pFuncs)
{
pfnOnFreeEntPrivateData = _pfnOnFreeEntPrivateData;
pfnGameShutdown = _pfnGameShutdown;
pfnShouldCollide = _pfnShouldCollide;
pfnCvarValue = _pfnCvarValue;
pfnCvarValue2 = _pfnCvarValue2;
Q_memcpy(this, _pFuncs, sizeof(NEW_DLL_FUNCTIONS));
}
void meta_new_dll_functions_t::copy_to(NEW_DLL_FUNCTIONS *_pFuncs)
void meta_new_dll_functions_t::copy_to(NEW_DLL_FUNCTIONS *_pFuncs) const
{
#if 0
// TODO: Implemented check regamedll
@ -25,6 +15,16 @@ void meta_new_dll_functions_t::copy_to(NEW_DLL_FUNCTIONS *_pFuncs)
Q_memcpy(_pFuncs, this, sizeof(NEW_DLL_FUNCTIONS));
}
void meta_enginefuncs_t::set_from(enginefuncs_t* _pFuncs)
{
Q_memcpy(this, _pFuncs, sizeof(enginefuncs_t));
}
void meta_enginefuncs_t::copy_to(enginefuncs_t* _pFuncs) const
{
Q_memcpy(_pFuncs, this, sizeof(enginefuncs_t));
}
void HL_enginefuncs_t::initialise_interface(enginefuncs_t* _pFuncs)
{
set_from(_pFuncs);

View File

@ -10,72 +10,23 @@
// meta_new_dll_functions_t
struct meta_new_dll_functions_t: public NEW_DLL_FUNCTIONS
{
meta_new_dll_functions_t();
meta_new_dll_functions_t(
void (*pfnOnFreeEntPrivateData)(edict_t *),
void (*pfnGameShutdown)(),
int (*pfnShouldCollide)(edict_t *, edict_t *),
void (*pfnCvarValue)(const edict_t *, const char *),
void (*pfnCvarValue2)(const edict_t *, int, const char *, const char *)
);
meta_new_dll_functions_t(const meta_new_dll_functions_t&);
meta_new_dll_functions_t& operator=(const meta_new_dll_functions_t&);
// Fill this object with pointers copied from a NEW_DLL_FUNCTIONS struct.
void set_from(NEW_DLL_FUNCTIONS* pFuncs);
// Copy the pointers from this object to a NEW_DLL_FUNCTIONS struct.
void copy_to(NEW_DLL_FUNCTIONS* pFuncs);
void copy_to(NEW_DLL_FUNCTIONS* pFuncs) const;
};
inline meta_new_dll_functions_t::meta_new_dll_functions_t()
{
Q_memset(this, 0, sizeof(meta_new_dll_functions_t));
}
inline meta_new_dll_functions_t::meta_new_dll_functions_t(const meta_new_dll_functions_t& _rhs)
{
Q_memcpy(this, &_rhs, sizeof(NEW_DLL_FUNCTIONS));
}
inline meta_new_dll_functions_t& meta_new_dll_functions_t::operator=(const meta_new_dll_functions_t& _rhs)
{
Q_memcpy(this, &_rhs, sizeof(NEW_DLL_FUNCTIONS));
return *this;
}
inline void meta_new_dll_functions_t::set_from(NEW_DLL_FUNCTIONS* _pFuncs)
{
Q_memcpy(this, _pFuncs, sizeof(NEW_DLL_FUNCTIONS));
}
// meta_enginefuncs_t
struct meta_enginefuncs_t : public enginefuncs_t
{
meta_enginefuncs_t() {};
meta_enginefuncs_t(enginefuncs_t* pFuncs)
{
set_from(pFuncs);
};
// Fill this object with pointers copied from an enginefuncs_t struct.
void set_from(enginefuncs_t* pFuncs);
// Copy the pointers from this object to an enginefuncs_t struct.
void copy_to(enginefuncs_t* pFuncs);
void copy_to(enginefuncs_t* pFuncs) const;
};
inline void meta_enginefuncs_t::set_from(enginefuncs_t* _pFuncs)
{
Q_memcpy(this, _pFuncs, sizeof(enginefuncs_t));
}
inline void meta_enginefuncs_t::copy_to(enginefuncs_t* _pFuncs)
{
Q_memcpy(_pFuncs, this, sizeof(enginefuncs_t));
}
// This is a specialisation of the meta_enginefuncs_t struct which is only
// used for the initial copy of the engine functions, i.e. those we get
// passed from the HL engine right at the beginning.

View File

@ -16,8 +16,7 @@ option_t global_options[] =
gamedll_t GameDLL;
meta_globals_t PublicMetaGlobals;
meta_globals_t PrivateMetaGlobals;
meta_globals_t g_metaGlobals;
meta_enginefuncs_t g_plugin_engfuncs;
@ -26,7 +25,7 @@ MRegCmdList *g_regCmds;
MRegCvarList *g_regCvars;
MRegMsgList *g_regMsgs;
MPlayerList g_Players;
MPlayerList g_players;
unsigned int CALL_API_count = 0;
@ -55,16 +54,6 @@ void metamod_startup()
META_CONS("Metamod build: " __TIME__ " " __DATE__ " (" APP_VERSION_STRD ")");
META_CONS("Metamod from: " APP_COMMITS_URL APP_COMMIT_ID " " APP_COMMIT_AUTHOR "");
// If running with "+developer", allow an opportunity to break in with
// a debugger.
if ((int) CVAR_GET_FLOAT("developer") != 0)
{
//sleep(10); // TODO: WAT??????
}
// specify our new() handler
mm_set_new_handler();
// Get gamedir, very early on, because it seems we need it all over the
// place here at the start.
if (!meta_init_gamedll())
@ -149,11 +138,6 @@ void metamod_startup()
if (g_engine.pl_funcs->pfnQueryClientCvarValue)
g_engine.pl_funcs->pfnQueryClientCvarValue = meta_QueryClientCvarValue;
#ifdef UNFINISHED
// Init the list of event/logline hooks.
Hooks = new MHookList();
#endif
// Before, we loaded plugins before loading the game DLL, so that if no
// plugins caught engine functions, we could pass engine funcs straight
// to game dll, rather than acting as intermediary. (Should perform
@ -236,7 +220,7 @@ void metamod_startup()
// Set initial GameDLL fields (name, gamedir).
// meta_errno values:
// - ME_NULLRESULT _getcwd failed
mBOOL meta_init_gamedll(void)
bool meta_init_gamedll(void)
{
char gamedir[PATH_MAX];
char *cp;
@ -277,7 +261,7 @@ mBOOL meta_init_gamedll(void)
if (!_getcwd(buf, sizeof(buf)))
{
META_WARNING("dll: Couldn't get cwd; %s", strerror(errno));
RETURN_ERRNO(mFALSE, ME_NULLRESULT);
RETURN_ERRNO(false, ME_NULLRESULT);
}
Q_snprintf(GameDLL.gamedir, sizeof(GameDLL.gamedir), "%s/%s", buf, gamedir);
@ -286,7 +270,7 @@ mBOOL meta_init_gamedll(void)
}
META_DEBUG(3, ("Game: %s", GameDLL.name));
return mTRUE;
return true;
}
// Load game DLL.
@ -294,7 +278,7 @@ mBOOL meta_init_gamedll(void)
// - ME_DLOPEN couldn't dlopen game dll file
// - ME_DLMISSING couldn't find required routine in game dll
// (GiveFnptrsToDll, GetEntityAPI, GetEntityAPI2)
mBOOL meta_load_gamedll(void)
bool meta_load_gamedll(void)
{
int iface_vers;
int found = 0;
@ -308,16 +292,19 @@ mBOOL meta_load_gamedll(void)
{
META_ERROR("dll: Unrecognized game: %s", GameDLL.name);
// meta_errno should be already set in lookup_game()
return mFALSE;
return false;
}
// open the game DLL
if (!(GameDLL.handle = DLOPEN(GameDLL.pathname)))
{
META_ERROR("dll: Couldn't load game DLL %s: %s", GameDLL.pathname, DLERROR());
RETURN_ERRNO(mFALSE, ME_DLOPEN);
RETURN_ERRNO(false, ME_DLOPEN);
}
// prepare meta_engfuncs
compile_engine_callbacks();
// Used to only pass our table of engine funcs if a loaded plugin
// wanted to catch one of the functions, but now that plugins are
// dynamically loadable at any time, we have to always pass our table,
@ -330,7 +317,7 @@ mBOOL meta_load_gamedll(void)
else
{
META_ERROR("dll: Couldn't find GiveFnptrsToDll() in game DLL '%s': %s", GameDLL.name, DLERROR());
RETURN_ERRNO(mFALSE, ME_DLMISSING);
RETURN_ERRNO(false, ME_DLMISSING);
}
// Yes...another macro.
@ -389,9 +376,20 @@ mBOOL meta_load_gamedll(void)
if (!found)
{
META_ERROR("dll: Couldn't find either GetEntityAPI nor GetEntityAPI2 in game DLL '%s'", GameDLL.name);
RETURN_ERRNO(mFALSE, ME_DLMISSING);
RETURN_ERRNO(false, ME_DLMISSING);
}
// prepare gamedll callbacks
compile_gamedll_callbacks();
META_LOG("Game DLL for '%s' loaded successfully", GameDLL.desc);
return mTRUE;
return true;
}
void meta_rebuild_callbacks()
{
g_jit.clear_callbacks();
compile_engine_callbacks();
compile_gamedll_callbacks();
}

View File

@ -5,7 +5,7 @@
#include "mreg.h" // MRegCmdList, etc
#include "conf_meta.h" // MConfig
#include "osdep.h" // NAME_MAX, etc
#include "types_meta.h" // mBOOL
#include "types_meta.h" // bool
#include "mplayer.h" // MPlayerList
#include "meta_eiface.h" // HL_enginefuncs_t, meta_enginefuncs_t
#include "engine_t.h" // engine_t, Engine
@ -72,8 +72,7 @@ extern MHookList *Hooks;
// Data provided to plugins.
// Separate copies to prevent plugins from modifying "readable" parts.
// See meta_api.h for meta_globals_t structure.
extern meta_globals_t PublicMetaGlobals;
extern meta_globals_t PrivateMetaGlobals;
extern meta_globals_t g_metaGlobals;
// hook function tables
extern DLL_FUNCTIONS *pHookedDllFunctions;
@ -83,8 +82,8 @@ extern NEW_DLL_FUNCTIONS *pHookedNewDllFunctions;
// Safety check for metamod-bot-plugin bugfix.
// engine_api->pfnRunPlayerMove calls dllapi-functions before it returns.
// This causes problems with bots running as metamod plugins, because
// metamod assumed that PublicMetaGlobals is free to be used.
// With call_count we can fix this by backuping up PublicMetaGlobals if
// metamod assumed that g_metaGlobals is free to be used.
// With call_count we can fix this by backuping up g_metaGlobals if
// it's already being used.
extern unsigned int CALL_API_count;
@ -94,12 +93,13 @@ extern int requestid_counter;
// (patch by BAILOPAN)
// Holds cached player info, right now only things for querying cvars
// Max players is always 32, small enough that we can use a static array
extern MPlayerList g_Players;
extern MPlayerList g_players;
void metamod_startup();
mBOOL meta_init_gamedll();
mBOOL meta_load_gamedll();
bool meta_init_gamedll();
bool meta_load_gamedll();
void meta_rebuild_callbacks();
// lotsa macros...
@ -155,231 +155,3 @@ mBOOL meta_load_gamedll();
// couldn't seem to generalize the two into a form that the compiler would
// accept. Thus there are "_void" versions of the 5 macros; these are
// listed first.
// macros for void-returning functions
// declare/init some variables
#define SETUP_API_CALLS_void(FN_TYPE, pfnName, api_info_table) \
int i; \
META_RES mres = MRES_UNSET, status = MRES_UNSET, prev_mres = MRES_UNSET; \
MPlugin *iplug; \
FN_TYPE pfn_routine = NULL; \
int loglevel = api_info_table.pfnName.loglevel; \
const char *pfn_string = api_info_table.pfnName.name; \
meta_globals_t backup_meta_globals; \
/* fix bug with metamod-bot-plugins (hullu)*/ \
if (CALL_API_count++>0) \
/* backup publicmetaglobals */ \
backup_meta_globals = PublicMetaGlobals;
// call each plugin
#define CALL_PLUGIN_API_void(post, pfnName, pfn_args, api_table) \
prev_mres = MRES_UNSET; \
for (i = 0; i < g_plugins->endlist; i++) { \
iplug = &g_plugins->plist[i]; \
if (iplug->status != PL_RUNNING) \
continue; \
if (iplug->api_table && (pfn_routine = iplug->api_table->pfnName)); \
else \
/* plugin doesn't provide this function */ \
continue; \
/* initialize PublicMetaGlobals */ \
PublicMetaGlobals.mres = MRES_UNSET; \
PublicMetaGlobals.prev_mres = prev_mres; \
PublicMetaGlobals.status = status; \
/* call plugin */ \
META_DEBUG(loglevel, ("Calling %s:%s%s()", iplug->file, pfn_string, (post?"_Post":""))); \
pfn_routine pfn_args; \
/* plugin's result code */ \
mres = PublicMetaGlobals.mres; \
if (mres > status) \
status = mres; \
/* save this for successive plugins to see */ \
prev_mres = mres; \
if (mres == MRES_UNSET) \
META_ERROR("Plugin didn't set meta_result: %s:%s%s()", iplug->file, pfn_string, (post?"_Post":"")); \
if (post && mres == MRES_SUPERCEDE) \
META_ERROR("MRES_SUPERCEDE not valid in Post functions: %s:%s%s()", iplug->file, pfn_string, (post?"_Post":"")); \
}
// call "real" function, from gamedll
#define CALL_GAME_API_void(pfnName, pfn_args, api_table) \
CALL_API_count--; \
if (status == MRES_SUPERCEDE) { \
META_DEBUG(loglevel, ("Skipped (supercede) %s:%s()", GameDLL.file, pfn_string)); \
/* don't return here; superceded game routine, but still allow \
* _post routines to run. \
*/ \
} \
else if (GameDLL.funcs.api_table) { \
pfn_routine = GameDLL.funcs.api_table->pfnName; \
if (pfn_routine) { \
META_DEBUG(loglevel, ("Calling %s:%s()", GameDLL.file, pfn_string)); \
pfn_routine pfn_args; \
} \
/* don't complain for NULL routines in NEW_DLL_FUNCTIONS */ \
else if ((void *)GameDLL.funcs.api_table != (void *)GameDLL.funcs.newapi_table) { \
META_ERROR("Couldn't find api call: %s:%s", GameDLL.file, pfn_string); \
status = MRES_UNSET; \
} \
} \
else { \
META_DEBUG(loglevel, ("No api table defined for api call: %s:%s", GameDLL.file, pfn_string)); \
} \
CALL_API_count++;
// call "real" function, from engine
#define CALL_ENGINE_API_void(pfnName, pfn_args) \
CALL_API_count--; \
if (status == MRES_SUPERCEDE) { \
META_DEBUG(loglevel, ("Skipped (supercede) engine:%s()", pfn_string)); \
/* don't return here; superceded game routine, but still allow \
* _post routines to run. \
*/ \
} \
else { \
pfn_routine = g_engine.funcs->pfnName; \
if (pfn_routine) { \
META_DEBUG(loglevel, ("Calling engine:%s()", pfn_string)); \
pfn_routine pfn_args; \
} \
else { \
META_ERROR("Couldn't find api call: engine:%s", pfn_string); \
status = MRES_UNSET; \
} \
} \
CALL_API_count++;
// return (void)
#define RETURN_API_void() \
if (--CALL_API_count>0) \
/*restore backup*/ \
PublicMetaGlobals = backup_meta_globals; \
return;
// macros for type-returning functions
// declare/init some variables
#define SETUP_API_CALLS(ret_t, ret_init, FN_TYPE, pfnName, api_info_table) \
int i; \
ret_t dllret = ret_init; \
ret_t override_ret = ret_init; \
ret_t pub_override_ret = ret_init; \
ret_t orig_ret = ret_init; \
ret_t pub_orig_ret = ret_init; \
META_RES mres = MRES_UNSET, status = MRES_UNSET, prev_mres = MRES_UNSET; \
MPlugin *iplug; \
FN_TYPE pfn_routine = NULL; \
int loglevel = api_info_table.pfnName.loglevel; \
const char *pfn_string = api_info_table.pfnName.name; \
meta_globals_t backup_meta_globals; \
/*Fix bug with metamod-bot-plugins*/ \
if (CALL_API_count++>0) \
/*Backup PublicMetaGlobals*/ \
backup_meta_globals = PublicMetaGlobals;
// call each plugin
#define CALL_PLUGIN_API(post, ret_init, pfnName, pfn_args, MRES_TYPE, api_table) \
override_ret = ret_init; \
prev_mres = MRES_UNSET; \
for (i = 0; i < g_plugins->endlist; i++) { \
if (g_plugins->plist[i].status != PL_RUNNING) \
continue; \
iplug = &g_plugins->plist[i]; \
if (iplug->api_table && (pfn_routine = iplug->api_table->pfnName)); \
else \
/* plugin doesn't provide this function */ \
continue; \
/* initialize PublicMetaGlobals */ \
PublicMetaGlobals.mres = MRES_UNSET; \
PublicMetaGlobals.prev_mres = prev_mres; \
PublicMetaGlobals.status = status; \
pub_orig_ret = orig_ret; \
PublicMetaGlobals.orig_ret = &pub_orig_ret; \
if (status == MRES_TYPE) { \
pub_override_ret = override_ret; \
PublicMetaGlobals.override_ret = &pub_override_ret; \
} \
/* call plugin */ \
META_DEBUG(loglevel, ("Calling %s:%s%s()", iplug->file, pfn_string, (post?"_Post":""))); \
dllret = pfn_routine pfn_args; \
/* plugin's result code */ \
mres = PublicMetaGlobals.mres; \
if (mres > status) \
status = mres; \
/* save this for successive plugins to see */ \
prev_mres = mres; \
if (mres == MRES_TYPE) \
override_ret = pub_override_ret = dllret; \
else if (mres == MRES_UNSET) \
META_ERROR("Plugin didn't set meta_result: %s:%s%s()", iplug->file, pfn_string, (post?"_Post":"")); \
else if (post && mres == MRES_SUPERCEDE) \
META_ERROR("MRES_SUPERCEDE not valid in Post functions: %s:%s%s()", iplug->file, pfn_string, (post?"_Post":"")); \
}
// call "real" function, from gamedll
#define CALL_GAME_API(pfnName, pfn_args, api_table) \
CALL_API_count--; \
if (status == MRES_SUPERCEDE) { \
META_DEBUG(loglevel, ("Skipped (supercede) %s:%s()", GameDLL.file, pfn_string)); \
orig_ret = pub_orig_ret = override_ret; \
PublicMetaGlobals.orig_ret = &pub_orig_ret; \
/* don't return here; superceded game routine, but still allow \
* _post routines to run. \
*/ \
} \
else if (GameDLL.funcs.api_table) { \
pfn_routine = GameDLL.funcs.api_table->pfnName; \
if (pfn_routine) { \
META_DEBUG(loglevel, ("Calling %s:%s()", GameDLL.file, pfn_string)); \
dllret = pfn_routine pfn_args; \
orig_ret = dllret; \
} \
/* don't complain for NULL routines in NEW_DLL_FUNCTIONS */ \
else if ((void *)GameDLL.funcs.api_table != (void *)GameDLL.funcs.newapi_table) { \
META_ERROR("Couldn't find api call: %s:%s", GameDLL.file, pfn_string); \
status = MRES_UNSET; \
} \
} \
else { \
META_DEBUG(loglevel, ("No api table defined for api call: %s:%s", GameDLL.file, pfn_string)); \
} \
CALL_API_count++;
// call "real" function, from engine
#define CALL_ENGINE_API(pfnName, pfn_args) \
CALL_API_count--; \
if (status == MRES_SUPERCEDE) { \
META_DEBUG(loglevel, ("Skipped (supercede) engine:%s()", pfn_string)); \
orig_ret = pub_orig_ret = override_ret; \
PublicMetaGlobals.orig_ret = &pub_orig_ret; \
/* don't return here; superceded game routine, but still allow \
* _post routines to run. \
*/ \
} \
else { \
pfn_routine = g_engine.funcs->pfnName; \
if (pfn_routine) { \
META_DEBUG(loglevel, ("Calling engine:%s()", pfn_string)); \
dllret = pfn_routine pfn_args; \
orig_ret = dllret; \
} \
else { \
META_ERROR("Couldn't find api call: engine:%s", pfn_string); \
status = MRES_UNSET; \
} \
} \
CALL_API_count++;
// return a value
#define RETURN_API() \
if (--CALL_API_count>0) \
/*Restore backup*/ \
PublicMetaGlobals = backup_meta_globals; \
if (status == MRES_OVERRIDE) { \
META_DEBUG(loglevel, ("Returning (override) %s()", pfn_string)); \
return override_ret; \
} \
else \
return orig_ret;

View File

@ -248,7 +248,7 @@ MPlugin* MPluginList::plugin_addload(plid_t plid, const char* fname, PLUG_LOADTI
RETURN_ERRNO(NULL, ME_NOTFOUND);
}
if (pl_temp.resolve() != mTRUE)
if (pl_temp.resolve() != true)
{
META_DEBUG(1, ("Couldn't resolve given path into a file: %s", pl_temp.file));
RETURN_ERRNO(NULL, ME_NOTFOUND);
@ -351,7 +351,7 @@ MPlugin* MPluginList::add(MPlugin* padd)
// Read plugins.ini at server startup.
// meta_errno values:
// - ME_NOFILE ini file missing or empty
mBOOL MPluginList::ini_startup()
bool MPluginList::ini_startup()
{
FILE *fp;
char line[MAX_STRBUF_LEN];
@ -361,7 +361,7 @@ mBOOL MPluginList::ini_startup()
if (!valid_gamedir_file(inifile))
{
META_ERROR("ini: Metamod plugins file empty or missing: %s", inifile);
RETURN_ERRNO(mFALSE, ME_NOFILE);
RETURN_ERRNO(false, ME_NOFILE);
}
full_gamedir_path(inifile, inifile);
@ -369,7 +369,7 @@ mBOOL MPluginList::ini_startup()
if (!fp)
{
META_ERROR("ini: Unable to open plugins file '%s': %s", inifile, strerror(errno));
RETURN_ERRNO(mFALSE, ME_NOFILE);
RETURN_ERRNO(false, ME_NOFILE);
}
META_LOG("ini: Begin reading plugins list: %s", inifile);
@ -428,13 +428,13 @@ mBOOL MPluginList::ini_startup()
META_ERROR("ini: Warning; no plugins found to load?");
}
return mTRUE;
return true;
}
// Re-read plugins.ini looking for added/deleted/changed plugins.
// meta_errno values:
// - ME_NOFILE ini file missing or empty
mBOOL MPluginList::ini_refresh()
bool MPluginList::ini_refresh()
{
FILE *fp;
char line[MAX_STRBUF_LEN];
@ -446,7 +446,7 @@ mBOOL MPluginList::ini_refresh()
if (!fp)
{
META_ERROR("ini: Unable to open plugins file '%s': %s", inifile, strerror(errno));
RETURN_ERRNO(mFALSE, ME_NOFILE);
RETURN_ERRNO(false, ME_NOFILE);
}
META_LOG("ini: Begin re-reading plugins list: %s", inifile);
@ -561,7 +561,7 @@ mBOOL MPluginList::ini_refresh()
META_ERROR("ini: Warning; no plugins found to load?");
}
return mTRUE;
return true;
}
// Load a plugin from a console command.
@ -571,30 +571,26 @@ mBOOL MPluginList::ini_refresh()
// - ME_ALREADY this plugin already loaded
// - errno's from add()
// - errno's from load()
mBOOL MPluginList::cmd_addload(const char* args)
bool MPluginList::cmd_addload(const char* args)
{
MPlugin pl_temp;
MPlugin pl_temp = {};
MPlugin *pl_found, *pl_added;
// XXX move back to comands_meta ?
// parse into a temp plugin
Q_memset(&pl_temp, 0, sizeof(pl_temp));
if (pl_temp.cmd_parseline(args) != mTRUE)
if (pl_temp.cmd_parseline(args) != true)
{
META_CONS("Couldn't parse 'meta load' arguments: %s", args);
// meta_errno should be already set in cmd_parseline()
return mFALSE;
return false;
}
// resolve given path into a file; accepts various "shortcut"
// pathnames.
if (pl_temp.resolve() != mTRUE)
if (pl_temp.resolve() != true)
{
// Couldn't find a matching file on disk
META_CONS("Couldn't resolve given path into a file: %s", pl_temp.file);
// meta_errno should be already set in resolve()
return mFALSE;
return false;
}
// Try to find plugin with this pathname in the current list of
@ -603,14 +599,14 @@ mBOOL MPluginList::cmd_addload(const char* args)
{
// Already in list
META_CONS("Plugin '%s' already in current list; file=%s desc='%s'", pl_temp.file, pl_found->file, pl_found->desc);
RETURN_ERRNO(mFALSE, ME_ALREADY);
RETURN_ERRNO(false, ME_ALREADY);
}
// new plugin; add to list
if (!(pl_added = add(&pl_temp)))
{
META_CONS("Couldn't add plugin '%s' to list; see log", pl_temp.desc);
// meta_errno should be already set in add()
return mFALSE;
return false;
}
// try to load new plugin
@ -632,26 +628,28 @@ mBOOL MPluginList::cmd_addload(const char* args)
show(0);
// meta_errno should be already set in load()
return mFALSE;
return false;
}
META_CONS("Loaded plugin '%s' successfully", pl_added->desc);
META_CONS("Rebuilding callbacks...");
meta_rebuild_callbacks();
show(0);
return mTRUE;
return true;
}
// Load plugins at startup.
// meta_errno values:
// - errno's from ini_startup()
mBOOL MPluginList::load()
bool MPluginList::load()
{
int n = 0;
if (!ini_startup())
{
META_ERROR("Problem loading plugins.ini: %s", inifile);
// meta_errno should be already set in ini_startup()
return mFALSE;
return false;
}
META_LOG("dll: Loading plugins...");
@ -660,21 +658,24 @@ mBOOL MPluginList::load()
if (plist[i].status < PL_VALID)
continue;
if (plist[i].load(PT_STARTUP) == mTRUE)
if (plist[i].load(PT_STARTUP) == true)
n++;
else
// all plugins should be loadable at startup...
META_ERROR("dll: Failed to load plugin '%s'", plist[i].file);
}
META_LOG("dll: Rebuilding callbacks...");
meta_rebuild_callbacks();
META_LOG("dll: Finished loading %d plugins", n);
return mTRUE;
return true;
}
// Update list of loaded plugins from ini file, and load any new/changed plugins.
// meta_errno values:
// - errno's from ini_refresh()
mBOOL MPluginList::refresh(PLUG_LOADTIME now)
bool MPluginList::refresh(PLUG_LOADTIME now)
{
int i, ndone = 0, nkept = 0, nloaded = 0, nunloaded = 0, nreloaded = 0, ndelayed = 0;
MPlugin* iplug;
@ -683,7 +684,7 @@ mBOOL MPluginList::refresh(PLUG_LOADTIME now)
{
META_ERROR("dll: Problem reloading plugins.ini: %s", inifile);
// meta_errno should be already set in ini_refresh()
return mFALSE;
return false;
}
META_LOG("dll: Updating plugins...");
@ -752,8 +753,11 @@ mBOOL MPluginList::refresh(PLUG_LOADTIME now)
ndone++;
}
META_LOG("dll: Rebuilding callbacks...");
meta_rebuild_callbacks();
META_LOG("dll: Finished updating %d plugins; kept %d, loaded %d, unloaded %d, reloaded %d, delayed %d", ndone, nkept, nloaded, nunloaded, nreloaded, ndelayed);
return mTRUE;
return true;
}
// Re-enable any plugins currently paused.
@ -869,10 +873,10 @@ void MPluginList::show_client(edict_t *pEntity)
META_CLIENT(pEntity, "%d plugins", n);
}
mBOOL MPluginList::found_child_plugins(int source_index)
bool MPluginList::found_child_plugins(int source_index) const
{
if (source_index <= 0)
return mFALSE;
return false;
for (int i = 0; i < endlist; i++)
{
@ -880,10 +884,10 @@ mBOOL MPluginList::found_child_plugins(int source_index)
continue;
if (plist[i].source_plugin_index == source_index)
return mTRUE;
return true;
}
return mFALSE;
return false;
}
void MPluginList::clear_source_plugin_index(int source_index)

View File

@ -1,6 +1,6 @@
#pragma once
#include "types_meta.h" // mBOOL
#include "types_meta.h" // bool
#include "mplugin.h" // class MPlugin
#include "plinfo.h" // plid_t, etc
@ -26,15 +26,15 @@ public:
MPlugin *find(DLHANDLE handle); // find by handle
MPlugin *add(MPlugin *padd);
mBOOL found_child_plugins(int source_index);
bool found_child_plugins(int source_index) const;
mBOOL ini_startup(void); // read inifile at startup
mBOOL ini_refresh(void); // re-read inifile
mBOOL cmd_addload(const char *args); // load from console command
bool ini_startup(void); // read inifile at startup
bool ini_refresh(void); // re-read inifile
bool cmd_addload(const char *args); // load from console command
MPlugin *plugin_addload(plid_t plid, const char *fname, PLUG_LOADTIME now); //load from plugin
mBOOL load(void); // load the list, at startup
mBOOL refresh(PLUG_LOADTIME now); // update from re-read inifile
bool load(void); // load the list, at startup
bool refresh(PLUG_LOADTIME now); // update from re-read inifile
void unpause_all(void); // unpause any paused plugins
void retry_all(PLUG_LOADTIME now); // retry any pending plugin actions
void show(int source_index = 0); // list plugins to console

View File

@ -1,6 +1,6 @@
#include "precompiled.h"
MPlayer::MPlayer() : isQueried(mFALSE)
MPlayer::MPlayer() : isQueried(false)
{
}
@ -18,7 +18,7 @@ void MPlayer::set_cvar_query(const char *cvar)
return;
}
isQueried = mTRUE;
isQueried = true;
Q_strncpy(cvarName, cvar, sizeof cvarName - 1);
cvarName[sizeof cvarName - 1] = '\0';
}
@ -26,7 +26,7 @@ void MPlayer::set_cvar_query(const char *cvar)
// Unmark player as querying a client cvar
void MPlayer::clear_cvar_query(const char *cvar)
{
isQueried = mFALSE;
isQueried = false;
cvarName[0] = '\0';
}

View File

@ -13,7 +13,7 @@ public:
const char *is_querying_cvar() const; // check if a player is querying a cvar. returns
private:
mBOOL isQueried; // is this player currently queried for a cvar value
bool isQueried; // is this player currently queried for a cvar value
char cvarName[64]; // name of the cvar if getting queried
};

View File

@ -5,7 +5,7 @@
// - ME_COMMENT ignored commented line
// - ME_FORMAT invalid line format
// - ME_OSNOTSUP plugin is not for this OS
mBOOL MPlugin::ini_parseline(char *line)
bool MPlugin::ini_parseline(char *line)
{
char *token;
char *ptr_token;
@ -22,19 +22,19 @@ mBOOL MPlugin::ini_parseline(char *line)
if (line[0] == '\0')
{
META_DEBUG(7, ("ini: Ignoring empty line: %s", line));
RETURN_ERRNO(mFALSE, ME_BLANK);
RETURN_ERRNO(false, ME_BLANK);
}
if (line[0] == '#' || line[0] == ';' || Q_strstr(line, "//") == line)
{
META_DEBUG(7, ("ini: Ignoring commented line: %s", line));
RETURN_ERRNO(mFALSE, ME_COMMENT);
RETURN_ERRNO(false, ME_COMMENT);
}
// grab platform ("win32" or "linux")
token = strtok_r(line, " \t", &ptr_token);
if (!token)
RETURN_ERRNO(mFALSE, ME_FORMAT);
RETURN_ERRNO(false, ME_FORMAT);
if (Q_stricmp(token, PLATFORM) == 0)
{
pfspecific = 0;
@ -47,14 +47,14 @@ mBOOL MPlugin::ini_parseline(char *line)
{
// plugin is not for this OS
META_DEBUG(7, ("ini: Ignoring entry for %s", token));
RETURN_ERRNO(mFALSE, ME_OSNOTSUP);
RETURN_ERRNO(false, ME_OSNOTSUP);
}
// grab filename
token = strtok_r(NULL, " \t\r\n", &ptr_token);
if (!token)
{
RETURN_ERRNO(mFALSE, ME_FORMAT);
RETURN_ERRNO(false, ME_FORMAT);
}
Q_strncpy(filename, token, sizeof filename - 1);
@ -90,13 +90,13 @@ mBOOL MPlugin::ini_parseline(char *line)
source = PS_INI;
status = PL_VALID;
return mTRUE;
return true;
}
// Unload a plugin from plugin request
// meta_errno values:
// - errno's from unload()
mBOOL MPlugin::plugin_unload(plid_t plid, PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
bool MPlugin::plugin_unload(plid_t plid, PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
{
PLUG_ACTION old_action;
MPlugin *pl_unloader;
@ -104,17 +104,17 @@ mBOOL MPlugin::plugin_unload(plid_t plid, PLUG_LOADTIME now, PL_UNLOAD_REASON re
if (!(pl_unloader = g_plugins->find(plid)))
{
META_WARNING("dll: Not unloading plugin '%s'; plugin that requested unload is not found.", desc);
RETURN_ERRNO(mFALSE, ME_BADREQ);
RETURN_ERRNO(false, ME_BADREQ);
}
else if (pl_unloader->index == index)
{
META_WARNING("dll: Not unloading plugin '%s'; Plugin tried to unload itself.", desc);
RETURN_ERRNO(mFALSE, ME_UNLOAD_SELF);
RETURN_ERRNO(false, ME_UNLOAD_SELF);
}
else if (is_unloader)
{
META_WARNING("dll: Not unloading plugin '%s'; Plugin is unloading plugin that tried to unload it.", desc);
RETURN_ERRNO(mFALSE, ME_UNLOAD_UNLOADER);
RETURN_ERRNO(false, ME_UNLOAD_UNLOADER);
}
else
{
@ -122,7 +122,7 @@ mBOOL MPlugin::plugin_unload(plid_t plid, PLUG_LOADTIME now, PL_UNLOAD_REASON re
}
//block unloader from being unloaded by other plugin
pl_unloader->is_unloader = mTRUE;
pl_unloader->is_unloader = true;
//try unload
old_action = action;
@ -130,11 +130,11 @@ mBOOL MPlugin::plugin_unload(plid_t plid, PLUG_LOADTIME now, PL_UNLOAD_REASON re
if (unload(now, reason, PNL_PLG_FORCED))
{
META_DEBUG(1,("Unloaded plugin '%s'", desc));
pl_unloader->is_unloader = mFALSE;
return mTRUE;
pl_unloader->is_unloader = false;
return true;
}
pl_unloader->is_unloader = mFALSE;
pl_unloader->is_unloader = false;
//can't unload plugin now, set delayed
if (meta_errno == ME_DELAYED)
@ -144,12 +144,12 @@ mBOOL MPlugin::plugin_unload(plid_t plid, PLUG_LOADTIME now, PL_UNLOAD_REASON re
META_DEBUG(2, ("dll: Failed unload plugin '%s'; can't detach now: allowed=%s; now=%s", desc, str_unloadable(), str_loadtime(PT_ANYTIME, SL_SIMPLE)));
}
return mFALSE;
return false;
}
// Parse a filename string from PEXT_LOAD_PLUGIN_BY_ *function into a plugin.
// meta_errno values:
mBOOL MPlugin::plugin_parseline(const char *fname, int loader_index)
bool MPlugin::plugin_parseline(const char *fname, int loader_index)
{
char *cp;
@ -177,13 +177,13 @@ mBOOL MPlugin::plugin_parseline(const char *fname, int loader_index)
source = PS_PLUGIN;
status = PL_VALID;
return mTRUE;
return true;
}
// Parse a line from console "load" command into a plugin.
// meta_errno values:
// - ME_FORMAT invalid line format
mBOOL MPlugin::cmd_parseline(const char *line)
bool MPlugin::cmd_parseline(const char *line)
{
char buf[NAME_MAX + PATH_MAX + MAX_DESC_LEN];
char *token;
@ -196,12 +196,12 @@ mBOOL MPlugin::cmd_parseline(const char *line)
// remove "load"
token = strtok_r(buf, " \t", &ptr_token);
if (!token)
RETURN_ERRNO(mFALSE, ME_FORMAT);
RETURN_ERRNO(false, ME_FORMAT);
// grab filename
token = strtok_r(NULL, " \t", &ptr_token);
if (!token)
RETURN_ERRNO(mFALSE, ME_FORMAT);
RETURN_ERRNO(false, ME_FORMAT);
Q_strncpy(filename, token, sizeof filename - 1);
filename[sizeof filename - 1] = '\0';
@ -236,34 +236,34 @@ mBOOL MPlugin::cmd_parseline(const char *line)
source = PS_CMD;
status = PL_VALID;
return mTRUE;
return true;
}
// Make sure this plugin has the necessary minimal information.
// meta_errno values:
// - ME_ARGUMENT missing necessary fields in plugin
mBOOL MPlugin::check_input(void)
bool MPlugin::check_input(void)
{
// doublecheck our input/state
if (status < PL_VALID)
{
META_ERROR("dll: Tried to operate on plugin[%d] with a non-valid status (%d)", index, str_status());
RETURN_ERRNO(mFALSE, ME_ARGUMENT);
RETURN_ERRNO(false, ME_ARGUMENT);
}
if (!file || !file[0])
{
META_ERROR("dll: Tried to operate on plugin[%d] with an empty file", index);
RETURN_ERRNO(mFALSE, ME_ARGUMENT);
RETURN_ERRNO(false, ME_ARGUMENT);
}
if (!filename[0])
{
META_ERROR("dll: Tried to operate on plugin[%d] with an empty filename", index);
RETURN_ERRNO(mFALSE, ME_ARGUMENT);
RETURN_ERRNO(false, ME_ARGUMENT);
}
if (!pathname[0])
{
META_ERROR("dll: Tried to operate on plugin[%d] with an empty pathname", index);
RETURN_ERRNO(mFALSE, ME_ARGUMENT);
RETURN_ERRNO(false, ME_ARGUMENT);
}
if (!desc[0])
@ -273,7 +273,7 @@ mBOOL MPlugin::check_input(void)
Q_snprintf(desc, sizeof(desc), "<%s>", file);
}
return mTRUE;
return true;
}
// Try to resolve a plugin's filename as a (possibly partial) path to an
@ -289,7 +289,7 @@ mBOOL MPlugin::check_input(void)
// meta_errno values:
// - ME_NOTFOUND couldn't find a matching file for the partial name
// - errno's from check_input()
mBOOL MPlugin::resolve(void)
bool MPlugin::resolve(void)
{
char *found;
char *cp;
@ -298,7 +298,7 @@ mBOOL MPlugin::resolve(void)
if (!check_input())
{
// details logged, meta_errno set in check_input()
return mFALSE;
return false;
}
if (is_absolute_path(filename))
found = resolve_prefix(filename);
@ -308,7 +308,7 @@ mBOOL MPlugin::resolve(void)
if (!found)
{
META_DEBUG(2, ("Couldn't resolve '%s' to file", filename));
RETURN_ERRNO(mFALSE, ME_NOTFOUND);
RETURN_ERRNO(false, ME_NOTFOUND);
}
META_DEBUG(2, ("Resolved '%s' to file '%s'", filename, found));
@ -337,7 +337,7 @@ mBOOL MPlugin::resolve(void)
filename[sizeof filename - 1] = '\0';
}
return mTRUE;
return true;
}
// For the given path, tries to find file in several possible
@ -495,17 +495,17 @@ char *MPlugin::resolve_suffix(char *path)
// Check if a passed string starts with a known platform postfix.
// It does not check beyond the period in order to work for both
// Linux and Win32.
static mBOOL is_platform_postfix(char *pf)
static bool is_platform_postfix(char *pf)
{
if (NULL == pf) return mFALSE;
if (NULL == pf) return false;
if (0 == Q_strncmp(pf, "_i386.", 6)) return mTRUE;
if (0 == Q_strncmp(pf, "_i486.", 6)) return mTRUE;
if (0 == Q_strncmp(pf, "_i586.", 6)) return mTRUE;
if (0 == Q_strncmp(pf, "_i686.", 6)) return mTRUE;
if (0 == Q_strncmp(pf, "_amd64.", 7)) return mTRUE;
if (0 == Q_strncmp(pf, "_i386.", 6)) return true;
if (0 == Q_strncmp(pf, "_i486.", 6)) return true;
if (0 == Q_strncmp(pf, "_i586.", 6)) return true;
if (0 == Q_strncmp(pf, "_i686.", 6)) return true;
if (0 == Q_strncmp(pf, "_amd64.", 7)) return true;
return mFALSE;
return false;
}
@ -521,22 +521,22 @@ static mBOOL is_platform_postfix(char *pf)
// the part up to the last dot, if one exists.
// meta_errno values:
// - none
mBOOL MPlugin::platform_match(MPlugin *other)
bool MPlugin::platform_match(MPlugin *other)
{
char *end, *other_end;
int prefixlen;
if (status == PL_EMPTY || other->status == PL_EMPTY)
return mFALSE;
return false;
if (Q_strcmp(file, other->file) == 0)
return mTRUE;
return true;
if (status >= PL_OPENED && other->status >= PL_OPENED && Q_strcmp(info->logtag, other->info->logtag) == 0)
return mTRUE;
return true;
if (*desc != '\0' && Q_stricmp(desc, other->desc) == 0)
return mTRUE;
return true;
end = Q_strrchr(file, '_');
if (end == NULL || !is_platform_postfix(end)) end = Q_strrchr(file, '.');
@ -546,16 +546,16 @@ mBOOL MPlugin::platform_match(MPlugin *other)
other_end = Q_strrchr(other->file, '.');
if (end == NULL || other_end == NULL)
return mFALSE;
return false;
prefixlen = end - file;
if ((other_end - other->file) != prefixlen)
return mFALSE;
return false;
if (Q_strncmp(file, other->file, prefixlen) == 0)
return mTRUE;
return true;
return mFALSE;
return false;
}
@ -569,22 +569,22 @@ mBOOL MPlugin::platform_match(MPlugin *other)
// - errno's from query()
// - errno's from attach()
// - errno's from check_input()
mBOOL MPlugin::load(PLUG_LOADTIME now)
bool MPlugin::load(PLUG_LOADTIME now)
{
if (!check_input())
{
// details logged, meta_errno set in check_input()
RETURN_ERRNO(mFALSE, ME_ARGUMENT);
RETURN_ERRNO(false, ME_ARGUMENT);
}
if (status >= PL_RUNNING)
{
META_ERROR("dll: Not loading plugin '%s'; already loaded (status=%s)", desc, str_status());
RETURN_ERRNO(mFALSE, ME_ALREADY);
RETURN_ERRNO(false, ME_ALREADY);
}
if (action != PA_LOAD && action != PA_ATTACH)
{
META_ERROR("dll: Not loading plugin '%s'; not marked for load (action=%s)", desc, str_action());
RETURN_ERRNO(mFALSE, ME_BADREQ);
RETURN_ERRNO(false, ME_BADREQ);
}
if (status < PL_OPENED)
@ -605,7 +605,7 @@ mBOOL MPlugin::load(PLUG_LOADTIME now)
status = PL_BADFILE;
info = NULL; //prevent crash
// meta_errno should be already set in query()
return mFALSE;
return false;
}
status = PL_OPENED;
}
@ -617,19 +617,19 @@ mBOOL MPlugin::load(PLUG_LOADTIME now)
{
// will try to attach again at next opportunity
META_DEBUG(2, ("dll: Delaying load plugin '%s'; can't attach now: allowed=%s; now=%s", desc, str_loadable(), str_loadtime(now, SL_SIMPLE)));
RETURN_ERRNO(mFALSE, ME_DELAYED);
RETURN_ERRNO(false, ME_DELAYED);
}
else
{
META_DEBUG(2, ("dll: Failed load plugin '%s'; can't attach now: allowed=%s; now=%s", desc, str_loadable(), str_loadtime(now, SL_SIMPLE)));
// don't try to attach again later
action = PA_NONE;
RETURN_ERRNO(mFALSE, ME_NOTALLOWED);
RETURN_ERRNO(false, ME_NOTALLOWED);
}
}
// attach plugin; get function tables
if (attach(now) != mTRUE)
if (attach(now) != true)
{
META_ERROR("dll: Failed to attach plugin '%s'", desc);
// Note we don't dlclose() here, since we're returning PL_FAILED,
@ -639,7 +639,7 @@ mBOOL MPlugin::load(PLUG_LOADTIME now)
// (segfault) after dlclosed.
status = PL_FAILED;
// meta_errno should be already set in attach()
return mFALSE;
return false;
}
status = PL_RUNNING;
@ -661,7 +661,7 @@ mBOOL MPlugin::load(PLUG_LOADTIME now)
META_LOG("dll: Loaded plugin '%s': %s v%s %s, %s", desc, info->name,
info->version, info->date, info->author);
return mTRUE;
return true;
}
// Query a plugin:
@ -675,7 +675,7 @@ mBOOL MPlugin::load(PLUG_LOADTIME now)
// - ME_DLMISSING couldn't find a query() or giveFuncs() in plugin
// - ME_DLERROR plugin query() returned error
// - ME_NULLDATA info struct from query() was null
mBOOL MPlugin::query(void)
bool MPlugin::query(void)
{
META_INIT_FN pfn_init;
GIVE_ENGINE_FUNCTIONS_FN pfn_give_engfuncs;
@ -686,7 +686,7 @@ mBOOL MPlugin::query(void)
{
META_ERROR("dll: Failed query plugin '%s'; Couldn't open file '%s': %s",
desc, pathname, DLERROR());
RETURN_ERRNO(mFALSE, ME_DLOPEN);
RETURN_ERRNO(false, ME_DLOPEN);
}
// First, we check to see if they have a Meta_Query. We would normally
@ -704,7 +704,7 @@ mBOOL MPlugin::query(void)
{
META_ERROR("dll: Failed query plugin '%s'; Couldn't find Meta_Query(): %s", desc, DLERROR());
// caller will dlclose()
RETURN_ERRNO(mFALSE, ME_DLMISSING);
RETURN_ERRNO(false, ME_DLMISSING);
}
// Call Meta_Init, if present. This is an optional plugin routine to
@ -739,7 +739,7 @@ mBOOL MPlugin::query(void)
// META_ERROR("dll: Couldn't find GiveFnptrsToDll() in plugin '%s': %s", desc, DLERROR());
META_ERROR("dll: Failed query plugin '%s'; Couldn't find GiveFnptrsToDll(): %s", desc, DLERROR());
// caller will dlclose()
RETURN_ERRNO(mFALSE, ME_DLMISSING);
RETURN_ERRNO(false, ME_DLMISSING);
}
pfn_give_engfuncs(g_engine.pl_funcs, g_engine.globals);
META_DEBUG(6, ("dll: Plugin '%s': Called GiveFnptrsToDll()", desc));
@ -807,17 +807,17 @@ mBOOL MPlugin::query(void)
META_ERROR("dll: Rejected plugin '%s' due to interface version incompatibility (mm=%s, pl=%s)", desc, META_INTERFACE_VERSION, info->ifvers);
// meta_errno is set already above
// caller will dlclose()
return mFALSE;
return false;
}
else if (meta_errno != ME_NOERROR)
// some other error, already logged
return mFALSE;
return false;
if (!info)
{
META_ERROR("dll: Failed query plugin '%s'; Empty info structure", desc);
// caller will dlclose()
RETURN_ERRNO(mFALSE, ME_NULLRESULT);
RETURN_ERRNO(false, ME_NULLRESULT);
}
// Replace temporary desc with plugin's internal name.
@ -828,7 +828,7 @@ mBOOL MPlugin::query(void)
}
META_DEBUG(6, ("dll: Plugin '%s': Query successful", desc));
return mTRUE;
return true;
}
// Attach a plugin:
@ -850,7 +850,7 @@ mBOOL MPlugin::query(void)
// - ME_DLMISSING couldn't find meta_attach() in plugin
// - ME_DLERROR plugin attach() returned error
// - ME_NOMEM failed malloc
mBOOL MPlugin::attach(PLUG_LOADTIME now)
bool MPlugin::attach(PLUG_LOADTIME now)
{
int ret;
int iface_vers;
@ -866,7 +866,7 @@ mBOOL MPlugin::attach(PLUG_LOADTIME now)
if (!gamedll_funcs.dllapi_table)
{
META_ERROR("dll: Failed attach plugin '%s': Failed malloc() for dllapi_table");
RETURN_ERRNO(mFALSE, ME_NOMEM);
RETURN_ERRNO(false, ME_NOMEM);
}
Q_memcpy(gamedll_funcs.dllapi_table, GameDLL.funcs.dllapi_table, sizeof(DLL_FUNCTIONS));
}
@ -876,7 +876,7 @@ mBOOL MPlugin::attach(PLUG_LOADTIME now)
if (!gamedll_funcs.newapi_table)
{
META_ERROR("dll: Failed attach plugin '%s': Failed malloc() for newapi_table");
RETURN_ERRNO(mFALSE, ME_NOMEM);
RETURN_ERRNO(false, ME_NOMEM);
}
static_cast<meta_new_dll_functions_t *>(gamedll_funcs.newapi_table)->set_from(GameDLL.funcs.newapi_table);
}
@ -884,18 +884,18 @@ mBOOL MPlugin::attach(PLUG_LOADTIME now)
{
META_ERROR("dll: Failed attach plugin '%s': Couldn't find Meta_Attach(): %s", desc, DLERROR());
// caller will dlclose()
RETURN_ERRNO(mFALSE, ME_DLMISSING);
RETURN_ERRNO(false, ME_DLMISSING);
}
Q_memset(&meta_table, 0, sizeof(meta_table));
// get table of function tables,
// give public meta globals
ret = pfn_attach(now, &meta_table, &PublicMetaGlobals, &gamedll_funcs);
ret = pfn_attach(now, &meta_table, &g_metaGlobals, &gamedll_funcs);
if (ret != TRUE)
{
META_ERROR("dll: Failed attach plugin '%s': Error from Meta_Attach(): %d", desc, ret);
// caller will dlclose()
RETURN_ERRNO(mFALSE, ME_DLERROR);
RETURN_ERRNO(false, ME_DLERROR);
}
META_DEBUG(6, ("dll: Plugin '%s': Called Meta_Attach() successfully", desc));
@ -953,7 +953,27 @@ mBOOL MPlugin::attach(PLUG_LOADTIME now)
// Look for g_engine interface.
iface_vers = ENGINE_INTERFACE_VERSION;
GET_FUNC_TABLE_FROM_PLUGIN(pfnGetEngineFunctions, "GetEngineFunctions", engine_table, GET_ENGINE_FUNCTIONS_FN, meta_enginefuncs_t, &iface_vers, iface_vers, ENGINE_INTERFACE_VERSION);
if (meta_table.pfnGetEngineFunctions) {
if (!engine_table) engine_table = (meta_enginefuncs_t *)calloc(1, sizeof(meta_enginefuncs_t));
if (meta_table.pfnGetEngineFunctions(engine_table, &iface_vers)) {
do {
if (meta_debug.value < 3) break; else (*g_engfuncs.pfnAlertMessage)(at_logged, "[META] (debug:%d) %s\n", 3, UTIL_VarArgs("dll: Plugin '%s': Found %s", desc, "GetEngineFunctions"));
}
while (0);
}
else {
META_ERROR("dll: Failure calling %s in plugin '%s'", "GetEngineFunctions", desc);
if (iface_vers != 138) META_ERROR("dll: Interface version didn't match; expected %d, found %d", 138, iface_vers);
}
}
else {
do {
if (meta_debug.value < 5) break; else (*g_engfuncs.pfnAlertMessage)(at_logged, "[META] (debug:%d) %s\n", 5, UTIL_VarArgs("dll: Plugin '%s': No %s", desc, "GetEngineFunctions"));
}
while (0);
if (engine_table) free(engine_table);
engine_table = 0;
};
iface_vers = ENGINE_INTERFACE_VERSION;
GET_FUNC_TABLE_FROM_PLUGIN(pfnGetEngineFunctions_Post, "GetEngineFunctions_Post", engine_post_table, GET_ENGINE_FUNCTIONS_FN, meta_enginefuncs_t, &iface_vers, iface_vers, ENGINE_INTERFACE_VERSION);
@ -963,7 +983,7 @@ mBOOL MPlugin::attach(PLUG_LOADTIME now)
}
time_loaded = time(NULL);
return mTRUE;
return true;
}
// Unload a plugin. Check time, detach.
@ -974,25 +994,25 @@ mBOOL MPlugin::attach(PLUG_LOADTIME now)
// - ME_DELAYED unload request is delayed (till changelevel?)
// - ME_NOTALLOWED plugin not unloadable after startup
// - errno's from check_input()
mBOOL MPlugin::unload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason, PL_UNLOAD_REASON real_reason)
bool MPlugin::unload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason, PL_UNLOAD_REASON real_reason)
{
if (!check_input())
{
// details logged, meta_errno set in check_input()
RETURN_ERRNO(mFALSE, ME_ARGUMENT);
RETURN_ERRNO(false, ME_ARGUMENT);
}
if (status < PL_RUNNING)
{
if (reason != PNL_CMD_FORCED && reason != PNL_RELOAD)
{
META_ERROR("dll: Not unloading plugin '%s'; already unloaded (status=%s)", desc, str_status());
RETURN_ERRNO(mFALSE, ME_ALREADY);
RETURN_ERRNO(false, ME_ALREADY);
}
}
if (action != PA_UNLOAD && action != PA_RELOAD)
{
META_WARNING("dll: Not unloading plugin '%s'; not marked for unload (action=%s)", desc, str_action());
RETURN_ERRNO(mFALSE, ME_BADREQ);
RETURN_ERRNO(false, ME_BADREQ);
}
// Are we allowed to detach this plugin at this time?
@ -1010,14 +1030,14 @@ mBOOL MPlugin::unload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason, PL_UNLOAD_REAS
META_DEBUG(2, ("dll: Delaying unload plugin '%s'; can't detach now: allowed=%s; now=%s", desc, str_unloadable(), str_loadtime(now, SL_SIMPLE)));
// caller should give message to user
// try to unload again at next opportunity
RETURN_ERRNO(mFALSE, ME_DELAYED);
RETURN_ERRNO(false, ME_DELAYED);
}
else
{
META_DEBUG(2, ("dll: Failed unload plugin '%s'; can't detach now: allowed=%s; now=%s", desc, str_unloadable(), str_loadtime(now, SL_SIMPLE)));
// don't try to unload again later
action = PA_NONE;
RETURN_ERRNO(mFALSE, ME_NOTALLOWED);
RETURN_ERRNO(false, ME_NOTALLOWED);
}
}
}
@ -1042,7 +1062,7 @@ mBOOL MPlugin::unload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason, PL_UNLOAD_REAS
{
META_WARNING("dll: Failed to detach plugin '%s'; ", desc);
// meta_errno should be already set in detach()
return mFALSE;
return false;
}
}
@ -1083,14 +1103,14 @@ mBOOL MPlugin::unload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason, PL_UNLOAD_REAS
}
META_LOG("dll: Unloaded plugin '%s' for reason '%s'", desc, str_reason(reason, real_reason));
return mTRUE;
return true;
}
// Inform plugin we're going to unload it.
// meta_errno values:
// - ME_DLMISSING couldn't find meta_detach() in plugin
// - ME_DLERROR plugin detach() returned error
mBOOL MPlugin::detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
bool MPlugin::detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
{
int ret;
META_DETACH_FN pfn_detach;
@ -1099,24 +1119,24 @@ mBOOL MPlugin::detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
// dll is obviously detached. We shouldn't call DLSYM() with a NULL
// handle since this will DLSYM() ourself.
if (!handle)
return mTRUE;
return true;
if (!(pfn_detach = (META_DETACH_FN) DLSYM(handle, "Meta_Detach")))
{
META_ERROR("dll: Error detach plugin '%s': Couldn't find Meta_Detach(): %s", desc, DLERROR());
// caller will dlclose()
RETURN_ERRNO(mFALSE, ME_DLMISSING);
RETURN_ERRNO(false, ME_DLMISSING);
}
ret = pfn_detach(now, reason);
if (ret != TRUE)
{
META_ERROR("dll: Failed detach plugin '%s': Error from Meta_Detach(): %d", desc, ret);
RETURN_ERRNO(mFALSE, ME_DLERROR);
RETURN_ERRNO(false, ME_DLERROR);
}
META_DEBUG(6, ("dll: Plugin '%s': Called Meta_Detach() successfully", desc));
return mTRUE;
return true;
}
// Reload a plugin; unload and load again.
@ -1125,12 +1145,12 @@ mBOOL MPlugin::detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
// - errno's from check_input()
// - errno's from unload()
// - errno's from load()
mBOOL MPlugin::reload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
bool MPlugin::reload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
{
if (!check_input())
{
// details logged, meta_errno set in check_input()
RETURN_ERRNO(mFALSE, ME_ARGUMENT);
RETURN_ERRNO(false, ME_ARGUMENT);
}
// Are we allowed to load this plugin at this time?
// If we cannot load the plugin after unloading it, we keep it.
@ -1141,14 +1161,14 @@ mBOOL MPlugin::reload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
META_DEBUG(2, ("dll: Delaying reload plugin '%s'; would not be able to reattach now: allowed=%s; now=%s", desc, str_loadable(), str_loadtime(now, SL_SIMPLE)));
// caller should give message to user
// try to reload again at next opportunity
RETURN_ERRNO(mFALSE, ME_DELAYED);
RETURN_ERRNO(false, ME_DELAYED);
}
else
{
META_DEBUG(2, ("dll: Failed reload plugin '%s'; would not be able to reattach now: allowed=%s; now=%s", desc, str_loadable(), str_loadtime(now, SL_SIMPLE)));
// don't try to reload again later
action = PA_NONE;
RETURN_ERRNO(mFALSE, ME_NOTALLOWED);
RETURN_ERRNO(false, ME_NOTALLOWED);
}
}
@ -1162,17 +1182,17 @@ mBOOL MPlugin::reload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
{
META_WARNING("dll: Failed to unload plugin '%s' for reloading", desc);
// meta_errno should be set already in unload()
return mFALSE;
return false;
}
if (!load(now))
{
META_WARNING("dll: Failed to reload plugin '%s' after unloading", desc);
// meta_errno should be set already in load()
return mFALSE;
return false;
}
return mTRUE;
return true;
}
// Pause a plugin; temporarily disabled for API routines.
@ -1180,17 +1200,17 @@ mBOOL MPlugin::reload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
// - ME_ALREADY this plugin already paused
// - ME_BADREQ can't pause; not running
// - ME_NOTALLOWED plugin doesn't want to be paused
mBOOL MPlugin::pause()
bool MPlugin::pause()
{
if (status == PL_PAUSED)
{
META_ERROR("Not pausing plugin '%s'; already paused", desc);
RETURN_ERRNO(mFALSE, ME_ALREADY);
RETURN_ERRNO(false, ME_ALREADY);
}
if (status != PL_RUNNING)
{
META_ERROR("Cannot pause plugin '%s'; not currently running (status=%s)", desc, str_status());
RETURN_ERRNO(mFALSE, ME_BADREQ);
RETURN_ERRNO(false, ME_BADREQ);
}
// are we allowed to pause this plugin?
@ -1198,28 +1218,28 @@ mBOOL MPlugin::pause()
{
META_ERROR("Cannot pause plugin '%s'; not allowed by plugin (allowed=%s)", desc, str_unloadable());
action = PA_NONE;
RETURN_ERRNO(mFALSE, ME_NOTALLOWED);
RETURN_ERRNO(false, ME_NOTALLOWED);
}
status = PL_PAUSED;
META_LOG("Paused plugin '%s'", desc);
return mTRUE;
return true;
}
// Unpause a plugin.
// meta_errno values:
// - ME_BADREQ can't unpause; not paused
mBOOL MPlugin::unpause()
bool MPlugin::unpause()
{
if (status != PL_PAUSED)
{
META_ERROR("Cannot unpause plugin '%s'; not currently paused (status=%s)", desc, str_status());
RETURN_ERRNO(mFALSE, ME_BADREQ);
RETURN_ERRNO(false, ME_BADREQ);
}
status = PL_RUNNING;
META_LOG("Unpaused plugin '%s'", desc);
return mTRUE;
return true;
}
// Retry pending action, presumably from a previous failure.
@ -1228,7 +1248,7 @@ mBOOL MPlugin::unpause()
// - errno's from load()
// - errno's from unload()
// - errno's from reload()
mBOOL MPlugin::retry(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
bool MPlugin::retry(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
{
if (action == PA_LOAD)
return load(now);
@ -1241,7 +1261,7 @@ mBOOL MPlugin::retry(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
else
{
META_ERROR("No pending action to retry for plugin '%s'; (status=%s, action=%s)", desc, str_status(), str_action());
RETURN_ERRNO(mFALSE, ME_BADREQ);
RETURN_ERRNO(false, ME_BADREQ);
}
}
@ -1250,12 +1270,12 @@ mBOOL MPlugin::retry(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
// meta_errno values:
// - ME_BADREQ not marked for clearing
// - ME_DLERROR failed to dlclose
mBOOL MPlugin::clear(void)
bool MPlugin::clear(void)
{
if (status != PL_FAILED && status != PL_BADFILE && status != PL_EMPTY && status != PL_OPENED)
{
META_ERROR("Cannot clear plugin '%s'; not marked as failed, empty, or open (status=%s)", desc, str_status());
RETURN_ERRNO(mFALSE, ME_BADREQ);
RETURN_ERRNO(false, ME_BADREQ);
}
// If file is open, close the file. Note: after this, attempts to
// reference any memory locations in the file will produce a segfault.
@ -1263,7 +1283,7 @@ mBOOL MPlugin::clear(void)
{
META_ERROR("dll: Couldn't close plugin file '%s': %s", file, DLERROR());
status = PL_FAILED;
RETURN_ERRNO(mFALSE, ME_DLERROR);
RETURN_ERRNO(false, ME_DLERROR);
}
handle = NULL;
@ -1291,9 +1311,9 @@ mBOOL MPlugin::clear(void)
gamedll_funcs.newapi_table = NULL;
source_plugin_index = 0;
unloader_index = 0;
is_unloader = mFALSE;
is_unloader = false;
return mTRUE;
return true;
}
// List information about plugin to console.
@ -1397,20 +1417,20 @@ void MPlugin::show()
// meta_errno values:
// - ME_NOFILE couldn't find file
// - ME_NOERROR no error; false indicates file not newer
mBOOL MPlugin::newer_file()
bool MPlugin::newer_file()
{
struct stat st;
time_t file_time;
if (stat(pathname, &st) != 0)
RETURN_ERRNO(mFALSE, ME_NOFILE);
RETURN_ERRNO(false, ME_NOFILE);
file_time = st.st_ctime > st.st_mtime ? st.st_ctime : st.st_mtime;
META_DEBUG(5, ("newer_file? file=%s; load=%d, file=%d; ctime=%d, mtime=%d", file, time_loaded, file_time, st.st_ctime, st.st_mtime));
if (file_time > time_loaded)
return mTRUE;
return true;
else
RETURN_ERRNO(mFALSE, ME_NOERROR);
RETURN_ERRNO(false, ME_NOERROR);
}
// Return a string describing status of plugin.

View File

@ -69,9 +69,9 @@ enum STR_SOURCE
// An individual plugin.
class MPlugin {
private:
mBOOL query();
mBOOL attach(PLUG_LOADTIME now);
mBOOL detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
bool query();
bool attach(PLUG_LOADTIME now);
bool detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
gamedll_funcs_t gamedll_funcs;
mutil_funcs_t mutil_funcs;
@ -91,7 +91,7 @@ public:
time_t time_loaded; // when plugin was loaded
int source_plugin_index; // who loaded this plugin
int unloader_index;
mBOOL is_unloader; // fix to prevent other plugins unload active unloader.
bool is_unloader; // fix to prevent other plugins unload active unloader.
DLL_FUNCTIONS *dllapi_table;
DLL_FUNCTIONS *dllapi_post_table;
@ -100,29 +100,29 @@ public:
enginefuncs_t *engine_table;
enginefuncs_t *engine_post_table;
mBOOL ini_parseline(char *line); // parse line from inifile
mBOOL cmd_parseline(const char *line); // parse from console command
mBOOL plugin_parseline(const char *fname, int loader_index); // parse from plugin
mBOOL check_input();
bool ini_parseline(char *line); // parse line from inifile
bool cmd_parseline(const char *line); // parse from console command
bool plugin_parseline(const char *fname, int loader_index); // parse from plugin
bool check_input();
mBOOL resolve(); // find a matching file on disk
bool resolve(); // find a matching file on disk
char *resolve_dirs(char *path);
char *resolve_prefix(char *path);
char *resolve_suffix(char *path);
mBOOL platform_match(MPlugin* plugin);
bool platform_match(MPlugin* plugin);
mBOOL load(PLUG_LOADTIME now);
mBOOL unload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason, PL_UNLOAD_REASON real_reason);
mBOOL reload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
mBOOL pause();
mBOOL unpause();
mBOOL retry(PLUG_LOADTIME now, PL_UNLOAD_REASON reason); // if previously failed
mBOOL clear();
mBOOL plugin_unload(plid_t plid, PLUG_LOADTIME now, PL_UNLOAD_REASON reason); // other plugin unloading
bool load(PLUG_LOADTIME now);
bool unload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason, PL_UNLOAD_REASON real_reason);
bool reload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
bool pause();
bool unpause();
bool retry(PLUG_LOADTIME now, PL_UNLOAD_REASON reason); // if previously failed
bool clear();
bool plugin_unload(plid_t plid, PLUG_LOADTIME now, PL_UNLOAD_REASON reason); // other plugin unloading
void show(); // print info about plugin to console
mBOOL newer_file(); // check for newer file on disk
bool newer_file(); // check for newer file on disk
const char *str_status(STR_STATUS fmt);
const char *str_action(STR_ACTION fmt);

View File

@ -17,16 +17,16 @@ void MRegCmd::init(int idx)
// meta_errno values:
// - ME_BADREQ function disabled/invalid
// - ME_ARGUMENT function pointer is null
mBOOL MRegCmd::call()
bool MRegCmd::call()
{
mBOOL ret;
bool ret;
// can we expect to call this function?
if (status != RG_VALID)
RETURN_ERRNO(mFALSE, ME_BADREQ);
RETURN_ERRNO(false, ME_BADREQ);
if (!pfnCmd)
RETURN_ERRNO(mFALSE, ME_ARGUMENT);
RETURN_ERRNO(false, ME_ARGUMENT);
// try to call this function
ret = os_safe_call(pfnCmd);
@ -43,14 +43,12 @@ mBOOL MRegCmd::call()
return ret;
}
MRegCmdList::MRegCmdList()
: mlist(0), size(REG_CMD_GROWSIZE), endlist(0)
MRegCmdList::MRegCmdList() : mlist(0), size(REG_CMD_GROWSIZE), endlist(0)
{
int i;
mlist = (MRegCmd *)Q_malloc(size * sizeof(MRegCmd));
// initialize array
for (i = 0; i < size; i++)
for (int i = 0; i < size; i++)
mlist[i].init(i + 1); // 1-based index
endlist = 0;
@ -59,7 +57,7 @@ MRegCmdList::MRegCmdList()
// Try to find a registered function with the given name.
// meta_errno values:
// - ME_NOTFOUND couldn't find a matching function
MRegCmd *MRegCmdList::find(const char *findname)
MRegCmd *MRegCmdList::find(const char *findname) const
{
for (int i = 0; i < endlist; i++)
{
@ -116,7 +114,7 @@ MRegCmd *MRegCmdList::add(const char *addname)
}
// Disable any functions belonging to the given plugin (by index id).
void MRegCmdList::disable(int plugin_id)
void MRegCmdList::disable(int plugin_id) const
{
for (int i = 0; i < size; i++)
{
@ -126,7 +124,7 @@ void MRegCmdList::disable(int plugin_id)
}
// List all the registered commands.
void MRegCmdList::show()
void MRegCmdList::show() const
{
int n = 0, a = 0;
MRegCmd *icmd;
@ -169,7 +167,7 @@ void MRegCmdList::show()
}
// List all the registered commands for the given plugin id.
void MRegCmdList::show(int plugin_id)
void MRegCmdList::show(int plugin_id) const
{
int n = 0;
MRegCmd *icmd;
@ -210,12 +208,12 @@ void MRegCvar::init(int idx)
// Set the cvar, copying values from given cvar.
// meta_errno values:
// - ME_ARGUMENT given cvar doesn't match this cvar
mBOOL MRegCvar::set(cvar_t *src)
bool MRegCvar::set(cvar_t *src) const
{
if (Q_stricmp(src->name, data->name))
{
META_ERROR("Tried to set cvar with mismatched name; src=%s dst=%s", src->name, data->name);
RETURN_ERRNO(mFALSE, ME_ARGUMENT);
RETURN_ERRNO(false, ME_ARGUMENT);
}
// Would like to free() existing string, but can't tell where it was
@ -224,7 +222,7 @@ mBOOL MRegCvar::set(cvar_t *src)
data->flags = src->flags;
data->value = src->value;
data->next = src->next;
return mTRUE;
return true;
}
// Constructor
@ -306,7 +304,7 @@ MRegCvar *MRegCvarList::find(const char *findname)
}
// Disable any cvars belonging to the given plugin (by index id).
void MRegCvarList::disable(int plugin_id)
void MRegCvarList::disable(int plugin_id) const
{
int i;
MRegCvar *icvar;
@ -325,7 +323,7 @@ void MRegCvarList::disable(int plugin_id)
}
// List all the registered cvars.
void MRegCvarList::show()
void MRegCvarList::show() const
{
int i, n = 0, a = 0;
MRegCvar *icvar;
@ -371,7 +369,7 @@ void MRegCvarList::show()
}
// List the registered cvars for the given plugin id.
void MRegCvarList::show(int plugin_id)
void MRegCvarList::show(int plugin_id) const
{
int n = 0;
MRegCvar *icvar;

View File

@ -1,5 +1,5 @@
#pragma once
#include "types_meta.h" // mBOOL
#include "types_meta.h" // bool
// Number of entries to add to reglists when they need to grow. Typically
// more cvars than commands, so we grow them at different increments.
@ -35,7 +35,7 @@ public:
REG_STATUS status; // whether corresponding plugin is loaded
void init(int idx); // init values, as not using constructors
mBOOL call(); // try to call the function
bool call(); // try to call the function
private:
int index; // 1-based
@ -46,11 +46,11 @@ class MRegCmdList {
public:
MRegCmdList();
MRegCmd *find(const char *findname); // find by MRegCmd->name
MRegCmd *find(const char *findname) const; // find by MRegCmd->name
MRegCmd *add(const char *addname);
void disable(int plugin_id); // change status to Invalid
void show(); // list all funcs to console
void show(int plugin_id); // list given plugin's funcs to console
void disable(int plugin_id) const; // change status to Invalid
void show() const; // list all funcs to console
void show(int plugin_id) const; // list given plugin's funcs to console
private:
MRegCmd *mlist; // malloc'd array of registered commands
@ -73,7 +73,7 @@ public:
REG_STATUS status; // whether corresponding plugin is loaded
void init(int idx); // init values, as not using constructors
mBOOL set(cvar_t *src);
bool set(cvar_t *src) const;
private:
int index; // 1-based
@ -87,9 +87,9 @@ public:
MRegCvar *add(const char *addname);
MRegCvar *find(const char *findname); // find by MRegCvar->data.name
void disable(int plugin_id); // change status to Invalid
void show(); // list all cvars to console
void show(int plugin_id); // list given plugin's cvars to console
void disable(int plugin_id) const; // change status to Invalid
void show() const; // list all cvars to console
void show(int plugin_id) const; // list given plugin's cvars to console
private:
MRegCvar *vlist; // malloc'd array of registered cvars

View File

@ -323,7 +323,7 @@ int mutil_UnloadMetaPluginByHandle(plid_t plid, void *plugin_handle, PLUG_LOADTI
const char* mutil_IsQueryingClientCvar(plid_t plid, const edict_t* pEdict)
{
return g_Players.is_querying_cvar(pEdict);
return g_players.is_querying_cvar(pEdict);
}
int mutil_MakeRequestId(plid_t plid)

View File

@ -1,18 +1,6 @@
#include "precompiled.h"
mBOOL dlclose_handle_invalid;
// To keep the rest of the sources clean and keep not only OS but also
// compiler dependant differences in this file, we define a local function
// to set the new handler.
void mm_set_new_handler()
{
#if defined(_MSC_VER) && (_MSC_VER < 1300)
_set_new_handler(meta_new_handler);
#else
std::set_new_handler(meta_new_handler);
#endif
}
bool dlclose_handle_invalid;
#ifdef _WIN32
// Since windows doesn't provide a verison of strtok_r(), we include one
@ -112,8 +100,7 @@ const char *DLFNAME(void *memptr)
// MSDN indicates that GetModuleFileName will leave string
// null-terminated, even if it's truncated because buffer is too small.
if (!GetModuleFileName((HMODULE)MBI.AllocationBase, fname,
sizeof(fname)-1))
if (!GetModuleFileName((HMODULE)MBI.AllocationBase, fname, sizeof(fname) - 1))
RETURN_ERRNO(NULL, ME_NOTFOUND);
if (!fname[0])
RETURN_ERRNO(NULL, ME_NOTFOUND);
@ -133,25 +120,25 @@ const char *DLFNAME(void *memptr)
// we need it for in this particular situation.
// meta_errno values:
// - ME_NOTFOUND couldn't find a matching sharedlib for this ptr
mBOOL IS_VALID_PTR(void *memptr)
bool IS_VALID_PTR(void *memptr)
{
Dl_info dli;
Q_memset(&dli, 0, sizeof(dli));
if (dladdr(memptr, &dli))
return mTRUE;
return true;
else
RETURN_ERRNO(mFALSE, ME_NOTFOUND);
RETURN_ERRNO(false, ME_NOTFOUND);
}
#elif defined(_WIN32)
// Use the native windows routine IsBadCodePtr.
// meta_errno values:
// - ME_BADMEMPTR not a valid memory pointer
mBOOL IS_VALID_PTR(void *memptr)
bool IS_VALID_PTR(void *memptr)
{
if (IsBadCodePtr((FARPROC) memptr))
RETURN_ERRNO(mFALSE, ME_BADMEMPTR);
RETURN_ERRNO(false, ME_BADMEMPTR);
else
return mTRUE;
return true;
}
#endif // _WIN32
@ -160,33 +147,13 @@ mBOOL IS_VALID_PTR(void *memptr)
// in plugin commands and produced confusing output ("plugin has been
// unloaded", when really it segfaultd), and (b) wasn't necessary since
// IS_VALID_PTR() should cover the situation.
mBOOL os_safe_call(REG_CMD_FN pfn)
bool os_safe_call(REG_CMD_FN pfn)
{
// try and see if this is a valid memory location
if (!IS_VALID_PTR((void *)pfn))
// meta_errno should be already set in is_valid_ptr()
return mFALSE;
return false;
pfn();
return mTRUE;
return true;
}
// See comments in osdep.h.
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
void __cdecl meta_new_handler()
{
return;
}
#elif defined(_MSC_VER)
int meta_new_handler(size_t size)
{
// This merely because we don't want the program to exit if new()
// fails..
return 0;
}
#else
void meta_new_handler()
{
return;
}
#endif

View File

@ -1,7 +1,7 @@
#pragma once
// Various differences between WIN32 and Linux.
#include "types_meta.h" // mBOOL
#include "types_meta.h" // bool
#include "mreg.h" // REG_CMD_FN, etc
#include "log_meta.h" // LOG_ERROR, etc
@ -20,7 +20,7 @@
#define PLATFORM_DLEXT ".so"
#endif
extern mBOOL dlclose_handle_invalid;
extern bool dlclose_handle_invalid;
// Functions & types for DLL open/close/etc operations.
#ifdef _WIN32
@ -38,11 +38,11 @@ extern mBOOL dlclose_handle_invalid;
{
if (!handle)
{
dlclose_handle_invalid = mTRUE;
dlclose_handle_invalid = true;
return 1;
}
dlclose_handle_invalid = mFALSE;
dlclose_handle_invalid = false;
// NOTE: Windows FreeLibrary returns success=nonzero, fail=zero,
// which is the opposite of the unix convention, thus the '!'.
return !FreeLibrary(handle);
@ -73,10 +73,10 @@ extern mBOOL dlclose_handle_invalid;
{
if (!handle)
{
dlclose_handle_invalid = mTRUE;
dlclose_handle_invalid = true;
return 1;
}
dlclose_handle_invalid = mFALSE;
dlclose_handle_invalid = false;
return dlclose(handle);
}
inline const char *DLERROR()
@ -89,10 +89,10 @@ extern mBOOL dlclose_handle_invalid;
#endif
const char *DLFNAME(void *memptr);
mBOOL IS_VALID_PTR(void *memptr);
bool IS_VALID_PTR(void *memptr);
// Attempt to call the given function pointer, without segfaulting.
mBOOL os_safe_call(REG_CMD_FN pfn);
bool os_safe_call(REG_CMD_FN pfn);
// Windows doesn't have an strtok_r() routine, so we write our own.
#ifdef _WIN32
@ -167,217 +167,6 @@ mBOOL os_safe_call(REG_CMD_FN pfn);
#endif
#endif // _WIN32
// Our handler for new().
//
// Thanks to notes from:
// http://dragon.klte.hu/~kollarl/C++/node45.html
//
// At one point it appeared MSVC++ was no longer different from gcc, according
// to:
// http://msdn.microsoft.com/library/en-us/vclang98/stdlib/info/NEW.asp
//
// However, this page is apparently no longer available from MSDN. The
// only thing now is:
// http://msdn.microsoft.com/library/en-us/vccore98/HTML/_crt_malloc.asp
//
// According to Fritz Elfert <felfert@to.com>:
// set_new_handler() is just a stub which (according to comments in the
// MSVCRT debugging sources) should never be used. It is just an ugly
// hack to make STL compile. It does _not_ set the new handler but
// always calls _set_new_handler(0) instead. _set_new_handler is the
// "real" function and uses the "old" semantic; handler-type is:
// int newhandler(size_t)
//
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
void __cdecl meta_new_handler();
#elif defined(_MSC_VER)
int meta_new_handler(size_t size);
#else
void meta_new_handler();
#endif
// To keep the rest of the sources clean and keep not only OS but also
// compiler dependant differences in this file, we define a local function
// to set the new handler.
void mm_set_new_handler( void );
// Thread handling...
#if defined(__linux) || defined(__APPLE__)
#include <pthread.h>
typedef pthread_t THREAD_T;
// returns 0==success, non-zero==failure
inline int THREAD_CREATE(THREAD_T *tid, void (*func)())
{
int ret;
ret = pthread_create(tid, NULL, (void *(*)(void*)) func, NULL);
if (ret != 0)
{
META_ERROR("Failure starting thread: %s", strerror(ret));
return ret;
}
ret = pthread_detach(*tid);
if (ret != 0)
META_ERROR("Failure detaching thread: %s", strerror(ret));
return ret;
}
#elif defined(_WIN32)
// See:
// http://msdn.microsoft.com/library/en-us/dllproc/prothred_4084.asp
typedef DWORD THREAD_T;
// returns 0==success, non-zero==failure
inline int THREAD_CREATE(THREAD_T *tid, void (*func)())
{
HANDLE ret;
// win32 returns NULL==failure, non-NULL==success
ret = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) func, NULL, 0, tid);
if (ret == NULL)
META_ERROR("Failure starting thread: %s", str_GetLastError());
return ret == NULL;
}
#endif // _WIN32
#define THREAD_OK 0
// Mutex handling...
#if defined(__linux) || defined(__APPLE__)
typedef pthread_mutex_t MUTEX_T;
inline int MUTEX_INIT(MUTEX_T *mutex)
{
int ret;
ret = pthread_mutex_init(mutex, NULL);
if (ret != THREAD_OK)
META_ERROR("mutex_init failed: %s", strerror(ret));
return ret;
}
inline int MUTEX_LOCK(MUTEX_T *mutex)
{
int ret;
ret = pthread_mutex_lock(mutex);
if (ret != THREAD_OK)
META_ERROR("mutex_lock failed: %s", strerror(ret));
return ret;
}
inline int MUTEX_UNLOCK(MUTEX_T *mutex)
{
int ret;
ret = pthread_mutex_unlock(mutex);
if (ret != THREAD_OK)
META_ERROR("mutex_unlock failed: %s", strerror(ret));
return ret;
}
#elif defined(_WIN32)
// Win32 has "mutexes" as well, but CS's are simpler.
// See:
// http://msdn.microsoft.com/library/en-us/dllproc/synchro_2a2b.asp
typedef CRITICAL_SECTION MUTEX_T;
// Note win32 routines don't return any error (return void).
inline int MUTEX_INIT(MUTEX_T *mutex)
{
InitializeCriticalSection(mutex);
return THREAD_OK;
}
inline int MUTEX_LOCK(MUTEX_T *mutex)
{
EnterCriticalSection(mutex);
return THREAD_OK;
}
inline int MUTEX_UNLOCK(MUTEX_T *mutex)
{
LeaveCriticalSection(mutex);
return THREAD_OK;
}
#endif // _WIN32
// Condition variables...
#if defined(__linux) || defined(__APPLE__)
typedef pthread_cond_t COND_T;
inline int COND_INIT(COND_T *cond)
{
int ret;
ret = pthread_cond_init(cond, NULL);
if (ret != THREAD_OK)
META_ERROR("cond_init failed: %s", strerror(ret));
return ret;
}
inline int COND_WAIT(COND_T *cond, MUTEX_T *mutex)
{
int ret;
ret = pthread_cond_wait(cond, mutex);
if (ret != THREAD_OK)
META_ERROR("cond_wait failed: %s", strerror(ret));
return ret;
}
inline int COND_SIGNAL(COND_T *cond)
{
int ret;
ret = pthread_cond_signal(cond);
if (ret != THREAD_OK)
META_ERROR("cond_signal failed: %s", strerror(ret));
return ret;
}
#elif defined(_WIN32)
// Since win32 doesn't provide condition-variables, we have to model
// them with mutex/critical-sections and win32 events. This uses the
// second (SetEvent) solution from:
//
// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
//
// but without the waiters_count overhead, since we don't need
// broadcast functionality anyway. Or actually, I guess it's more like
// the first (PulseEvent) solution, but with SetEven rather than
// PulseEvent. :)
//
// See also:
// http://msdn.microsoft.com/library/en-us/dllproc/synchro_8ann.asp
typedef HANDLE COND_T;
inline int COND_INIT(COND_T *cond)
{
*cond = CreateEvent(NULL, // security attributes (none)
FALSE, // manual-reset type (false==auto-reset)
FALSE, // initial state (unsignaled)
NULL); // object name (unnamed)
// returns NULL on error
if (*cond == NULL)
{
META_ERROR("cond_init failed: %s", str_GetLastError());
return -1;
}
else
return 0;
}
inline int COND_WAIT(COND_T *cond, MUTEX_T *mutex)
{
DWORD ret;
LeaveCriticalSection(mutex);
ret = WaitForSingleObject(*cond, INFINITE);
EnterCriticalSection(mutex);
// returns WAIT_OBJECT_0 if object was signaled; other return
// values indicate errors.
if (ret == WAIT_OBJECT_0)
return 0;
else
{
META_ERROR("cond_wait failed: %s", str_GetLastError());
return -1;
}
}
inline int COND_SIGNAL(COND_T *cond)
{
BOOL ret;
ret = SetEvent(*cond);
// returns zero on failure
if (ret == 0)
{
META_ERROR("cond_signal failed: %s", str_GetLastError());
return -1;
}
else
return 0;
}
#endif // _WIN32
// Normalize/standardize a pathname.
// - For win32, this involves:
// - Turning backslashes (\) into slashes (/), so that config files and

View File

@ -10,16 +10,15 @@
#include <signal.h> // sigaction, etc
#endif
#if defined(_MSC_VER) && (_MSC_VER < 1300)
#include <new.h> // set_new_handler()
#else
#include <new> // set_new_handler()
#endif
#include "jitasm.h"
#include <extdll.h>
#include <studio.h>
#include <studioapi.h>
#include <vector>
#include <array>
#include "osdep.h"
#include "api_info.h"
#include "commands_meta.h"
@ -45,3 +44,4 @@
#include "sdk_util.h"
#include "enginecallbacks.h"
#include "utils.h"
#include "callback_jit.h"

View File

@ -62,7 +62,7 @@ void meta_command_handler()
return;
}
if (icmd->call() != mTRUE)
if (icmd->call() != true)
{
META_CONS("[metamod: command '%s' unavailable; plugin unloaded]", cmd);
}
@ -201,6 +201,6 @@ int meta_RegUserMsg(const char *pszName, int iSize)
// Intercept and record queries
void meta_QueryClientCvarValue(const edict_t *player, const char *cvarName)
{
g_Players.set_player_cvar_query(player, cvarName);
g_players.set_player_cvar_query(player, cvarName);
(*g_engfuncs.pfnQueryClientCvarValue)(player, cvarName);
}

View File

@ -1,10 +1,7 @@
#pragma once
// Our own boolean type, for stricter type matching.
enum mBOOL { mFALSE = 0, mTRUE, };
// Like C's errno, for our various functions; describes causes of failure
// or mFALSE returns.
// or false returns.
enum META_ERRNO
{
ME_NOERROR = 0,

View File

@ -19,3 +19,42 @@ const char* LOCALINFO(char* key)
{
return ENTITY_KEYVALUE(NULL, key);
}
char* execmem_allocator::allocate(const size_t n)
{
if (!m_pages.size() || m_used + n > Pagesize)
allocate_page();
auto ptr = reinterpret_cast<char *>(m_pages.back()) + m_used;
m_used += n;
return ptr;
}
void execmem_allocator::deallocate_all()
{
for (auto page : m_pages)
#ifdef WIN32
VirtualFree(page, 0, MEM_RELEASE);
#else
munmap(page, Pagesize);
#endif
m_pages.clear();
}
size_t execmem_allocator::memoryUsed() const
{
return (m_pages.size() - 1) * Pagesize + m_used;
}
void execmem_allocator::allocate_page()
{
#ifdef WIN32
auto page = VirtualAlloc(NULL, Pagesize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else
auto page = mmap(NULL, Pagesize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
#endif
m_used = 0;
m_pages.push_back(page);
}

View File

@ -1,5 +1,24 @@
#pragma once
class execmem_allocator
{
public:
char* allocate(const size_t n);
void deallocate_all();
size_t memoryUsed() const;
private:
void allocate_page();
enum
{
Pagesize = 4096
};
size_t m_used = 0;
std::vector<void *> m_pages;
};
bool is_yes(const char* str);
bool is_no(const char* str);