Skip to content

Instantly share code, notes, and snippets.

@ProdigySim
Created January 27, 2013 20:58
Show Gist options
  • Save ProdigySim/4650446 to your computer and use it in GitHub Desktop.
Save ProdigySim/4650446 to your computer and use it in GitHub Desktop.
some potential patches for sm-central
# HG changeset patch
# Parent bf0211912ba1b67fc60d80038627156bb85e2779
Gamerules GetData natives.
diff -r bf0211912ba1 -r 03044c5b5fdf extensions/sdktools/gamerulesnatives.cpp
--- a/extensions/sdktools/gamerulesnatives.cpp Sun Jan 27 12:49:25 2013 -0800
+++ b/extensions/sdktools/gamerulesnatives.cpp Sun Jan 27 12:50:49 2013 -0800
@@ -87,6 +87,18 @@
PropField_String_T, /**< Valid for Data fields. Read only! */
};
+#define MAX_VALID_OFFSET 32768
+
+#define ASSERT_GAMERULES_FOUND() \
+ if (!g_pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, "")) \
+ return pContext->ThrowNativeError("Gamerules lookup failed.");
+
+#define ASSERT_VALID_OFFSET(offset) \
+ if (offset <= 0 || offset > MAX_VALID_OFFSET) \
+ { \
+ return pContext->ThrowNativeError("Offset %d is invalid", offset); \
+ }
+
#define FIND_PROP_SEND(type, type_name) \
sm_sendprop_info_t info;\
if (!gamehelpers->FindSendPropInfo(g_szGameRulesProxy, prop, &info)) \
@@ -573,7 +585,6 @@
return (dest - start);
}
-//
static cell_t GameRules_SetPropString(IPluginContext *pContext, const cell_t *params)
{
@@ -629,6 +640,322 @@
return len;
}
+// Data reads
+static cell_t GameRules_GetData(IPluginContext *pContext, const cell_t *params)
+{
+ int offset = params[1];
+ ASSERT_VALID_OFFSET(offset);
+
+ ASSERT_GAMERULES_FOUND();
+
+ void * pGameRules = *g_pGameRules;
+ int size = params[2];
+
+ switch (size)
+ {
+ case 4:
+ return *(int *)((uint8_t *)pGameRules + offset);
+ case 2:
+ return *(short *)((uint8_t *)pGameRules + offset);
+ case 1:
+ return *((uint8_t *)pGameRules + offset);
+ default:
+ return pContext->ThrowNativeError("Integer size %d is invalid", size);
+ }
+}
+
+static cell_t GameRules_SetData(IPluginContext *pContext, const cell_t *params)
+{
+ int offset = params[1];
+ ASSERT_VALID_OFFSET(offset);
+
+ bool sendChange = true;
+ if (params[4] == 0)
+ sendChange = false;
+
+ CBaseEntity *pProxy = NULL;
+ if (sendChange && ((pProxy = GetGameRulesProxyEnt()) == NULL))
+ return pContext->ThrowNativeError("Couldn't find gamerules proxy entity.");
+
+ ASSERT_GAMERULES_FOUND();
+
+ void * pGameRules = *g_pGameRules;
+
+ int size = params[3];
+ switch (size)
+ {
+ case 4:
+ {
+ int32_t value = params[2];
+ *(int32_t *)((uint8_t *)pGameRules + offset) = value;
+ if (sendChange)
+ {
+ *(int32_t *)((intptr_t)pProxy + offset) = value;
+ gamehelpers->SetEdictStateChanged(gamehelpers->EdictOfIndex(gamehelpers->EntityToBCompatRef(pProxy)), offset);
+ }
+ break;
+ }
+ case 2:
+ {
+ int16_t value = (int16_t)params[2];
+ *(int16_t *)((uint8_t *)pGameRules + offset) = value;
+ if (sendChange)
+ {
+ *(int16_t *)((intptr_t)pProxy + offset) = value;
+ gamehelpers->SetEdictStateChanged(gamehelpers->EdictOfIndex(gamehelpers->EntityToBCompatRef(pProxy)), offset);
+ }
+ break;
+ }
+ case 1:
+ {
+ int8_t value = (int8_t)params[2];
+ *((int8_t *)pGameRules + offset) = value;
+ if (sendChange)
+ {
+ *(int8_t *)((intptr_t)pProxy + offset) = value;
+ gamehelpers->SetEdictStateChanged(gamehelpers->EdictOfIndex(gamehelpers->EntityToBCompatRef(pProxy)), offset);
+ }
+ break;
+ }
+ default:
+ return pContext->ThrowNativeError("Integer size %d is invalid", size);
+ }
+
+ return 1;
+}
+
+static cell_t GameRules_GetDataFloat(IPluginContext *pContext, const cell_t *params)
+{
+ int offset = params[1];
+ ASSERT_VALID_OFFSET(offset);
+
+ ASSERT_GAMERULES_FOUND();
+
+ void * pGameRules = *g_pGameRules;
+
+ float f = *(float *)((uint8_t *)pGameRules + offset);
+
+ return sp_ftoc(f);
+}
+
+static cell_t GameRules_SetDataFloat(IPluginContext *pContext, const cell_t *params)
+{
+ int offset = params[1];
+ ASSERT_VALID_OFFSET(offset);
+
+ bool sendChange = true;
+ if (params[3] == 0)
+ sendChange = false;
+
+ CBaseEntity *pProxy = NULL;
+ if (sendChange && ((pProxy = GetGameRulesProxyEnt()) == NULL))
+ return pContext->ThrowNativeError("Couldn't find gamerules proxy entity.");
+
+ ASSERT_GAMERULES_FOUND();
+
+ void * pGameRules = *g_pGameRules;
+
+ float value = sp_ctof(params[2]);
+
+ *(float *)((uint8_t *)pGameRules + offset) = value;
+
+ if (sendChange)
+ {
+ *(float *)((intptr_t)pProxy + offset) = value;
+ gamehelpers->SetEdictStateChanged(gamehelpers->EdictOfIndex(gamehelpers->EntityToBCompatRef(pProxy)), offset);
+ }
+
+ return 1;
+}
+
+static cell_t GameRules_GetDataEnt(IPluginContext *pContext, const cell_t *params)
+{
+ int offset = params[1];
+ ASSERT_VALID_OFFSET(offset);
+
+ ASSERT_GAMERULES_FOUND();
+
+ void *pGameRules = *g_pGameRules;
+
+ CBaseHandle &hndl = *(CBaseHandle *)((intptr_t)pGameRules + offset);
+ CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(hndl.GetEntryIndex());
+
+ if (!pEntity || ((IServerEntity *)pEntity)->GetRefEHandle() != hndl)
+ {
+ return -1;
+ }
+
+ return gamehelpers->EntityToBCompatRef(pEntity);
+}
+
+static cell_t GameRules_SetDataEnt(IPluginContext *pContext, const cell_t *params)
+{
+ int offset = params[1];
+ ASSERT_VALID_OFFSET(offset);
+
+ bool sendChange = true;
+ if (params[3] == 0)
+ sendChange = false;
+
+ CBaseEntity *pProxy = NULL;
+ if (sendChange && ((pProxy = GetGameRulesProxyEnt()) == NULL))
+ return pContext->ThrowNativeError("Couldn't find gamerules proxy entity.");
+
+ ASSERT_GAMERULES_FOUND();
+
+ void *pGameRules = *g_pGameRules;
+
+ CBaseHandle &hndl = *(CBaseHandle *)((intptr_t)pGameRules + offset);
+ CBaseEntity *pOther;
+
+ if (params[2] == -1)
+ {
+ hndl.Set(NULL);
+ }
+ else
+ {
+ pOther = gamehelpers->ReferenceToEntity(params[2]);
+
+ if (!pOther)
+ {
+ return pContext->ThrowNativeError("Entity %d (%d) is invalid", gamehelpers->ReferenceToIndex(params[4]), params[4]);
+ }
+
+ IHandleEntity *pHandleEnt = (IHandleEntity *)pOther;
+ hndl.Set(pHandleEnt);
+ }
+
+ if (sendChange)
+ {
+ CBaseHandle &hndl = *(CBaseHandle *)((intptr_t)pProxy + offset);
+ if (params[2] == -1)
+ {
+ hndl.Set(NULL);
+ }
+ else
+ {
+ IHandleEntity *pHandleEnt = (IHandleEntity *)pOther;
+ hndl.Set(pHandleEnt);
+ }
+
+ gamehelpers->SetEdictStateChanged(gamehelpers->EdictOfIndex(gamehelpers->EntityToBCompatRef(pProxy)), offset);
+ }
+
+ return 0;
+}
+
+static cell_t GameRules_GetDataVector(IPluginContext *pContext, const cell_t *params)
+{
+ int offset = params[1];
+ ASSERT_VALID_OFFSET(offset);
+
+ ASSERT_GAMERULES_FOUND();
+
+ void * pGameRules = *g_pGameRules;
+ Vector *v = (Vector *)((uint8_t *)pGameRules + offset);
+
+ cell_t *vec;
+ pContext->LocalToPhysAddr(params[2], &vec);
+
+ vec[0] = sp_ftoc(v->x);
+ vec[1] = sp_ftoc(v->y);
+ vec[2] = sp_ftoc(v->z);
+
+ return 1;
+}
+
+static cell_t GameRules_SetDataVector(IPluginContext *pContext, const cell_t *params)
+{
+ int offset = params[1];
+ ASSERT_VALID_OFFSET(offset);
+
+ bool sendChange = true;
+ if (params[3] == 0)
+ sendChange = false;
+
+ CBaseEntity *pProxy = NULL;
+ if (sendChange && ((pProxy = GetGameRulesProxyEnt()) == NULL))
+ return pContext->ThrowNativeError("Couldn't find gamerules proxy entity.");
+
+ ASSERT_GAMERULES_FOUND();
+
+ void * pGameRules = *g_pGameRules;
+
+ Vector *v = (Vector *)((uint8_t *)pGameRules + offset);
+
+ cell_t *vec;
+ pContext->LocalToPhysAddr(params[2], &vec);
+
+ v->x = sp_ctof(vec[0]);
+ v->y = sp_ctof(vec[1]);
+ v->z = sp_ctof(vec[2]);
+
+ if (sendChange)
+ {
+ v = (Vector *)((intptr_t)pProxy + offset);
+ v->x = sp_ctof(vec[0]);
+ v->y = sp_ctof(vec[1]);
+ v->z = sp_ctof(vec[2]);
+ gamehelpers->SetEdictStateChanged(gamehelpers->EdictOfIndex(gamehelpers->EntityToBCompatRef(pProxy)), offset);
+ }
+
+ return 1;
+}
+
+static cell_t GameRules_GetDataString(IPluginContext *pContext, const cell_t *params)
+{
+ int offset = params[1];
+ ASSERT_VALID_OFFSET(offset);
+
+ ASSERT_GAMERULES_FOUND();
+
+ void *pGameRules = *g_pGameRules;
+
+ size_t len;
+ const char *src;
+
+ src = (char *)((intptr_t)pGameRules + offset);
+
+ pContext->StringToLocalUTF8(params[2], params[3], src, &len);
+
+ return len;
+}
+
+static cell_t GameRules_SetDataString(IPluginContext *pContext, const cell_t *params)
+{
+ int offset = params[1];
+ ASSERT_VALID_OFFSET(offset);
+
+ bool sendChange = true;
+ if (params[3] == 0)
+ sendChange = false;
+
+ CBaseEntity *pProxy = NULL;
+ if (sendChange && ((pProxy = GetGameRulesProxyEnt()) == NULL))
+ return pContext->ThrowNativeError("Couldn't find gamerules proxy entity.");
+
+ ASSERT_GAMERULES_FOUND();
+
+ void *pGameRules = *g_pGameRules;
+ int maxlen = DT_MAX_STRING_BUFFERSIZE;
+
+ char *src;
+ char *dest = (char *)((intptr_t)pGameRules + offset);
+
+ pContext->LocalToString(params[2], &src);
+ size_t len = strncopy(dest, src, maxlen);
+
+ if (sendChange)
+ {
+ dest = (char *)((intptr_t)pProxy + offset);
+ strncopy(dest, src, maxlen);
+ gamehelpers->SetEdictStateChanged(gamehelpers->EdictOfIndex(gamehelpers->EntityToBCompatRef(pProxy)), offset);
+ }
+
+ return len;
+}
+
+
sp_nativeinfo_t g_GameRulesNatives[] =
{
{"GameRules_GetProp", GameRules_GetProp},
@@ -641,6 +968,18 @@
{"GameRules_SetPropVector", GameRules_SetPropVector},
{"GameRules_GetPropString", GameRules_GetPropString},
{"GameRules_SetPropString", GameRules_SetPropString},
+
+ {"GameRules_GetData", GameRules_GetData},
+ {"GameRules_SetData", GameRules_SetData},
+ {"GameRules_GetDataFloat", GameRules_GetDataFloat},
+ {"GameRules_SetDataFloat", GameRules_SetDataFloat},
+ {"GameRules_GetDataEnt", GameRules_GetDataEnt},
+ {"GameRules_SetDataEnt", GameRules_SetDataEnt},
+ {"GameRules_GetDataVector", GameRules_GetDataVector},
+ {"GameRules_SetDataVector", GameRules_SetDataVector},
+ {"GameRules_GetDataString", GameRules_GetDataString},
+ {"GameRules_SetDataString", GameRules_SetDataString},
+
{NULL, NULL},
};
diff -r bf0211912ba1 -r 03044c5b5fdf plugins/include/sdktools_gamerules.inc
--- a/plugins/include/sdktools_gamerules.inc Sun Jan 27 12:49:25 2013 -0800
+++ b/plugins/include/sdktools_gamerules.inc Sun Jan 27 12:50:49 2013 -0800
@@ -186,6 +186,113 @@
native GameRules_SetPropString(const String:prop[], const String:buffer[], bool:changeState=false);
/**
+ * Retrieves an integer value from the given offset in the gamerules entity.
+ *
+ * @param offset Offset to use.
+ * @param size Number of bytes to read (valid values are 1, 2, or 4).
+ * @return Value at the given offset.
+ * @error Not supported.
+ */
+native GameRules_GetData(offset, size=4);
+
+/**
+ * Sets an integer value at the given offset in the gamerules entity.
+ *
+ * @param offset Offset to use.
+ * @param value Value to set.
+ * @param size Number of bytes to write (valid values are 1, 2, or 4).
+ * @param changeState True to propagate the change to clients through the gamerules proxy entity.
+ * @error Not supported.
+ * @noreturn
+ */
+native GameRules_SetData(offset, any:value, size=4, bool:changeState=false);
+
+/**
+ * Retrieves a float value from the given offset in the gamerules entity.
+ *
+ * @param offset Offset to use.
+ * @return Value at the given offset.
+ * @error Not supported.
+ */
+native Float:GameRules_GetDataFloat(offset);
+
+/**
+ * Sets a float value at the given offset in the gamerules entity.
+ *
+ * @param offset Offset to use.
+ * @param value Value to set.
+ * @param changeState True to propagate the change to clients through the gamerules proxy entity.
+ * @noreturn
+ * @error Not supported.
+ */
+native GameRules_SetDataFloat(offset, Float:value, bool:changeState=false);
+
+/**
+ * Retrieves a entity index from the given offset in the gamerules entity.
+ *
+ * @param offset Offset to use.
+ * @return Entity index at the given offset.
+ * If there is no entity, or the entity is not valid,
+ * then -1 is returned.
+ * @error Not supported.
+ */
+native GameRules_GetDataEnt(offset);
+
+/**
+ * Sets an entity index at the given offset in the gamerules entity.
+ *
+ * @param offset Offset to use.
+ * @param other Entity index to set, or -1 to unset.
+ * @param changeState True to propagate the change to clients through the gamerules proxy entity.
+ * @noreturn
+ * @error Not supported.
+ */
+native GameRules_SetDataEnt(offset, other, bool:changeState=false);
+
+/**
+ * Retrieves a vector of floats from the gamerules entity at the given offset.
+ *
+ * @param offset Offset to use.
+ * @param vec Vector buffer to store data in.
+ * @noreturn
+ * @error Not supported.
+ */
+native GameRules_GetDataVector(offset, Float:vec[3]);
+
+/**
+ * Sets a vector of floats in the gamerules entity at the given offset.
+ *
+ * @param offset Offset to use.
+ * @param vec Vector to set.
+ * @param changeState True to propagate the change to clients through the gamerules proxy entity.
+ * @noreturn
+ * @error Not supported.
+ */
+native GameRules_SetDataVector(offset, const Float:vec[3], bool:changeState=false);
+
+/**
+ * Gets a string from the gamerules entity at the given offset.
+ *
+ * @param offset Offset to use.
+ * @param buffer Destination string buffer.
+ * @param maxlen Maximum length of output string buffer.
+ * @return Number of non-null bytes written.
+ * @error Not supported.
+ */
+native GameRules_GetDataString(offset, String:buffer[], maxlen);
+
+/**
+ * Sets a string from the gamerules entity at the given offset.
+ *
+ * @param offset Offset to use.
+ * @param buffer String to set.
+ * @param changeState True to propagate the change to clients through the gamerules proxy entity.
+ * @return Number of non-null bytes written.
+ * @error Not supported.
+ */
+native GameRules_SetDataString(offset, const String:buffer[], bool:changeState=false);
+
+/**
* Gets the current round state.
*
* @return Round state.
# HG changeset patch
# Parent 03044c5b5fdf18441bd454a45ea1cc84d8ca08ce
Added missing changeState parameter to GameRules_SetProp natives documentation.
diff -r 03044c5b5fdf -r e78a123071d3 plugins/include/sdktools_gamerules.inc
--- a/plugins/include/sdktools_gamerules.inc Sun Jan 27 12:50:49 2013 -0800
+++ b/plugins/include/sdktools_gamerules.inc Sun Jan 27 12:52:18 2013 -0800
@@ -93,6 +93,7 @@
* This value is auto-detected, and the size parameter is
* only used as a fallback in case detection fails.
* @param element Element # (starting from 0) if property is an array.
+ * @param changeState True to propagate the change to clients through the gamerules proxy entity.
* @error Not supported.
* @noreturn
*/
@@ -114,6 +115,7 @@
* @param prop Property name.
* @param value Value to set.
* @param element Element # (starting from 0) if property is an array.
+ * @param changeState True to propagate the change to clients through the gamerules proxy entity.
* @noreturn
* @error Not supported.
*/
@@ -137,6 +139,7 @@
* @param prop Property name.
* @param other Entity index to set, or -1 to unset.
* @param element Element # (starting from 0) if property is an array.
+ * @param changeState True to propagate the change to clients through the gamerules proxy entity.
* @noreturn
* @error Not supported.
*/
@@ -159,6 +162,7 @@
* @param prop Property name.
* @param vec Vector to set.
* @param element Element # (starting from 0) if property is an array.
+ * @param changeState True to propagate the change to clients through the gamerules proxy entity.
* @noreturn
* @error Not supported.
*/
@@ -180,6 +184,7 @@
*
* @param prop Property to use.
* @param buffer String to set.
+ * @param changeState True to propagate the change to clients through the gamerules proxy entity.
* @return Number of non-null bytes written.
* @error Not supported.
*/
# HG changeset patch
# Parent e78a123071d34147555539df6796369d8e3b75d4
Fix GameRules_SetPropVector writing data to unexpected addresses instead of to the proxy entity.
diff -r e78a123071d3 -r 10343da6e00f extensions/sdktools/gamerulesnatives.cpp
--- a/extensions/sdktools/gamerulesnatives.cpp Sun Jan 27 12:52:18 2013 -0800
+++ b/extensions/sdktools/gamerulesnatives.cpp Sun Jan 27 12:53:44 2013 -0800
@@ -519,7 +519,7 @@
if (sendChange)
{
- v = (Vector *)((intptr_t)g_pGameRules + offset);
+ v = (Vector *)((intptr_t)pProxy + offset);
v->x = sp_ctof(vec[0]);
v->y = sp_ctof(vec[1]);
v->z = sp_ctof(vec[2]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment