diff --git a/core/smn_bitbuffer.cpp b/core/smn_bitbuffer.cpp index b6692069..48483d04 100644 --- a/core/smn_bitbuffer.cpp +++ b/core/smn_bitbuffer.cpp @@ -328,7 +328,310 @@ static cell_t smn_BfWriteAngles(IPluginContext *pCtx, const cell_t *params) return 1; } -REGISTER_NATIVES(wrbitbufnatives) +static cell_t smn_BfReadBool(IPluginContext *pCtx, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError herr; + HandleSecurity sec; + bf_read *pBitBuf; + + sec.pOwner = NULL; + sec.pIdentity = g_pCoreIdent; + + if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf)) + != HandleError_None) + { + return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr); + } + + return pBitBuf->ReadOneBit() ? 1 : 0; +} + +static cell_t smn_BfReadByte(IPluginContext *pCtx, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError herr; + HandleSecurity sec; + bf_read *pBitBuf; + + sec.pOwner = NULL; + sec.pIdentity = g_pCoreIdent; + + if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf)) + != HandleError_None) + { + return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr); + } + + return pBitBuf->ReadByte(); +} + +static cell_t smn_BfReadChar(IPluginContext *pCtx, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError herr; + HandleSecurity sec; + bf_read *pBitBuf; + + sec.pOwner = NULL; + sec.pIdentity = g_pCoreIdent; + + if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf)) + != HandleError_None) + { + return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr); + } + + return pBitBuf->ReadChar(); +} + +static cell_t smn_BfReadShort(IPluginContext *pCtx, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError herr; + HandleSecurity sec; + bf_read *pBitBuf; + + sec.pOwner = NULL; + sec.pIdentity = g_pCoreIdent; + + if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf)) + != HandleError_None) + { + return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr); + } + + return pBitBuf->ReadShort(); +} + +static cell_t smn_BfReadWord(IPluginContext *pCtx, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError herr; + HandleSecurity sec; + bf_read *pBitBuf; + + sec.pOwner = NULL; + sec.pIdentity = g_pCoreIdent; + + if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf)) + != HandleError_None) + { + return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr); + } + + return pBitBuf->ReadWord(); +} + +static cell_t smn_BfReadNum(IPluginContext *pCtx, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError herr; + HandleSecurity sec; + bf_read *pBitBuf; + + sec.pOwner = NULL; + sec.pIdentity = g_pCoreIdent; + + if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf)) + != HandleError_None) + { + return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr); + } + + return static_cast(pBitBuf->ReadLong()); +} + +static cell_t smn_BfReadFloat(IPluginContext *pCtx, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError herr; + HandleSecurity sec; + bf_read *pBitBuf; + + sec.pOwner = NULL; + sec.pIdentity = g_pCoreIdent; + + if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf)) + != HandleError_None) + { + return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr); + } + + return sp_ftoc(pBitBuf->ReadFloat()); +} + +static cell_t smn_BfReadString(IPluginContext *pCtx, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError herr; + HandleSecurity sec; + bf_read *pBitBuf; + char *buf; + + sec.pOwner = NULL; + sec.pIdentity = g_pCoreIdent; + + if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf)) + != HandleError_None) + { + return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr); + } + + pCtx->LocalToPhysAddr(params[2], (cell_t **)&buf); + if (!pBitBuf->ReadString(buf, params[3], params[4] ? true : false)) + { + return pCtx->ThrowNativeError("Destination string buffer is too short, try increasing its size"); + } + + return 1; +} + +static cell_t smn_BfReadEntity(IPluginContext *pCtx, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError herr; + HandleSecurity sec; + bf_read *pBitBuf; + + sec.pOwner = NULL; + sec.pIdentity = g_pCoreIdent; + + if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf)) + != HandleError_None) + { + return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr); + } + + return pBitBuf->ReadShort(); +} + +static cell_t smn_BfReadAngle(IPluginContext *pCtx, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError herr; + HandleSecurity sec; + bf_read *pBitBuf; + + sec.pOwner = NULL; + sec.pIdentity = g_pCoreIdent; + + if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf)) + != HandleError_None) + { + return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr); + } + + return sp_ftoc(pBitBuf->ReadBitAngle(params[2])); +} + +static cell_t smn_BfReadCoord(IPluginContext *pCtx, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError herr; + HandleSecurity sec; + bf_read *pBitBuf; + + sec.pOwner = NULL; + sec.pIdentity = g_pCoreIdent; + + if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf)) + != HandleError_None) + { + return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr); + } + + return sp_ftoc(pBitBuf->ReadBitCoord()); +} + +static cell_t smn_BfReadVecCoord(IPluginContext *pCtx, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError herr; + HandleSecurity sec; + bf_read *pBitBuf; + + sec.pOwner = NULL; + sec.pIdentity = g_pCoreIdent; + + if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf)) + != HandleError_None) + { + return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr); + } + + cell_t *pVec; + pCtx->LocalToPhysAddr(params[2], &pVec); + + Vector vec; + pBitBuf->ReadBitVec3Coord(vec); + + pVec[0] = sp_ftoc(vec.x); + pVec[1] = sp_ftoc(vec.y); + pVec[2] = sp_ftoc(vec.z); + + return 1; +} + +static cell_t smn_BfReadVecNormal(IPluginContext *pCtx, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError herr; + HandleSecurity sec; + bf_read *pBitBuf; + + sec.pOwner = NULL; + sec.pIdentity = g_pCoreIdent; + + if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf)) + != HandleError_None) + { + return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr); + } + + cell_t *pVec; + pCtx->LocalToPhysAddr(params[2], &pVec); + + Vector vec; + pBitBuf->ReadBitVec3Normal(vec); + + pVec[0] = sp_ftoc(vec.x); + pVec[1] = sp_ftoc(vec.y); + pVec[2] = sp_ftoc(vec.z); + + return 1; +} + +static cell_t smn_BfReadAngles(IPluginContext *pCtx, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError herr; + HandleSecurity sec; + bf_read *pBitBuf; + + sec.pOwner = NULL; + sec.pIdentity = g_pCoreIdent; + + if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf)) + != HandleError_None) + { + return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr); + } + + cell_t *pAng; + pCtx->LocalToPhysAddr(params[2], &pAng); + + QAngle ang; + pBitBuf->ReadBitAngles(ang); + + pAng[0] = sp_ftoc(ang.x); + pAng[1] = sp_ftoc(ang.y); + pAng[2] = sp_ftoc(ang.z); + + return 1; +} + +REGISTER_NATIVES(bitbufnatives) { {"BfWriteBool", smn_BfWriteBool}, {"BfWriteByte", smn_BfWriteByte}, @@ -344,5 +647,19 @@ REGISTER_NATIVES(wrbitbufnatives) {"BfWriteVecCoord", smn_BfWriteVecCoord}, {"BfWriteVecNormal", smn_BfWriteVecNormal}, {"BfWriteAngles", smn_BfWriteAngles}, + {"BfReadBool", smn_BfReadBool}, + {"BfReadByte", smn_BfReadByte}, + {"BfReadChar", smn_BfReadChar}, + {"BfReadShort", smn_BfReadShort}, + {"BfReadWord", smn_BfReadWord}, + {"BfReadNum", smn_BfReadNum}, + {"BfReadFloat", smn_BfReadFloat}, + {"BfReadString", smn_BfReadString}, + {"BfReadEntity", smn_BfReadEntity}, + {"BfReadAngle", smn_BfReadAngle}, + {"BfReadCoord", smn_BfReadCoord}, + {"BfReadVecCoord", smn_BfReadVecCoord}, + {"BfReadVecNormal", smn_BfReadVecNormal}, + {"BfReadAngles", smn_BfReadAngles}, {NULL, NULL} }; diff --git a/core/smn_usermsgs.cpp b/core/smn_usermsgs.cpp index cc6567f2..d62fdc85 100644 --- a/core/smn_usermsgs.cpp +++ b/core/smn_usermsgs.cpp @@ -18,7 +18,11 @@ #include "smn_usermsgs.h" HandleType_t g_WrBitBufType; +HandleType_t g_RdBitBufType; Handle_t g_CurMsgHandle; +Handle_t g_ReadBufHandle; +bf_read g_ReadBitBuf; + int g_MsgPlayers[256]; bool g_IsMsgInExec = false; @@ -45,15 +49,30 @@ private: void UsrMessageNatives::OnSourceModAllInitialized() { + HandleAccess sec; + sec.access[HandleAccess_Delete] |= HANDLE_RESTRICT_IDENTITY; + g_WrBitBufType = g_HandleSys.CreateType("BitBufWriter", this, 0, NULL, NULL, g_pCoreIdent, NULL); + g_RdBitBufType = g_HandleSys.CreateType("BitBufReader", this, 0, NULL, &sec, g_pCoreIdent, NULL); + + g_ReadBufHandle = g_HandleSys.CreateHandle(g_RdBitBufType, &g_ReadBitBuf, NULL, g_pCoreIdent, NULL); + g_PluginSys.AddPluginsListener(this); } void UsrMessageNatives::OnSourceModShutdown() { + HandleSecurity sec; + sec.pIdentity = g_pCoreIdent; + + g_HandleSys.FreeHandle(g_ReadBufHandle, &sec); + g_HandleSys.RemoveType(g_WrBitBufType, g_pCoreIdent); + g_HandleSys.RemoveType(g_RdBitBufType, g_pCoreIdent); + g_PluginSys.RemovePluginsListener(this); g_WrBitBufType = 0; + g_RdBitBufType = 0; } void UsrMessageNatives::OnHandleDestroy(HandleType_t type, void *object) @@ -221,8 +240,10 @@ void MsgListenerWrapper::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilte cell_t res; size_t size = _FillInPlayers(g_MsgPlayers, pFilter); + g_ReadBitBuf.StartReading(bf->GetBasePointer(), bf->GetNumBytesWritten()); + m_Hook->PushCell(msg_id); - m_Hook->PushCell(0); //:TODO: push handle! + m_Hook->PushCell(g_ReadBufHandle); m_Hook->PushArray(g_MsgPlayers, size); m_Hook->PushCell(size); m_Hook->PushCell(pFilter->IsReliable()); @@ -235,8 +256,10 @@ ResultType MsgListenerWrapper::InterceptUserMessage(int msg_id, bf_write *bf, IR cell_t res = static_cast(Pl_Continue); size_t size = _FillInPlayers(g_MsgPlayers, pFilter); + g_ReadBitBuf.StartReading(bf->GetBasePointer(), bf->GetNumBytesWritten()); + m_Intercept->PushCell(msg_id); - m_Intercept->PushCell(0); //:TODO: push handle! + m_Intercept->PushCell(g_ReadBufHandle); m_Intercept->PushArray(g_MsgPlayers, size); m_Intercept->PushCell(size); m_Intercept->PushCell(pFilter->IsReliable()); diff --git a/core/sourcemod.h b/core/sourcemod.h index 2913d71a..0a4009a4 100644 --- a/core/sourcemod.h +++ b/core/sourcemod.h @@ -102,5 +102,6 @@ private: extern SourceModBase g_SourceMod; extern HandleType_t g_WrBitBufType; +extern HandleType_t g_RdBitBufType; #endif //_INCLUDE_SOURCEMOD_GLOBALHEADER_H_ diff --git a/plugins/include/bitbuffer.inc b/plugins/include/bitbuffer.inc index b6ec5bdf..db7cd4ec 100644 --- a/plugins/include/bitbuffer.inc +++ b/plugins/include/bitbuffer.inc @@ -133,7 +133,7 @@ native BfWriteCoord(Handle:bf, Float:coord); /** * Writes a 3D vector of coordinates to a writable bitbuffer (bf_write). * - * @param bif bf_write handle to write to. + * @param bf bf_write handle to write to. * @param coord Coordinate array to write. * @noreturn * @error Invalid or incorrect Handle. @@ -143,7 +143,7 @@ native BfWriteVecCoord(Handle:bf, Float:coord[3]); /** * Writes a 3D normal vector to a writable bitbuffer (bf_write). * - * @param bif bf_write handle to write to. + * @param bf bf_write handle to write to. * @param vec Vector to write. * @noreturn * @error Invalid or incorrect Handle. @@ -153,9 +153,143 @@ native BfWriteVecNormal(Handle:bf, Float:vec[3]); /** * Writes a 3D angle vector to a writable bitbuffer (bf_write). * - * @param bif bf_write handle to write to. + * @param bf bf_write handle to write to. * @param angles Angle vector to write. * @noreturn * @error Invalid or incorrect Handle. */ native BfWriteAngles(Handle:bf, Float:angles[3]); + +/** + * Reads a single bit from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Bit value read. + * @error Invalid or incorrect Handle. + */ +native bool:BfReadBool(Handle:bf); + +/** + * Reads a byte from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Byte value read (read as 8bit). + * @error Invalid or incorrect Handle. + */ +native BfReadByte(Handle:bf); + +/** + * Reads a character from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Character value read. + * @error Invalid or incorrect Handle. + */ +native BfReadChar(Handle:bf); + +/** + * Reads a 16bit integer from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Integer value read (read as 16bit). + * @error Invalid or incorrect Handle. + */ +native BfReadShort(Handle:bf); + +/** + * Reads a 16bit unsigned integer from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Integer value read (read as 16bit). + * @error Invalid or incorrect Handle. + */ +native BfReadWord(Handle:bf); + +/** + * Reads a normal integer to a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Integer value read (read as 32bit). + * @error Invalid or incorrect Handle. + */ +native BfReadNum(Handle:bf); + +/** + * Reads a floating point number from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Floating point value read. + * @error Invalid or incorrect Handle. + */ +native Float:BfReadFloat(Handle:bf); + +/** + * Reads a string from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @param buffer Destination string buffer. + * @param maxlength Maximum length of output string buffer. + * @param Line If true the buffer will be copied until it reaches a '\n' or a null terminator. + * @noreturn + * @error Invalid or incorrect Handle, destination string buffer was too short. + */ +native BfReadString(Handle:bf, String:buffer[], maxlength, bool:Line=false); + +/** + * Reads an entity from a readable bitbuffer (bf_read). + * @note This is a wrapper around BfReadShort(). + * + * @param bf bf_read handle to read from. + * @return Entity index read. + * @error Invalid or incorrect Handle. + */ +native BfReadEntity(Handle:bf); + +/** + * Reads a bit angle from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @param numBits Optional number of bits to use. + * @return Angle read. + * @error Invalid or incorrect Handle. + */ +native Float:BfReadAngle(Handle:bf, numBits=8); + +/** + * Reads a coordinate from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @return Coordinate read. + * @error Invalid or incorrect Handle. + */ +native Float:BfReadCoord(Handle:bf); + +/** + * Reads a 3D vector of coordinates from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @param coord Destination coordinate array. + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfReadVecCoord(Handle:bf, Float:coord[3]); + +/** + * Reads a 3D normal vector from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @param vec Destination vector array. + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfReadVecNormal(Handle:bf, Float:vec[3]); + +/** + * Reads a 3D angle vector from a readable bitbuffer (bf_read). + * + * @param bf bf_read handle to read from. + * @param angles Destination angle vector. + * @noreturn + * @error Invalid or incorrect Handle. + */ +native BfReadAngles(Handle:bf, Float:angles[3]); diff --git a/public/IUserMessages.h b/public/IUserMessages.h index 6307c336..d3d8b775 100644 --- a/public/IUserMessages.h +++ b/public/IUserMessages.h @@ -59,7 +59,7 @@ namespace SourceMod * @param msg_id Message Id. * @param bf bf_write structure containing written bytes. * @param pFtiler Recipient filter. - * @return True to allow message, false to scrap it. + * @return Pl_Continue to allow message, Pl_Stop or Pl_Handled to scrap it. */ virtual ResultType InterceptUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter) {