From dd3000257cd6ea63d6760f42de4a184888921e56 Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Tue, 29 Nov 2022 18:11:43 +0100 Subject: [PATCH 01/20] Project: Restructure --- CMakeLists.txt | 4 +- README.md | 2 +- api/CMakeLists.txt | 7 ---- api/versions/CMakeLists.txt | 3 -- api/versions/cgsc3.h | 40 ------------------- cgsc.h | 17 +++++--- api/cod4x.h => cod4x.h | 5 --- extensions/CMakeLists.txt | 1 - api/plugin.h => plugin.h | 6 --- {api/sys => sys}/CMakeLists.txt | 0 {api/sys => sys}/compatibility.c | 0 {api/sys => sys}/compatibility.h | 0 {api/utils => utils}/CMakeLists.txt | 0 {api/utils => utils}/__test__/CMakeLists.txt | 0 {api/utils => utils}/__test__/utils.test.c | 2 +- {api/utils => utils}/utils.c | 0 {api/utils => utils}/utils.h | 0 .../versions => versions}/CMakeLists.txt | 2 + {extensions/versions => versions}/cgsc3.c | 2 +- versions/cgsc3.h | 12 ++++++ {extensions/versions => versions}/cgsc4.c | 2 +- {api/versions => versions}/cgsc4.h | 4 ++ 22 files changed, 36 insertions(+), 73 deletions(-) delete mode 100644 api/CMakeLists.txt delete mode 100644 api/versions/CMakeLists.txt delete mode 100644 api/versions/cgsc3.h rename api/cod4x.h => cod4x.h (74%) rename api/plugin.h => plugin.h (96%) rename {api/sys => sys}/CMakeLists.txt (100%) rename {api/sys => sys}/compatibility.c (100%) rename {api/sys => sys}/compatibility.h (100%) rename {api/utils => utils}/CMakeLists.txt (100%) rename {api/utils => utils}/__test__/CMakeLists.txt (100%) rename {api/utils => utils}/__test__/utils.test.c (88%) rename {api/utils => utils}/utils.c (100%) rename {api/utils => utils}/utils.h (100%) rename {extensions/versions => versions}/CMakeLists.txt (69%) rename {extensions/versions => versions}/cgsc3.c (98%) create mode 100644 versions/cgsc3.h rename {extensions/versions => versions}/cgsc4.c (90%) rename {api/versions => versions}/cgsc4.h (92%) diff --git a/CMakeLists.txt b/CMakeLists.txt index d0562b0..42715ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,9 +34,11 @@ endif() # Build add_library(CGSC) -add_subdirectory(api) add_subdirectory(asm) add_subdirectory(extensions) +add_subdirectory(sys) +add_subdirectory(utils) +add_subdirectory(versions) target_compile_definitions(CGSC PUBLIC COD4X18UPDATE) target_include_directories(CGSC PUBLIC . .. ../version ../../plugins) diff --git a/README.md b/README.md index 324dcb0..d65d5ba 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![CodeFactor](https://img.shields.io/codefactor/grade/github/Iswenzz/CGSC?label=codefactor&logo=codefactor)](https://www.codefactor.io/repository/github/iswenzz/CGSC) [![License](https://img.shields.io/github/license/Iswenzz/CGSC?color=blue&logo=gitbook&logoColor=white)](https://github.com/Iswenzz/CGSC/blob/master/LICENSE) -This Call of Duty 4X source extension adds new utilities for use in the creation of new plugins. Such things include new functions to get data types that the original source doesn't offer and adds the ability to call functions defined in GSC from the C files. To use this extension you must add the CGSC files included in the release section to the `/src/CGSC` folder, and then compile the CoD4X server source. More detailed instructions can be found towards the bottom of this document. +This Call of Duty 4X source extension adds new utilities to extended the server and the creation of new plugins. Such things include new functions to get data types that the original source doesn't offer and adds the ability to call functions defined in GSC from the C files. To use this extension you must add the CGSC files included in the release section to the `/src/CGSC` folder, and then compile the CoD4X server source. More detailed instructions can be found towards the bottom of this document. ``Note: Depending on the version of Call of Duty 4X that you're running, some features of CGSC may not be available.`` diff --git a/api/CMakeLists.txt b/api/CMakeLists.txt deleted file mode 100644 index 5d366df..0000000 --- a/api/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -add_subdirectory(sys) -add_subdirectory(utils) -add_subdirectory(versions) - -target_sources(CGSC PRIVATE - cod4x.h - plugin.h) diff --git a/api/versions/CMakeLists.txt b/api/versions/CMakeLists.txt deleted file mode 100644 index 8a855c7..0000000 --- a/api/versions/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -target_sources(CGSC PRIVATE - cgsc3.h - cgsc4.h) diff --git a/api/versions/cgsc3.h b/api/versions/cgsc3.h deleted file mode 100644 index 446700c..0000000 --- a/api/versions/cgsc3.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once -#include "cgsc.h" - -#define IGScrVmPub scrVmPub -#define IGScrVarGlob scrVarGlob - -extern char* SL_ConvertToString(unsigned int index); -extern char* var_typename[]; - -enum $0E0E04F36A22A28F2C0A7A22DC12DAE9 -{ - VAR_UNDEFINED = 0x0, - VAR_BEGIN_REF = 0x1, - VAR_POINTER = 0x1, - VAR_STRING = 0x2, - VAR_ISTRING = 0x3, - VAR_VECTOR = 0x4, - VAR_END_REF = 0x5, - VAR_FLOAT = 0x5, - VAR_INTEGER = 0x6, - VAR_CODEPOS = 0x7, - VAR_PRECODEPOS = 0x8, - VAR_FUNCTION = 0x9, - VAR_STACK = 0xA, - VAR_ANIMATION = 0xB, - VAR_DEVELOPER_CODEPOS = 0xC, - VAR_INCLUDE_CODEPOS = 0xD, - VAR_THREAD = 0xE, - VAR_NOTIFY_THREAD = 0xF, - VAR_TIME_THREAD = 0x10, - VAR_CHILD_THREAD = 0x11, - VAR_OBJECT = 0x12, - VAR_DEAD_ENTITY = 0x13, - VAR_ENTITY = 0x14, - VAR_ARRAY = 0x15, - VAR_DEAD_THREAD = 0x16, - VAR_COUNT = 0x17, - VAR_THREAD_LIST = 0x18, - VAR_ENDON_LIST = 0x19 -}; diff --git a/cgsc.h b/cgsc.h index bab42b6..5f5c8ef 100644 --- a/cgsc.h +++ b/cgsc.h @@ -1,9 +1,9 @@ #pragma once #ifdef COD4X18UPDATE - #include "api/cod4x.h" + #include "cod4x.h" #else - #include "api/plugin.h" + #include "plugin.h" #endif #ifdef PLUGIN_HANDLER_VERSION_MAJOR @@ -13,9 +13,9 @@ #define CGSC_EQ(version) CGSCH == version #if PLUGIN_HANDLER_VERSION_MAJOR >= 4 - #include "api/versions/cgsc4.h" + #include "versions/cgsc4.h" #elif PLUGIN_HANDLER_VERSION_MAJOR >= 3 - #include "api/versions/cgsc3.h" + #include "versions/cgsc3.h" #endif #endif @@ -98,14 +98,19 @@ struct scrStringDebugGlob_t int ignoreLeaks; }; +struct __attribute__((aligned (64))) scrVarGlob_t +{ + VariableValueInternal* variableList; +}; + typedef struct { uint32_t length; VariableValue *items; } VariableValueArray; -#include "api/sys/compatibility.h" -#include "api/utils/utils.h" +#include "sys/compatibility.h" +#include "utils/utils.h" #include "extensions/functions.h" #include "extensions/variables.h" diff --git a/api/cod4x.h b/cod4x.h similarity index 74% rename from api/cod4x.h rename to cod4x.h index 77cf694..e716278 100644 --- a/api/cod4x.h +++ b/cod4x.h @@ -13,8 +13,3 @@ #endif #undef ASSERT - -struct __attribute__((aligned(64))) scrVarGlob_t -{ - VariableValueInternal *variableList; -}; diff --git a/extensions/CMakeLists.txt b/extensions/CMakeLists.txt index b859517..9ee8b22 100644 --- a/extensions/CMakeLists.txt +++ b/extensions/CMakeLists.txt @@ -1,5 +1,4 @@ add_subdirectory(__test__) -add_subdirectory(versions) target_sources(CGSC PRIVATE functions.c diff --git a/api/plugin.h b/plugin.h similarity index 96% rename from api/plugin.h rename to plugin.h index 6861bab..16daf18 100644 --- a/api/plugin.h +++ b/plugin.h @@ -26,12 +26,6 @@ if (CGSC_UnsupportedMessage(condition, "CGSC: This feature is unsupported in thi return; \ } -typedef struct -{ - uint16_t entnum; - uint16_t classnum; -} Plugin_Scr_entref_t; - struct VariableStackBuffer { const char *pos; diff --git a/api/sys/CMakeLists.txt b/sys/CMakeLists.txt similarity index 100% rename from api/sys/CMakeLists.txt rename to sys/CMakeLists.txt diff --git a/api/sys/compatibility.c b/sys/compatibility.c similarity index 100% rename from api/sys/compatibility.c rename to sys/compatibility.c diff --git a/api/sys/compatibility.h b/sys/compatibility.h similarity index 100% rename from api/sys/compatibility.h rename to sys/compatibility.h diff --git a/api/utils/CMakeLists.txt b/utils/CMakeLists.txt similarity index 100% rename from api/utils/CMakeLists.txt rename to utils/CMakeLists.txt diff --git a/api/utils/__test__/CMakeLists.txt b/utils/__test__/CMakeLists.txt similarity index 100% rename from api/utils/__test__/CMakeLists.txt rename to utils/__test__/CMakeLists.txt diff --git a/api/utils/__test__/utils.test.c b/utils/__test__/utils.test.c similarity index 88% rename from api/utils/__test__/utils.test.c rename to utils/__test__/utils.test.c index 107d2fc..71f8cbe 100644 --- a/api/utils/__test__/utils.test.c +++ b/utils/__test__/utils.test.c @@ -1,4 +1,4 @@ -#include "api/utils/utils.h" +#include "utils/utils.h" #include TEST test_fmt() diff --git a/api/utils/utils.c b/utils/utils.c similarity index 100% rename from api/utils/utils.c rename to utils/utils.c diff --git a/api/utils/utils.h b/utils/utils.h similarity index 100% rename from api/utils/utils.h rename to utils/utils.h diff --git a/extensions/versions/CMakeLists.txt b/versions/CMakeLists.txt similarity index 69% rename from extensions/versions/CMakeLists.txt rename to versions/CMakeLists.txt index 9b4ef85..158b098 100644 --- a/extensions/versions/CMakeLists.txt +++ b/versions/CMakeLists.txt @@ -1,3 +1,5 @@ target_sources(CGSC PRIVATE + cgsc3.h cgsc3.c + cgsc4.h cgsc4.c) diff --git a/extensions/versions/cgsc3.c b/versions/cgsc3.c similarity index 98% rename from extensions/versions/cgsc3.c rename to versions/cgsc3.c index 7a3f10c..1c47db7 100644 --- a/extensions/versions/cgsc3.c +++ b/versions/cgsc3.c @@ -1,4 +1,4 @@ -#include "cgsc.h" +#include "cgsc3.h" #if CGSC_EQ(3) struct scrVmGlob_t diff --git a/versions/cgsc3.h b/versions/cgsc3.h new file mode 100644 index 0000000..643fe52 --- /dev/null +++ b/versions/cgsc3.h @@ -0,0 +1,12 @@ +#pragma once +#include "cgsc.h" + +#if CGSC_EQ(3) + +#define IGScrVmPub scrVmPub +#define IGScrVarGlob scrVarGlob + +extern char* SL_ConvertToString(unsigned int index); +extern char* var_typename[]; + +#endif diff --git a/extensions/versions/cgsc4.c b/versions/cgsc4.c similarity index 90% rename from extensions/versions/cgsc4.c rename to versions/cgsc4.c index e9f258c..e26a5d0 100644 --- a/extensions/versions/cgsc4.c +++ b/versions/cgsc4.c @@ -1,4 +1,4 @@ -#include "cgsc.h" +#include "cgsc4.h" #if CGSC_EQ(4) void Scr_AddFunc(const char *codePosValue) diff --git a/api/versions/cgsc4.h b/versions/cgsc4.h similarity index 92% rename from api/versions/cgsc4.h rename to versions/cgsc4.h index 262778f..76538bc 100644 --- a/api/versions/cgsc4.h +++ b/versions/cgsc4.h @@ -1,6 +1,8 @@ #pragma once #include "cgsc.h" +#if CGSC_EQ(4) + extern struct scrVarGlob_t gScrVarGlob; extern unsigned int Scr_AllocString(const char *s); extern void Scr_AddIString(const char *value); @@ -9,3 +11,5 @@ extern void IncInParam(); #define IGScrVmPub gScrVmPub #define IGScrVmGlob gScrVmGlob #define IGScrVarGlob gScrVarGlob.variableList + +#endif From b54f58db07396cb870226375932bf1eda150c77e Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Tue, 29 Nov 2022 18:32:21 +0100 Subject: [PATCH 02/20] Project: Refactor doc and renames --- asm/cgsc_export.asm | 3 +- asm/cgsc_function.asm | 2 +- cgsc.h | 10 +-- docs/api.md | 4 +- extensions/functions.h | 110 ++++++++++-------------------- extensions/variables.h | 149 ++++++++++++++++------------------------- plugin.h | 9 +-- sys/compatibility.h | 39 ++++------- utils/utils.h | 38 ++++------- versions/cgsc3.c | 6 ++ versions/cgsc4.c | 2 + 11 files changed, 138 insertions(+), 234 deletions(-) diff --git a/asm/cgsc_export.asm b/asm/cgsc_export.asm index 45ad3a1..968f3fc 100644 --- a/asm/cgsc_export.asm +++ b/asm/cgsc_export.asm @@ -26,9 +26,10 @@ p%2 dd %2 %endmacro -; CGSC +; Rename ralias Plugin_Scr_GetFunction, Scr_GetFunc +; Export pexport Scr_ReturnResult pexport Scr_AddFunc pexport Scr_AddVariable diff --git a/asm/cgsc_function.asm b/asm/cgsc_function.asm index 30d46df..7151d9d 100644 --- a/asm/cgsc_function.asm +++ b/asm/cgsc_function.asm @@ -14,7 +14,7 @@ SECTION .text -; Scr_ExecThreadResult(int, unsigned int) +; Scr_ExecThreadResult(int threadId, unsigned int argsCount) Scr_ExecThreadResult: push ebp mov ebp, esp diff --git a/cgsc.h b/cgsc.h index 5f5c8ef..10c9691 100644 --- a/cgsc.h +++ b/cgsc.h @@ -23,11 +23,8 @@ #define COD4X(version) SYS_COMMONVERSION #endif -/** - * @brief - * Adds the definition for plugin exports. - */ -#define Plugin(type, definition) \ +/// @brief Adds the definition for cod4x server and plugin export. +#define EXPORT(type, definition) \ type definition; \ type Plugin_##definition @@ -110,7 +107,6 @@ typedef struct } VariableValueArray; #include "sys/compatibility.h" -#include "utils/utils.h" - #include "extensions/functions.h" #include "extensions/variables.h" +#include "utils/utils.h" diff --git a/docs/api.md b/docs/api.md index e0f6167..9ab4abc 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,10 +1,10 @@ # API ### ``Macros`` -Creating a plugin export function definition: +Define a function for cod4x server and plugin export. ```c -Plugin(float, Sys_GetCommonVersion()); +EXPORT(float, Sys_GetCommonVersion()); ```
diff --git a/extensions/functions.h b/extensions/functions.h index 995bd2c..a0e4cd5 100644 --- a/extensions/functions.h +++ b/extensions/functions.h @@ -1,95 +1,59 @@ #pragma once #include "cgsc.h" -/** - * @todo - Experimental feature. - * - * @brief This variable is used to keep track of param count for a single call, - * and can only be used in non-thread safe environment. - */ +/// @brief This variable is used to keep track of param count for a single call, +/// and can only be used in non-thread safe environment. +/// @todo - Experimental feature. __attribute__((used)) static int __callArgNumber = 0; -/** - * @brief Alloc a new GSC float param before calling the function with Scr_CallFunction/Scr_CallMethod. - */ +/// @brief Alloc a new GSC float param before calling the function with Scr_CallFunction/Scr_CallMethod. #define FLOAT(val) Scr_SetParamGeneric(__callArgNumber, val, VAR_FLOAT) -/** - * @brief Alloc a new GSC int param before calling the function with Scr_CallFunction/Scr_CallMethod. - */ +/// @brief Alloc a new GSC int param before calling the function with Scr_CallFunction/Scr_CallMethod. #define INT(val) Scr_SetParamGeneric(__callArgNumber, val, VAR_INTEGER) -/** - * @brief Alloc a new GSC vector param before calling the function with Scr_CallFunction/Scr_CallMethod. - */ +/// @brief Alloc a new GSC vector param before calling the function with Scr_CallFunction/Scr_CallMethod. #define VECTOR(val) Scr_SetParamGeneric(__callArgNumber, val, VAR_VECTOR) -/** - * @brief Alloc a new GSC pointer param before calling the function with Scr_CallFunction/Scr_CallMethod. - */ +/// @brief Alloc a new GSC pointer param before calling the function with Scr_CallFunction/Scr_CallMethod. #define POINTER(val) Scr_SetParamGeneric(__callArgNumber, val, VAR_POINTER) -/** - * @brief Alloc a new GSC string param before calling the function with Scr_CallFunction/Scr_CallMethod. - */ +/// @brief Alloc a new GSC string param before calling the function with Scr_CallFunction/Scr_CallMethod. #define STRING(val) Scr_SetParamGeneric(__callArgNumber, val, VAR_STRING) -/** - * @brief Alloc a new GSC localized string param before calling the function with Scr_CallFunction/Scr_CallMethod. - */ +/// @brief Alloc a new GSC localized string param before calling the function with Scr_CallFunction/Scr_CallMethod. #define ISTRING(val) Scr_SetParamGeneric(__callArgNumber, val, VAR_ISTRING) -/** - * @brief Alloc a new GSC function param before calling the function with Scr_CallFunction/Scr_CallMethod. - */ +/// @brief Alloc a new GSC function param before calling the function with Scr_CallFunction/Scr_CallMethod. #define FUNC(val) Scr_SetParamGeneric(__callArgNumber, val, VAR_FUNCTION) -/** - * @brief Alloc a new GSC undefined param before calling the function with Scr_CallFunction/Scr_CallMethod. - */ +/// @brief Alloc a new GSC undefined param before calling the function with Scr_CallFunction/Scr_CallMethod. #define UNDEFINED() Scr_SetParamGeneric(__callArgNumber, NULL, VAR_UNDEFINED) -/** - * @brief Alloc a new GSC generic param before calling the function with Scr_CallFunction/Scr_CallMethod. - * - * @param paramnum - The param index to alloc. - * @param var - The value of the generic variable. - * @param type - The type of the generic variable. - * @return qboolean - Boolean result. - */ -Plugin(qboolean, Scr_SetParamGeneric(unsigned int paramnum, void *var, int type)); - -/** - * @todo - * - * @brief Call the specified GSC function pointer - * This function is experimental. - * - * @param function - The GSC function pointer. - * @param ... - GSC alloc macros can be written here only for convenience. - */ -Plugin(void, Scr_CallFunction(void (*function)(void), ...)); - -/** - * @todo - * - * @brief Call the specified GSC method pointer - * This function is experimental. - * - * @param function - The GSC function pointer. - * @param ent - The GSC entref. - * @param ... - GSC alloc macros can be written here only for convenience. - */ -Plugin(void, Scr_CallMethod(void (*function)(scr_entref_t), scr_entref_t ent, ...)); - -/** - * @brief Get the GSC thread return value. - */ -Plugin(int, Scr_GetThreadReturn()); - -/** - * @brief GScr test function. - * - * @param entref - GSC entref. - */ +/// @brief Alloc a new GSC generic param before calling the function with Scr_CallFunction/Scr_CallMethod. +/// @param paramnum - The param index to alloc. +/// @param var - The value of the generic variable. +/// @param type - The type of the generic variable. +/// @return qboolean - Boolean result. +EXPORT(qboolean, Scr_SetParamGeneric(unsigned int paramnum, void *var, int type)); + +/// @brief Call the specified GSC function pointer. This function is experimental. +/// @param function - The GSC function pointer. +/// @param ... - GSC alloc macros can be written here only for convenience. +/// @todo +EXPORT(void, Scr_CallFunction(void (*function)(void), ...)); + +/// @brief Call the specified GSC method pointer. This function is experimental. +/// This function is experimental. +/// @param function - The GSC function pointer. +/// @param ent - The GSC entref. +/// @param ... - GSC alloc macros can be written here only for convenience. +/// @todo +EXPORT(void, Scr_CallMethod(void (*function)(scr_entref_t), scr_entref_t ent, ...)); + +/// @brief Get the GSC thread return value. +EXPORT(int, Scr_GetThreadReturn()); + +/// @brief GScr test function. +/// @param entref - GSC entref. void GScr_Test(scr_entref_t entref); diff --git a/extensions/variables.h b/extensions/variables.h index f6bfafc..2834f91 100644 --- a/extensions/variables.h +++ b/extensions/variables.h @@ -1,96 +1,59 @@ #pragma once #include "cgsc.h" -/** - * @brief Create a new VariableValueArray with a fixed length. - * The array can be freed with Scr_FreeArray. - * - * @param length - The array length. - */ -Plugin(VariableValueArray, Scr_CreateArray(int length)); - -/** - * @brief Free the variables of VariableValueArray. - * - * @param array - The VariableValueArray to free. - */ -Plugin(void, Scr_FreeArray(VariableValueArray* array)); - -/** - * @brief Get a GSC array from specified param number. - * - * @param paramnum - GSC param number. - * @return VariableValueArray - The GSC array. - */ -Plugin(VariableValueArray, Scr_GetArray(unsigned int paramnum)); - -/** - * @brief Get a GSC variable reference from the specified param number. - * If the param number is not found it will allocate a default one. - * - * @param paramnum - GSC param number. - * @return VariableValue* - GSC variable reference. - */ -Plugin(VariableValue*, Scr_SelectParamOrDefault(unsigned int paramnum)); - -/** - * @brief Get a GSC variable reference from the specified param number. - * - * @param paramnum - GSC param number. - * @return VariableValue* - GSC variable reference. - */ -Plugin(VariableValue*, Scr_SelectParam(unsigned int paramnum)); - -/** - * @brief Get a GSC variable reference from the GSC stack with the specified index. - * - * @param paramnum - Index to get from the GSC stack. - * @return VariableValue* - GSC variable reference. - */ -Plugin(VariableValue*, Scr_GetTop(unsigned int paramnum)); - -/** - * @brief Get a copy of the last GSC return variable. - * - * @return VariableValue - The copied variable. - */ -Plugin(VariableValue, Scr_ReturnResult()); - -/** - * @brief Call a GSC function and keep the GSC return value uncleared. - * - * @param callbackHook - GSC function ID. - * @param numArgs - GSC function args count. - * @return short - The GSC thread id to be freed with Scr_FreeThread(). - */ -Plugin(short, Scr_ExecThreadResult(int callbackHook, unsigned int numArgs)); - -/** - * @brief Return a GSC Function from specified codeposvalue. - * This function is untested. - * - * @param codePosValue - */ -Plugin(void, Scr_AddFunc(const char *codePosValue)); - -/** - * @brief Return a GSC variable. - * - * @param var - The GSC variable to return. - */ -Plugin(void, Scr_AddVariable(VariableValue var)); - -/** - * @brief Get the flags from GSC array object. - * - * @param array - The GSC array. - * @return uint32_t - Flags value. - */ -Plugin(uint32_t, Scr_GetArrayFlags(VariableValueArray array)); - -/** - * @brief Get the pointer object type. - * - * @param int - The type id. - */ -Plugin(unsigned int, Scr_GetObjectType(unsigned int id)); +/// @brief Create a new VariableValueArray with a fixed length. +/// The array can be freed with Scr_FreeArray.The array can be freed with Scr_FreeArray. +/// @param length - The array length. +EXPORT(VariableValueArray, Scr_CreateArray(int length)); + +/// @brief Free the variables of VariableValueArray. +/// @param array - The VariableValueArray to free. +EXPORT(void, Scr_FreeArray(VariableValueArray* array)); + +/// @brief Get a GSC array from specified param number. +/// @param paramnum - GSC param number. +/// @return VariableValueArray - The GSC array. +EXPORT(VariableValueArray, Scr_GetArray(unsigned int paramnum)); + +/// @brief Get a GSC variable reference from the specified param number. +/// If the param number is not found it will allocate a default one. +/// @param paramnum - GSC param number. +/// @return VariableValue* - GSC variable reference. +EXPORT(VariableValue*, Scr_SelectParamOrDefault(unsigned int paramnum)); + +/// @brief Get a GSC variable reference from the specified param number. +/// @param paramnum - GSC param number. +/// @return VariableValue* - GSC variable reference. +EXPORT(VariableValue*, Scr_SelectParam(unsigned int paramnum)); + +/// @brief Get a GSC variable reference from the GSC stack with the specified index. +/// @param paramnum - Index to get from the GSC stack. +/// @return VariableValue* - GSC variable reference. +EXPORT(VariableValue*, Scr_GetTop(unsigned int paramnum)); + +/// @brief Get a copy of the last GSC return variable. +/// @return VariableValue - The copied variable. +EXPORT(VariableValue, Scr_ReturnResult()); + +/// @brief Call a GSC function and keep the GSC return value uncleared. +/// @param callbackHook - GSC function ID. +/// @param numArgs - GSC function args count. +/// @return short - The GSC thread id to be freed with Scr_FreeThread(). +EXPORT(short, Scr_ExecThreadResult(int callbackHook, unsigned int numArgs)); + +/// @brief Return a GSC Function from specified codeposvalue. This function is untested. +/// @param codePosValue - The code pos value. +EXPORT(void, Scr_AddFunc(const char *codePosValue)); + +/// @brief Return a GSC variable. +/// @param var - The GSC variable to return. +EXPORT(void, Scr_AddVariable(VariableValue var)); + +/// @brief Get the flags from GSC array object. +/// @param array - The GSC array. +/// @return uint32_t - Flags value. +EXPORT(uint32_t, Scr_GetArrayFlags(VariableValueArray array)); + +/// @brief Get the pointer object type. +/// @param int - The type id. +EXPORT(unsigned int, Scr_GetObjectType(unsigned int id)); diff --git a/plugin.h b/plugin.h index 16daf18..976dbf4 100644 --- a/plugin.h +++ b/plugin.h @@ -86,10 +86,7 @@ enum $0E0E04F36A22A28F2C0A7A22DC12DAE9 VAR_ENDON_LIST = 0x19 }; -/** - * @brief Get GSC function id from specified param num. - * - * @param paramnum - GSC param index. - * @return int - The GSC function id. - */ +/// @brief Get GSC function id from specified param num. +/// @param paramnum - GSC param index. +/// @return The GSC function id. int Plugin_Scr_GetFunction(unsigned int paramnum); diff --git a/sys/compatibility.h b/sys/compatibility.h index 56c5c5e..1857914 100644 --- a/sys/compatibility.h +++ b/sys/compatibility.h @@ -1,36 +1,21 @@ #pragma once #include "cgsc.h" -/** - * @brief Returns server version. - */ -Plugin(float, Sys_GetCommonVersion()); +/// @brief Returns server version. +EXPORT(float, Sys_GetCommonVersion()); -/** - * @brief Check if CGSC version is unsupported. - * throws a GSC error if true. - * - * @param versionCondition - The version condition returned by macros - * such as CGSC(ver) or CGSC_EQ(ver) etc... - * @return qboolean - */ +/// @brief Check if CGSC version is unsupported, throws a GSC error if true. +/// @param versionCondition - The version condition returned by macros such as CGSC(ver) or CGSC_EQ(ver) etc... +/// @return qboolean CGSC_Unsupported(qboolean versionCondition); -/** - * @brief Check if CGSC version is unsupported. - * throws a GSC error with a message if true. - * - * @param versionCondition - The version condition returned by macros - * such as CGSC(ver) or CGSC_EQ(ver) etc... - * @param format - The format string. - * @param ... - The format arguments. - * @return qboolean - */ +/// @brief Check if CGSC version is unsupported, throws a GSC error with a message if true. +/// @param versionCondition - The version condition returned by macros such as CGSC(ver) or CGSC_EQ(ver) etc... +/// @param format - The format string. +/// @param ... - The format arguments. +/// @return qboolean CGSC_UnsupportedMessage(qboolean versionCondition, char *format, ...); -/** - * @brief Check if CGSC supports indexed string. - * - * @return qboolean - */ +/// @brief Check if CGSC supports indexed string. +/// @return qboolean CGSC_SupportIndexedString(); diff --git a/utils/utils.h b/utils/utils.h index 0389ebd..fd13363 100644 --- a/utils/utils.h +++ b/utils/utils.h @@ -1,9 +1,7 @@ #pragma once #include "cgsc.h" -/** - * @brief Print a formated string to the console. - */ +/// @brief Print a formated string to the console. #if CGSC(4) #ifdef PLUGIN #define CGSC_Printf(fmt, ...) Com_Printf(fmt, __VA_ARGS__); @@ -14,33 +12,25 @@ #define CGSC_Printf(fmt, ...) Com_Printf(fmt, __VA_ARGS__); #endif +/// @brief Get a register value. #define GetRegisterValue(var, reg) \ register int _register asm(reg); \ *var = _register; -/** - * @brief Format a string. - * - * @param format - The string to format. - * @param ... - The format arguments. - * @return char* - The formatted string. - */ +/// @brief Format a string. +/// @param format - The string to format. +/// @param ... - The format arguments. +/// @return The formatted string. char *fmt(char *format, ...); -/** - * @brief Check if a flag is set in the GSC array flag variable. - * - * @param var - GSC array flag variable. - * @param flag - The flag to test. - * @return qboolean - The result of the test. - */ +/// @brief Check if a flag is set in the GSC array flag variable. +/// @param var - GSC array flag variable. +/// @param flag - The flag to test. +/// @return The result of the test. qboolean HasFlag(int var, int flag); -/** - * @brief Check if the specified flag is the only flag set in the GSC array flag variable. - * - * @param var - GSC array flag variable. - * @param flag - The flag to test. - * @return qboolean - The result of the test. - */ +/// @brief Check if the specified flag is the only flag set in the GSC array flag variable. +/// @param var - GSC array flag variable. +/// @param flag - The flag to test. +/// @return The result of the test. qboolean IsFlag(int var, int flag); diff --git a/versions/cgsc3.c b/versions/cgsc3.c index 1c47db7..c5a1d38 100644 --- a/versions/cgsc3.c +++ b/versions/cgsc3.c @@ -21,12 +21,18 @@ __attribute__((unused)) scrVmPub_t gScrVmPub = {0}; __attribute__((unused)) struct scrVmGlob_t gScrVmGlob = {0}; __attribute__((unused)) scrVarPub_t gScrVarPub; +/// @brief Get the object type. +/// @param id - The object id. +/// @return unsigned int Scr_GetObjectType(unsigned int id) { assert((IGScrVarGlob[VARIABLELIST_PARENT_BEGIN + id].w.status & VAR_STAT_MASK) != VAR_STAT_FREE); return VAR_TYPE((&IGScrVarGlob[id + VARIABLELIST_PARENT_BEGIN])); } +/// @brief Get the array size. +/// @param id - The array id. +/// @return int GetArraySize(int id) { VariableValueInternal *entryValue; diff --git a/versions/cgsc4.c b/versions/cgsc4.c index e26a5d0..3f6de85 100644 --- a/versions/cgsc4.c +++ b/versions/cgsc4.c @@ -1,6 +1,8 @@ #include "cgsc4.h" #if CGSC_EQ(4) +/// @brief Add a function pointer to the GSC stack. +/// @param codePosValue - The code pos value. void Scr_AddFunc(const char *codePosValue) { IncInParam(); From 0fa9085939e6681251091e7fd881d9451ca23690 Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Tue, 29 Nov 2022 20:48:56 +0100 Subject: [PATCH 03/20] Project: Plugin build --- .conan/patches/CMakeLists.txt.patch | 18 ------ CMakeLists.txt | 31 +++++----- asm/cgsc_export.asm | 23 +++++++- conanfile.py | 89 ++++++++++++++--------------- plugin.h | 59 +++++++++++++++++++ sys/compatibility.h | 6 +- 6 files changed, 143 insertions(+), 83 deletions(-) delete mode 100644 .conan/patches/CMakeLists.txt.patch diff --git a/.conan/patches/CMakeLists.txt.patch b/.conan/patches/CMakeLists.txt.patch deleted file mode 100644 index 3e92297..0000000 --- a/.conan/patches/CMakeLists.txt.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- CMakeLists.txt 2022-04-12 17:01:55.826989300 +0200 -+++ CMakeLists.txt 2022-04-12 17:05:15.011813500 +0200 -@@ -35,14 +35,9 @@ - # Build - add_library(CGSC) - add_subdirectory(api) --add_subdirectory(asm) --add_subdirectory(extensions) - --target_compile_definitions(CGSC PUBLIC COD4X18UPDATE) --target_include_directories(CGSC PUBLIC . .. ../version ../../plugins) -+target_include_directories(CGSC PUBLIC . cod4x/plugins) - target_sources(CGSC PRIVATE cgsc.h) -- --set_target_properties(CGSC PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ../../../lib) - source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES}) - - # Pack diff --git a/CMakeLists.txt b/CMakeLists.txt index 42715ee..be125ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.16.0) -project(CGSC VERSION 1.1.0 LANGUAGES C) +project(CGSC VERSION 1.2.0 LANGUAGES C) set_property(GLOBAL PROPERTY USE_FOLDERS ON) set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) @@ -33,18 +33,23 @@ if(ENABLE_TESTING) endif() # Build -add_library(CGSC) -add_subdirectory(asm) -add_subdirectory(extensions) -add_subdirectory(sys) -add_subdirectory(utils) -add_subdirectory(versions) - -target_compile_definitions(CGSC PUBLIC COD4X18UPDATE) -target_include_directories(CGSC PUBLIC . .. ../version ../../plugins) -target_sources(CGSC PRIVATE cgsc.h) - -set_target_properties(CGSC PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ../../../lib) +if(PLUGIN) + add_library(CGSC INTERFACE CGSC/cgsc.h CGSC/plugin.h) + target_include_directories(CGSC INTERFACE . cod4x/plugins) +else() + add_library(CGSC STATIC cgsc.h cod4x.h) + + add_subdirectory(asm) + add_subdirectory(extensions) + add_subdirectory(sys) + add_subdirectory(utils) + add_subdirectory(versions) + + target_compile_definitions(CGSC PUBLIC COD4X18UPDATE) + target_include_directories(CGSC PUBLIC . .. ../version ../../plugins) + set_target_properties(CGSC PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ../../../lib) +endif() + source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES}) # Pack diff --git a/asm/cgsc_export.asm b/asm/cgsc_export.asm index 968f3fc..bb27433 100644 --- a/asm/cgsc_export.asm +++ b/asm/cgsc_export.asm @@ -12,6 +12,20 @@ p%1 dd %1 %endmacro +; CGSC exports +%macro cgsc 1 + SECTION .text + %ifdef Win32 + EXPORT %1 + %endif + global %1 + %1: jmp dword [p%1] + + SECTION .rodata + extern %1 + p%1 dd %1 +%endmacro + ; Rename function %macro ralias 2 SECTION .text @@ -29,7 +43,7 @@ ; Rename ralias Plugin_Scr_GetFunction, Scr_GetFunc -; Export +; Plugin export pexport Scr_ReturnResult pexport Scr_AddFunc pexport Scr_AddVariable @@ -46,4 +60,9 @@ pexport Scr_GetTop pexport Sys_GetCommonVersion pexport Scr_SelectParamOrDefault pexport Scr_SelectParam -pexport Scr_SetParamGeneric \ No newline at end of file +pexport Scr_SetParamGeneric + +; CGSC export +cgsc CGSC_Unsupported +cgsc CGSC_UnsupportedMessage +cgsc CGSC_SupportIndexedString diff --git a/conanfile.py b/conanfile.py index 961f4bc..4e39c41 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,49 +1,44 @@ -from conans import ConanFile, CMake, tools +from conans import ConanFile, CMake + class CGSC(ConanFile): - name = "CGSC" - version = "1.1.1" - license = "LICENCE" - url = "https://github.com/Iswenzz/CGSC" - description = "Call of Duty 4X source extension that adds new features for creating plugins not offered in the original source." - - generators = "cmake" - exports_sources = "LICENSE", "README.md", "CMakeLists.txt", "cgsc.h" - - settings = "os", "arch", "compiler", "build_type" - options = {"enable_testing": [True, False]} - default_options = {"enable_testing": False} - - def build_requirements(self): - if self.options.enable_testing: - self.build_requires("greatest/1.5.0", force_host_context=True) - - def export_plugin_api(self): - self.copy("pinc.h", src="../../plugins", dst="cod4x/plugins") - self.copy("declarations.h", src="../../plugins", dst="cod4x/plugins") - self.copy("plugin_declarations.h", src="../../plugins", dst="cod4x/plugins") - self.copy("callback_declarations.h", src="../../plugins", dst="cod4x/plugins") - self.copy("function_declarations.h", src="../../plugins", dst="cod4x/plugins") - - def export_sources(self): - self.copy(".conan/*") - self.copy("api/*") - self.copy("*.h", src="extensions", dst="extensions") - self.export_plugin_api() - - def build(self): - tools.patch(patch_file=".conan/patches/CMakeLists.txt.patch") - cmake_release = CMake(self, build_type="Release") - cmake_release.configure() - cmake_release.build() - - def package(self): - self.copy("LICENSE, README.md") - self.copy("*.h", dst="include", excludes="cod4x") - self.copy("*.a", dst="lib", keep_path=False) - self.copy("*.lib", dst="lib", keep_path=False) - self.copy("*.dll", dst="bin", keep_path=False) - self.copy("*.so", dst="bin", keep_path=False) - - def package_info(self): - self.cpp_info.libs = ["CGSC"] + name = "CGSC" + version = "1.2.0" + license = "LICENCE" + url = "https://github.com/Iswenzz/CGSC" + description = "Call of Duty 4X source extension that adds new features for creating plugins not offered in the original source." + + generators = "cmake" + exports_sources = "LICENSE", "README.md", "CMakeLists.txt", ".conan/*" + + settings = "os", "arch", "compiler", "build_type" + options = {"enable_testing": [True, False]} + default_options = {"enable_testing": False} + no_copy_source = True + + def build_requirements(self): + if self.options.enable_testing: + self.build_requires("greatest/1.5.0", force_host_context=True) + + def export_sources(self): + self.copy("cgsc.h", dst="CGSC") + self.copy("plugin.h", dst="CGSC") + self.copy("*.h", src="extensions", dst="CGSC/extensions") + self.copy("*.h", src="sys", dst="CGSC/sys") + self.copy("*.h", src="utils", dst="CGSC/utils") + self.copy("*.h", src="versions", dst="CGSC/versions") + + def build(self): + cmake_release = CMake(self, build_type="Release") + cmake_release.definitions["CONAN_DISABLE_CHECK_COMPILER"] = True + cmake_release.definitions["PLUGIN"] = True + cmake_release.configure() + cmake_release.build() + + def package(self): + self.copy("LICENSE, README.md") + self.copy("*.h", dst="include", excludes="cod4x") + self.copy("*.a", dst="lib", keep_path=False) + self.copy("*.lib", dst="lib", keep_path=False) + self.copy("*.dll", dst="bin", keep_path=False) + self.copy("*.so", dst="bin", keep_path=False) diff --git a/plugin.h b/plugin.h index 976dbf4..0789bfd 100644 --- a/plugin.h +++ b/plugin.h @@ -54,6 +54,65 @@ typedef struct int type; } VariableValue; +union ObjectInfo_u +{ + uint16_t size; + uint16_t entnum; + uint16_t nextEntId; + uint16_t self; +}; + +struct ObjectInfo +{ + uint16_t refCount; + union ObjectInfo_u u; +}; + +union VariableValueInternal_u +{ + uint16_t next; + union VariableUnion u; + struct ObjectInfo o; +}; + +union VariableValueInternal_w +{ + unsigned int status; + unsigned int type; + unsigned int name; + unsigned int classnum; + unsigned int notifyName; + unsigned int waitTime; + unsigned int parentLocalId; +}; + +union VariableValueInternal_v +{ + uint16_t next; + uint16_t index; +}; + +union Variable_u +{ + uint16_t prev; + uint16_t prevSibling; +}; + +struct Variable +{ + uint16_t id; + union Variable_u u; +}; + +typedef struct +{ + struct Variable hash; + union VariableValueInternal_u u; + union VariableValueInternal_w w; + union VariableValueInternal_v v; + uint16_t nextSibling; +}VariableValueInternal; + enum $0E0E04F36A22A28F2C0A7A22DC12DAE9 { VAR_UNDEFINED = 0x0, diff --git a/sys/compatibility.h b/sys/compatibility.h index 1857914..3edc54b 100644 --- a/sys/compatibility.h +++ b/sys/compatibility.h @@ -7,15 +7,15 @@ EXPORT(float, Sys_GetCommonVersion()); /// @brief Check if CGSC version is unsupported, throws a GSC error if true. /// @param versionCondition - The version condition returned by macros such as CGSC(ver) or CGSC_EQ(ver) etc... /// @return -qboolean CGSC_Unsupported(qboolean versionCondition); +EXPORT(qboolean, CGSC_Unsupported(qboolean versionCondition)); /// @brief Check if CGSC version is unsupported, throws a GSC error with a message if true. /// @param versionCondition - The version condition returned by macros such as CGSC(ver) or CGSC_EQ(ver) etc... /// @param format - The format string. /// @param ... - The format arguments. /// @return -qboolean CGSC_UnsupportedMessage(qboolean versionCondition, char *format, ...); +EXPORT(qboolean, CGSC_UnsupportedMessage(qboolean versionCondition, char *format, ...)); /// @brief Check if CGSC supports indexed string. /// @return -qboolean CGSC_SupportIndexedString(); +EXPORT(qboolean, CGSC_SupportIndexedString()); From ec76e187ab79bcae4ab722b1e46f55ecae3d5d6b Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Tue, 29 Nov 2022 21:26:12 +0100 Subject: [PATCH 04/20] CGSC: DLL export --- asm/cgsc_export.asm | 6 +----- cgsc.h | 7 +++++++ plugin.h | 7 ------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/asm/cgsc_export.asm b/asm/cgsc_export.asm index bb27433..efc747a 100644 --- a/asm/cgsc_export.asm +++ b/asm/cgsc_export.asm @@ -14,14 +14,10 @@ ; CGSC exports %macro cgsc 1 - SECTION .text + SECTION .rodata %ifdef Win32 EXPORT %1 %endif - global %1 - %1: jmp dword [p%1] - - SECTION .rodata extern %1 p%1 dd %1 %endmacro diff --git a/cgsc.h b/cgsc.h index 10c9691..f28e4bb 100644 --- a/cgsc.h +++ b/cgsc.h @@ -28,6 +28,13 @@ type definition; \ type Plugin_##definition +#define CHECK_UNSUPPORTED(condition) \ +if (CGSC_UnsupportedMessage(condition, "CGSC: This feature is unsupported in this version.")) \ +{ \ + Scr_AddUndefined(); \ + return; \ +} + #define CLASS_NUM_COUNT sizeof(gScrClassMap) / sizeof(gScrClassMap[0]) #define DEBUG_REFCOUNT_SIZE 65536 #define MAX_ARRAYINDEX 0x800000 diff --git a/plugin.h b/plugin.h index 0789bfd..e697a33 100644 --- a/plugin.h +++ b/plugin.h @@ -19,13 +19,6 @@ if (Plugin_Scr_GetNumParam() != count) \ return; \ } -#define CHECK_UNSUPPORTED(condition) \ -if (CGSC_UnsupportedMessage(condition, "CGSC: This feature is unsupported in this version.")) \ -{ \ - Scr_AddUndefined(); \ - return; \ -} - struct VariableStackBuffer { const char *pos; From 992a6d6c86b94fde98619b81c3c0e8509b01c886 Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Tue, 29 Nov 2022 21:33:31 +0100 Subject: [PATCH 05/20] Updated README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d65d5ba..3c25fea 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![CodeFactor](https://img.shields.io/codefactor/grade/github/Iswenzz/CGSC?label=codefactor&logo=codefactor)](https://www.codefactor.io/repository/github/iswenzz/CGSC) [![License](https://img.shields.io/github/license/Iswenzz/CGSC?color=blue&logo=gitbook&logoColor=white)](https://github.com/Iswenzz/CGSC/blob/master/LICENSE) -This Call of Duty 4X source extension adds new utilities to extended the server and the creation of new plugins. Such things include new functions to get data types that the original source doesn't offer and adds the ability to call functions defined in GSC from the C files. To use this extension you must add the CGSC files included in the release section to the `/src/CGSC` folder, and then compile the CoD4X server source. More detailed instructions can be found towards the bottom of this document. +This Call of Duty 4X source extension adds new utilities to extend the server and the creation of new plugins. Such things include new functions to get data types that the original source doesn't offer and adds the ability to call functions defined in GSC from the C files. To use this extension you must add the CGSC files included in the release section to the `/src/CGSC` folder, and then compile the CoD4X server source. More detailed instructions can be found towards the bottom of this document. ``Note: Depending on the version of Call of Duty 4X that you're running, some features of CGSC may not be available.`` From a6d13a485e96a178fd84a7951487d06c81075819 Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Thu, 8 Dec 2022 21:24:43 +0100 Subject: [PATCH 06/20] CGSC: Copy static libraries Can't find anything to combine static libraries with cmake --- CMakeLists.txt | 9 +++++++++ README.md | 6 +++--- cgsc.h | 1 + conanfile.py | 3 ++- sys/CMakeLists.txt | 2 ++ sys/async.c | 7 +++++++ sys/async.h | 10 ++++++++++ 7 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 sys/async.c create mode 100644 sys/async.h diff --git a/CMakeLists.txt b/CMakeLists.txt index be125ff..bdc924b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,8 +50,17 @@ else() set_target_properties(CGSC PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ../../../lib) endif() +target_link_libraries(CGSC PUBLIC ${CONAN_LIBS}) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES}) +set(STATIC_DEPENDENCIES + ${CONAN_LIB_DIRS_LIBUV}/libuv_a.a) + +foreach(dependency ${STATIC_DEPENDENCIES}) + add_custom_command(TARGET CGSC POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${dependency} ../../../lib) +endforeach() + # Pack install(TARGETS CGSC LIBRARY DESTINATION lib) install(DIRECTORY src/ DESTINATION lib/include/CGSC diff --git a/README.md b/README.md index 3c25fea..dda1cb9 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,9 @@ Then simply build the cod4x source with ``make``. ################################## # CGSC CGSC_DIR=$(SRC_DIR)/CGSC -WIN_LLIBS:=$(WIN_LLIBS) CGSC -LINUX_LLIBS:=$(LINUX_LLIBS) CGSC -BSD_LLIBS:=$(BSD_LLIBS) CGSC +WIN_LLIBS:=$(WIN_LLIBS) CGSC uv_a iphlpapi psapi userenv ws2_32 +LINUX_LLIBS:=$(LINUX_LLIBS) CGSC uv_a dl pthread rt +BSD_LLIBS:=$(BSD_LLIBS) CGSC uv_a dl pthread rt WIN_LFLAGS:=$(WIN_LFLAGS) -mconsole diff --git a/cgsc.h b/cgsc.h index f28e4bb..af22bb1 100644 --- a/cgsc.h +++ b/cgsc.h @@ -114,6 +114,7 @@ typedef struct } VariableValueArray; #include "sys/compatibility.h" +#include "sys/async.h" #include "extensions/functions.h" #include "extensions/variables.h" #include "utils/utils.h" diff --git a/conanfile.py b/conanfile.py index 4e39c41..43b40cd 100644 --- a/conanfile.py +++ b/conanfile.py @@ -6,10 +6,11 @@ class CGSC(ConanFile): version = "1.2.0" license = "LICENCE" url = "https://github.com/Iswenzz/CGSC" - description = "Call of Duty 4X source extension that adds new features for creating plugins not offered in the original source." + description = "Call of Duty 4X source extension that adds new utilities to extend the server and the creation of new plugins." generators = "cmake" exports_sources = "LICENSE", "README.md", "CMakeLists.txt", ".conan/*" + requires = ["libuv/1.44.2"] settings = "os", "arch", "compiler", "build_type" options = {"enable_testing": [True, False]} diff --git a/sys/CMakeLists.txt b/sys/CMakeLists.txt index 2736252..f17dca9 100644 --- a/sys/CMakeLists.txt +++ b/sys/CMakeLists.txt @@ -1,3 +1,5 @@ target_sources(CGSC PRIVATE + async.c + async.h compatibility.c compatibility.h) diff --git a/sys/async.c b/sys/async.c new file mode 100644 index 0000000..7872846 --- /dev/null +++ b/sys/async.c @@ -0,0 +1,7 @@ +#include "async.h" +#include + +void Async_HandlerInitialize() +{ + uv_run(uv_default_loop(), UV_RUN_DEFAULT); +} diff --git a/sys/async.h b/sys/async.h new file mode 100644 index 0000000..187be95 --- /dev/null +++ b/sys/async.h @@ -0,0 +1,10 @@ +#pragma once + +/// @brief Initialize the async workers. +void Async_HandlerInitialize(); + +/// @brief Shutdown the async workers. +void Async_HandlerShutdown(); + +/// @brief Call a function asynchronously. +void Async_Call(); From c72e3da5a54ab42ca45adb2d461ecdf675fd60ec Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Thu, 8 Dec 2022 23:22:00 +0100 Subject: [PATCH 07/20] Async: libuv asynchronous calls with thread pool --- sys/async.c | 25 ++++++++++++++++++++++--- sys/async.h | 22 ++++++++++++++++------ 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/sys/async.c b/sys/async.c index 7872846..e44ffd9 100644 --- a/sys/async.c +++ b/sys/async.c @@ -1,7 +1,26 @@ #include "async.h" -#include -void Async_HandlerInitialize() +void AsyncShutdown() { - uv_run(uv_default_loop(), UV_RUN_DEFAULT); + uv_loop_close(uv_default_loop()); +} + +void AsyncCall(void *data, uv_work_cb callback, uv_after_work_cb callbackDone) +{ + uv_work_t *req = (uv_work_t *)malloc(sizeof(uv_work_t)); + req->data = data; + + if (!callbackDone) + callbackDone = &AsyncNull; + uv_queue_work(uv_default_loop(), req, callback, callbackDone); +} + +void AsyncNull(uv_work_t* req, int status) +{ + AsyncFree(req); +} + +void AsyncFree(uv_work_t* req) +{ + free(req); } diff --git a/sys/async.h b/sys/async.h index 187be95..d77d731 100644 --- a/sys/async.h +++ b/sys/async.h @@ -1,10 +1,20 @@ #pragma once +#include -/// @brief Initialize the async workers. -void Async_HandlerInitialize(); +/// @brief Shutdown all async operations. +void AsyncShutdown(); -/// @brief Shutdown the async workers. -void Async_HandlerShutdown(); +/// @brief Make an async call. +/// @param data - The data to pass. +/// @param callback - The async callback. +/// @param callbackDone - The callback when the async operation is completed. +void AsyncCall(void *data, uv_work_cb callback, uv_after_work_cb callbackDone); -/// @brief Call a function asynchronously. -void Async_Call(); +/// @brief Default after worker callback. +/// @param req - The worker request. +/// @param status - The request status. +void AsyncNull(uv_work_t* req, int status); + +/// @brief Free a worker request. +/// @param req - The worker request. +void AsyncFree(uv_work_t* req); From ab8a86e51245c530c3f2fb21ef28147435725d9f Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Fri, 9 Dec 2022 16:26:32 +0100 Subject: [PATCH 08/20] Updated README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dda1cb9..7b4c588 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ This Call of Duty 4X source extension adds new utilities to extend the server an ## Instructions In order to use this extension, just download the archived file down below, and extract it to the cod4x server's ``src/CGSC`` directory, then copy the makefile snippet below and paste it before the default rule. -Then simply build the cod4x source with ``make``. +Then simply build the library with the build instructions and recompile the cod4x source with ``make``. ### **[Download](https://github.com/Iswenzz/CGSC/releases)** From 7a7a72c1cb571bfad61acc8b76be7f1ad2a316b5 Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Fri, 9 Dec 2022 16:26:44 +0100 Subject: [PATCH 09/20] ASM: Export async functions --- asm/cgsc_export.asm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asm/cgsc_export.asm b/asm/cgsc_export.asm index efc747a..15635cf 100644 --- a/asm/cgsc_export.asm +++ b/asm/cgsc_export.asm @@ -57,6 +57,10 @@ pexport Sys_GetCommonVersion pexport Scr_SelectParamOrDefault pexport Scr_SelectParam pexport Scr_SetParamGeneric +pexport AsyncShutdown +pexport AsyncCall +pexport AsyncNull +pexport AsyncFree ; CGSC export cgsc CGSC_Unsupported From 39fca467878192a86fc1a1b1be9e32d38b600435 Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Fri, 9 Dec 2022 17:55:16 +0100 Subject: [PATCH 10/20] Async: Return worker pointer & documentation --- CMakeLists.txt | 18 +++++++++--------- README.md | 2 +- docs/async.md | 33 +++++++++++++++++++++++++++++++++ sys/async.c | 4 +++- sys/async.h | 9 +++++---- 5 files changed, 51 insertions(+), 15 deletions(-) create mode 100644 docs/async.md diff --git a/CMakeLists.txt b/CMakeLists.txt index bdc924b..fe7d47f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,21 +45,21 @@ else() add_subdirectory(utils) add_subdirectory(versions) + target_link_libraries(CGSC PUBLIC ${CONAN_LIBS}) target_compile_definitions(CGSC PUBLIC COD4X18UPDATE) target_include_directories(CGSC PUBLIC . .. ../version ../../plugins) set_target_properties(CGSC PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ../../../lib) -endif() -target_link_libraries(CGSC PUBLIC ${CONAN_LIBS}) -source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES}) + set(STATIC_DEPENDENCIES + ${CONAN_LIB_DIRS_LIBUV}/libuv_a.a) -set(STATIC_DEPENDENCIES - ${CONAN_LIB_DIRS_LIBUV}/libuv_a.a) + foreach(dependency ${STATIC_DEPENDENCIES}) + add_custom_command(TARGET CGSC POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${dependency} ../../../lib) + endforeach() +endif() -foreach(dependency ${STATIC_DEPENDENCIES}) - add_custom_command(TARGET CGSC POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${dependency} ../../../lib) -endforeach() +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES}) # Pack install(TARGETS CGSC LIBRARY DESTINATION lib) diff --git a/README.md b/README.md index 7b4c588..34bd4be 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![CodeFactor](https://img.shields.io/codefactor/grade/github/Iswenzz/CGSC?label=codefactor&logo=codefactor)](https://www.codefactor.io/repository/github/iswenzz/CGSC) [![License](https://img.shields.io/github/license/Iswenzz/CGSC?color=blue&logo=gitbook&logoColor=white)](https://github.com/Iswenzz/CGSC/blob/master/LICENSE) -This Call of Duty 4X source extension adds new utilities to extend the server and the creation of new plugins. Such things include new functions to get data types that the original source doesn't offer and adds the ability to call functions defined in GSC from the C files. To use this extension you must add the CGSC files included in the release section to the `/src/CGSC` folder, and then compile the CoD4X server source. More detailed instructions can be found towards the bottom of this document. +This Call of Duty 4X source extension adds new utilities to extend the server and the creation of new plugins. Such things include new functions to get data types that the original source doesn't offer, the ability to call functions defined in GSC from the C files and async workers for expensive operations on the server. To use this extension you must add the CGSC files included in the release section to the `/src/CGSC` folder, and then compile the CoD4X server source. More detailed instructions can be found towards the bottom of this document. ``Note: Depending on the version of Call of Duty 4X that you're running, some features of CGSC may not be available.`` diff --git a/docs/async.md b/docs/async.md new file mode 100644 index 0000000..e87c46f --- /dev/null +++ b/docs/async.md @@ -0,0 +1,33 @@ +# Async + +### ``AsyncShutdown`` +Shutdown the async handler, this should be called when the server shutdown. + +```c +AsyncShutdown(); +``` +
+ +### ``AsyncCall`` +Make an async call with the provided callbacks and data. + +```c +uv_work_t *worker = AsyncCall(data, callback, completionCallback); +``` +
+ +### ``AsyncNull`` +Default worker completion callback, this default callback calls AsyncFree. + +```c +uv_work_t *worker = AsyncCall(data, callback, &AsyncNull); +``` +
+ +### ``AsyncFree`` +Free a worker request. + +```c +AsyncFree(worker); +``` +
diff --git a/sys/async.c b/sys/async.c index e44ffd9..35f5ff7 100644 --- a/sys/async.c +++ b/sys/async.c @@ -5,7 +5,7 @@ void AsyncShutdown() uv_loop_close(uv_default_loop()); } -void AsyncCall(void *data, uv_work_cb callback, uv_after_work_cb callbackDone) +uv_work_t *AsyncCall(void *data, uv_work_cb callback, uv_after_work_cb callbackDone) { uv_work_t *req = (uv_work_t *)malloc(sizeof(uv_work_t)); req->data = data; @@ -13,6 +13,8 @@ void AsyncCall(void *data, uv_work_cb callback, uv_after_work_cb callbackDone) if (!callbackDone) callbackDone = &AsyncNull; uv_queue_work(uv_default_loop(), req, callback, callbackDone); + + return req; } void AsyncNull(uv_work_t* req, int status) diff --git a/sys/async.h b/sys/async.h index d77d731..5ae87b8 100644 --- a/sys/async.h +++ b/sys/async.h @@ -1,16 +1,17 @@ #pragma once #include -/// @brief Shutdown all async operations. +/// @brief Shutdown all async operations, this should be called when the server shutdown. void AsyncShutdown(); -/// @brief Make an async call. +/// @brief Make an async call with the provided callbacks and data. /// @param data - The data to pass. /// @param callback - The async callback. /// @param callbackDone - The callback when the async operation is completed. -void AsyncCall(void *data, uv_work_cb callback, uv_after_work_cb callbackDone); +/// @return The worker pointer. +uv_work_t *AsyncCall(void *data, uv_work_cb callback, uv_after_work_cb callbackDone); -/// @brief Default after worker callback. +/// @brief Default worker completion callback, this default callback calls AsyncFree. /// @param req - The worker request. /// @param status - The request status. void AsyncNull(uv_work_t* req, int status); From 2ebfe0740be52cb277c6851b900c191a29fe9c5a Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Sat, 10 Dec 2022 15:55:25 +0100 Subject: [PATCH 11/20] CMake: Package plugin/server usage --- conanfile.py | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/conanfile.py b/conanfile.py index 43b40cd..32d6abb 100644 --- a/conanfile.py +++ b/conanfile.py @@ -13,33 +13,27 @@ class CGSC(ConanFile): requires = ["libuv/1.44.2"] settings = "os", "arch", "compiler", "build_type" - options = {"enable_testing": [True, False]} - default_options = {"enable_testing": False} + options = {"enable_testing": [True, False], "plugin": [True, False]} + default_options = {"enable_testing": False, "plugin": True} no_copy_source = True def build_requirements(self): if self.options.enable_testing: self.build_requires("greatest/1.5.0", force_host_context=True) - def export_sources(self): - self.copy("cgsc.h", dst="CGSC") - self.copy("plugin.h", dst="CGSC") - self.copy("*.h", src="extensions", dst="CGSC/extensions") - self.copy("*.h", src="sys", dst="CGSC/sys") - self.copy("*.h", src="utils", dst="CGSC/utils") - self.copy("*.h", src="versions", dst="CGSC/versions") - def build(self): cmake_release = CMake(self, build_type="Release") cmake_release.definitions["CONAN_DISABLE_CHECK_COMPILER"] = True - cmake_release.definitions["PLUGIN"] = True + if self.options.plugin: + cmake_release.definitions["PLUGIN"] = True + else: + cmake_release.definitions["COD4X18UPDATE"] = True cmake_release.configure() cmake_release.build() + def export_sources(self): + self.copy("*.h", dst="CGSC", keep_path=True) + def package(self): self.copy("LICENSE, README.md") - self.copy("*.h", dst="include", excludes="cod4x") - self.copy("*.a", dst="lib", keep_path=False) - self.copy("*.lib", dst="lib", keep_path=False) - self.copy("*.dll", dst="bin", keep_path=False) - self.copy("*.so", dst="bin", keep_path=False) + self.copy("*.h", dst="include") From 31f7ac594cceb74d54c4abd82228c037ec48549d Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Sun, 11 Dec 2022 12:53:36 +0100 Subject: [PATCH 12/20] Support: CGSC3 update --- cgsc.h | 4 ++++ cod4x.h | 10 ++++------ versions/cgsc3.c | 2 ++ versions/cgsc3.h | 34 ++++++++++++++++++++++++++++++++++ versions/cgsc4.h | 5 +++++ 5 files changed, 49 insertions(+), 6 deletions(-) diff --git a/cgsc.h b/cgsc.h index af22bb1..b27ba03 100644 --- a/cgsc.h +++ b/cgsc.h @@ -1,5 +1,9 @@ #pragma once +#ifdef _WIN32 + #define NOGDI +#endif + #ifdef COD4X18UPDATE #include "cod4x.h" #else diff --git a/cod4x.h b/cod4x.h index e716278..6eaf643 100644 --- a/cod4x.h +++ b/cod4x.h @@ -1,15 +1,13 @@ #pragma once #define COD4X +#ifndef PLUGIN_HANDLER_VERSION_MAJOR + #include +#endif + #include #include #include -#include -#include #include -#ifndef PLUGIN_HANDLER_VERSION_MAJOR - #include -#endif - #undef ASSERT diff --git a/versions/cgsc3.c b/versions/cgsc3.c index c5a1d38..3d2d9ed 100644 --- a/versions/cgsc3.c +++ b/versions/cgsc3.c @@ -1,4 +1,6 @@ #include "cgsc3.h" +#include + #if CGSC_EQ(3) struct scrVmGlob_t diff --git a/versions/cgsc3.h b/versions/cgsc3.h index 643fe52..029a5cd 100644 --- a/versions/cgsc3.h +++ b/versions/cgsc3.h @@ -9,4 +9,38 @@ extern char* SL_ConvertToString(unsigned int index); extern char* var_typename[]; +#ifdef COD4X +enum $0E0E04F36A22A28F2C0A7A22DC12DAE9 +{ + VAR_UNDEFINED = 0x0, + VAR_BEGIN_REF = 0x1, + VAR_POINTER = 0x1, + VAR_STRING = 0x2, + VAR_ISTRING = 0x3, + VAR_VECTOR = 0x4, + VAR_END_REF = 0x5, + VAR_FLOAT = 0x5, + VAR_INTEGER = 0x6, + VAR_CODEPOS = 0x7, + VAR_PRECODEPOS = 0x8, + VAR_FUNCTION = 0x9, + VAR_STACK = 0xA, + VAR_ANIMATION = 0xB, + VAR_DEVELOPER_CODEPOS = 0xC, + VAR_INCLUDE_CODEPOS = 0xD, + VAR_THREAD = 0xE, + VAR_NOTIFY_THREAD = 0xF, + VAR_TIME_THREAD = 0x10, + VAR_CHILD_THREAD = 0x11, + VAR_OBJECT = 0x12, + VAR_DEAD_ENTITY = 0x13, + VAR_ENTITY = 0x14, + VAR_ARRAY = 0x15, + VAR_DEAD_THREAD = 0x16, + VAR_COUNT = 0x17, + VAR_THREAD_LIST = 0x18, + VAR_ENDON_LIST = 0x19 +}; +#endif + #endif diff --git a/versions/cgsc4.h b/versions/cgsc4.h index 76538bc..5c334f8 100644 --- a/versions/cgsc4.h +++ b/versions/cgsc4.h @@ -3,6 +3,11 @@ #if CGSC_EQ(4) +#ifdef COD4X + #include + #include +#endif + extern struct scrVarGlob_t gScrVarGlob; extern unsigned int Scr_AllocString(const char *s); extern void Scr_AddIString(const char *value); From a18ddf55850646f9e5dc1ec7d5cd25b7e1715d40 Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Sun, 11 Dec 2022 18:14:22 +0100 Subject: [PATCH 13/20] Async: Status --- cgsc.h | 3 +++ sys/async.h | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/cgsc.h b/cgsc.h index b27ba03..3f30ad3 100644 --- a/cgsc.h +++ b/cgsc.h @@ -2,6 +2,9 @@ #ifdef _WIN32 #define NOGDI + #include + #include + #include #endif #ifdef COD4X18UPDATE diff --git a/sys/async.h b/sys/async.h index 5ae87b8..ef02a42 100644 --- a/sys/async.h +++ b/sys/async.h @@ -1,21 +1,30 @@ #pragma once +#include "cgsc.h" #include +typedef enum +{ + ASYNC_NULL, + ASYNC_PENDING, + ASYNC_SUCCESSFUL, + ASYNC_FAILURE, +} async_status; + /// @brief Shutdown all async operations, this should be called when the server shutdown. -void AsyncShutdown(); +EXPORT(void, AsyncShutdown()); /// @brief Make an async call with the provided callbacks and data. /// @param data - The data to pass. /// @param callback - The async callback. /// @param callbackDone - The callback when the async operation is completed. /// @return The worker pointer. -uv_work_t *AsyncCall(void *data, uv_work_cb callback, uv_after_work_cb callbackDone); +EXPORT(uv_work_t *, AsyncCall(void *data, uv_work_cb callback, uv_after_work_cb callbackDone)); /// @brief Default worker completion callback, this default callback calls AsyncFree. /// @param req - The worker request. /// @param status - The request status. -void AsyncNull(uv_work_t* req, int status); +EXPORT(void, AsyncNull(uv_work_t* req, int status)); /// @brief Free a worker request. /// @param req - The worker request. -void AsyncFree(uv_work_t* req); +EXPORT(void, AsyncFree(uv_work_t* req)); From bb3c20263e66a8a378f36e99d3c6fe4a3061444f Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Sun, 11 Dec 2022 23:17:10 +0100 Subject: [PATCH 14/20] CGSC: Relative import for verions --- versions/cgsc3.h | 2 +- versions/cgsc4.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/versions/cgsc3.h b/versions/cgsc3.h index 029a5cd..633045f 100644 --- a/versions/cgsc3.h +++ b/versions/cgsc3.h @@ -1,5 +1,5 @@ #pragma once -#include "cgsc.h" +#include "../cgsc.h" #if CGSC_EQ(3) diff --git a/versions/cgsc4.h b/versions/cgsc4.h index 5c334f8..f9dd654 100644 --- a/versions/cgsc4.h +++ b/versions/cgsc4.h @@ -1,5 +1,5 @@ #pragma once -#include "cgsc.h" +#include "../cgsc.h" #if CGSC_EQ(4) From 89d29bc702e735b04a3169ef0fd910b23ae493c7 Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Sun, 11 Dec 2022 23:20:04 +0100 Subject: [PATCH 15/20] CGSC: Relative import --- extensions/functions.h | 2 +- extensions/variables.h | 2 +- sys/async.h | 2 +- sys/compatibility.h | 2 +- utils/utils.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/extensions/functions.h b/extensions/functions.h index a0e4cd5..ce4e2b9 100644 --- a/extensions/functions.h +++ b/extensions/functions.h @@ -1,5 +1,5 @@ #pragma once -#include "cgsc.h" +#include "../cgsc.h" /// @brief This variable is used to keep track of param count for a single call, /// and can only be used in non-thread safe environment. diff --git a/extensions/variables.h b/extensions/variables.h index 2834f91..24e7d43 100644 --- a/extensions/variables.h +++ b/extensions/variables.h @@ -1,5 +1,5 @@ #pragma once -#include "cgsc.h" +#include "../cgsc.h" /// @brief Create a new VariableValueArray with a fixed length. /// The array can be freed with Scr_FreeArray.The array can be freed with Scr_FreeArray. diff --git a/sys/async.h b/sys/async.h index ef02a42..ff2bbac 100644 --- a/sys/async.h +++ b/sys/async.h @@ -1,5 +1,5 @@ #pragma once -#include "cgsc.h" +#include "../cgsc.h" #include typedef enum diff --git a/sys/compatibility.h b/sys/compatibility.h index 3edc54b..2cfed39 100644 --- a/sys/compatibility.h +++ b/sys/compatibility.h @@ -1,5 +1,5 @@ #pragma once -#include "cgsc.h" +#include "../cgsc.h" /// @brief Returns server version. EXPORT(float, Sys_GetCommonVersion()); diff --git a/utils/utils.h b/utils/utils.h index fd13363..44e18d3 100644 --- a/utils/utils.h +++ b/utils/utils.h @@ -1,5 +1,5 @@ #pragma once -#include "cgsc.h" +#include "../cgsc.h" /// @brief Print a formated string to the console. #if CGSC(4) From 6cf70f92b32aad0ba8c987a7c80b2034d98e96b0 Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Sat, 17 Dec 2022 22:48:47 +0100 Subject: [PATCH 16/20] System: Compatibility functions --- asm/cgsc_export.asm | 2 +- docs/api.md | 34 ++++++++++++++++++++++++++++++++++ sys/compatibility.c | 7 +++++++ sys/compatibility.h | 5 ++++- 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/asm/cgsc_export.asm b/asm/cgsc_export.asm index 15635cf..cb706c6 100644 --- a/asm/cgsc_export.asm +++ b/asm/cgsc_export.asm @@ -19,7 +19,6 @@ EXPORT %1 %endif extern %1 - p%1 dd %1 %endmacro ; Rename function @@ -63,6 +62,7 @@ pexport AsyncNull pexport AsyncFree ; CGSC export +cgsc CGSC_Version cgsc CGSC_Unsupported cgsc CGSC_UnsupportedMessage cgsc CGSC_SupportIndexedString diff --git a/docs/api.md b/docs/api.md index 9ab4abc..2dcf29f 100644 --- a/docs/api.md +++ b/docs/api.md @@ -18,6 +18,11 @@ Checking CGSC plugin handler version: #if CGSC_EQ(3) #endif ``` + +```c +CHECK_UNSUPPORTED(CGSC_EQ(3)); +``` + ```c // major version, minor version if (CGSCH >= 4 && CGSCL >= 0) @@ -36,6 +41,35 @@ Renaming a function to export: ```assembly ralias Com_Printf CGSC_Printf ``` + +Exporting a function with the CGSC prefix: +```assembly +cgsc CGSC_Version +``` +
+ +#### ``CGSC_Version()`` +Get the CGSC version. + +```c +if (CGSC_Version() >= 3.0) +``` +
+ +#### ``CGSC_Unsupported()`` +Check for unsupported version. + +```c +if (CGSC_Unsupported(version == 3.0)) +``` +
+ +#### ``CGSC_UnsupportedMessage(, )`` +Check for unsupported version. + +```c +if (CGSC_Unsupported(version == 3.0, "Unsupported version")) +```
#### ``Sys_GetCommonVersion()`` diff --git a/sys/compatibility.c b/sys/compatibility.c index 74ce391..6121ec3 100644 --- a/sys/compatibility.c +++ b/sys/compatibility.c @@ -1,6 +1,13 @@ #include "compatibility.h" #include +float CGSC_Version() +{ + char version[20] = { 0 }; + sprintf(version, "%d.%d", PLUGIN_HANDLER_VERSION_MAJOR, PLUGIN_HANDLER_VERSION_MINOR); + return atof(version); +} + qboolean CGSC_Unsupported(qboolean versionCondition) { if (!versionCondition) return qfalse; diff --git a/sys/compatibility.h b/sys/compatibility.h index 2cfed39..512b4f4 100644 --- a/sys/compatibility.h +++ b/sys/compatibility.h @@ -1,9 +1,12 @@ #pragma once #include "../cgsc.h" -/// @brief Returns server version. +/// @brief Get server version. EXPORT(float, Sys_GetCommonVersion()); +/// @brief Get CGSC version. +EXPORT(float, CGSC_Version()); + /// @brief Check if CGSC version is unsupported, throws a GSC error if true. /// @param versionCondition - The version condition returned by macros such as CGSC(ver) or CGSC_EQ(ver) etc... /// @return From c6387f16a87508d7a61ccdb4f96a690d930e67a2 Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Sun, 18 Dec 2022 00:09:01 +0100 Subject: [PATCH 17/20] System: Includes --- sys/compatibility.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/compatibility.c b/sys/compatibility.c index 6121ec3..dd38fad 100644 --- a/sys/compatibility.c +++ b/sys/compatibility.c @@ -1,5 +1,6 @@ #include "compatibility.h" #include +#include float CGSC_Version() { From c17eeed227409469d1e9ed08648ff2f91cabf196 Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Sun, 18 Dec 2022 00:26:32 +0100 Subject: [PATCH 18/20] Exports: Fix --- asm/cgsc_export.asm | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/asm/cgsc_export.asm b/asm/cgsc_export.asm index cb706c6..84ce85a 100644 --- a/asm/cgsc_export.asm +++ b/asm/cgsc_export.asm @@ -12,15 +12,6 @@ p%1 dd %1 %endmacro -; CGSC exports -%macro cgsc 1 - SECTION .rodata - %ifdef Win32 - EXPORT %1 - %endif - extern %1 -%endmacro - ; Rename function %macro ralias 2 SECTION .text @@ -60,9 +51,7 @@ pexport AsyncShutdown pexport AsyncCall pexport AsyncNull pexport AsyncFree - -; CGSC export -cgsc CGSC_Version -cgsc CGSC_Unsupported -cgsc CGSC_UnsupportedMessage -cgsc CGSC_SupportIndexedString +pexport CGSC_Version +pexport CGSC_Unsupported +pexport CGSC_UnsupportedMessage +pexport CGSC_SupportIndexedString From 637d66fa52c5f9769b159796f39b89772b31140d Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Sun, 18 Dec 2022 00:37:31 +0100 Subject: [PATCH 19/20] Macro: Fix --- cgsc.h | 7 ------- cod4x.h | 7 +++++++ plugin.h | 7 +++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/cgsc.h b/cgsc.h index 3f30ad3..08b3f8e 100644 --- a/cgsc.h +++ b/cgsc.h @@ -35,13 +35,6 @@ type definition; \ type Plugin_##definition -#define CHECK_UNSUPPORTED(condition) \ -if (CGSC_UnsupportedMessage(condition, "CGSC: This feature is unsupported in this version.")) \ -{ \ - Scr_AddUndefined(); \ - return; \ -} - #define CLASS_NUM_COUNT sizeof(gScrClassMap) / sizeof(gScrClassMap[0]) #define DEBUG_REFCOUNT_SIZE 65536 #define MAX_ARRAYINDEX 0x800000 diff --git a/cod4x.h b/cod4x.h index 6eaf643..54b529b 100644 --- a/cod4x.h +++ b/cod4x.h @@ -5,6 +5,13 @@ #include #endif +#define CHECK_UNSUPPORTED(condition) \ +if (CGSC_UnsupportedMessage(condition, "CGSC: This feature is unsupported in this version.")) \ +{ \ + Scr_AddUndefined(); \ + return; \ +} + #include #include #include diff --git a/plugin.h b/plugin.h index e697a33..27281ef 100644 --- a/plugin.h +++ b/plugin.h @@ -19,6 +19,13 @@ if (Plugin_Scr_GetNumParam() != count) \ return; \ } +#define CHECK_UNSUPPORTED(condition) \ +if (Plugin_CGSC_UnsupportedMessage(condition, "CGSC: This feature is unsupported in this version.")) \ +{ \ + Plugin_Scr_AddUndefined(); \ + return; \ +} + struct VariableStackBuffer { const char *pos; From ba8359869702b8048b1412ec351a96c7a7cb2605 Mon Sep 17 00:00:00 2001 From: Iswenzz Date: Sun, 18 Dec 2022 14:36:15 +0100 Subject: [PATCH 20/20] Docs: Updated API --- docs/api.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/api.md b/docs/api.md index 2dcf29f..a0a820e 100644 --- a/docs/api.md +++ b/docs/api.md @@ -41,11 +41,6 @@ Renaming a function to export: ```assembly ralias Com_Printf CGSC_Printf ``` - -Exporting a function with the CGSC prefix: -```assembly -cgsc CGSC_Version -```
#### ``CGSC_Version()``