完全搞定除了皮肤

This commit is contained in:
Huoji's
2023-10-06 05:08:40 +08:00
parent 40fc60e481
commit 9232d1c390
30 changed files with 3076 additions and 852 deletions

View File

@@ -216,14 +216,18 @@
<ClInclude Include="sdk\public\bitvec.h" />
<ClInclude Include="sdk\public\eiface.h" />
<ClInclude Include="sdk\public\IAppSystem.h" />
<ClInclude Include="sdk\public\irecipientfilter.h" />
<ClInclude Include="sdk\public\iserver.h" />
<ClInclude Include="sdk\public\mathlib.h" />
<ClInclude Include="sdk\public\recipientfilters.h" />
<ClInclude Include="sdk\public\string_t.h" />
<ClInclude Include="sdk\public\utlmap.h" />
<ClInclude Include="sdk\public\utlrbtree.h" />
<ClInclude Include="sdk\sdk.h" />
<ClInclude Include="sdk\tier1\bufferstring.h" />
<ClInclude Include="sdk\tier1\cbyteswap.h" />
<ClInclude Include="sdk\tier1\utlblockmemory.h" />
<ClInclude Include="sdk\tier1\utlbuffer.h" />
<ClInclude Include="sdk\tier1\utlfixedmemory.h" />
<ClInclude Include="sdk\tier1\UtlMemory.hpp" />
<ClInclude Include="sdk\tier1\UtlString.hpp" />

View File

@@ -330,6 +330,18 @@
<ClInclude Include="weapon.h">
<Filter>头文件\native_sdk</Filter>
</ClInclude>
<ClInclude Include="sdk\public\irecipientfilter.h">
<Filter>头文件\sdk\public</Filter>
</ClInclude>
<ClInclude Include="sdk\public\recipientfilters.h">
<Filter>头文件\sdk\public</Filter>
</ClInclude>
<ClInclude Include="sdk\tier1\utlbuffer.h">
<Filter>头文件\sdk\tier1</Filter>
</ClInclude>
<ClInclude Include="sdk\tier1\cbyteswap.h">
<Filter>头文件\sdk\tier1</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">

View File

@@ -1,6 +1,20 @@
#include "events.h"
namespace events {
auto OnPlayerSpawnEvent(IGameEvent* event) -> void {
UnkGameEventStruct_t userIdNameParams{"userid"};
const auto playerPawn = reinterpret_cast<CCSPlayerPawn*>(
event->GetPlayerPawn(&userIdNameParams));
if (playerPawn == nullptr) {
return;
}
const auto player = playerPawn->GetPlayerController();
if (player == nullptr) {
return;
}
const auto playerIndex = player->GetRefEHandle().GetEntryIndex();
ScriptCallBacks::luaCall_onPlayerSpawn(playerIndex);
}
auto OnPlayerDeathEvent(IGameEvent* event) -> void {
UnkGameEventStruct_t userIdNameParams{"userid"};
UnkGameEventStruct_t attackerNameParams{"attacker"};

View File

@@ -10,4 +10,5 @@ auto OnPlayerConnect(int slot, const char* pszName, uint64_t xuid,
auto OnPlayerDisconnect(int slot, const char* pszName, uint64_t xuid,
const char* pszNetworkID, const char* pszAddress,
bool bFakePlayer) -> void;
auto OnPlayerSpawnEvent(IGameEvent* event) -> void;
} // namespace events

View File

@@ -37,28 +37,9 @@ static void DebugPrintA(const char* format, ...) {
#include "memory.h"
// sdk
#include "sdk/gameevent/IGameEvent.h"
#include "sdk/tier1/bufferstring.h"
#include "sdk/public/eiface.h"
#include "sdk/player/playerslot.h"
#include "sdk/sdk.h"
#include "sdk/public/mathlib.h"
#include "sdk/public/string_t.h"
#include "sdk/tier1/UtlMemory.hpp"
#include "sdk/tier1/utlfixedmemory.h"
#include "sdk/tier1/utlblockmemory.h"
#include "sdk/tier1/UtlString.hpp"
#include "sdk/interfaces/interfaces.h"
#include "sdk/public/eiface.h"
#include "sdk/gameevent/IGameEvent.h"
#include "sdk/convar/convar.hpp"
#include "sdk/tier1/bufferstring.h"
#include "sdk/public/bitvec.h"
#include "sdk/public/iserver.h"
#include "sdk/public/utlrbtree.h"
#include "sdk/public/utlmap.h"
#include "offset.h"
#include "native_sdk.h"

View File

@@ -1,17 +1,17 @@
#include "hooks.h"
extern auto GetGameGlobals() -> CGlobalVars*;
namespace hooks {
// "player_connect"
VMTHook* VMT_IServerGameClient;
VMTHook* VMT_INetworkServerServiceInteFace;
VMTHook* VMT_ISource2ServerInterFace;
FireEventServerSide_t original_FireEventServerSide = NULL;
OnClientConnect_t original_OnClientConnected = NULL;
OnClientDisconnect_t original_OnClientDisconnect = NULL;
Host_Say_t original_Host_Say = NULL;
StartupServer_t origin_StartServer = NULL;
GameFrame_t origin_GameFrame = NULL;
namespace hooks {
// "player_connect"
VMTHook* VMT_IServerGameClient;
VMTHook* VMT_INetworkServerServiceInteFace;
VMTHook* VMT_ISource2ServerInterFace;
void __fastcall hook_GameFrame(void* rcx, bool simulating, bool bFirstTick,
bool bLastTick) {
/**
@@ -128,11 +128,16 @@ bool __fastcall hook_FireEventServerSide(CGameEventManager* rcx,
static constexpr auto player_death =
hash_32_fnv1a_const("player_death");
static constexpr auto player_chat = hash_32_fnv1a_const("player_chat");
static constexpr auto player_spawn =
hash_32_fnv1a_const("player_spawn");
switch (hash_32_fnv1a_const(eventName)) {
case player_death:
events::OnPlayerDeathEvent(event);
break;
case player_spawn:
events::OnPlayerSpawnEvent(event);
break;
// V<><56>bug,<2C><EFBFBD><E2B2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/*
case player_chat:

View File

@@ -7,10 +7,8 @@ typedef void(__fastcall* OnClientConnect_t)(void*, CPlayerSlot, const char*, uin
typedef void(__fastcall* OnClientDisconnect_t)(void*, CPlayerSlot, int, const char*, uint64_t, const char*);
typedef void(__fastcall* StartupServer_t)(void*, const GameSessionConfiguration_t&, ISource2WorldSession*, const char*);
typedef void(__fastcall* GameFrame_t)(void*, bool, bool, bool);
extern FireEventServerSide_t original_FireEventServerSide;
extern Host_Say_t original_Host_Say;
namespace hooks {
extern Host_Say_t original_Host_Say;
auto init() -> bool;
auto unload() -> void;
}

View File

@@ -23,7 +23,8 @@ auto CSchemaSystem::FindTypeScopeForModule(const char* module)
}
auto CBaseEntity::IsBasePlayerController() -> bool {
return CALL_VIRTUAL(bool, 144, this);
return true;
//return CALL_VIRTUAL(bool, 146, this);
}
auto CBaseEntity::SpawnClientEntity() -> void { CALL_VIRTUAL(void, 19, this); }
auto CBasePlayer::ForceRespawn() -> void {

View File

@@ -14,7 +14,10 @@ NetworkStateChanged_t FnNetworkStateChanged;
RespawnPlayer_t FnRespawnPlayer;
GiveNamedItem_t FnGiveNamedItem;
EntityRemove_t FnEntityRemove;
//CreateGameRuleInterFace_t FnCreateCCSGameRulesInterFace;
UTIL_SayTextFilter_t FnUTIL_SayTextFilter;
UTIL_ClientPrintAll_t FnUTIL_ClientPrintAll;
ClientPrint_t FnClientPrint;
// CreateGameRuleInterFace_t FnCreateCCSGameRulesInterFace;
bool InitOffsetSuccess = false;
namespace InterFaces {
CSchemaSystem* SchemaSystem;
@@ -30,18 +33,19 @@ CCSGameRules* CCSGameRulesInterFace;
}; // namespace InterFaces
auto SafeDelayInit(void* ctx) -> void {
// <20><>Ҫ<EFBFBD><D2AA>Ϸ<EFBFBD><CFB7><EFBFBD>ú<EFBFBD><C3BA><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
InterFaces::CCSGameRulesInterFace =
reinterpret_cast<CCSGameRules*>(Memory::read<CCSGameRules*>(CCSGameRulesInterFacePtr));
InterFaces::CCSGameRulesInterFace = reinterpret_cast<CCSGameRules*>(
Memory::read<CCSGameRules*>(CCSGameRulesInterFacePtr));
while (InterFaces::CCSGameRulesInterFace == 0)
{
InterFaces::CCSGameRulesInterFace =
reinterpret_cast<CCSGameRules*>(Memory::read<CCSGameRules*>(CCSGameRulesInterFacePtr));
while (InterFaces::CCSGameRulesInterFace == 0) {
InterFaces::CCSGameRulesInterFace = reinterpret_cast<CCSGameRules*>(
Memory::read<CCSGameRules*>(CCSGameRulesInterFacePtr));
Sleep(100);
}
InitOffsetSuccess = true;
LOG("[huoji]InterFaces::CCSGameRulesInterFace : %llx \n", InterFaces::CCSGameRulesInterFace);
LOG("m_bForceTeamChangeSilent: %d \n", InterFaces::CCSGameRulesInterFace->m_bForceTeamChangeSilent());
LOG("[huoji]InterFaces::CCSGameRulesInterFace : %llx \n",
InterFaces::CCSGameRulesInterFace);
LOG("m_bForceTeamChangeSilent: %d \n",
InterFaces::CCSGameRulesInterFace->m_bForceTeamChangeSilent());
}
auto Init() -> bool {
CModule server("server.dll");
@@ -65,14 +69,15 @@ auto Init() -> bool {
server.FindPattern(pattern_CreateCCSGameRulesInterFacePtr)
.ToAbsolute(3, 0)
.Get(CCSGameRulesInterFacePtr);
server.FindPattern(pattern_FnRespawnPlayer)
.Get(FnRespawnPlayer);
server.FindPattern(pattern_FnEntityRemove)
.Get(FnEntityRemove);
server.FindPattern(pattern_FnGiveNamedItemPtr)
.Get(FnGiveNamedItem);
server.FindPattern(pattern_FnRespawnPlayer).Get(FnRespawnPlayer);
server.FindPattern(pattern_FnEntityRemove).Get(FnEntityRemove);
server.FindPattern(pattern_FnGiveNamedItemPtr).Get(FnGiveNamedItem);
server.FindPattern(pattern_fnHost_SayPtr).Get(Host_SayPtr);
server.FindPattern(pattern_ServerHashFunctionPtr).Get(FnServerHashFunction);
server.FindPattern(pattern_UTIL_ClientPrintAll).Get(FnUTIL_ClientPrintAll);
server.FindPattern(pattern_FnClientPrint).Get(FnClientPrint);
server.FindPattern(pattern_FnUTIL_SayTextFilter).Get(FnUTIL_SayTextFilter);
InterFaces::SchemaSystem = reinterpret_cast<CSchemaSystem*>(
schemasystem.FindInterface("SchemaSystem_001").Get());
// InterFaces::GameEventManager = reinterpret_cast<IGameEventManager2*>(
@@ -112,6 +117,8 @@ auto Init() -> bool {
LOG("[huoji]FnStateChanged : %llx \n", FnStateChanged);
LOG("[huoji]FnRespawnPlayer : %llx \n", FnRespawnPlayer);
LOG("[huoji]FnGiveNamedItem : %llx \n", FnGiveNamedItem);
LOG("[huoji]FnClientPrint : %llx \n", FnClientPrint);
LOG("[huoji]FnUTIL_ClientPrintAll : %llx \n", FnUTIL_ClientPrintAll);
LOG("[huoji]MaxGlobals : %d \n", global::MaxPlayers);
@@ -132,13 +139,15 @@ auto Init() -> bool {
CGameEntitySystem::GetInstance());
LOG("init offset success !\n");
CreateThread(NULL, 0,
reinterpret_cast<LPTHREAD_START_ROUTINE>(SafeDelayInit),
NULL, 0, NULL);
reinterpret_cast<LPTHREAD_START_ROUTINE>(SafeDelayInit), NULL,
0, NULL);
// LOG("FnServerHashFunction: %llx \n", FnServerHashFunction("here",
// sizeof("here") - 1, 0x31415926));
return FnEntityRemove && FnRespawnPlayer && FnGiveNamedItem && FnServerHashFunction && Host_SayPtr && InterFaces::IVEngineServer &&
return FnEntityRemove && FnRespawnPlayer && FnGiveNamedItem &&
FnServerHashFunction && Host_SayPtr && InterFaces::IVEngineServer &&
InterFaces::GameResourceServiceServer &&
InterFaces::IServerGameClient && InterFaces::GameEventManager &&
InterFaces::SchemaSystem && FireEventServerSidePtr && FnNetworkStateChanged;
InterFaces::SchemaSystem && FireEventServerSidePtr &&
FnNetworkStateChanged;
}
} // namespace Offset

View File

@@ -4,6 +4,7 @@
class CEntityInstance;
class CCSPlayerPawn;
class CGameEntitySystem;
class CCSPlayerController;
typedef uint64_t(__fastcall* HashFunction_t)(const char*, unsigned int,
unsigned int);
typedef void(__fastcall* StateChanged_t)(void* networkTransmitComponent,
@@ -17,7 +18,13 @@ typedef void(__fastcall* GiveNamedItem_t)(void* itemService,
const char* pchName, void* iSubType,
void* pScriptItem, void* a5,
void* a6);
typedef void* (__fastcall* EntityRemove_t)(CGameEntitySystem*, void*, void*, uint64_t);
typedef void*(__fastcall* EntityRemove_t)(CGameEntitySystem*, void*, void*,
uint64_t);
typedef void*(__fastcall* UTIL_SayTextFilter_t)(IRecipientFilter&, const char*,
CCSPlayerController*, uint64_t);
typedef void(__fastcall* UTIL_ClientPrintAll_t)(int msg_dest, const char* msg_name, const char* param1, const char* param2, const char* param3, const char* param4);
typedef void(__fastcall* ClientPrint_t)(CCSPlayerController* player, int msg_dest, const char* msg_name, const char* param1, const char* param2, const char* param3, const char* param4);
class CSchemaSystem;
class CGameResourceService;
class CLocalize;
@@ -73,7 +80,16 @@ static const auto pattern_FnRespawnPlayer = THE_GAME_SIG(
"?? ?? 74 ?? 48 ?? ?? ?? ?? ?? ?? 48 8B CF 48 8B 10 48 8B ?? ?? ?? ?? ?? "
"48 8D ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ??");
static const auto pattern_FnEntityRemove = THE_GAME_SIG(
"48 85 D2 0F ?? ?? ?? ?? ?? 57 48 ?? ?? ?? 48 89 ?? ?? ?? 48 8B F9 48 8B ?? ?? 48 85 DB 0F ?? ?? ?? ?? ?? 48 ?? ?? ?? 75 ?? 33 D2 48 8B CB E8 ?? ?? ?? ?? 48 8D ?? ?? 41 ?? ?? 48 8B D3 48 8B ?? ?? ?? 48 ?? ?? ?? 5F E9 ?? ?? ?? ??");
"48 85 D2 0F ?? ?? ?? ?? ?? 57 48 ?? ?? ?? 48 89 ?? ?? ?? 48 8B F9 48 8B "
"?? ?? 48 85 DB 0F ?? ?? ?? ?? ?? 48 ?? ?? ?? 75 ?? 33 D2 48 8B CB E8 ?? "
"?? ?? ?? 48 8D ?? ?? 41 ?? ?? 48 8B D3 48 8B ?? ?? ?? 48 ?? ?? ?? 5F E9 "
"?? ?? ?? ??");
static const auto pattern_FnUTIL_SayTextFilter = THE_GAME_SIG(
"48 89 5C 24 ?? 55 56 57 48 8D 6C 24 ?? 48 81 EC ?? ?? ?? ?? 49 8B D8");
static const auto pattern_UTIL_ClientPrintAll = THE_GAME_SIG(
"48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 48 81 EC 70 01 ?? ?? 8B E9");
static const auto pattern_FnClientPrint = THE_GAME_SIG(
"48 85 C9 0F 84 ?? ?? ?? ?? 48 8B C4 48 89 58 18");
extern uint64_t GameResourceServicePtr;
extern uint64_t FireEventServerSidePtr;
extern uint64_t Module_tier0;
@@ -85,6 +101,9 @@ extern NetworkStateChanged_t FnNetworkStateChanged;
extern RespawnPlayer_t FnRespawnPlayer;
extern GiveNamedItem_t FnGiveNamedItem;
extern EntityRemove_t FnEntityRemove;
extern UTIL_SayTextFilter_t FnUTIL_SayTextFilter;
extern UTIL_ClientPrintAll_t FnUTIL_ClientPrintAll;
extern ClientPrint_t FnClientPrint;
extern bool InitOffsetSuccess;
auto Init() -> bool;
}; // namespace Offset

View File

@@ -43,6 +43,7 @@ auto ExcutePlayerAction(int playerIndex,
break;
}
auto player = EntitySystem->GetBaseEntity(playerIndex);
if (player == nullptr) {
break;
}
@@ -119,7 +120,6 @@ auto luaApi_RespawnPlayer(lua_State* luaVm) -> int {
if (playerPawn == nullptr) {
return;
}
LOG("respawn player: %llx \n", playerPawn);
Offset::FnRespawnPlayer(playerPawn);
});
return 0;
@@ -190,12 +190,13 @@ auto luaApi_GetPlayerWeaponInfo(lua_State* luaVm) -> _luaApi_WeaponInfo {
if (weapon == nullptr) {
continue;
}
const auto weaponIndex =
const auto _weaponIndex =
weapon->GetRefEHandle().GetEntryIndex();
if (weaponIndex != weaponIndex) {
if (weaponIndex != _weaponIndex) {
continue;
}
activeWeapon = handle->Get<CBasePlayerWeapon>();
break;
}
if (activeWeapon == nullptr) {
break;
@@ -230,6 +231,7 @@ auto luaApi_GetPlayerWeaponInfo(lua_State* luaVm) -> _luaApi_WeaponInfo {
? _luaApi_WeaponType::kGun
: _luaApi_WeaponType::kOther));
info.weaponIndex = weaponIndex;
//LOG("luaApi_GetPlayerWeaponInfo: %s %s %s %d \n", info.weaponName.c_str(), info.weaponBaseName.c_str(), checkWeaponName, weaponIndex);
} while (false);
});
return info;
@@ -407,6 +409,65 @@ auto luaApi_GivePlayerWeapon(lua_State* luaVm) -> int {
auto luApi_GetPlayerAllWeaponIndex(lua_State* luaVm) -> int {
// param: playerIndex:int
const auto playerIndex = lua_tointeger(luaVm, 1);
// Create a new table on the Lua stack
lua_newtable(luaVm);
ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
do {
const auto weaponServices = playerController->m_hPawn()
.Get<CCSPlayerPawn>()
->m_pWeaponServices();
if (weaponServices == nullptr) {
break;
}
const auto weapons = weaponServices->m_hMyWeapons();
int index = 1; // Lua tables start at index 1
for (CHandle* handle = weapons.begin(); handle < weapons.end();
++handle) {
const auto weapon = handle->Get();
if (weapon == nullptr) {
continue;
}
const auto activeWeapon = handle->Get<CBasePlayerWeapon>();
const auto attributeManager = activeWeapon->m_AttributeManager();
if (activeWeapon == nullptr) {
break;
}
const auto itemView = attributeManager->m_Item();
if (itemView == nullptr) {
break;
}
const auto itemStaticData = itemView->GetStaticData();
if (itemView == nullptr) {
break;
}
const char* checkWeaponName =
Offset::InterFaces::ILocalize->FindSafe(
itemStaticData->m_pszItemBaseName);
if (checkWeaponName == nullptr || strlen(checkWeaponName) < 1) {
break;
}
//printf("weapon name: %s \n", itemStaticData->GetSimpleWeaponName());
const auto weaponIndex =
weapon->GetRefEHandle().GetEntryIndex();
// Push the value onto the stack
lua_pushinteger(luaVm, weaponIndex);
// Set the table at index position
lua_rawseti(luaVm, -2, index++);
}
} while (false);
});
// Return the table regardless of success or failure
return 1;
}
auto luaApi_MakePlayerWeaponDrop(lua_State* luaVm) -> int {
// param: playerIndex:int, itemClass:string
const auto playerIndex = lua_tointeger(luaVm, 1);
const auto weaponIndex = lua_tointeger(luaVm, 2);
auto isSuccess = false;
ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
do {
@@ -417,38 +478,28 @@ auto luApi_GetPlayerAllWeaponIndex(lua_State* luaVm) -> int {
break;
}
const auto weapons = weaponServices->m_hMyWeapons();
// Create a new table on the Lua stack
lua_newtable(luaVm);
int index = 1; // Lua tables start at index 1
CBasePlayerWeapon* activeWeapon = 0;
for (CHandle* handle = weapons.begin(); handle < weapons.end();
++handle) {
const auto weapon = handle->Get();
if (weapon == nullptr) {
if (handle->GetEntryIndex() != weaponIndex) {
continue;
}
const auto weaponIndex =
weapon->GetRefEHandle().GetEntryIndex();
// Push the index and then the value onto the stack
lua_pushinteger(luaVm, index++);
lua_pushinteger(luaVm, weaponIndex);
// The table is now below the key-value pair in the stack,
// so we use -3 to indicate its position
lua_settable(luaVm, -3);
const auto weapon = handle->Get<CBasePlayerWeapon>();
if (weapon == nullptr) {
break;
}
activeWeapon = weapon;
break;
}
if (activeWeapon == nullptr) {
break;
}
weaponServices->RemoveWeapon(activeWeapon);
isSuccess = true;
} while (false);
});
if (!isSuccess) {
// If unsuccessful, remove the table from the stack
lua_pop(luaVm, 1);
}
lua_pop(luaVm, 2);
lua_pushboolean(luaVm, isSuccess);
// Return the number of results (either the table or false)
return 1;
}
auto luaApi_RemovePlayerWeapon(lua_State* luaVm) -> int {
@@ -476,6 +527,7 @@ auto luaApi_RemovePlayerWeapon(lua_State* luaVm) -> int {
continue;
}
activeWeapon = weapon;
break;
}
if (activeWeapon == nullptr) {
break;
@@ -488,8 +540,35 @@ auto luaApi_RemovePlayerWeapon(lua_State* luaVm) -> int {
});
lua_pop(luaVm, 2);
lua_pushboolean(luaVm, isSuccess);
return 1;
return 0;
}
auto luaApi_SendToPlayerChat(lua_State* luaVm) -> int {
// param: playerIndex:int, message:string
const auto playerIndex = lua_tointeger(luaVm, 1);
const auto hudType = lua_tointeger(luaVm, 2);
const auto message = lua_tostring(luaVm, 3);
if (hudType >= _HubType::kMax || hudType < _HubType::kNotify) {
lua_pop(luaVm, 3);
return 0;
}
ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
SdkTools::SentChatToClient(playerController,
static_cast<_HubType>(hudType), message);
});
lua_pop(luaVm, 3);
return 0;
}
auto luaApi_SentToAllPlayerChat(lua_State* luaVm) -> int {
// param: playerIndex:int, message:string
const auto message = lua_tostring(luaVm, 1);
const auto hudType = lua_tointeger(luaVm, 2);
if (hudType >= _HubType::kMax || hudType < _HubType::kNotify) {
lua_pop(luaVm, 3);
return 0;
}
SdkTools::SendConsoleChat(static_cast<_HubType>(hudType), message);
lua_pop(luaVm, 2);
return 0;
}
auto initFunciton(lua_State* luaVm) -> void {
lua_register(luaVm, "ListenToGameEvent", luaApi_ListenToGameEvent);
@@ -514,6 +593,12 @@ auto initFunciton(lua_State* luaVm) -> void {
lua_register(luaVm, "luApi_GetPlayerAllWeaponIndex",
luApi_GetPlayerAllWeaponIndex);
lua_register(luaVm, "luaApi_RemovePlayerWeapon", luaApi_RemovePlayerWeapon);
lua_register(luaVm, "luaApi_MakePlayerWeaponDrop",
luaApi_MakePlayerWeaponDrop);
lua_register(luaVm, "luaApi_SendToPlayerChat", luaApi_SendToPlayerChat);
lua_register(luaVm, "luaApi_SentToAllPlayerChat",
luaApi_SentToAllPlayerChat);
luabridge::getGlobalNamespace(luaVm)
.beginClass<_luaApi_WeaponInfo>("WeaponInfo")
.addConstructor<void (*)(void)>()

View File

@@ -10,6 +10,8 @@ std::unordered_map<uint32_t, _CallbackNames> callbackNameWithEnumMap{
_CallbackNames::kOnPlayerDisconnect},
{hash_32_fnv1a_const("player_death"), _CallbackNames::kOnPlayerDeath},
{hash_32_fnv1a_const("player_chat"), _CallbackNames::kOnPlayerSpeak},
{hash_32_fnv1a_const("player_spawn"), _CallbackNames::kOnPlayerSpawn},
};
auto CallBackNameToEnum(const char* name) -> _CallbackNames {
if (name == nullptr) {
@@ -35,7 +37,7 @@ auto ExcuteCallbackInAllLuaVm(_CallbackNames cbType,
if (luaVMCallbackLists.find(cbType) == luaVMCallbackLists.end()) {
continue;
}
LOG("excute callback %d in %s \n", cbType, pluginName.c_str());
// LOG("excute callback %d in %s \n", cbType, pluginName.c_str());
const auto luaRefIndex = luaVMCallbackLists.at(cbType);
cb(luaVm, luaRefIndex);
}
@@ -129,4 +131,19 @@ auto luaCall_onPlayerSpeak(int speaker, int chatType, std::string message)
});
return result;
}
auto luaCall_onPlayerSpawn(int player) -> void {
ExcuteCallbackInAllLuaVm(_CallbackNames::kOnPlayerSpawn,
[&](lua_State* luaVm, int refIndex) -> void {
lua_rawgeti(luaVm, LUA_REGISTRYINDEX,
refIndex);
if (lua_isfunction(luaVm, -1)) {
lua_pushinteger(luaVm, player);
if (lua_pcall(luaVm, 1, 0, 0) != LUA_OK) {
LOG("Error calling Lua callback: %s\n",
lua_tostring(luaVm, -1));
lua_pop(luaVm, 1);
}
}
});
}
} // namespace ScriptCallBacks

View File

@@ -7,7 +7,8 @@ enum class _CallbackNames {
kOnPlayerConnect,
kOnPlayerDisconnect,
kOnPlayerDeath,
kOnPlayerSpeak
kOnPlayerSpeak,
kOnPlayerSpawn
};
extern std::unordered_map<lua_State*, std::unordered_map<_CallbackNames, int>>
callbackList;
@@ -22,4 +23,5 @@ auto luaCall_onPlayerDisconnect(int player, int slot, const char* pszName,
auto luaCall_onPlayerDeath(int victim, int killer, bool isHeadShot) -> void;
auto luaCall_onPlayerSpeak(int speaker, int chatType, std::string message)
-> bool;
auto luaCall_onPlayerSpawn(int player) -> void;
} // namespace ScriptCallBacks

View File

@@ -1,18 +1,116 @@
#include "convar.hpp"
inline const char** CCommand::ArgV() const
{
return ArgC() ? (const char**)m_Args.Base() : NULL;
inline const char** CCommand::ArgV() const {
return ArgC() ? (const char**)m_Args.Base() : NULL;
}
inline const char* CCommand::ArgS() const
{
return m_nArgv0Size ? (m_ArgSBuffer.Base() + m_nArgv0Size) : "";
inline const char* CCommand::ArgS() const {
return m_nArgv0Size ? (m_ArgSBuffer.Base() + m_nArgv0Size) : "";
}
inline const char* CCommand::operator[](int nIndex) const
{
return Arg(nIndex);
inline const char* CCommand::operator[](int nIndex) const {
return Arg(nIndex);
}
static characterset_t s_BreakSet;
static bool s_bBuiltBreakSet = false;
void CharacterSetBuild(characterset_t* pSetBuffer, const char* pszSetString) {
int i = 0;
// Test our pointers
if (!pSetBuffer || !pszSetString) return;
memset(pSetBuffer->set, 0, sizeof(pSetBuffer->set));
while (pszSetString[i]) {
pSetBuffer->set[static_cast<size_t>(pszSetString[i])] = 1;
i++;
}
}
//-----------------------------------------------------------------------------
// Tokenizer class
//-----------------------------------------------------------------------------
CCommand::CCommand() {
if (!s_bBuiltBreakSet) {
s_bBuiltBreakSet = true;
CharacterSetBuild(&s_BreakSet, "{}()':");
}
Reset();
}
CCommand::CCommand(int nArgC, const char** ppArgV) {
Assert(nArgC > 0);
if (!s_bBuiltBreakSet) {
s_bBuiltBreakSet = true;
CharacterSetBuild(&s_BreakSet, "{}()':");
}
Reset();
char* pBuf = m_ArgvBuffer.Base();
char* pSBuf = m_ArgSBuffer.Base();
for (int i = 0; i < nArgC; ++i) {
m_Args.AddToTail(pBuf);
int nLen = strlen(ppArgV[i]);
memcpy(pBuf, ppArgV[i], nLen + 1);
if (i == 0) {
m_nArgv0Size = nLen;
}
pBuf += nLen + 1;
bool bContainsSpace = strchr(ppArgV[i], ' ') != NULL;
if (bContainsSpace) {
*pSBuf++ = '\"';
}
memcpy(pSBuf, ppArgV[i], nLen);
pSBuf += nLen;
if (bContainsSpace) {
*pSBuf++ = '\"';
}
if (i != nArgC - 1) {
*pSBuf++ = ' ';
}
}
}
bool CCommand::Tokenize(const char* pCommand, characterset_t* pBreakSet) {
__debugbreak();
return false;
}
void CCommand::Reset() {
m_nArgv0Size = 0;
m_ArgSBuffer.RemoveAll();
m_ArgvBuffer.RemoveAll();
m_Args.RemoveAll();
}
characterset_t* CCommand::DefaultBreakSet() { return &s_BreakSet; }
//-----------------------------------------------------------------------------
// Helper function to parse arguments to commands.
//-----------------------------------------------------------------------------
int CCommand::FindArg(const char* pName) const {
int nArgC = ArgC();
for (int i = 1; i < nArgC; i++) {
if (!_stricmp(Arg(i), pName)) return (i + 1) < nArgC ? i + 1 : -1;
}
return -1;
}
int CCommand::FindArgInt(const char* pName, int nDefaultVal) const {
int idx = FindArg(pName);
if (idx != -1)
return atoi(m_Args[idx]);
else
return nDefaultVal;
}
//-----------------------------------------------------------------------------
// Default console command autocompletion function
//-----------------------------------------------------------------------------
int DefaultCompletionFunc(const char* partial,
CUtlVector<CUtlString>& commands) {
return 0;
}

View File

@@ -1,129 +1,83 @@
#pragma once
#include "../sdk.h"
#include "../tier1/UtlVector.hpp"
struct characterset_t
{
char set[256];
struct characterset_t {
char set[256];
};
class ConCommandBase
{
friend class CCvar;
friend class ConCommand;
class ConCommandBase {
friend class CCvar;
friend class ConCommand;
protected:
ConCommandBase(void);
public:
protected:
ConCommandBase(void);
~ConCommandBase(void);
// Check flag
bool IsFlagSet(int64_t flag) const;
// Set flag
void AddFlags(int64_t flags);
// Clear flag
void RemoveFlags(int64_t flags);
public:
~ConCommandBase(void);
// Check flag
bool IsFlagSet(int64_t flag) const;
// Set flag
void AddFlags(int64_t flags);
// Clear flag
void RemoveFlags(int64_t flags);
int64_t GetFlags() const;
int64_t GetFlags() const;
// Return name of cvar
const char* GetName(void) const;
// Return name of cvar
const char* GetName(void) const;
// Return help text for cvar
const char* GetHelpText(void) const;
// Return help text for cvar
const char* GetHelpText(void) const;
private:
// Static data
const char* m_pszName;
const char* m_pszHelpString;
private:
// Static data
const char* m_pszName;
const char* m_pszHelpString;
// ConVar flags
int64_t m_nFlags;
// ConVar flags
int64_t m_nFlags;
};
template< class T, size_t SIZE, class I = int >
class CUtlMemoryFixedGrowable : public CUtlMemory< T, I >
{
typedef CUtlMemory< T, I > BaseClass;
class CCommand {
public:
CCommand();
CCommand(int nArgC, const char** ppArgV);
virtual bool Tokenize(const char* pCommand,
characterset_t* pBreakSet = NULL);
virtual void Reset();
public:
CUtlMemoryFixedGrowable(int nGrowSize = 0, int nInitSize = SIZE) : BaseClass(m_pFixedMemory, SIZE)
{
Assert(nInitSize == 0 || nInitSize == SIZE);
}
int ArgC() const { return m_Args.Count(); }
const char** ArgV() const;
const char* ArgS()
const; // All args that occur after the 0th arg, in string form
const char* GetCommandString() const {
return ArgC() ? m_ArgSBuffer.Base() : "";
}
const char* operator[](int nIndex) const; // Gets at arguments
const char* Arg(int nIndex) const {
// FIXME: Many command handlers appear to not be particularly careful
// about checking for valid argc range. For now, we're going to
// do the extra check and return an empty string if it's out of range
if (nIndex < 0 || nIndex >= ArgC()) return "";
return m_Args[nIndex];
}
void EnsureCapacity(int num)
{
if (CUtlMemory<T>::m_nAllocationCount >= num)
return;
// Helper functions to parse arguments to commands.
//
// Returns index of argument, or -1 if no such argument.
int FindArg(const char* pName) const;
BaseClass::EnsureCapacity(num);
}
int FindArgInt(const char* pName, int nDefaultVal) const;
private:
T m_pFixedMemory[SIZE];
static int MaxCommandLength() { return COMMAND_MAX_LENGTH - 1; }
static characterset_t* DefaultBreakSet();
private:
enum {
COMMAND_MAX_ARGC = 64,
COMMAND_MAX_LENGTH = 512,
};
int m_nArgv0Size;
CUtlVectorFixedGrowable<char, COMMAND_MAX_LENGTH> m_ArgSBuffer;
CUtlVectorFixedGrowable<char, COMMAND_MAX_LENGTH> m_ArgvBuffer;
CUtlVectorFixedGrowable<char*, COMMAND_MAX_ARGC> m_Args;
};
template< class T, size_t MAX_SIZE >
class CUtlVectorFixedGrowable : public CUtlVector< T, CUtlMemoryFixedGrowable<T, MAX_SIZE > >
{
typedef CUtlVector< T, CUtlMemoryFixedGrowable<T, MAX_SIZE > > BaseClass;
public:
// constructor, destructor
CUtlVectorFixedGrowable(int growSize = 0) : BaseClass(growSize, MAX_SIZE) {}
};
class CCommand
{
public:
CCommand();
CCommand(int nArgC, const char** ppArgV);
virtual bool Tokenize(const char* pCommand, characterset_t* pBreakSet = NULL);
virtual void Reset();
int ArgC() const {
return m_Args.Count();
}
const char** ArgV() const;
const char* ArgS() const; // All args that occur after the 0th arg, in string form
const char* GetCommandString() const
{
return ArgC() ? m_ArgSBuffer.Base() : "";
}
const char* operator[](int nIndex) const; // Gets at arguments
const char* Arg(int nIndex) const {
// FIXME: Many command handlers appear to not be particularly careful
// about checking for valid argc range. For now, we're going to
// do the extra check and return an empty string if it's out of range
if (nIndex < 0 || nIndex >= ArgC())
return "";
return m_Args[nIndex];
}
// Helper functions to parse arguments to commands.
//
// Returns index of argument, or -1 if no such argument.
int FindArg(const char* pName) const;
int FindArgInt(const char* pName, int nDefaultVal) const;
static int MaxCommandLength()
{
return COMMAND_MAX_LENGTH - 1;
}
static characterset_t* DefaultBreakSet();
private:
enum
{
COMMAND_MAX_ARGC = 64,
COMMAND_MAX_LENGTH = 512,
};
int m_nArgv0Size;
CUtlVectorFixedGrowable<char, COMMAND_MAX_LENGTH> m_ArgSBuffer;
CUtlVectorFixedGrowable<char, COMMAND_MAX_LENGTH> m_ArgvBuffer;
CUtlVectorFixedGrowable<char*, COMMAND_MAX_ARGC> m_Args;
};

View File

@@ -1,9 +1,3 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
//===========================================================================//
#ifndef BITVEC_H
#define BITVEC_H
#ifdef _WIN32

View File

@@ -0,0 +1,17 @@
#pragma once
#include "eiface.h"
//-----------------------------------------------------------------------------
// Purpose: Generic interface for routing messages to users
//-----------------------------------------------------------------------------
class IRecipientFilter
{
public:
virtual ~IRecipientFilter() {}
virtual bool IsReliable(void) const = 0;
virtual bool IsInitMessage(void) const = 0;
virtual int GetRecipientCount(void) const = 0;
virtual CEntityIndex GetRecipientIndex(int slot) const = 0;
};

View File

@@ -0,0 +1,62 @@
#pragma once
#include "../sdk.h"
class CSingleRecipientFilter : public IRecipientFilter
{
public:
CSingleRecipientFilter(int iRecipient, bool bReliable = true, bool bInitMessage = false) :
m_iRecipient(iRecipient), m_bReliable(bReliable), m_bInitMessage(bInitMessage) {}
~CSingleRecipientFilter() override {}
bool IsReliable(void) const override { return m_bReliable; }
bool IsInitMessage(void) const override { return m_bInitMessage; }
int GetRecipientCount(void) const override { return 1; }
CEntityIndex GetRecipientIndex(int slot) const override { return CEntityIndex(m_iRecipient); }
private:
bool m_bReliable;
bool m_bInitMessage;
int m_iRecipient;
};
class CCopyRecipientFilter : public IRecipientFilter
{
public:
CCopyRecipientFilter(IRecipientFilter *source, int iExcept)
{
m_bReliable = source->IsReliable();
m_bInitMessage = source->IsInitMessage();
m_Recipients.RemoveAll();
for (int i = 0; i < source->GetRecipientCount(); i++)
{
if (source->GetRecipientIndex(i).Get() != iExcept)
m_Recipients.AddToTail(source->GetRecipientIndex(i));
}
}
~CCopyRecipientFilter() override {}
bool IsReliable(void) const override { return m_bReliable; }
bool IsInitMessage(void) const override { return m_bInitMessage; }
int GetRecipientCount(void) const override { return m_Recipients.Count(); }
CEntityIndex GetRecipientIndex(int slot) const override
{
if (slot < 0 || slot >= GetRecipientCount())
return CEntityIndex(-1);
return m_Recipients[slot];
}
private:
bool m_bReliable;
bool m_bInitMessage;
CUtlVectorFixed<CEntityIndex, 64> m_Recipients;
};

View File

@@ -1,11 +1,3 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Header: $
// $NoKeywords: $
//=============================================================================//
#ifndef UTLRBTREE_H
#define UTLRBTREE_H

View File

@@ -1,61 +1,109 @@
#pragma once
#include <string>
#include <array>
#include <Windows.h>
#include <Psapi.h>
#include <thread>
#include <unordered_map>
#include <map>
#include <shared_mutex>
#include <sstream>
#include <filesystem>
#include <limits.h>
#include <cstdint>
#define CORRECT_PATH_SEPARATOR '\\'
#define CORRECT_PATH_SEPARATOR_S "\\"
#define INCORRECT_PATH_SEPARATOR '/'
#define INCORRECT_PATH_SEPARATOR_S "/"
#define FMTFUNCTION( a, b )
enum EStringConvertErrorPolicy
{
_STRINGCONVERTFLAG_SKIP = 1,
_STRINGCONVERTFLAG_FAIL = 2,
_STRINGCONVERTFLAG_ASSERT = 4,
#define FMTFUNCTION(a, b)
enum EStringConvertErrorPolicy {
_STRINGCONVERTFLAG_SKIP = 1,
_STRINGCONVERTFLAG_FAIL = 2,
_STRINGCONVERTFLAG_ASSERT = 4,
STRINGCONVERT_REPLACE = 0,
STRINGCONVERT_SKIP = _STRINGCONVERTFLAG_SKIP,
STRINGCONVERT_FAIL = _STRINGCONVERTFLAG_FAIL,
STRINGCONVERT_REPLACE = 0,
STRINGCONVERT_SKIP = _STRINGCONVERTFLAG_SKIP,
STRINGCONVERT_FAIL = _STRINGCONVERTFLAG_FAIL,
STRINGCONVERT_ASSERT_REPLACE = _STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_REPLACE,
STRINGCONVERT_ASSERT_SKIP = _STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_SKIP,
STRINGCONVERT_ASSERT_FAIL = _STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_FAIL,
STRINGCONVERT_ASSERT_REPLACE =
_STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_REPLACE,
STRINGCONVERT_ASSERT_SKIP = _STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_SKIP,
STRINGCONVERT_ASSERT_FAIL = _STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_FAIL,
};
enum EUniverse
{
k_EUniverseInvalid = 0,
k_EUniversePublic = 1,
k_EUniverseBeta = 2,
k_EUniverseInternal = 3,
k_EUniverseDev = 4,
// k_EUniverseRC = 5, // no such universe anymore
k_EUniverseMax
enum EUniverse {
k_EUniverseInvalid = 0,
k_EUniversePublic = 1,
k_EUniverseBeta = 2,
k_EUniverseInternal = 3,
k_EUniverseDev = 4,
// k_EUniverseRC = 5, // no such universe anymore
k_EUniverseMax
};
#define Plat_FastMemset memset
#define Plat_FastMemcpy memcpy
#define RESTRICT __restrict
#define RESTRICT_FUNC __declspec(restrict)
#define FORCEINLINE_TEMPLATE __forceinline
#define RESTRICT __restrict
#define RESTRICT_FUNC __declspec(restrict)
#define FORCEINLINE_TEMPLATE __forceinline
#define PAD_NUMBER(number, boundary) \
( ((number) + ((boundary)-1)) / (boundary) ) * (boundary)
(((number) + ((boundary)-1)) / (boundary)) * (boundary)
typedef __int64 intp;
#ifndef Assert
typedef unsigned __int64 uintp; // (ie, sizeof(intp) >= sizeof(int) &&
// sizeof(intp) >= sizeof(void *)
typedef unsigned char uint8;
typedef signed char int8;
typedef __int16 int16;
typedef unsigned __int16 uint16;
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;
typedef unsigned int uint;
#define Assert
#endif // !Assert
template <class T>
inline T* Construct(T* pMemory)
{
return ::new(pMemory) T;
inline T* Construct(T* pMemory) {
return ::new (pMemory) T;
}
template <class T>
inline void Destruct(T* pMemory)
{
pMemory->~T();
inline void Destruct(T* pMemory) {
pMemory->~T();
#ifdef _DEBUG
memset((void*)pMemory, 0xDD, sizeof(T));
memset((void*)pMemory, 0xDD, sizeof(T));
#endif
}
#include "../head.h"
template <typename T>
inline T AlignValue(T val, uintptr_t alignment) {
return (T)(((uintptr_t)val + alignment - 1) & ~(alignment - 1));
}
#include "player/playerslot.h"
#include "public/mathlib.h"
#include "public/string_t.h"
#include "tier1/UtlMemory.hpp"
#include "tier1/utlfixedmemory.h"
#include "tier1/utlblockmemory.h"
#include "tier1/UtlString.hpp"
#include "tier1/UtlVector.hpp"
#include "tier1/bufferstring.h"
#include "tier1/cbyteswap.h"
#include "tier1/utlbuffer.h"
#include "public/eiface.h"
#include "public/bitvec.h"
#include "public/iserver.h"
#include "public/utlrbtree.h"
#include "public/utlmap.h"
#include "public/IRecipientFilter.h"
#include "public/recipientfilters.h"
#include "interfaces/interfaces.h"
#include "gameevent/IGameEvent.h"
#include "convar/convar.hpp"
#include "gameevent/IGameEvent.h"
#include "tier1/bufferstring.h"
#include "public/eiface.h"

View File

@@ -4,10 +4,11 @@
#define UTLMEMORY_TRACK_ALLOC()
#define MEM_ALLOC_CREDIT_CLASS()
#define UTLMEMORY_TRACK_FREE()
template< class T, class I = int >
class CUtlMemory
{
public:
#define Assert
template <class T, class I = int>
class CUtlMemory {
public:
// constructor, destructor
CUtlMemory(int nGrowSize = 0, int nInitSize = 0);
CUtlMemory(T* pMemory, int numElements);
@@ -17,20 +18,26 @@ public:
// Set the size by which the memory grows
void Init(int nGrowSize = 0, int nInitSize = 0);
class Iterator_t
{
public:
class Iterator_t {
public:
Iterator_t(I i) : index(i) {}
I index;
bool operator==(const Iterator_t it) const { return index == it.index; }
bool operator!=(const Iterator_t it) const { return index != it.index; }
};
Iterator_t First() const { return Iterator_t(IsIdxValid(0) ? 0 : InvalidIndex()); }
Iterator_t Next(const Iterator_t &it) const { return Iterator_t(IsIdxValid(it.index + 1) ? it.index + 1 : InvalidIndex()); }
I GetIndex(const Iterator_t &it) const { return it.index; }
bool IsIdxAfter(I i, const Iterator_t &it) const { return i > it.index; }
bool IsValidIterator(const Iterator_t &it) const { return IsIdxValid(it.index); }
Iterator_t First() const {
return Iterator_t(IsIdxValid(0) ? 0 : InvalidIndex());
}
Iterator_t Next(const Iterator_t& it) const {
return Iterator_t(IsIdxValid(it.index + 1) ? it.index + 1
: InvalidIndex());
}
I GetIndex(const Iterator_t& it) const { return it.index; }
bool IsIdxAfter(I i, const Iterator_t& it) const { return i > it.index; }
bool IsValidIterator(const Iterator_t& it) const {
return IsIdxValid(it.index);
}
Iterator_t InvalidIterator() const { return Iterator_t(InvalidIndex()); }
// element access
@@ -41,7 +48,7 @@ public:
bool IsIdxValid(I i) const;
static const I INVALID_INDEX = (I)-1; // For use with COMPILE_TIME_ASSERT
static const I INVALID_INDEX = (I)-1; // For use with COMPILE_TIME_ASSERT
static I InvalidIndex() { return INVALID_INDEX; }
T* Base();
@@ -49,11 +56,11 @@ public:
void SetExternalBuffer(T* pMemory, int numElements);
void SetExternalBuffer(const T* pMemory, int numElements);
void AssumeMemory(T *pMemory, int nSize);
void AssumeMemory(T* pMemory, int nSize);
T* Detach();
void *DetachMemory();
void* DetachMemory();
void Swap(CUtlMemory< T, I > &mem);
void Swap(CUtlMemory<T, I>& mem);
void ConvertToGrowableMemory(int nGrowSize);
int NumAllocated() const;
int Count() const;
@@ -65,14 +72,10 @@ public:
bool IsReadOnly() const;
void SetGrowSize(int size);
protected:
void ValidateGrowSize()
{
protected:
void ValidateGrowSize() {}
}
enum
{
enum {
EXTERNAL_BUFFER_MARKER = -1,
EXTERNAL_CONST_BUFFER_MARKER = -2,
};
@@ -86,48 +89,45 @@ protected:
// constructor, destructor
//-----------------------------------------------------------------------------
template< class T, class I >
CUtlMemory<T, I>::CUtlMemory(int nGrowSize, int nInitAllocationCount) : m_pMemory(0),
m_nAllocationCount(nInitAllocationCount), m_nGrowSize(nGrowSize)
{
template <class T, class I>
CUtlMemory<T, I>::CUtlMemory(int nGrowSize, int nInitAllocationCount)
: m_pMemory(0),
m_nAllocationCount(nInitAllocationCount),
m_nGrowSize(nGrowSize) {
ValidateGrowSize();
if(m_nAllocationCount) {
if (m_nAllocationCount) {
m_pMemory = (T*)new unsigned char[m_nAllocationCount * sizeof(T)];
//m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T));
// m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T));
}
}
template< class T, class I >
CUtlMemory<T, I>::CUtlMemory(T* pMemory, int numElements) : m_pMemory(pMemory),
m_nAllocationCount(numElements)
{
template <class T, class I>
CUtlMemory<T, I>::CUtlMemory(T* pMemory, int numElements)
: m_pMemory(pMemory), m_nAllocationCount(numElements) {
// Special marker indicating externally supplied modifyable memory
m_nGrowSize = EXTERNAL_BUFFER_MARKER;
}
template< class T, class I >
CUtlMemory<T, I>::CUtlMemory(const T* pMemory, int numElements) : m_pMemory((T*)pMemory),
m_nAllocationCount(numElements)
{
template <class T, class I>
CUtlMemory<T, I>::CUtlMemory(const T* pMemory, int numElements)
: m_pMemory((T*)pMemory), m_nAllocationCount(numElements) {
// Special marker indicating externally supplied modifyable memory
m_nGrowSize = EXTERNAL_CONST_BUFFER_MARKER;
}
template< class T, class I >
CUtlMemory<T, I>::~CUtlMemory()
{
template <class T, class I>
CUtlMemory<T, I>::~CUtlMemory() {
Purge();
}
template< class T, class I >
void CUtlMemory<T, I>::Init(int nGrowSize /*= 0*/, int nInitSize /*= 0*/)
{
template <class T, class I>
void CUtlMemory<T, I>::Init(int nGrowSize /*= 0*/, int nInitSize /*= 0*/) {
Purge();
m_nGrowSize = nGrowSize;
m_nAllocationCount = nInitSize;
ValidateGrowSize();
if(m_nAllocationCount) {
if (m_nAllocationCount) {
UTLMEMORY_TRACK_ALLOC();
MEM_ALLOC_CREDIT_CLASS();
m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T));
@@ -137,28 +137,24 @@ void CUtlMemory<T, I>::Init(int nGrowSize /*= 0*/, int nInitSize /*= 0*/)
//-----------------------------------------------------------------------------
// Fast swap
//-----------------------------------------------------------------------------
template< class T, class I >
void CUtlMemory<T, I>::Swap(CUtlMemory<T, I> &mem)
{
template <class T, class I>
void CUtlMemory<T, I>::Swap(CUtlMemory<T, I>& mem) {
V_swap(m_nGrowSize, mem.m_nGrowSize);
V_swap(m_pMemory, mem.m_pMemory);
V_swap(m_nAllocationCount, mem.m_nAllocationCount);
}
//-----------------------------------------------------------------------------
// Switches the buffer from an external memory buffer to a reallocatable buffer
//-----------------------------------------------------------------------------
template< class T, class I >
void CUtlMemory<T, I>::ConvertToGrowableMemory(int nGrowSize)
{
if(!IsExternallyAllocated())
return;
template <class T, class I>
void CUtlMemory<T, I>::ConvertToGrowableMemory(int nGrowSize) {
if (!IsExternallyAllocated()) return;
m_nGrowSize = nGrowSize;
if(m_nAllocationCount) {
if (m_nAllocationCount) {
int nNumBytes = m_nAllocationCount * sizeof(T);
T *pMemory = (T*)malloc(nNumBytes);
T* pMemory = (T*)malloc(nNumBytes);
memcpy(pMemory, m_pMemory, nNumBytes);
m_pMemory = pMemory;
} else {
@@ -166,13 +162,11 @@ void CUtlMemory<T, I>::ConvertToGrowableMemory(int nGrowSize)
}
}
//-----------------------------------------------------------------------------
// Attaches the buffer to external memory....
//-----------------------------------------------------------------------------
template< class T, class I >
void CUtlMemory<T, I>::SetExternalBuffer(T* pMemory, int numElements)
{
template <class T, class I>
void CUtlMemory<T, I>::SetExternalBuffer(T* pMemory, int numElements) {
// Blow away any existing allocated memory
Purge();
@@ -183,9 +177,8 @@ void CUtlMemory<T, I>::SetExternalBuffer(T* pMemory, int numElements)
m_nGrowSize = EXTERNAL_BUFFER_MARKER;
}
template< class T, class I >
void CUtlMemory<T, I>::SetExternalBuffer(const T* pMemory, int numElements)
{
template <class T, class I>
void CUtlMemory<T, I>::SetExternalBuffer(const T* pMemory, int numElements) {
// Blow away any existing allocated memory
Purge();
@@ -196,9 +189,8 @@ void CUtlMemory<T, I>::SetExternalBuffer(const T* pMemory, int numElements)
m_nGrowSize = EXTERNAL_CONST_BUFFER_MARKER;
}
template< class T, class I >
void CUtlMemory<T, I>::AssumeMemory(T* pMemory, int numElements)
{
template <class T, class I>
void CUtlMemory<T, I>::AssumeMemory(T* pMemory, int numElements) {
// Blow away any existing allocated memory
Purge();
@@ -207,121 +199,100 @@ void CUtlMemory<T, I>::AssumeMemory(T* pMemory, int numElements)
m_nAllocationCount = numElements;
}
template< class T, class I >
void *CUtlMemory<T, I>::DetachMemory()
{
if(IsExternallyAllocated())
return NULL;
template <class T, class I>
void* CUtlMemory<T, I>::DetachMemory() {
if (IsExternallyAllocated()) return NULL;
void *pMemory = m_pMemory;
void* pMemory = m_pMemory;
m_pMemory = 0;
m_nAllocationCount = 0;
return pMemory;
}
template< class T, class I >
inline T* CUtlMemory<T, I>::Detach()
{
template <class T, class I>
inline T* CUtlMemory<T, I>::Detach() {
return (T*)DetachMemory();
}
//-----------------------------------------------------------------------------
// element access
//-----------------------------------------------------------------------------
template< class T, class I >
inline T& CUtlMemory<T, I>::operator[](I i)
{
template <class T, class I>
inline T& CUtlMemory<T, I>::operator[](I i) {
return m_pMemory[i];
}
template< class T, class I >
inline const T& CUtlMemory<T, I>::operator[](I i) const
{
template <class T, class I>
inline const T& CUtlMemory<T, I>::operator[](I i) const {
return m_pMemory[i];
}
template< class T, class I >
inline T& CUtlMemory<T, I>::Element(I i)
{
template <class T, class I>
inline T& CUtlMemory<T, I>::Element(I i) {
return m_pMemory[i];
}
template< class T, class I >
inline const T& CUtlMemory<T, I>::Element(I i) const
{
template <class T, class I>
inline const T& CUtlMemory<T, I>::Element(I i) const {
return m_pMemory[i];
}
//-----------------------------------------------------------------------------
// is the memory externally allocated?
//-----------------------------------------------------------------------------
template< class T, class I >
bool CUtlMemory<T, I>::IsExternallyAllocated() const
{
template <class T, class I>
bool CUtlMemory<T, I>::IsExternallyAllocated() const {
return (m_nGrowSize < 0);
}
//-----------------------------------------------------------------------------
// is the memory read only?
//-----------------------------------------------------------------------------
template< class T, class I >
bool CUtlMemory<T, I>::IsReadOnly() const
{
template <class T, class I>
bool CUtlMemory<T, I>::IsReadOnly() const {
return (m_nGrowSize == EXTERNAL_CONST_BUFFER_MARKER);
}
template< class T, class I >
void CUtlMemory<T, I>::SetGrowSize(int nSize)
{
template <class T, class I>
void CUtlMemory<T, I>::SetGrowSize(int nSize) {
m_nGrowSize = nSize;
ValidateGrowSize();
}
//-----------------------------------------------------------------------------
// Gets the base address (can change when adding elements!)
//-----------------------------------------------------------------------------
template< class T, class I >
inline T* CUtlMemory<T, I>::Base()
{
template <class T, class I>
inline T* CUtlMemory<T, I>::Base() {
return m_pMemory;
}
template< class T, class I >
inline const T *CUtlMemory<T, I>::Base() const
{
template <class T, class I>
inline const T* CUtlMemory<T, I>::Base() const {
return m_pMemory;
}
//-----------------------------------------------------------------------------
// Size
//-----------------------------------------------------------------------------
template< class T, class I >
inline int CUtlMemory<T, I>::NumAllocated() const
{
template <class T, class I>
inline int CUtlMemory<T, I>::NumAllocated() const {
return m_nAllocationCount;
}
template< class T, class I >
inline int CUtlMemory<T, I>::Count() const
{
template <class T, class I>
inline int CUtlMemory<T, I>::Count() const {
return m_nAllocationCount;
}
//-----------------------------------------------------------------------------
// Is element index valid?
//-----------------------------------------------------------------------------
template< class T, class I >
inline bool CUtlMemory<T, I>::IsIdxValid(I i) const
{
// GCC warns if I is an unsigned type and we do a ">= 0" against it (since the comparison is always 0).
// We Get the warning even if we cast inside the expression. It only goes away if we assign to another variable.
template <class T, class I>
inline bool CUtlMemory<T, I>::IsIdxValid(I i) const {
// GCC warns if I is an unsigned type and we do a ">= 0" against it (since
// the comparison is always 0). We Get the warning even if we cast inside
// the expression. It only goes away if we assign to another variable.
long x = i;
return (x >= 0) && (x < m_nAllocationCount);
}
@@ -329,22 +300,22 @@ inline bool CUtlMemory<T, I>::IsIdxValid(I i) const
//-----------------------------------------------------------------------------
// Grows the memory
//-----------------------------------------------------------------------------
inline int UtlMemory_CalcNewAllocationCount(int nAllocationCount, int nGrowSize, int nNewSize, int nBytesItem)
{
if(nGrowSize) {
inline int UtlMemory_CalcNewAllocationCount(int nAllocationCount, int nGrowSize,
int nNewSize, int nBytesItem) {
if (nGrowSize) {
nAllocationCount = ((1 + ((nNewSize - 1) / nGrowSize)) * nGrowSize);
} else {
if(!nAllocationCount) {
if (!nAllocationCount) {
// Compute an allocation which is at least as big as a cache line...
nAllocationCount = (31 + nBytesItem) / nBytesItem;
}
while(nAllocationCount < nNewSize) {
while (nAllocationCount < nNewSize) {
#ifndef _X360
nAllocationCount *= 2;
#else
int nNewAllocationCount = (nAllocationCount * 9) / 8; // 12.5 %
if(nNewAllocationCount > nAllocationCount)
int nNewAllocationCount = (nAllocationCount * 9) / 8; // 12.5 %
if (nNewAllocationCount > nAllocationCount)
nAllocationCount = nNewAllocationCount;
else
nAllocationCount *= 2;
@@ -355,40 +326,43 @@ inline int UtlMemory_CalcNewAllocationCount(int nAllocationCount, int nGrowSize,
return nAllocationCount;
}
template< class T, class I >
void CUtlMemory<T, I>::Grow(int num)
{
if(IsExternallyAllocated()) {
// Can't grow a buffer whose memory was externally allocated
template <class T, class I>
void CUtlMemory<T, I>::Grow(int num) {
if (IsExternallyAllocated()) {
// Can't grow a buffer whose memory was externally allocated
return;
}
auto oldAllocationCount = m_nAllocationCount;
// Make sure we have at least numallocated + num allocations.
// Use the grow rules specified for this memory (in m_nGrowSize)
int nAllocationRequested = m_nAllocationCount + num;
int nNewAllocationCount = UtlMemory_CalcNewAllocationCount(m_nAllocationCount, m_nGrowSize, nAllocationRequested, sizeof(T));
int nNewAllocationCount = UtlMemory_CalcNewAllocationCount(
m_nAllocationCount, m_nGrowSize, nAllocationRequested, sizeof(T));
// if m_nAllocationRequested wraps index type I, recalculate
if((int)(I)nNewAllocationCount < nAllocationRequested) {
if((int)(I)nNewAllocationCount == 0 && (int)(I)(nNewAllocationCount - 1) >= nAllocationRequested) {
--nNewAllocationCount; // deal w/ the common case of m_nAllocationCount == MAX_USHORT + 1
if ((int)(I)nNewAllocationCount < nAllocationRequested) {
if ((int)(I)nNewAllocationCount == 0 &&
(int)(I)(nNewAllocationCount - 1) >= nAllocationRequested) {
--nNewAllocationCount; // deal w/ the common case of
// m_nAllocationCount == MAX_USHORT + 1
} else {
if((int)(I)nAllocationRequested != nAllocationRequested) {
// we've been asked to grow memory to a size s.t. the index type can't address the requested amount of memory
if ((int)(I)nAllocationRequested != nAllocationRequested) {
// we've been asked to grow memory to a size s.t. the index type
// can't address the requested amount of memory
return;
}
while((int)(I)nNewAllocationCount < nAllocationRequested) {
nNewAllocationCount = (nNewAllocationCount + nAllocationRequested) / 2;
while ((int)(I)nNewAllocationCount < nAllocationRequested) {
nNewAllocationCount =
(nNewAllocationCount + nAllocationRequested) / 2;
}
}
}
m_nAllocationCount = nNewAllocationCount;
if(m_pMemory) {
if (m_pMemory) {
auto ptr = new unsigned char[m_nAllocationCount * sizeof(T)];
memcpy(ptr, m_pMemory, oldAllocationCount * sizeof(T));
@@ -398,38 +372,33 @@ void CUtlMemory<T, I>::Grow(int num)
}
}
//-----------------------------------------------------------------------------
// Makes sure we've got at least this much memory
//-----------------------------------------------------------------------------
template< class T, class I >
inline void CUtlMemory<T, I>::EnsureCapacity(int num)
{
if(m_nAllocationCount >= num)
return;
template <class T, class I>
inline void CUtlMemory<T, I>::EnsureCapacity(int num) {
if (m_nAllocationCount >= num) return;
if(IsExternallyAllocated()) {
// Can't grow a buffer whose memory was externally allocated
if (IsExternallyAllocated()) {
// Can't grow a buffer whose memory was externally allocated
return;
}
m_nAllocationCount = num;
if(m_pMemory) {
if (m_pMemory) {
m_pMemory = (T*)realloc(m_pMemory, m_nAllocationCount * sizeof(T));
} else {
m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T));
}
}
//-----------------------------------------------------------------------------
// Memory deallocation
//-----------------------------------------------------------------------------
template< class T, class I >
void CUtlMemory<T, I>::Purge()
{
if(!IsExternallyAllocated()) {
if(m_pMemory) {
template <class T, class I>
void CUtlMemory<T, I>::Purge() {
if (!IsExternallyAllocated()) {
if (m_pMemory) {
free((void*)m_pMemory);
m_pMemory = 0;
}
@@ -437,33 +406,32 @@ void CUtlMemory<T, I>::Purge()
}
}
template< class T, class I >
void CUtlMemory<T, I>::Purge(int numElements)
{
if(numElements > m_nAllocationCount) {
template <class T, class I>
void CUtlMemory<T, I>::Purge(int numElements) {
if (numElements > m_nAllocationCount) {
// Ensure this isn't a grow request in disguise.
return;
}
// If we have zero elements, simply do a purge:
if(numElements == 0) {
if (numElements == 0) {
Purge();
return;
}
if(IsExternallyAllocated()) {
// Can't shrink a buffer whose memory was externally allocated, fail silently like purge
if (IsExternallyAllocated()) {
// Can't shrink a buffer whose memory was externally allocated, fail
// silently like purge
return;
}
// If the number of elements is the same as the allocation count, we are done.
if(numElements == m_nAllocationCount) {
// If the number of elements is the same as the allocation count, we are
// done.
if (numElements == m_nAllocationCount) {
return;
}
if(!m_pMemory) {
if (!m_pMemory) {
// Allocation count is non zero, but memory is null.
assert(m_pMemory);
return;
@@ -476,10 +444,9 @@ void CUtlMemory<T, I>::Purge(int numElements)
// The CUtlMemory class:
// A growable memory class which doubles in size by default.
//-----------------------------------------------------------------------------
template< class T, int nAlignment >
class CUtlMemoryAligned : public CUtlMemory<T>
{
public:
template <class T, int nAlignment>
class CUtlMemoryAligned : public CUtlMemory<T> {
public:
// constructor, destructor
CUtlMemoryAligned(int nGrowSize = 0, int nInitSize = 0);
CUtlMemoryAligned(T* pMemory, int numElements);
@@ -499,31 +466,29 @@ public:
// Memory deallocation
void Purge();
// Purge all but the given number of elements (NOT IMPLEMENTED IN CUtlMemoryAligned)
// Purge all but the given number of elements (NOT IMPLEMENTED IN
// CUtlMemoryAligned)
void Purge(int numElements) { __debugbreak(); }
private:
void *Align(const void *pAddr);
private:
void* Align(const void* pAddr);
};
//-----------------------------------------------------------------------------
// Aligns a pointer
//-----------------------------------------------------------------------------
template< class T, int nAlignment >
void *CUtlMemoryAligned<T, nAlignment>::Align(const void *pAddr)
{
template <class T, int nAlignment>
void* CUtlMemoryAligned<T, nAlignment>::Align(const void* pAddr) {
size_t nAlignmentMask = nAlignment - 1;
return (void*)(((size_t)pAddr + nAlignmentMask) & (~nAlignmentMask));
}
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
template< class T, int nAlignment >
CUtlMemoryAligned<T, nAlignment>::CUtlMemoryAligned(int nGrowSize, int nInitAllocationCount)
{
template <class T, int nAlignment>
CUtlMemoryAligned<T, nAlignment>::CUtlMemoryAligned(int nGrowSize,
int nInitAllocationCount) {
CUtlMemory<T>::m_pMemory = 0;
CUtlMemory<T>::m_nAllocationCount = nInitAllocationCount;
CUtlMemory<T>::m_nGrowSize = nGrowSize;
@@ -531,78 +496,83 @@ CUtlMemoryAligned<T, nAlignment>::CUtlMemoryAligned(int nGrowSize, int nInitAllo
// Alignment must be a power of two
COMPILE_TIME_ASSERT((nAlignment & (nAlignment - 1)) == 0);
if(CUtlMemory<T>::m_nAllocationCount) {
if (CUtlMemory<T>::m_nAllocationCount) {
UTLMEMORY_TRACK_ALLOC();
MEM_ALLOC_CREDIT_CLASS();
CUtlMemory<T>::m_pMemory = (T*)_aligned_malloc(nInitAllocationCount * sizeof(T), nAlignment);
CUtlMemory<T>::m_pMemory =
(T*)_aligned_malloc(nInitAllocationCount * sizeof(T), nAlignment);
}
}
template< class T, int nAlignment >
CUtlMemoryAligned<T, nAlignment>::CUtlMemoryAligned(T* pMemory, int numElements)
{
template <class T, int nAlignment>
CUtlMemoryAligned<T, nAlignment>::CUtlMemoryAligned(T* pMemory,
int numElements) {
// Special marker indicating externally supplied memory
CUtlMemory<T>::m_nGrowSize = CUtlMemory<T>::EXTERNAL_BUFFER_MARKER;
CUtlMemory<T>::m_pMemory = (T*)Align(pMemory);
CUtlMemory<T>::m_nAllocationCount = ((int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory) / sizeof(T);
CUtlMemory<T>::m_nAllocationCount =
((int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory) /
sizeof(T);
}
template< class T, int nAlignment >
CUtlMemoryAligned<T, nAlignment>::CUtlMemoryAligned(const T* pMemory, int numElements)
{
template <class T, int nAlignment>
CUtlMemoryAligned<T, nAlignment>::CUtlMemoryAligned(const T* pMemory,
int numElements) {
// Special marker indicating externally supplied memory
CUtlMemory<T>::m_nGrowSize = CUtlMemory<T>::EXTERNAL_CONST_BUFFER_MARKER;
CUtlMemory<T>::m_pMemory = (T*)Align(pMemory);
CUtlMemory<T>::m_nAllocationCount = ((int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory) / sizeof(T);
CUtlMemory<T>::m_nAllocationCount =
((int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory) /
sizeof(T);
}
template< class T, int nAlignment >
CUtlMemoryAligned<T, nAlignment>::~CUtlMemoryAligned()
{
template <class T, int nAlignment>
CUtlMemoryAligned<T, nAlignment>::~CUtlMemoryAligned() {
Purge();
}
//-----------------------------------------------------------------------------
// Attaches the buffer to external memory....
//-----------------------------------------------------------------------------
template< class T, int nAlignment >
void CUtlMemoryAligned<T, nAlignment>::SetExternalBuffer(T* pMemory, int numElements)
{
template <class T, int nAlignment>
void CUtlMemoryAligned<T, nAlignment>::SetExternalBuffer(T* pMemory,
int numElements) {
// Blow away any existing allocated memory
Purge();
CUtlMemory<T>::m_pMemory = (T*)Align(pMemory);
CUtlMemory<T>::m_nAllocationCount = ((int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory) / sizeof(T);
CUtlMemory<T>::m_nAllocationCount =
((int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory) /
sizeof(T);
// Indicate that we don't own the memory
CUtlMemory<T>::m_nGrowSize = CUtlMemory<T>::EXTERNAL_BUFFER_MARKER;
}
template< class T, int nAlignment >
void CUtlMemoryAligned<T, nAlignment>::SetExternalBuffer(const T* pMemory, int numElements)
{
template <class T, int nAlignment>
void CUtlMemoryAligned<T, nAlignment>::SetExternalBuffer(const T* pMemory,
int numElements) {
// Blow away any existing allocated memory
Purge();
CUtlMemory<T>::m_pMemory = (T*)Align(pMemory);
CUtlMemory<T>::m_nAllocationCount = ((int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory) / sizeof(T);
CUtlMemory<T>::m_nAllocationCount =
((int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory) /
sizeof(T);
// Indicate that we don't own the memory
CUtlMemory<T>::m_nGrowSize = CUtlMemory<T>::EXTERNAL_CONST_BUFFER_MARKER;
}
//-----------------------------------------------------------------------------
// Grows the memory
//-----------------------------------------------------------------------------
template< class T, int nAlignment >
void CUtlMemoryAligned<T, nAlignment>::Grow(int num)
{
if(this->IsExternallyAllocated()) {
// Can't grow a buffer whose memory was externally allocated
template <class T, int nAlignment>
void CUtlMemoryAligned<T, nAlignment>::Grow(int num) {
if (this->IsExternallyAllocated()) {
// Can't grow a buffer whose memory was externally allocated
return;
}
@@ -612,31 +582,33 @@ void CUtlMemoryAligned<T, nAlignment>::Grow(int num)
// Use the grow rules specified for this memory (in m_nGrowSize)
int nAllocationRequested = CUtlMemory<T>::m_nAllocationCount + num;
CUtlMemory<T>::m_nAllocationCount = UtlMemory_CalcNewAllocationCount(CUtlMemory<T>::m_nAllocationCount, CUtlMemory<T>::m_nGrowSize, nAllocationRequested, sizeof(T));
CUtlMemory<T>::m_nAllocationCount = UtlMemory_CalcNewAllocationCount(
CUtlMemory<T>::m_nAllocationCount, CUtlMemory<T>::m_nGrowSize,
nAllocationRequested, sizeof(T));
UTLMEMORY_TRACK_ALLOC();
if(CUtlMemory<T>::m_pMemory) {
if (CUtlMemory<T>::m_pMemory) {
MEM_ALLOC_CREDIT_CLASS();
CUtlMemory<T>::m_pMemory = (T*)MemAlloc_ReallocAligned(CUtlMemory<T>::m_pMemory, CUtlMemory<T>::m_nAllocationCount * sizeof(T), nAlignment);
CUtlMemory<T>::m_pMemory = (T*)MemAlloc_ReallocAligned(
CUtlMemory<T>::m_pMemory,
CUtlMemory<T>::m_nAllocationCount * sizeof(T), nAlignment);
} else {
MEM_ALLOC_CREDIT_CLASS();
CUtlMemory<T>::m_pMemory = (T*)MemAlloc_AllocAligned(CUtlMemory<T>::m_nAllocationCount * sizeof(T), nAlignment);
CUtlMemory<T>::m_pMemory = (T*)MemAlloc_AllocAligned(
CUtlMemory<T>::m_nAllocationCount * sizeof(T), nAlignment);
}
}
//-----------------------------------------------------------------------------
// Makes sure we've got at least this much memory
//-----------------------------------------------------------------------------
template< class T, int nAlignment >
inline void CUtlMemoryAligned<T, nAlignment>::EnsureCapacity(int num)
{
if(CUtlMemory<T>::m_nAllocationCount >= num)
return;
template <class T, int nAlignment>
inline void CUtlMemoryAligned<T, nAlignment>::EnsureCapacity(int num) {
if (CUtlMemory<T>::m_nAllocationCount >= num) return;
if(this->IsExternallyAllocated()) {
// Can't grow a buffer whose memory was externally allocated
if (this->IsExternallyAllocated()) {
// Can't grow a buffer whose memory was externally allocated
return;
}
@@ -646,28 +618,131 @@ inline void CUtlMemoryAligned<T, nAlignment>::EnsureCapacity(int num)
UTLMEMORY_TRACK_ALLOC();
if(CUtlMemory<T>::m_pMemory) {
if (CUtlMemory<T>::m_pMemory) {
MEM_ALLOC_CREDIT_CLASS();
CUtlMemory<T>::m_pMemory = (T*)MemAlloc_ReallocAligned(CUtlMemory<T>::m_pMemory, CUtlMemory<T>::m_nAllocationCount * sizeof(T), nAlignment);
CUtlMemory<T>::m_pMemory = (T*)MemAlloc_ReallocAligned(
CUtlMemory<T>::m_pMemory,
CUtlMemory<T>::m_nAllocationCount * sizeof(T), nAlignment);
} else {
MEM_ALLOC_CREDIT_CLASS();
CUtlMemory<T>::m_pMemory = (T*)MemAlloc_AllocAligned(CUtlMemory<T>::m_nAllocationCount * sizeof(T), nAlignment);
CUtlMemory<T>::m_pMemory = (T*)MemAlloc_AllocAligned(
CUtlMemory<T>::m_nAllocationCount * sizeof(T), nAlignment);
}
}
//-----------------------------------------------------------------------------
// Memory deallocation
//-----------------------------------------------------------------------------
template< class T, int nAlignment >
void CUtlMemoryAligned<T, nAlignment>::Purge()
{
if(!this->IsExternallyAllocated()) {
if(CUtlMemory<T>::m_pMemory) {
template <class T, int nAlignment>
void CUtlMemoryAligned<T, nAlignment>::Purge() {
if (!this->IsExternallyAllocated()) {
if (CUtlMemory<T>::m_pMemory) {
UTLMEMORY_TRACK_FREE();
MemAlloc_FreeAligned(CUtlMemory<T>::m_pMemory);
CUtlMemory<T>::m_pMemory = 0;
}
CUtlMemory<T>::m_nAllocationCount = 0;
}
}
}
//-----------------------------------------------------------------------------
// The CUtlMemoryFixed class:
// A fixed memory class
//-----------------------------------------------------------------------------
template <typename T, size_t SIZE, int nAlignment = 0>
class CUtlMemoryFixed {
public:
// constructor, destructor
CUtlMemoryFixed(int nGrowSize = 0, int nInitSize = 0) {
}
CUtlMemoryFixed(T* pMemory, int numElements) { ; }
// Can we use this index?
bool IsIdxValid(int i) const { return (i >= 0) && (i < SIZE); }
// Specify the invalid ('null') index that we'll only return on failure
static const int INVALID_INDEX = -1; // For use with COMPILE_TIME_ASSERT
static int InvalidIndex() { return INVALID_INDEX; }
// Gets the base address
T* Base() {
if (nAlignment == 0)
return (T*)(&m_Memory[0]);
else
return (T*)AlignValue(&m_Memory[0], nAlignment);
}
const T* Base() const {
if (nAlignment == 0)
return (T*)(&m_Memory[0]);
else
return (T*)AlignValue(&m_Memory[0], nAlignment);
}
// element access
T& operator[](int i) {
Assert(IsIdxValid(i));
return Base()[i];
}
const T& operator[](int i) const {
Assert(IsIdxValid(i));
return Base()[i];
}
T& Element(int i) {
Assert(IsIdxValid(i));
return Base()[i];
}
const T& Element(int i) const {
Assert(IsIdxValid(i));
return Base()[i];
}
// Attaches the buffer to external memory....
void SetExternalBuffer(T* pMemory, int numElements) { }
// Size
int NumAllocated() const { return SIZE; }
int Count() const { return SIZE; }
// Grows the memory, so that at least allocated + num elements are allocated
void Grow(int num = 1) { Assert(0); }
// Makes sure we've got at least this much memory
void EnsureCapacity(int num) { Assert(num <= SIZE); }
// Memory deallocation
void Purge() {}
// Purge all but the given number of elements (NOT IMPLEMENTED IN
// CUtlMemoryFixed)
void Purge(int numElements) { Assert(0); }
// is the memory externally allocated?
bool IsExternallyAllocated() const { return false; }
// Set the size by which the memory grows
void SetGrowSize(int size) {}
class Iterator_t {
public:
Iterator_t(int i) : index(i) {}
int index;
bool operator==(const Iterator_t it) const { return index == it.index; }
bool operator!=(const Iterator_t it) const { return index != it.index; }
};
Iterator_t First() const {
return Iterator_t(IsIdxValid(0) ? 0 : InvalidIndex());
}
Iterator_t Next(const Iterator_t& it) const {
return Iterator_t(IsIdxValid(it.index + 1) ? it.index + 1
: InvalidIndex());
}
int GetIndex(const Iterator_t& it) const { return it.index; }
bool IsIdxAfter(int i, const Iterator_t& it) const { return i > it.index; }
bool IsValidIterator(const Iterator_t& it) const {
return IsIdxValid(it.index);
}
Iterator_t InvalidIterator() const { return Iterator_t(InvalidIndex()); }
private:
char m_Memory[SIZE * sizeof(T) + nAlignment];
};

View File

@@ -1,21 +1,18 @@
#pragma once
#include <stdint.h>
#include <cstring>
#include "UtlMemory.hpp"
#include "../sdk.h"
#define _Utl_Vector_assert
template <class T>
inline T* CopyConstruct(T* pMemory, T const& src)
{
return ::new(pMemory) T(src);
inline T* CopyConstruct(T* pMemory, T const& src) {
return ::new (pMemory) T(src);
}
template< class T, class A = CUtlMemory<T> >
class CUtlVector
{
typedef T *iterator;
typedef const T *const_iterator;
template <class T, class A = CUtlMemory<T> >
class CUtlVector {
typedef T* iterator;
typedef const T* const_iterator;
typedef A CAllocator;
public:
public:
typedef T ElemType_t;
// constructor, destructor
@@ -24,7 +21,7 @@ public:
~CUtlVector();
// Copy the array.
CUtlVector<T, A>& operator=(const CUtlVector<T, A> &other);
CUtlVector<T, A>& operator=(const CUtlVector<T, A>& other);
// element access
T& operator[](int i);
@@ -57,52 +54,60 @@ public:
// Adds multiple elements, uses default constructor
int AddMultipleToHead(int num);
int AddMultipleToTail(int num);
int AddMultipleToTail(int num, const T *pToCopy);
int AddMultipleToTail(int num, const T* pToCopy);
int InsertMultipleBefore(int elem, int num);
int InsertMultipleBefore(int elem, int num, const T *pToCopy);
int InsertMultipleBefore(int elem, int num, const T* pToCopy);
int InsertMultipleAfter(int elem, int num);
// Calls RemoveAll() then AddMultipleToTail.
void SetSize(int size);
void SetCount(int count);
void SetCountNonDestructively(int count); //sets count by adding or removing elements to tail TODO: This should probably be the default behavior for SetCount
void CopyArray(const T *pArray, int size); //Calls SetSize and copies each element.
// Fast swap
void Swap(CUtlVector< T, A > &vec);
void SetCountNonDestructively(
int count); // sets count by adding or removing elements to tail TODO:
// This should probably be the default behavior for
// SetCount
void CopyArray(const T* pArray,
int size); // Calls SetSize and copies each element.
// Fast swap
void Swap(CUtlVector<T, A>& vec);
// Add the specified array to the tail.
int AddVectorToTail(CUtlVector<T, A> const &src);
int AddVectorToTail(CUtlVector<T, A> const& src);
// Finds an element (element needs operator== defined)
int GetOffset(const T& src) const;
void FillWithValue(const T& src);
bool HasElement(const T& src) const;
// Makes sure we have enough memory allocated to store a requested # of elements
// Makes sure we have enough memory allocated to store a requested # of
// elements
void EnsureCapacity(int num);
// Makes sure we have at least this many elements
void EnsureCount(int num);
// Element removal
void FastRemove(int elem); // doesn't preserve order
void Remove(int elem); // preserves order, shifts elements
bool FindAndRemove(const T& src); // removes first occurrence of src, preserves order, shifts elements
bool FindAndFastRemove(const T& src); // removes first occurrence of src, doesn't preserve order
void RemoveMultiple(int elem, int num); // preserves order, shifts elements
void RemoveMultipleFromHead(int num); // removes num elements from tail
void RemoveMultipleFromTail(int num); // removes num elements from tail
void RemoveAll(); // doesn't deallocate memory
void Purge(); // Memory deallocation
// Purges the list and calls delete on each element in it.
void FastRemove(int elem); // doesn't preserve order
void Remove(int elem); // preserves order, shifts elements
bool FindAndRemove(const T& src); // removes first occurrence of src,
// preserves order, shifts elements
bool FindAndFastRemove(const T& src); // removes first occurrence of src,
// doesn't preserve order
void RemoveMultiple(int elem, int num); // preserves order, shifts elements
void RemoveMultipleFromHead(int num); // removes num elements from tail
void RemoveMultipleFromTail(int num); // removes num elements from tail
void RemoveAll(); // doesn't deallocate memory
void Purge(); // Memory deallocation
// Purges the list and calls delete on each element in it.
void PurgeAndDeleteElements();
// Compacts the vector to the number of elements actually in use
// Compacts the vector to the number of elements actually in use
void Compact();
// Set the size by which it grows when it needs to allocate more memory.
void SetGrowSize(int size) { m_Memory.SetGrowSize(size); }
int NumAllocated() const; // Only use this if you really know what you're doing!
void Sort(int(__cdecl *pfnCompare)(const T *, const T *));
int NumAllocated()
const; // Only use this if you really know what you're doing!
void Sort(int(__cdecl* pfnCompare)(const T*, const T*));
iterator begin() { return Base(); }
const_iterator begin() const { return Base(); }
iterator end() { return Base() + Count(); }
const_iterator end() const { return Base() + Count(); }
iterator begin() { return Base(); }
const_iterator begin() const { return Base(); }
iterator end() { return Base() + Count(); }
const_iterator end() const { return Base() + Count(); }
protected:
protected:
// Can't copy this unless we explicitly do it!
CUtlVector(CUtlVector const& vec) { _Utl_Vector_assert(0); }
@@ -113,153 +118,130 @@ protected:
void ShiftElementsRight(int elem, int num = 1);
void ShiftElementsLeft(int elem, int num = 1);
public:
public:
CAllocator m_Memory;
int m_Size;
// For easier access to the elements through the debugger
// it's in release builds so this can be used in libraries correctly
T *m_pElements;
T* m_pElements;
inline void ResetDbgInfo()
{
m_pElements = Base();
}
inline void ResetDbgInfo() { m_pElements = Base(); }
};
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
template< typename T, class A >
inline CUtlVector<T, A>::CUtlVector(int growSize, int initSize) :
m_Memory(growSize, initSize), m_Size(0)
{
template <typename T, class A>
inline CUtlVector<T, A>::CUtlVector(int growSize, int initSize)
: m_Memory(growSize, initSize), m_Size(0) {
ResetDbgInfo();
}
template< typename T, class A >
inline CUtlVector<T, A>::CUtlVector(T* pMemory, int allocationCount, int numElements) :
m_Memory(pMemory, allocationCount), m_Size(numElements)
{
template <typename T, class A>
inline CUtlVector<T, A>::CUtlVector(T* pMemory, int allocationCount,
int numElements)
: m_Memory(pMemory, allocationCount), m_Size(numElements) {
ResetDbgInfo();
}
template< typename T, class A >
inline CUtlVector<T, A>::~CUtlVector()
{
template <typename T, class A>
inline CUtlVector<T, A>::~CUtlVector() {
Purge();
}
template< typename T, class A >
inline CUtlVector<T, A>& CUtlVector<T, A>::operator=(const CUtlVector<T, A> &other)
{
template <typename T, class A>
inline CUtlVector<T, A>& CUtlVector<T, A>::operator=(
const CUtlVector<T, A>& other) {
int nCount = other.Count();
SetSize(nCount);
for(int i = 0; i < nCount; i++) {
for (int i = 0; i < nCount; i++) {
(*this)[i] = other[i];
}
return *this;
}
//-----------------------------------------------------------------------------
// element access
//-----------------------------------------------------------------------------
template< typename T, class A >
inline T& CUtlVector<T, A>::operator[](int i)
{
template <typename T, class A>
inline T& CUtlVector<T, A>::operator[](int i) {
_Utl_Vector_assert(i < m_Size);
return m_Memory[i];
}
template< typename T, class A >
inline const T& CUtlVector<T, A>::operator[](int i) const
{
template <typename T, class A>
inline const T& CUtlVector<T, A>::operator[](int i) const {
_Utl_Vector_assert(i < m_Size);
return m_Memory[i];
}
template< typename T, class A >
inline T& CUtlVector<T, A>::Element(int i)
{
template <typename T, class A>
inline T& CUtlVector<T, A>::Element(int i) {
_Utl_Vector_assert(i < m_Size);
return m_Memory[i];
}
template< typename T, class A >
inline const T& CUtlVector<T, A>::Element(int i) const
{
template <typename T, class A>
inline const T& CUtlVector<T, A>::Element(int i) const {
_Utl_Vector_assert(i < m_Size);
return m_Memory[i];
}
template< typename T, class A >
inline T& CUtlVector<T, A>::Head()
{
template <typename T, class A>
inline T& CUtlVector<T, A>::Head() {
_Utl_Vector_assert(m_Size > 0);
return m_Memory[0];
}
template< typename T, class A >
inline const T& CUtlVector<T, A>::Head() const
{
template <typename T, class A>
inline const T& CUtlVector<T, A>::Head() const {
_Utl_Vector_assert(m_Size > 0);
return m_Memory[0];
}
template< typename T, class A >
inline T& CUtlVector<T, A>::Tail()
{
template <typename T, class A>
inline T& CUtlVector<T, A>::Tail() {
_Utl_Vector_assert(m_Size > 0);
return m_Memory[m_Size - 1];
}
template< typename T, class A >
inline const T& CUtlVector<T, A>::Tail() const
{
template <typename T, class A>
inline const T& CUtlVector<T, A>::Tail() const {
_Utl_Vector_assert(m_Size > 0);
return m_Memory[m_Size - 1];
}
//-----------------------------------------------------------------------------
// Count
//-----------------------------------------------------------------------------
template< typename T, class A >
inline int CUtlVector<T, A>::Count() const
{
template <typename T, class A>
inline int CUtlVector<T, A>::Count() const {
return m_Size;
}
//-----------------------------------------------------------------------------
// Is element index valid?
//-----------------------------------------------------------------------------
template< typename T, class A >
inline bool CUtlVector<T, A>::IsValidIndex(int i) const
{
template <typename T, class A>
inline bool CUtlVector<T, A>::IsValidIndex(int i) const {
return (i >= 0) && (i < m_Size);
}
//-----------------------------------------------------------------------------
// Returns in invalid index
//-----------------------------------------------------------------------------
template< typename T, class A >
inline int CUtlVector<T, A>::InvalidIndex()
{
template <typename T, class A>
inline int CUtlVector<T, A>::InvalidIndex() {
return -1;
}
//-----------------------------------------------------------------------------
// Grows the vector
//-----------------------------------------------------------------------------
template< typename T, class A >
void CUtlVector<T, A>::GrowVector(int num)
{
if(m_Size + num > m_Memory.NumAllocated()) {
template <typename T, class A>
void CUtlVector<T, A>::GrowVector(int num) {
if (m_Size + num > m_Memory.NumAllocated()) {
m_Memory.Grow(m_Size + num - m_Memory.NumAllocated());
}
@@ -267,29 +249,27 @@ void CUtlVector<T, A>::GrowVector(int num)
ResetDbgInfo();
}
//-----------------------------------------------------------------------------
// Sorts the vector
//-----------------------------------------------------------------------------
template< typename T, class A >
void CUtlVector<T, A>::Sort(int(__cdecl *pfnCompare)(const T *, const T *))
{
typedef int(__cdecl *QSortCompareFunc_t)(const void *, const void *);
if(Count() <= 1)
return;
template <typename T, class A>
void CUtlVector<T, A>::Sort(int(__cdecl* pfnCompare)(const T*, const T*)) {
typedef int(__cdecl * QSortCompareFunc_t)(const void*, const void*);
if (Count() <= 1) return;
if(Base()) {
if (Base()) {
qsort(Base(), Count(), sizeof(T), (QSortCompareFunc_t)(pfnCompare));
} else {
_Utl_Vector_assert(0);
// this path is untested
// if you want to sort vectors that use a non-sequential memory allocator,
// you'll probably want to patch in a quicksort algorithm here
// I just threw in this bubble sort to have something just in case...
// if you want to sort vectors that use a non-sequential memory
// allocator, you'll probably want to patch in a quicksort algorithm
// here I just threw in this bubble sort to have something just in
// case...
for(int i = m_Size - 1; i >= 0; --i) {
for(int j = 1; j <= i; ++j) {
if(pfnCompare(&Element(j - 1), &Element(j)) < 0) {
for (int i = m_Size - 1; i >= 0; --i) {
for (int j = 1; j <= i; ++j) {
if (pfnCompare(&Element(j - 1), &Element(j)) < 0) {
V_swap(Element(j - 1), Element(j));
}
}
@@ -300,45 +280,39 @@ void CUtlVector<T, A>::Sort(int(__cdecl *pfnCompare)(const T *, const T *))
//-----------------------------------------------------------------------------
// Makes sure we have enough memory allocated to store a requested # of elements
//-----------------------------------------------------------------------------
template< typename T, class A >
void CUtlVector<T, A>::EnsureCapacity(int num)
{
template <typename T, class A>
void CUtlVector<T, A>::EnsureCapacity(int num) {
MEM_ALLOC_CREDIT_CLASS();
m_Memory.EnsureCapacity(num);
ResetDbgInfo();
}
//-----------------------------------------------------------------------------
// Makes sure we have at least this many elements
//-----------------------------------------------------------------------------
template< typename T, class A >
void CUtlVector<T, A>::EnsureCount(int num)
{
if(Count() < num) {
template <typename T, class A>
void CUtlVector<T, A>::EnsureCount(int num) {
if (Count() < num) {
AddMultipleToTail(num - Count());
}
}
//-----------------------------------------------------------------------------
// Shifts elements
//-----------------------------------------------------------------------------
template< typename T, class A >
void CUtlVector<T, A>::ShiftElementsRight(int elem, int num)
{
template <typename T, class A>
void CUtlVector<T, A>::ShiftElementsRight(int elem, int num) {
_Utl_Vector_assert(IsValidIndex(elem) || (m_Size == 0) || (num == 0));
int numToMove = m_Size - elem - num;
if((numToMove > 0) && (num > 0))
if ((numToMove > 0) && (num > 0))
memmove(&Element(elem + num), &Element(elem), numToMove * sizeof(T));
}
template< typename T, class A >
void CUtlVector<T, A>::ShiftElementsLeft(int elem, int num)
{
template <typename T, class A>
void CUtlVector<T, A>::ShiftElementsLeft(int elem, int num) {
_Utl_Vector_assert(IsValidIndex(elem) || (m_Size == 0) || (num == 0));
int numToMove = m_Size - elem - num;
if((numToMove > 0) && (num > 0)) {
if ((numToMove > 0) && (num > 0)) {
memmove(&Element(elem), &Element(elem + num), numToMove * sizeof(T));
#ifdef _DEBUG
@@ -347,31 +321,26 @@ void CUtlVector<T, A>::ShiftElementsLeft(int elem, int num)
}
}
//-----------------------------------------------------------------------------
// Adds an element, uses default constructor
//-----------------------------------------------------------------------------
template< typename T, class A >
inline int CUtlVector<T, A>::AddToHead()
{
template <typename T, class A>
inline int CUtlVector<T, A>::AddToHead() {
return InsertBefore(0);
}
template< typename T, class A >
inline int CUtlVector<T, A>::AddToTail()
{
template <typename T, class A>
inline int CUtlVector<T, A>::AddToTail() {
return InsertBefore(m_Size);
}
template< typename T, class A >
inline int CUtlVector<T, A>::InsertAfter(int elem)
{
template <typename T, class A>
inline int CUtlVector<T, A>::InsertAfter(int elem) {
return InsertBefore(elem + 1);
}
template< typename T, class A >
int CUtlVector<T, A>::InsertBefore(int elem)
{
template <typename T, class A>
int CUtlVector<T, A>::InsertBefore(int elem) {
// Can insert at the end
_Utl_Vector_assert((elem == Count()) || IsValidIndex(elem));
@@ -381,39 +350,38 @@ int CUtlVector<T, A>::InsertBefore(int elem)
return elem;
}
//-----------------------------------------------------------------------------
// Adds an element, uses copy constructor
//-----------------------------------------------------------------------------
template< typename T, class A >
inline int CUtlVector<T, A>::AddToHead(const T& src)
{
template <typename T, class A>
inline int CUtlVector<T, A>::AddToHead(const T& src) {
// Can't insert something that's in the list... reallocation may hose us
_Utl_Vector_assert((Base() == NULL) || (&src < Base()) || (&src >= (Base() + Count())));
_Utl_Vector_assert((Base() == NULL) || (&src < Base()) ||
(&src >= (Base() + Count())));
return InsertBefore(0, src);
}
template< typename T, class A >
inline int CUtlVector<T, A>::AddToTail(const T& src)
{
template <typename T, class A>
inline int CUtlVector<T, A>::AddToTail(const T& src) {
// Can't insert something that's in the list... reallocation may hose us
_Utl_Vector_assert((Base() == NULL) || (&src < Base()) || (&src >= (Base() + Count())));
_Utl_Vector_assert((Base() == NULL) || (&src < Base()) ||
(&src >= (Base() + Count())));
return InsertBefore(m_Size, src);
}
template< typename T, class A >
inline int CUtlVector<T, A>::InsertAfter(int elem, const T& src)
{
template <typename T, class A>
inline int CUtlVector<T, A>::InsertAfter(int elem, const T& src) {
// Can't insert something that's in the list... reallocation may hose us
_Utl_Vector_assert((Base() == NULL) || (&src < Base()) || (&src >= (Base() + Count())));
_Utl_Vector_assert((Base() == NULL) || (&src < Base()) ||
(&src >= (Base() + Count())));
return InsertBefore(elem + 1, src);
}
template< typename T, class A >
int CUtlVector<T, A>::InsertBefore(int elem, const T& src)
{
template <typename T, class A>
int CUtlVector<T, A>::InsertBefore(int elem, const T& src) {
// Can't insert something that's in the list... reallocation may hose us
_Utl_Vector_assert((Base() == NULL) || (&src < Base()) || (&src >= (Base() + Count())));
_Utl_Vector_assert((Base() == NULL) || (&src < Base()) ||
(&src >= (Base() + Count())));
// Can insert at the end
_Utl_Vector_assert((elem == Count()) || IsValidIndex(elem));
@@ -424,74 +392,69 @@ int CUtlVector<T, A>::InsertBefore(int elem, const T& src)
return elem;
}
//-----------------------------------------------------------------------------
// Adds multiple elements, uses default constructor
//-----------------------------------------------------------------------------
template< typename T, class A >
inline int CUtlVector<T, A>::AddMultipleToHead(int num)
{
template <typename T, class A>
inline int CUtlVector<T, A>::AddMultipleToHead(int num) {
return InsertMultipleBefore(0, num);
}
template< typename T, class A >
inline int CUtlVector<T, A>::AddMultipleToTail(int num)
{
template <typename T, class A>
inline int CUtlVector<T, A>::AddMultipleToTail(int num) {
return InsertMultipleBefore(m_Size, num);
}
template< typename T, class A >
inline int CUtlVector<T, A>::AddMultipleToTail(int num, const T *pToCopy)
{
template <typename T, class A>
inline int CUtlVector<T, A>::AddMultipleToTail(int num, const T* pToCopy) {
// Can't insert something that's in the list... reallocation may hose us
_Utl_Vector_assert((Base() == NULL) || !pToCopy || (pToCopy + num <= Base()) || (pToCopy >= (Base() + Count())));
_Utl_Vector_assert((Base() == NULL) || !pToCopy ||
(pToCopy + num <= Base()) ||
(pToCopy >= (Base() + Count())));
return InsertMultipleBefore(m_Size, num, pToCopy);
}
template< typename T, class A >
int CUtlVector<T, A>::InsertMultipleAfter(int elem, int num)
{
template <typename T, class A>
int CUtlVector<T, A>::InsertMultipleAfter(int elem, int num) {
return InsertMultipleBefore(elem + 1, num);
}
template< typename T, class A >
void CUtlVector<T, A>::SetCount(int count)
{
template <typename T, class A>
void CUtlVector<T, A>::SetCount(int count) {
RemoveAll();
AddMultipleToTail(count);
}
template< typename T, class A >
inline void CUtlVector<T, A>::SetSize(int size)
{
template <typename T, class A>
inline void CUtlVector<T, A>::SetSize(int size) {
SetCount(size);
}
template< typename T, class A >
void CUtlVector<T, A>::SetCountNonDestructively(int count)
{
template <typename T, class A>
void CUtlVector<T, A>::SetCountNonDestructively(int count) {
int delta = count - m_Size;
if(delta > 0) AddMultipleToTail(delta);
else if(delta < 0) RemoveMultipleFromTail(-delta);
if (delta > 0)
AddMultipleToTail(delta);
else if (delta < 0)
RemoveMultipleFromTail(-delta);
}
template< typename T, class A >
void CUtlVector<T, A>::CopyArray(const T *pArray, int size)
{
template <typename T, class A>
void CUtlVector<T, A>::CopyArray(const T* pArray, int size) {
// Can't insert something that's in the list... reallocation may hose us
_Utl_Vector_assert((Base() == NULL) || !pArray || (Base() >= (pArray + size)) || (pArray >= (Base() + Count())));
_Utl_Vector_assert((Base() == NULL) || !pArray ||
(Base() >= (pArray + size)) ||
(pArray >= (Base() + Count())));
SetSize(size);
for(int i = 0; i < size; i++) {
for (int i = 0; i < size; i++) {
(*this)[i] = pArray[i];
}
}
template< typename T, class A >
void CUtlVector<T, A>::Swap(CUtlVector< T, A > &vec)
{
template <typename T, class A>
void CUtlVector<T, A>::Swap(CUtlVector<T, A>& vec) {
m_Memory.Swap(vec.m_Memory);
V_swap(m_Size, vec.m_Size);
#ifndef _X360
@@ -499,9 +462,8 @@ void CUtlVector<T, A>::Swap(CUtlVector< T, A > &vec)
#endif
}
template< typename T, class A >
int CUtlVector<T, A>::AddVectorToTail(CUtlVector const &src)
{
template <typename T, class A>
int CUtlVector<T, A>::AddVectorToTail(CUtlVector const& src) {
_Utl_Vector_assert(&src != this);
int base = Count();
@@ -510,19 +472,17 @@ int CUtlVector<T, A>::AddVectorToTail(CUtlVector const &src)
int nSrcCount = src.Count();
EnsureCapacity(base + nSrcCount);
// Copy the elements.
// Copy the elements.
m_Size += nSrcCount;
for(int i = 0; i < nSrcCount; i++) {
for (int i = 0; i < nSrcCount; i++) {
CopyConstruct(&Element(base + i), src[i]);
}
return base;
}
template< typename T, class A >
inline int CUtlVector<T, A>::InsertMultipleBefore(int elem, int num)
{
if(num == 0)
return elem;
template <typename T, class A>
inline int CUtlVector<T, A>::InsertMultipleBefore(int elem, int num) {
if (num == 0) return elem;
// Can insert at the end
_Utl_Vector_assert((elem == Count()) || IsValidIndex(elem));
@@ -531,18 +491,17 @@ inline int CUtlVector<T, A>::InsertMultipleBefore(int elem, int num)
ShiftElementsRight(elem, num);
// Invoke default constructors
for(int i = 0; i < num; ++i) {
for (int i = 0; i < num; ++i) {
Construct(&Element(elem + i));
}
return elem;
}
template< typename T, class A >
inline int CUtlVector<T, A>::InsertMultipleBefore(int elem, int num, const T *pToInsert)
{
if(num == 0)
return elem;
template <typename T, class A>
inline int CUtlVector<T, A>::InsertMultipleBefore(int elem, int num,
const T* pToInsert) {
if (num == 0) return elem;
// Can insert at the end
_Utl_Vector_assert((elem == Count()) || IsValidIndex(elem));
@@ -551,12 +510,12 @@ inline int CUtlVector<T, A>::InsertMultipleBefore(int elem, int num, const T *pT
ShiftElementsRight(elem, num);
// Invoke default constructors
if(!pToInsert) {
for(int i = 0; i < num; ++i) {
if (!pToInsert) {
for (int i = 0; i < num; ++i) {
Construct(&Element(elem + i));
}
} else {
for(int i = 0; i < num; i++) {
for (int i = 0; i < num; i++) {
CopyConstruct(&Element(elem + i), pToInsert[i]);
}
}
@@ -564,204 +523,215 @@ inline int CUtlVector<T, A>::InsertMultipleBefore(int elem, int num, const T *pT
return elem;
}
//-----------------------------------------------------------------------------
// Finds an element (element needs operator== defined)
//-----------------------------------------------------------------------------
template< typename T, class A >
int CUtlVector<T, A>::GetOffset(const T& src) const
{
for(int i = 0; i < Count(); ++i) {
if(Element(i) == src)
return i;
template <typename T, class A>
int CUtlVector<T, A>::GetOffset(const T& src) const {
for (int i = 0; i < Count(); ++i) {
if (Element(i) == src) return i;
}
return -1;
}
template< typename T, class A >
void CUtlVector<T, A>::FillWithValue(const T& src)
{
for(int i = 0; i < Count(); i++) {
template <typename T, class A>
void CUtlVector<T, A>::FillWithValue(const T& src) {
for (int i = 0; i < Count(); i++) {
Element(i) = src;
}
}
template< typename T, class A >
bool CUtlVector<T, A>::HasElement(const T& src) const
{
template <typename T, class A>
bool CUtlVector<T, A>::HasElement(const T& src) const {
return (GetOffset(src) >= 0);
}
//-----------------------------------------------------------------------------
// Element removal
//-----------------------------------------------------------------------------
template< typename T, class A >
void CUtlVector<T, A>::FastRemove(int elem)
{
template <typename T, class A>
void CUtlVector<T, A>::FastRemove(int elem) {
_Utl_Vector_assert(IsValidIndex(elem));
Destruct(&Element(elem));
if(m_Size > 0) {
if(elem != m_Size - 1)
if (m_Size > 0) {
if (elem != m_Size - 1)
memcpy(&Element(elem), &Element(m_Size - 1), sizeof(T));
--m_Size;
}
}
template< typename T, class A >
void CUtlVector<T, A>::Remove(int elem)
{
template <typename T, class A>
void CUtlVector<T, A>::Remove(int elem) {
Destruct(&Element(elem));
ShiftElementsLeft(elem);
--m_Size;
}
template< typename T, class A >
bool CUtlVector<T, A>::FindAndRemove(const T& src)
{
template <typename T, class A>
bool CUtlVector<T, A>::FindAndRemove(const T& src) {
int elem = GetOffset(src);
if(elem != -1) {
if (elem != -1) {
Remove(elem);
return true;
}
return false;
}
template< typename T, class A >
bool CUtlVector<T, A>::FindAndFastRemove(const T& src)
{
template <typename T, class A>
bool CUtlVector<T, A>::FindAndFastRemove(const T& src) {
int elem = GetOffset(src);
if(elem != -1) {
if (elem != -1) {
FastRemove(elem);
return true;
}
return false;
}
template< typename T, class A >
void CUtlVector<T, A>::RemoveMultiple(int elem, int num)
{
template <typename T, class A>
void CUtlVector<T, A>::RemoveMultiple(int elem, int num) {
_Utl_Vector_assert(elem >= 0);
_Utl_Vector_assert(elem + num <= Count());
for(int i = elem + num; --i >= elem; )
Destruct(&Element(i));
for (int i = elem + num; --i >= elem;) Destruct(&Element(i));
ShiftElementsLeft(elem, num);
m_Size -= num;
}
template< typename T, class A >
void CUtlVector<T, A>::RemoveMultipleFromHead(int num)
{
template <typename T, class A>
void CUtlVector<T, A>::RemoveMultipleFromHead(int num) {
_Utl_Vector_assert(num <= Count());
for(int i = num; --i >= 0; )
Destruct(&Element(i));
for (int i = num; --i >= 0;) Destruct(&Element(i));
ShiftElementsLeft(0, num);
m_Size -= num;
}
template< typename T, class A >
void CUtlVector<T, A>::RemoveMultipleFromTail(int num)
{
template <typename T, class A>
void CUtlVector<T, A>::RemoveMultipleFromTail(int num) {
_Utl_Vector_assert(num <= Count());
for(int i = m_Size - num; i < m_Size; i++)
Destruct(&Element(i));
for (int i = m_Size - num; i < m_Size; i++) Destruct(&Element(i));
m_Size -= num;
}
template< typename T, class A >
void CUtlVector<T, A>::RemoveAll()
{
for(int i = m_Size; --i >= 0; ) {
template <typename T, class A>
void CUtlVector<T, A>::RemoveAll() {
for (int i = m_Size; --i >= 0;) {
Destruct(&Element(i));
}
m_Size = 0;
}
//-----------------------------------------------------------------------------
// Memory deallocation
//-----------------------------------------------------------------------------
template< typename T, class A >
inline void CUtlVector<T, A>::Purge()
{
template <typename T, class A>
inline void CUtlVector<T, A>::Purge() {
RemoveAll();
m_Memory.Purge();
ResetDbgInfo();
}
template< typename T, class A >
inline void CUtlVector<T, A>::PurgeAndDeleteElements()
{
for(int i = 0; i < m_Size; i++) {
template <typename T, class A>
inline void CUtlVector<T, A>::PurgeAndDeleteElements() {
for (int i = 0; i < m_Size; i++) {
delete Element(i);
}
Purge();
}
template< typename T, class A >
inline void CUtlVector<T, A>::Compact()
{
template <typename T, class A>
inline void CUtlVector<T, A>::Compact() {
m_Memory.Purge(m_Size);
}
template< typename T, class A >
inline int CUtlVector<T, A>::NumAllocated() const
{
template <typename T, class A>
inline int CUtlVector<T, A>::NumAllocated() const {
return m_Memory.NumAllocated();
}
//-----------------------------------------------------------------------------
// Data and memory validation
//-----------------------------------------------------------------------------
#ifdef DBGFLAG_VALIDATE
template< typename T, class A >
void CUtlVector<T, A>::Validate(CValidator &validator, char *pchName)
{
template <typename T, class A>
void CUtlVector<T, A>::Validate(CValidator& validator, char* pchName) {
validator.Push(typeid(*this).name(), this, pchName);
m_Memory.Validate(validator, "m_Memory");
validator.Pop();
}
#endif // DBGFLAG_VALIDATE
#endif // DBGFLAG_VALIDATE
// A vector class for storing pointers, so that the elements pointed to by the pointers are deleted
// on exit.
template<class T> class CUtlVectorAutoPurge : public CUtlVector< T, CUtlMemory< T, int> >
{
public:
~CUtlVectorAutoPurge(void)
{
this->PurgeAndDeleteElements();
}
// A vector class for storing pointers, so that the elements pointed to by the
// pointers are deleted on exit.
template <class T>
class CUtlVectorAutoPurge : public CUtlVector<T, CUtlMemory<T, int> > {
public:
~CUtlVectorAutoPurge(void) { this->PurgeAndDeleteElements(); }
};
// easy string list class with dynamically allocated strings. For use with V_SplitString, etc.
// Frees the dynamic strings in destructor.
class CUtlStringList : public CUtlVectorAutoPurge< char *>
{
public:
void CopyAndAddToTail(char const *pString) // clone the string and add to the end
// easy string list class with dynamically allocated strings. For use with
// V_SplitString, etc. Frees the dynamic strings in destructor.
class CUtlStringList : public CUtlVectorAutoPurge<char*> {
public:
void CopyAndAddToTail(
char const* pString) // clone the string and add to the end
{
char *pNewStr = new char[1 + strlen(pString)];
char* pNewStr = new char[1 + strlen(pString)];
strcpy_s(pNewStr, 1 + strlen(pString), pString);
AddToTail(pNewStr);
}
static int __cdecl SortFunc(char * const * sz1, char * const * sz2)
{
static int __cdecl SortFunc(char* const* sz1, char* const* sz2) {
return strcmp(*sz1, *sz2);
}
};
template <class T, size_t MAX_SIZE>
class CUtlVectorFixed : public CUtlVector<T, CUtlMemoryFixed<T, MAX_SIZE> > {
typedef CUtlVector<T, CUtlMemoryFixed<T, MAX_SIZE> > BaseClass;
};
public:
// constructor, destructor
CUtlVectorFixed(int growSize = 0, int initSize = 0)
: BaseClass(growSize, initSize) {}
CUtlVectorFixed(T* pMemory, int numElements)
: BaseClass(pMemory, numElements) {}
};
template <class T, size_t SIZE, class I = int>
class CUtlMemoryFixedGrowable : public CUtlMemory<T, I> {
typedef CUtlMemory<T, I> BaseClass;
public:
CUtlMemoryFixedGrowable(int nGrowSize = 0, int nInitSize = SIZE)
: BaseClass(m_pFixedMemory, SIZE) {
Assert(nInitSize == 0 || nInitSize == SIZE);
}
void EnsureCapacity(int num) {
if (CUtlMemory<T>::m_nAllocationCount >= num) return;
BaseClass::EnsureCapacity(num);
}
private:
T m_pFixedMemory[SIZE];
};
template <class T, size_t MAX_SIZE>
class CUtlVectorFixedGrowable
: public CUtlVector<T, CUtlMemoryFixedGrowable<T, MAX_SIZE> > {
typedef CUtlVector<T, CUtlMemoryFixedGrowable<T, MAX_SIZE> > BaseClass;
public:
// constructor, destructor
CUtlVectorFixedGrowable(int growSize = 0) : BaseClass(growSize, MAX_SIZE) {}
};

View File

@@ -0,0 +1,8 @@
//========= Copyright <20> 1996-2006, Valve LLC, All rights reserved. ============
//
// Purpose: Low level byte swapping routines.
//
// $NoKeywords: $
//=============================================================================
#include "cbyteswap.h"

492
csgo2/sdk/tier1/cbyteswap.h Normal file
View File

@@ -0,0 +1,492 @@
//========= Copyright ?1996-2006, Valve LLC, All rights reserved. ============
//
// Purpose: Low level byte swapping routines.
//
// $NoKeywords: $
//=============================================================================
#ifndef BYTESWAP_H
#define BYTESWAP_H
#if defined(_WIN32)
#pragma once
#endif
#include "../sdk.h"
typedef enum _fieldtypes {
FIELD_VOID = 0, // No type or value
FIELD_FLOAT, // Any floating point value
FIELD_STRING, // A string ID (return from ALLOC_STRING)
FIELD_VECTOR, // Any vector, QAngle, or AngularImpulse
FIELD_QUATERNION, // A quaternion
FIELD_INTEGER, // Any integer or enum
FIELD_BOOLEAN, // boolean, implemented as an int, I may use this as a hint
// for compression
FIELD_SHORT, // 2 byte integer
FIELD_CHARACTER, // a byte
FIELD_COLOR32, // 8-bit per channel r,g,b,a (32bit color)
FIELD_EMBEDDED, // an embedded object with a datadesc, recursively traverse
// and embedded class/structure based on an additional
// typedescription
FIELD_CUSTOM, // special type that contains function pointers to it's
// read/write/parse functions
FIELD_CLASSPTR, // CBaseEntity *
FIELD_EHANDLE, // Entity handle
FIELD_POSITION_VECTOR, // A world coordinate (these are fixed up across
// level transitions automagically)
FIELD_TIME, // a floating point time (these are fixed up automatically
// too!)
FIELD_TICK, // an integer tick count( fixed up similarly to time)
FIELD_SOUNDNAME, // Engine string that is a sound name (needs precache)
FIELD_INPUT, // a list of inputed data fields (all derived from
// CMultiInputVar)
FIELD_FUNCTION, // A class function pointer (Think, Use, etc)
FIELD_VMATRIX, // a vmatrix (output coords are NOT worldspace)
// NOTE: Use float arrays for local transformations that don't need to be
// fixed up.
FIELD_VMATRIX_WORLDSPACE, // A VMatrix that maps some local space to world
// space (translation is fixed up on level
// transitions)
FIELD_MATRIX3X4_WORLDSPACE, // matrix3x4_t that maps some local space to
// world space (translation is fixed up on
// level transitions)
FIELD_INTERVAL, // a start and range floating point interval (
// e.g., 3.2->3.6 == 3.2 and 0.4 )
FIELD_UNUSED,
FIELD_VECTOR2D, // 2 floats
FIELD_INTEGER64, // 64bit integer
FIELD_VECTOR4D, // 4 floats
FIELD_RESOURCE,
FIELD_TYPEUNKNOWN,
FIELD_CSTRING,
FIELD_HSCRIPT,
FIELD_VARIANT,
FIELD_UINT64,
FIELD_FLOAT64,
FIELD_POSITIVEINTEGER_OR_NULL,
FIELD_HSCRIPT_NEW_INSTANCE,
FIELD_UINT,
FIELD_UTLSTRINGTOKEN,
FIELD_QANGLE,
FIELD_NETWORK_ORIGIN_CELL_QUANTIZED_VECTOR,
FIELD_HMATERIAL,
FIELD_HMODEL,
FIELD_NETWORK_QUANTIZED_VECTOR,
FIELD_NETWORK_QUANTIZED_FLOAT,
FIELD_DIRECTION_VECTOR_WORLDSPACE,
FIELD_QANGLE_WORLDSPACE,
FIELD_QUATERNION_WORLDSPACE,
FIELD_HSCRIPT_LIGHTBINDING,
FIELD_V8_VALUE,
FIELD_V8_OBJECT,
FIELD_V8_ARRAY,
FIELD_V8_CALLBACK_INFO,
FIELD_UTLSTRING,
FIELD_NETWORK_ORIGIN_CELL_QUANTIZED_POSITION_VECTOR,
FIELD_HRENDERTEXTURE,
FIELD_HPARTICLESYSTEMDEFINITION,
FIELD_UINT8,
FIELD_UINT16,
FIELD_CTRANSFORM,
FIELD_CTRANSFORM_WORLDSPACE,
FIELD_HPOSTPROCESSING,
FIELD_MATRIX3X4,
FIELD_SHIM,
FIELD_CMOTIONTRANSFORM,
FIELD_CMOTIONTRANSFORM_WORLDSPACE,
FIELD_ATTACHMENT_HANDLE,
FIELD_AMMO_INDEX,
FIELD_CONDITION_ID,
FIELD_AI_SCHEDULE_BITS,
FIELD_MODIFIER_HANDLE,
FIELD_ROTATION_VECTOR,
FIELD_ROTATION_VECTOR_WORLDSPACE,
FIELD_HVDATA,
FIELD_SCALE32,
FIELD_STRING_AND_TOKEN,
FIELD_ENGINE_TIME,
FIELD_ENGINE_TICK,
FIELD_WORLD_GROUP_ID,
FIELD_TYPECOUNT
} fieldtype_t;
struct inputdata_t;
class ISaveRestoreOps;
typedef void(__fastcall *inputfunc_t)(inputdata_t &data);
enum {
PC_NON_NETWORKED_ONLY = 0,
PC_NETWORKED_ONLY,
PC_COPYTYPE_COUNT,
PC_EVERYTHING = PC_COPYTYPE_COUNT,
};
enum {
TD_OFFSET_NORMAL = 0,
TD_OFFSET_PACKED = 1,
// Must be last
TD_OFFSET_COUNT,
};
struct datarun_t;
struct typedescription_t;
struct datacopyruns_t
{
public:
CUtlVector< datarun_t > m_vecRuns;
};
struct flattenedoffsets_t
{
CUtlVector< typedescription_t > m_Flattened;
int m_nPackedSize; // Contiguous memory to pack all of these together for TD_OFFSET_PACKED
int m_nPackedStartOffset;
};
struct datamapinfo_t
{
// Flattened list, with FIELD_EMBEDDED, FTYPEDESC_PRIVATE,
// and FTYPEDESC_OVERRIDE (overridden) fields removed
flattenedoffsets_t m_Flat;
datacopyruns_t m_CopyRuns;
};
struct optimized_datamap_t
{
// Optimized info for PC_NON_NETWORKED and PC_NETWORKED data
datamapinfo_t m_Info[PC_COPYTYPE_COUNT];
};
struct datamap_t
{
typedescription_t* dataDesc;
int dataNumFields;
char const* dataClassName;
datamap_t* baseMap;
int m_nPackedSize;
optimized_datamap_t* m_pOptimizedDataMap;
#if defined( _DEBUG )
bool bValidityChecked;
#endif // _DEBUG
};
struct typedescription_t {
fieldtype_t fieldType;
const char *fieldName;
int fieldOffset; // Local offset value
unsigned short fieldSize;
short flags;
// the name of the variable in the map/fgd data, or the name of the action
const char *externalName;
// pointer to the function set for save/restoring of custom data types
ISaveRestoreOps *pSaveRestoreOps;
// for associating function with string names
inputfunc_t inputFunc;
// For embedding additional datatables inside this one
datamap_t *td;
// Stores the actual member variable size in bytes
int fieldSizeInBytes;
// FTYPEDESC_OVERRIDE point to first baseclass instance if chains_validated
// has occurred
struct typedescription_t *override_field;
// Used to track exclusion of baseclass fields
int override_count;
// Tolerance for field errors for float fields
float fieldTolerance;
// For raw fields (including children of embedded stuff) this is the
// flattened offset
int flatOffset[TD_OFFSET_COUNT];
unsigned short flatGroup;
};
struct datarun_t
{
datarun_t() : m_nStartFlatField(0), m_nEndFlatField(0), m_nLength(0)
{
for (int i = 0; i < TD_OFFSET_COUNT; ++i)
{
m_nStartOffset[i] = 0;
}
}
// Indices of start/end fields in the flattened typedescription_t list
int m_nStartFlatField;
int m_nEndFlatField;
// Offsets for run in the packed/unpacked data (I think the run starts need to be properly aligned)
int m_nStartOffset[TD_OFFSET_COUNT];
int m_nLength;
};
class CByteswap {
public:
CByteswap() {
// Default behavior sets the target endian to match the machine native
// endian (no swap).
SetTargetBigEndian(IsMachineBigEndian());
}
//-----------------------------------------------------------------------------
// Write a single field.
//-----------------------------------------------------------------------------
void SwapFieldToTargetEndian(void *pOutputBuffer, void *pData,
typedescription_t *pField);
//-----------------------------------------------------------------------------
// Write a block of fields. Works a bit like the saverestore code.
//-----------------------------------------------------------------------------
void SwapFieldsToTargetEndian(void *pOutputBuffer, void *pBaseData,
datamap_t *pDataMap);
// Swaps fields for the templated type to the output buffer.
template <typename T>
inline void SwapFieldsToTargetEndian(T *pOutputBuffer, void *pBaseData,
unsigned int objectCount = 1) {
for (unsigned int i = 0; i < objectCount; ++i, ++pOutputBuffer) {
SwapFieldsToTargetEndian((void *)pOutputBuffer, pBaseData,
&T::m_DataMap);
pBaseData = (byte *)pBaseData + sizeof(T);
}
}
// Swaps fields for the templated type in place.
template <typename T>
inline void SwapFieldsToTargetEndian(T *pOutputBuffer,
unsigned int objectCount = 1) {
SwapFieldsToTargetEndian<T>(pOutputBuffer, (void *)pOutputBuffer,
objectCount);
}
//-----------------------------------------------------------------------------
// True if the current machine is detected as big endian.
// (Endienness is effectively detected at compile time when optimizations
// are enabled)
//-----------------------------------------------------------------------------
static bool IsMachineBigEndian() {
short nIsBigEndian = 1;
// if we are big endian, the first byte will be a 0, if little endian,
// it will be a one.
return (bool)(0 == *(char *)&nIsBigEndian);
}
//-----------------------------------------------------------------------------
// Sets the target byte ordering we are swapping to or from.
//
// Braindead Endian Reference:
// x86 is LITTLE Endian
// PowerPC is BIG Endian
//-----------------------------------------------------------------------------
inline void SetTargetBigEndian(bool bigEndian) {
m_bBigEndian = bigEndian;
m_bSwapBytes = IsMachineBigEndian() != bigEndian;
}
// Changes target endian
inline void FlipTargetEndian(void) {
m_bSwapBytes = !m_bSwapBytes;
m_bBigEndian = !m_bBigEndian;
}
// Forces byte swapping state, regardless of endianess
inline void ActivateByteSwapping(bool bActivate) {
SetTargetBigEndian(IsMachineBigEndian() != bActivate);
}
//-----------------------------------------------------------------------------
// Returns true if the target machine is the same as this one in endianness.
//
// Used to determine when a byteswap needs to take place.
//-----------------------------------------------------------------------------
inline bool IsSwappingBytes(void) // Are bytes being swapped?
{
return m_bSwapBytes;
}
inline bool IsTargetBigEndian(void) // What is the current target endian?
{
return m_bBigEndian;
}
//-----------------------------------------------------------------------------
// IsByteSwapped()
//
// When supplied with a chunk of input data and a constant or magic number
// (in native format) determines the endienness of the current machine in
// relation to the given input data.
//
// Returns:
// 1 if input is the same as nativeConstant.
// 0 if input is byteswapped relative to nativeConstant.
// -1 if input is not the same as nativeConstant and not byteswapped
// either.
//
// ( This is useful for detecting byteswapping in magic numbers in structure
// headers for example. )
//-----------------------------------------------------------------------------
template <typename T>
inline int SourceIsNativeEndian(T input, T nativeConstant) {
// If it's the same, it isn't byteswapped:
if (input == nativeConstant) return 1;
int output;
LowLevelByteSwap<T>(&output, &input);
if (output == nativeConstant) return 0;
Assert(0); // if we get here, input is neither a swapped nor unswapped
// version of nativeConstant.
return -1;
}
//-----------------------------------------------------------------------------
// Swaps an input buffer full of type T into the given output buffer.
//
// Swaps [count] items from the inputBuffer to the outputBuffer.
// If inputBuffer is omitted or NULL, then it is assumed to be the same as
// outputBuffer - effectively swapping the contents of the buffer in place.
//-----------------------------------------------------------------------------
template <typename T>
inline void SwapBuffer(T *outputBuffer, T *inputBuffer = NULL,
int count = 1) {
Assert(count >= 0);
Assert(outputBuffer);
// Fail gracefully in release:
if (count <= 0 || !outputBuffer) return;
// Optimization for the case when we are swapping in place.
if (inputBuffer == NULL) {
inputBuffer = outputBuffer;
}
// Swap everything in the buffer:
for (int i = 0; i < count; i++) {
LowLevelByteSwap<T>(&outputBuffer[i], &inputBuffer[i]);
}
}
//-----------------------------------------------------------------------------
// Swaps an input buffer full of type T into the given output buffer.
//
// Swaps [count] items from the inputBuffer to the outputBuffer.
// If inputBuffer is omitted or NULL, then it is assumed to be the same as
// outputBuffer - effectively swapping the contents of the buffer in place.
//-----------------------------------------------------------------------------
template <typename T>
inline void SwapBufferToTargetEndian(T *outputBuffer, T *inputBuffer = NULL,
int count = 1) {
Assert(count >= 0);
Assert(outputBuffer);
// Fail gracefully in release:
if (count <= 0 || !outputBuffer) return;
// Optimization for the case when we are swapping in place.
if (inputBuffer == NULL) {
inputBuffer = outputBuffer;
}
// Are we already the correct endienness? ( or are we swapping 1 byte
// items? )
if (!m_bSwapBytes || (sizeof(T) == 1)) {
// If we were just going to swap in place then return.
if (!inputBuffer) return;
// Otherwise copy the inputBuffer to the outputBuffer:
if (outputBuffer != inputBuffer)
memcpy(outputBuffer, inputBuffer, count * sizeof(T));
return;
}
// Swap everything in the buffer:
for (int i = 0; i < count; i++) {
LowLevelByteSwap<T>(&outputBuffer[i], &inputBuffer[i]);
}
}
private:
//-----------------------------------------------------------------------------
// The lowest level byte swapping workhorse of doom. output always contains
// the swapped version of input. ( Doesn't compare machine to target
// endianness )
//-----------------------------------------------------------------------------
template <typename T>
static void LowLevelByteSwap(T *output, T *input) {
T temp = *output;
#if defined(_X360)
// Intrinsics need the source type to be fixed-point
DWORD *word = (DWORD *)input;
switch (sizeof(T)) {
case 8: {
__storewordbytereverse(*(word + 1), 0, &temp);
__storewordbytereverse(*(word + 0), 4, &temp);
} break;
case 4:
__storewordbytereverse(*word, 0, &temp);
break;
case 2:
__storeshortbytereverse(*input, 0, &temp);
break;
case 1:
Q_memcpy(&temp, input, 1);
break;
default:
Assert("Invalid size in CByteswap::LowLevelByteSwap" && 0);
}
#else
for (size_t i = 0; i < sizeof(T); i++) {
((unsigned char *)&temp)[i] =
((unsigned char *)input)[sizeof(T) - (i + 1)];
}
#endif
memcpy(output, &temp, sizeof(T));
}
#if defined(_X360)
// specialized for void * to get 360 XDK compile working despite changelist
// 281331
//-----------------------------------------------------------------------------
// The lowest level byte swapping workhorse of doom. output always contains
// the swapped version of input. ( Doesn't compare machine to target
// endianness )
//-----------------------------------------------------------------------------
template <>
static void LowLevelByteSwap(void **output, void **input) {
AssertMsgOnce(sizeof(void *) == sizeof(unsigned int),
"void *'s on this platform are not four bytes!");
__storewordbytereverse(*reinterpret_cast<unsigned int *>(input), 0,
output);
}
#endif
unsigned int m_bSwapBytes : 1;
unsigned int m_bBigEndian : 1;
};
#endif /* !BYTESWAP_H */

View File

@@ -1,12 +1,3 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
// A growable memory class.
//===========================================================================//
#ifndef UTLBLOCKMEMORY_H
#define UTLBLOCKMEMORY_H

1355
csgo2/sdk/tier1/utlbuffer.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,3 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
// A growable memory class.
//===========================================================================//
#ifndef UTLFIXEDMEMORY_H
#define UTLFIXEDMEMORY_H

View File

@@ -1,34 +1,55 @@
#include "sdk_tools.h"
namespace SdkTools {
auto ProcessChatString(const std::string& input) -> std::tuple<bool, _ChatType, std::string>
{
_ChatType chatType;
std::string content;
bool success = true;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD> "say_team" <20><> "say" <20><>ͷ
if (input.size() >= 9 && input.substr(0, 9) == "say_team ") {
chatType = _ChatType::kTeam;
content = input.substr(9);
}
else if (input.size() >= 5 && input.substr(0, 4) == "say ") {
chatType = _ChatType::kAll;
content = input.substr(4);
}
else {
auto ProcessChatString(const std::string& input)
-> std::tuple<bool, _ChatType, std::string> {
_ChatType chatType;
std::string content;
bool success = true;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD> "say_team" <20><> "say" <20><>ͷ
if (input.size() >= 9 && input.substr(0, 9) == "say_team ") {
chatType = _ChatType::kTeam;
content = input.substr(9);
} else if (input.size() >= 5 && input.substr(0, 4) == "say ") {
chatType = _ChatType::kAll;
content = input.substr(4);
} else {
success = false;
}
if (success == true) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ű<EFBFBD>Χ
if (content.front() != '"' || content.back() != '"') {
success = false;
} else {
// <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD>
content = content.substr(1, content.size() - 2);
}
if (success == true) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ű<EFBFBD>Χ
if (content.front() != '"' || content.back() != '"') {
success = false;
}
else {
// <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD>
content = content.substr(1, content.size() - 2);
}
}
}
return std::make_tuple(success, chatType, content);
}
};
return std::make_tuple(success, chatType, content);
}
auto SentChatToClient(CCSPlayerController* player, _HubType hubtype, const char* msg, ...) -> void {
va_list args;
va_start(args, msg);
char buf[256];
vsnprintf(buf, sizeof(buf), msg, args);
va_end(args);
Offset::FnClientPrint(player, hubtype, buf, nullptr, nullptr, nullptr, nullptr);
}
auto SendConsoleChat(_HubType hubtype, const char* msg, ...) -> void
{
va_list args;
va_start(args, msg);
char buf[256];
vsnprintf(buf, sizeof(buf), msg, args);
va_end(args);
Offset::FnUTIL_ClientPrintAll(hubtype, buf, nullptr, nullptr, nullptr, nullptr);
}
}; // namespace SdkTools

View File

@@ -1,12 +1,19 @@
#pragma once
#include "head.h"
inline int PlayerSlot_to_EntityIndex(int PlayerSlot) { return PlayerSlot + 1; }
inline int EntityIndex_to_PlayerSlot(int EntityIndex) { return EntityIndex - 1; }
enum _ChatType
{
kTeam,
kAll
};
inline int EntityIndex_to_PlayerSlot(int EntityIndex) {
return EntityIndex - 1;
}
#define HUD_PRINTNOTIFY 1
#define HUD_PRINTCONSOLE 2
#define HUD_PRINTTALK 3
#define HUD_PRINTCENTER 4
enum _ChatType { kTeam, kAll };
enum _HubType { kNotify = 1, kConsole, kTalk, kCenter, kMax };
namespace SdkTools {
auto ProcessChatString(const std::string& input) -> std::tuple<bool, _ChatType, std::string>;
};
auto ProcessChatString(const std::string& input)
-> std::tuple<bool, _ChatType, std::string>;
auto SentChatToClient(CCSPlayerController* player, _HubType hubtype, const char* msg, ...) -> void;
auto SendConsoleChat(_HubType hubtype, const char* msg, ...) -> void;
}; // namespace SdkTools

View File

@@ -4,15 +4,15 @@ extern auto TimerCallBack(_GameTimer* timer) -> void;
extern auto RunTickCallBack(_GameTickRunTime* timer) -> void;
}; // namespace ScriptApis
namespace GameTimer {
std::shared_mutex mutex_timerList;
std::recursive_mutex mutex_timerList;
std::vector<_GameTimer*> timerList;
auto AddTimer(_GameTimer* timer) -> int {
std::unique_lock<std::shared_mutex> lock(mutex_timerList);
std::unique_lock<std::recursive_mutex> lock(mutex_timerList);
timerList.push_back(timer);
return timerList.size() - 1;
};
auto CleanUpTimers() -> void {
std::unique_lock<std::shared_mutex> lock(mutex_timerList);
std::unique_lock<std::recursive_mutex> lock(mutex_timerList);
for (auto it = timerList.begin(); it != timerList.end();) {
if ((*it)->m_bPreserveMapChange) {
++it;
@@ -23,7 +23,7 @@ auto CleanUpTimers() -> void {
}
};
auto ExcuteTimers() -> void {
std::shared_lock<std::shared_mutex> lock(mutex_timerList);
std::unique_lock<std::recursive_mutex> lock(mutex_timerList);
for (auto it = timerList.begin(); it != timerList.end();) {
if ((*it)->m_flLastExecute == -1) {
(*it)->m_flLastExecute = global::m_flUniversalTime;
@@ -44,21 +44,21 @@ auto ExcuteTimers() -> void {
}
}; // namespace GameTimer
namespace GameTickRunTime {
std::shared_mutex mutex_tickRunList;
std::recursive_mutex mutex_tickRunList;
std::vector<_GameTickRunTime*> tickRunList;
auto AddTickFunction(_GameTickRunTime* timer) -> void {
std::unique_lock<std::shared_mutex> lock(mutex_tickRunList);
std::unique_lock<std::recursive_mutex> lock(mutex_tickRunList);
tickRunList.push_back(timer);
};
auto CleanUpTickFunctions() -> void {
std::unique_lock<std::shared_mutex> lock(mutex_tickRunList);
std::unique_lock<std::recursive_mutex> lock(mutex_tickRunList);
for (auto it = tickRunList.begin(); it != tickRunList.end();) {
delete (*it);
it = tickRunList.erase(it);
}
};
auto ExcuteTickFunctions() -> void {
std::shared_lock<std::shared_mutex> lock(mutex_tickRunList);
std::unique_lock<std::recursive_mutex> lock(mutex_tickRunList);
for (auto it = tickRunList.begin(); it != tickRunList.end();) {
ScriptApis::RunTickCallBack(*it);
delete (*it);