mirror of
https://github.com/rehlds/reapi.git
synced 2025-01-16 08:38:08 +03:00
Reworked forward SV_WriteFullClientUpdate
This commit is contained in:
parent
1a9b80e168
commit
15efb24d1c
@ -37,7 +37,7 @@ void postEvaluate(NativeBinarySpec b) {
|
|||||||
|
|
||||||
void setupToolchain(NativeBinarySpec b) {
|
void setupToolchain(NativeBinarySpec b) {
|
||||||
ToolchainConfig cfg = rootProject.createToolchainConfig(b)
|
ToolchainConfig cfg = rootProject.createToolchainConfig(b)
|
||||||
cfg.projectInclude(project, '', '/src', '/src/mods', '/src/natives', '/include', '/include/metamod', '/include/cssdk/common', '/include/cssdk/dlls', '/include/cssdk/engine', '/include/cssdk/game_shared', '/include/cssdk/pm_shared', '/include/cssdk/public')
|
cfg.projectInclude(project, '', '/src', '/common', '/src/mods', '/src/natives', '/include', '/include/metamod', '/include/cssdk/common', '/include/cssdk/dlls', '/include/cssdk/engine', '/include/cssdk/game_shared', '/include/cssdk/pm_shared', '/include/cssdk/public')
|
||||||
cfg.singleDefines('HAVE_STRONG_TYPEDEF');
|
cfg.singleDefines('HAVE_STRONG_TYPEDEF');
|
||||||
|
|
||||||
if (cfg instanceof MsvcToolchainConfig) {
|
if (cfg instanceof MsvcToolchainConfig) {
|
||||||
@ -108,7 +108,7 @@ model {
|
|||||||
}
|
}
|
||||||
reapi_src(CppSourceSet) {
|
reapi_src(CppSourceSet) {
|
||||||
source {
|
source {
|
||||||
srcDirs "src", "include/cssdk/public"
|
srcDirs "src", "common", "include/cssdk/public"
|
||||||
include "**/*.cpp"
|
include "**/*.cpp"
|
||||||
|
|
||||||
exclude "precompiled.cpp"
|
exclude "precompiled.cpp"
|
||||||
|
364
reapi/common/info.cpp
Normal file
364
reapi/common/info.cpp
Normal file
@ -0,0 +1,364 @@
|
|||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
// NOTE: This file contains a lot of fixes that are not covered by REHLDS_FIXES define.
|
||||||
|
// TODO: Most of the Info_ functions can be speedup via removing unneded copy of key and values.
|
||||||
|
|
||||||
|
// Searches the string for the given
|
||||||
|
// key and returns the associated value, or an empty string.
|
||||||
|
const char *Info_ValueForKey(const char *s, const char *key)
|
||||||
|
{
|
||||||
|
// use few (two?) buffers so compares work without stomping on each other
|
||||||
|
static char value[INFO_MAX_BUFFER_VALUES][MAX_KV_LEN];
|
||||||
|
static int valueindex;
|
||||||
|
char pkey[MAX_KV_LEN];
|
||||||
|
char *c;
|
||||||
|
int nCount;
|
||||||
|
|
||||||
|
while (*s)
|
||||||
|
{
|
||||||
|
if (*s == '\\')
|
||||||
|
{
|
||||||
|
s++; // skip the slash
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy a key
|
||||||
|
nCount = 0;
|
||||||
|
c = pkey;
|
||||||
|
while (*s != '\\')
|
||||||
|
{
|
||||||
|
if (!*s)
|
||||||
|
{
|
||||||
|
// key should end with a \, not a NULL, but suppose its value as absent
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nCount >= MAX_KV_LEN)
|
||||||
|
{
|
||||||
|
s++;
|
||||||
|
continue; // skip oversized key chars till the slash or EOL
|
||||||
|
}
|
||||||
|
*c++ = *s++;
|
||||||
|
nCount++;
|
||||||
|
}
|
||||||
|
*c = 0;
|
||||||
|
s++; // skip the slash
|
||||||
|
|
||||||
|
// Copy a value
|
||||||
|
nCount = 0;
|
||||||
|
c = value[valueindex];
|
||||||
|
while (*s != '\\')
|
||||||
|
{
|
||||||
|
if (!*s)
|
||||||
|
{
|
||||||
|
break; // allow value to be ended with NULL
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nCount >= MAX_KV_LEN)
|
||||||
|
{
|
||||||
|
s++;
|
||||||
|
continue; // skip oversized value chars till the slash or EOL
|
||||||
|
}
|
||||||
|
|
||||||
|
*c++ = *s++;
|
||||||
|
nCount++;
|
||||||
|
}
|
||||||
|
*c = 0;
|
||||||
|
|
||||||
|
if (!Q_strcmp(key, pkey))
|
||||||
|
{
|
||||||
|
c = value[valueindex];
|
||||||
|
valueindex = (valueindex + 1) % INFO_MAX_BUFFER_VALUES;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Info_RemoveKey(char *s, const char *key)
|
||||||
|
{
|
||||||
|
char pkey[MAX_KV_LEN];
|
||||||
|
char value[MAX_KV_LEN];
|
||||||
|
char *start;
|
||||||
|
char *c;
|
||||||
|
int cmpsize;
|
||||||
|
int nCount;
|
||||||
|
|
||||||
|
if (Q_strstr(key, "\\"))
|
||||||
|
{
|
||||||
|
UTIL_ServerPrint("Can't use a key with a \\\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmpsize = Q_strlen(key);
|
||||||
|
if (cmpsize > MAX_KV_LEN - 1)
|
||||||
|
cmpsize = MAX_KV_LEN - 1;
|
||||||
|
|
||||||
|
while (*s)
|
||||||
|
{
|
||||||
|
start = s;
|
||||||
|
|
||||||
|
if (*s == '\\')
|
||||||
|
{
|
||||||
|
s++; // skip the slash
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy a key
|
||||||
|
nCount = 0;
|
||||||
|
c = pkey;
|
||||||
|
while (*s != '\\')
|
||||||
|
{
|
||||||
|
if (!*s)
|
||||||
|
{
|
||||||
|
break; // key should end with a \, not a NULL, but allow to remove it
|
||||||
|
}
|
||||||
|
if (nCount >= MAX_KV_LEN)
|
||||||
|
{
|
||||||
|
s++;
|
||||||
|
continue; // skip oversized key chars till the slash or EOL
|
||||||
|
}
|
||||||
|
*c++ = *s++;
|
||||||
|
nCount++;
|
||||||
|
}
|
||||||
|
*c = 0;
|
||||||
|
if (*s)
|
||||||
|
s++; // skip the slash
|
||||||
|
|
||||||
|
// Copy a value
|
||||||
|
nCount = 0;
|
||||||
|
c = value;
|
||||||
|
while (*s != '\\')
|
||||||
|
{
|
||||||
|
if (!*s)
|
||||||
|
{
|
||||||
|
break; // allow value to be ended with NULL
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nCount >= MAX_KV_LEN)
|
||||||
|
{
|
||||||
|
s++;
|
||||||
|
continue; // skip oversized value chars till the slash or EOL
|
||||||
|
}
|
||||||
|
|
||||||
|
*c++ = *s++;
|
||||||
|
nCount++;
|
||||||
|
}
|
||||||
|
*c = 0;
|
||||||
|
|
||||||
|
// Compare keys
|
||||||
|
if (!Q_strncmp(key, pkey, cmpsize))
|
||||||
|
{
|
||||||
|
Q_strcpy_s(start, s); // remove this part
|
||||||
|
s = start; // continue searching
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qboolean Info_IsKeyImportant(const char *key)
|
||||||
|
{
|
||||||
|
if (key[0] == '*')
|
||||||
|
return true;
|
||||||
|
if (!strcmp(key, "name"))
|
||||||
|
return true;
|
||||||
|
if (!strcmp(key, "model"))
|
||||||
|
return true;
|
||||||
|
if (!strcmp(key, "rate"))
|
||||||
|
return true;
|
||||||
|
if (!strcmp(key, "topcolor"))
|
||||||
|
return true;
|
||||||
|
if (!strcmp(key, "bottomcolor"))
|
||||||
|
return true;
|
||||||
|
if (!strcmp(key, "cl_updaterate"))
|
||||||
|
return true;
|
||||||
|
if (!strcmp(key, "cl_lw"))
|
||||||
|
return true;
|
||||||
|
if (!strcmp(key, "cl_lc"))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *Info_FindLargestKey(char *s, int maxsize)
|
||||||
|
{
|
||||||
|
static char largest_key[MAX_KV_LEN];
|
||||||
|
char key[MAX_KV_LEN];
|
||||||
|
char value[MAX_KV_LEN];
|
||||||
|
char *c;
|
||||||
|
int nCount;
|
||||||
|
int largest_size = 0;
|
||||||
|
|
||||||
|
largest_key[0] = 0;
|
||||||
|
|
||||||
|
while (*s)
|
||||||
|
{
|
||||||
|
if (*s == '\\')
|
||||||
|
{
|
||||||
|
s++; // skip the slash
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy a key
|
||||||
|
nCount = 0;
|
||||||
|
c = key;
|
||||||
|
while (*s != '\\')
|
||||||
|
{
|
||||||
|
// key should end with a \, not a NULL, return this key, so it will be deleted as wrong
|
||||||
|
if (!*s)
|
||||||
|
{
|
||||||
|
*c = 0;
|
||||||
|
strcpy(largest_key, key);
|
||||||
|
return largest_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
// oversized key, return this key, so it will be deleted as wrong
|
||||||
|
if (nCount >= MAX_KV_LEN)
|
||||||
|
{
|
||||||
|
*c = 0;
|
||||||
|
strcpy(largest_key, key);
|
||||||
|
return largest_key;
|
||||||
|
}
|
||||||
|
*c++ = *s++;
|
||||||
|
nCount++;
|
||||||
|
}
|
||||||
|
*c = 0;
|
||||||
|
s++; // skip the slash
|
||||||
|
|
||||||
|
// Get length
|
||||||
|
int size = c - key;
|
||||||
|
|
||||||
|
// Copy a value
|
||||||
|
nCount = 0;
|
||||||
|
c = value;
|
||||||
|
while (*s != '\\')
|
||||||
|
{
|
||||||
|
if (!*s)
|
||||||
|
{
|
||||||
|
break; // allow value to be ended with NULL
|
||||||
|
}
|
||||||
|
if (nCount >= MAX_KV_LEN) // oversized value, return this key, so it will be deleted as wrong
|
||||||
|
{
|
||||||
|
*c = 0;
|
||||||
|
strcpy(largest_key, key);
|
||||||
|
return largest_key;
|
||||||
|
}
|
||||||
|
*c++ = *s++;
|
||||||
|
nCount++;
|
||||||
|
}
|
||||||
|
*c = 0;
|
||||||
|
|
||||||
|
// Add length
|
||||||
|
size += c - value;
|
||||||
|
|
||||||
|
if (size > largest_size && !Info_IsKeyImportant(key))
|
||||||
|
{
|
||||||
|
largest_size = size;
|
||||||
|
strcpy(largest_key, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return largest_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Info_SetValueForStarKey(char *s, const char *key, const char *value, int maxsize)
|
||||||
|
{
|
||||||
|
char newArray[MAX_INFO_STRING];
|
||||||
|
char *v;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
if (!key || !value)
|
||||||
|
{
|
||||||
|
UTIL_ServerPrint("Keys and values can't be null\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key[0] == 0)
|
||||||
|
{
|
||||||
|
UTIL_ServerPrint("Keys can't be an empty string\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Q_strstr(key, "\\") || Q_strstr(value, "\\"))
|
||||||
|
{
|
||||||
|
UTIL_ServerPrint("Can't use keys or values with a \\\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Q_strstr(key, "..") || Q_strstr(value, ".."))
|
||||||
|
{
|
||||||
|
// TODO: Why silently return?
|
||||||
|
//UTIL_ServerPrint("Can't use keys or values with a ..\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Q_strstr(key, "\"") || Q_strstr(value, "\""))
|
||||||
|
{
|
||||||
|
UTIL_ServerPrint("Can't use keys or values with a \"\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int keyLen = Q_strlen(key);
|
||||||
|
int valueLan = Q_strlen(value);
|
||||||
|
|
||||||
|
if (keyLen >= MAX_KV_LEN || valueLan >= MAX_KV_LEN)
|
||||||
|
{
|
||||||
|
UTIL_ServerPrint("Keys and values must be < %i characters\n", MAX_KV_LEN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (!Q_UnicodeValidate(key) || !Q_UnicodeValidate(value))
|
||||||
|
{
|
||||||
|
UTIL_ServerPrint("Keys and values must be valid utf8 text\n");
|
||||||
|
return;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Remove current key/value and return if we doesn't specified to set a value
|
||||||
|
Info_RemoveKey(s, key);
|
||||||
|
if (value[0] == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create key/value pair
|
||||||
|
Q_snprintf(newArray, MAX_INFO_STRING - 1, "\\%s\\%s", key, value);
|
||||||
|
newArray[MAX_INFO_STRING - 1] = 0;
|
||||||
|
|
||||||
|
int neededLength = Q_strlen(newArray);
|
||||||
|
if ((int)Q_strlen(s) + neededLength >= maxsize)
|
||||||
|
{
|
||||||
|
// no more room in the buffer to add key/value
|
||||||
|
if (!Info_IsKeyImportant(key))
|
||||||
|
{
|
||||||
|
// no room to add setting
|
||||||
|
UTIL_ServerPrint("Info string length exceeded\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// keep removing the largest key/values until we have a room
|
||||||
|
char *largekey;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
largekey = Info_FindLargestKey(s, maxsize);
|
||||||
|
if (largekey[0] == 0)
|
||||||
|
{
|
||||||
|
// no room to add setting
|
||||||
|
UTIL_ServerPrint("Info string length exceeded\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Info_RemoveKey(s, largekey);
|
||||||
|
} while ((int)Q_strlen(s) + neededLength >= maxsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// auto lowercase team
|
||||||
|
bool lowerCaseValue = _stricmp(key, "team") == 0;
|
||||||
|
s += Q_strlen(s);
|
||||||
|
v = newArray;
|
||||||
|
while (*v)
|
||||||
|
{
|
||||||
|
c = (unsigned char)*v++;
|
||||||
|
if (lowerCaseValue)
|
||||||
|
{
|
||||||
|
c = tolower(c);
|
||||||
|
}
|
||||||
|
*s++ = c;
|
||||||
|
}
|
||||||
|
*s = 0;
|
||||||
|
}
|
10
reapi/common/info.h
Normal file
10
reapi/common/info.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Key + value + 2 x slash + NULL
|
||||||
|
const int MAX_INFO_STRING = 256;
|
||||||
|
const int MAX_KV_LEN = 127;
|
||||||
|
const int INFO_MAX_BUFFER_VALUES = 4;
|
||||||
|
|
||||||
|
const char *Info_ValueForKey(const char *s, const char *key);
|
||||||
|
void Info_RemoveKey(char *s, const char *key);
|
||||||
|
void Info_SetValueForStarKey(char *s, const char *key, const char *value, int maxsize);
|
@ -43,7 +43,7 @@ enum EngineFunc
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Description: Receiver is player index or 0 when update will be sended to all.
|
* Description: Receiver is player index or 0 when update will be sended to all.
|
||||||
* Params: (client, receiver, pinfo)
|
* Params: (const client, buffer, const receiver)
|
||||||
*/
|
*/
|
||||||
RH_SV_WriteFullClientUpdate,
|
RH_SV_WriteFullClientUpdate,
|
||||||
};
|
};
|
||||||
|
@ -34,10 +34,6 @@
|
|||||||
#include "com_progdefs.h"
|
#include "com_progdefs.h"
|
||||||
#include "com_delta_packet.h"
|
#include "com_delta_packet.h"
|
||||||
|
|
||||||
// Key + value + 2 x slash + NULL
|
|
||||||
const int MAX_INFO_STRING = 256;
|
|
||||||
const int MAX_KV_LEN = 127;
|
|
||||||
|
|
||||||
typedef struct client_frame_s
|
typedef struct client_frame_s
|
||||||
{
|
{
|
||||||
double senttime;
|
double senttime;
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the
|
|
||||||
* Free Software Foundation; either version 2 of the License, or (at
|
|
||||||
* your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
* In addition, as a special exception, the author gives permission to
|
|
||||||
* link the code of this program with the Half-Life Game Engine ("HL
|
|
||||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
|
||||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
|
||||||
* respects for all of the code used other than the HL Engine and MODs
|
|
||||||
* from Valve. If you modify this file, you may extend this exception
|
|
||||||
* to your version of the file, but you are not obligated to do so. If
|
|
||||||
* you do not wish to do so, delete this exception statement from your
|
|
||||||
* version.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
class string_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using unsigned int;
|
|
||||||
};
|
|
@ -11,6 +11,7 @@
|
|||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\common\info.h" />
|
||||||
<ClInclude Include="..\include\com_client.h" />
|
<ClInclude Include="..\include\com_client.h" />
|
||||||
<ClInclude Include="..\include\com_delta_packet.h" />
|
<ClInclude Include="..\include\com_delta_packet.h" />
|
||||||
<ClInclude Include="..\include\com_net.h" />
|
<ClInclude Include="..\include\com_net.h" />
|
||||||
@ -227,6 +228,7 @@
|
|||||||
<ClInclude Include="..\version\appversion.h" />
|
<ClInclude Include="..\version\appversion.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\common\info.cpp" />
|
||||||
<ClCompile Include="..\include\cssdk\common\parsemsg.cpp">
|
<ClCompile Include="..\include\cssdk\common\parsemsg.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
@ -336,7 +338,7 @@
|
|||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||||
<AdditionalIncludeDirectories>$(ProjectDir)\..\src;$(ProjectDir)\..\src\mods;$(ProjectDir)\..\src\natives;$(ProjectDir)\..\version;$(ProjectDir)\..\include;$(ProjectDir)\..\include\metamod;$(ProjectDir)\..\include\cssdk\common;$(ProjectDir)\..\include\cssdk\dlls;$(ProjectDir)\..\include\cssdk\engine;$(ProjectDir)\..\include\cssdk\game_shared;$(ProjectDir)\..\include\cssdk\pm_shared;$(ProjectDir)\..\include\cssdk\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(ProjectDir)\..\src;$(ProjectDir)\..\src\mods;$(ProjectDir)\..\src\natives;$(ProjectDir)\..\common;$(ProjectDir)\..\version;$(ProjectDir)\..\include;$(ProjectDir)\..\include\metamod;$(ProjectDir)\..\include\cssdk\common;$(ProjectDir)\..\include\cssdk\dlls;$(ProjectDir)\..\include\cssdk\engine;$(ProjectDir)\..\include\cssdk\game_shared;$(ProjectDir)\..\include\cssdk\pm_shared;$(ProjectDir)\..\include\cssdk\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<MinimalRebuild>false</MinimalRebuild>
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
@ -385,7 +387,7 @@
|
|||||||
<PreprocessorDefinitions>WIN32;HAVE_STRONG_TYPEDEF;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;HAVE_STRONG_TYPEDEF;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<SDLCheck>
|
<SDLCheck>
|
||||||
</SDLCheck>
|
</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>$(ProjectDir)\..\src;$(ProjectDir)\..\src\mods;$(ProjectDir)\..\src\natives;$(ProjectDir)\..\version;$(ProjectDir)\..\include;$(ProjectDir)\..\include\metamod;$(ProjectDir)\..\include\cssdk\common;$(ProjectDir)\..\include\cssdk\dlls;$(ProjectDir)\..\include\cssdk\engine;$(ProjectDir)\..\include\cssdk\game_shared;$(ProjectDir)\..\include\cssdk\pm_shared;$(ProjectDir)\..\include\cssdk\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(ProjectDir)\..\src;$(ProjectDir)\..\src\mods;$(ProjectDir)\..\src\natives;$(ProjectDir)\..\common;$(ProjectDir)\..\version;$(ProjectDir)\..\include;$(ProjectDir)\..\include\metamod;$(ProjectDir)\..\include\cssdk\common;$(ProjectDir)\..\include\cssdk\dlls;$(ProjectDir)\..\include\cssdk\engine;$(ProjectDir)\..\include\cssdk\game_shared;$(ProjectDir)\..\include\cssdk\pm_shared;$(ProjectDir)\..\include\cssdk\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||||
|
@ -58,6 +58,9 @@
|
|||||||
<Filter Include="version">
|
<Filter Include="version">
|
||||||
<UniqueIdentifier>{60b1b924-8415-4c1d-9fef-57e717e12f42}</UniqueIdentifier>
|
<UniqueIdentifier>{60b1b924-8415-4c1d-9fef-57e717e12f42}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="common">
|
||||||
|
<UniqueIdentifier>{8232a3e7-911f-4ee1-8223-03ac077d7bee}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\include\metamod\dllapi.h">
|
<ClInclude Include="..\include\metamod\dllapi.h">
|
||||||
@ -690,6 +693,9 @@
|
|||||||
<ClInclude Include="..\include\com_net.h">
|
<ClInclude Include="..\include\com_net.h">
|
||||||
<Filter>include</Filter>
|
<Filter>include</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\common\info.h">
|
||||||
|
<Filter>common</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\include\cssdk\common\parsemsg.cpp">
|
<ClCompile Include="..\include\cssdk\common\parsemsg.cpp">
|
||||||
@ -788,6 +794,9 @@
|
|||||||
<ClCompile Include="..\src\mods\queryfile_handler.cpp">
|
<ClCompile Include="..\src\mods\queryfile_handler.cpp">
|
||||||
<Filter>src\mods</Filter>
|
<Filter>src\mods</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\common\info.cpp">
|
||||||
|
<Filter>common</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\extra\amxmodx\scripting\include\reapi.inc">
|
<None Include="..\extra\amxmodx\scripting\include\reapi.inc">
|
||||||
|
@ -46,24 +46,21 @@ void Cvar_DirectSet(IRehldsHook_Cvar_DirectSet *chain, cvar_t *var, const char *
|
|||||||
callVoidForward(RH_Cvar_DirectSet, original, var, value);
|
callVoidForward(RH_Cvar_DirectSet, original, var, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SV_WriteFullClientUpdate(IRehldsHook_SV_WriteFullClientUpdate *chain, IGameClient *client, char *info, size_t maxlen, sizebuf_t *sb, IGameClient *receiver)
|
void SV_WriteFullClientUpdate_AMXX(SV_WriteFullClientUpdate_t *data, IGameClient *client, size_t buffer, IGameClient *receiver)
|
||||||
{
|
{
|
||||||
int receiver_id = 0;
|
auto original = [data](int _client, size_t _buffer, int _receiver)
|
||||||
if (receiver)
|
|
||||||
receiver_id = receiver->GetId() + 1;
|
|
||||||
|
|
||||||
auto original = [chain, sb](int _client, int _receiver, int _pinfo)
|
|
||||||
{
|
{
|
||||||
sizebuf_t* dest = sb;
|
data->m_chain->callNext(g_RehldsSvs->GetClient(_client - 1), (char *)_buffer, data->m_args.maxlen, data->m_args.message, g_RehldsSvs->GetClient(_receiver - 1));
|
||||||
IGameClient* receiver = nullptr;
|
|
||||||
if (_receiver) {
|
|
||||||
receiver = g_RehldsSvs->GetClient(_receiver - 1);
|
|
||||||
dest = receiver->GetNetChan()->GetMessageBuf();
|
|
||||||
}
|
|
||||||
chain->callNext(g_RehldsSvs->GetClient(_client - 1), (char *)_pinfo, MAX_INFO_STRING, dest, receiver);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
callVoidForward(RH_SV_WriteFullClientUpdate, original, client->GetId() + 1, receiver_id, int(info));
|
callVoidForward(RH_SV_WriteFullClientUpdate, original, client->GetId() + 1, buffer, receiver ? receiver->GetId() + 1 : AMX_NULLENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SV_WriteFullClientUpdate(IRehldsHook_SV_WriteFullClientUpdate *chain, IGameClient *client, char *buffer, size_t maxlen, sizebuf_t *sb, IGameClient *receiver)
|
||||||
|
{
|
||||||
|
SV_WriteFullClientUpdate_args_t args(sb, maxlen);
|
||||||
|
SV_WriteFullClientUpdate_t data(chain, args);
|
||||||
|
SV_WriteFullClientUpdate_AMXX(&data, client, (size_t)buffer, receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -857,7 +854,7 @@ void FileConsistencyProcess_AMXX(FileConsistencyProcess_t *data, IGameClient *cl
|
|||||||
int hashCopy = responseHash;
|
int hashCopy = responseHash;
|
||||||
auto original = [data, hashCopy](int _cl, const char *_filename, const char *_cmd, ResourceType_e _type, uint32 _hash, bool _isBreak)
|
auto original = [data, hashCopy](int _cl, const char *_filename, const char *_cmd, ResourceType_e _type, uint32 _hash, bool _isBreak)
|
||||||
{
|
{
|
||||||
data->m_chain->callNext(g_RehldsSvs->GetClient(_cl - 1), data->m_data, _type, hashCopy);
|
data->m_chain->callNext(g_RehldsSvs->GetClient(_cl - 1), data->m_args, _type, hashCopy);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (g_RecheckerFuncs->GetResource()->GetPrevHash() == responseHash) {
|
if (g_RecheckerFuncs->GetResource()->GetPrevHash() == responseHash) {
|
||||||
@ -888,7 +885,7 @@ void CmdExec_AMXX(CmdExec_t *data, IGameClient *cl, const char *filename, char *
|
|||||||
int hashCopy = responseHash;
|
int hashCopy = responseHash;
|
||||||
auto original = [data, hashCopy](int _cl, const char *_filename, char *_cmd, uint32 _responseHash)
|
auto original = [data, hashCopy](int _cl, const char *_filename, char *_cmd, uint32 _responseHash)
|
||||||
{
|
{
|
||||||
data->m_chain->callNext(g_RehldsSvs->GetClient(_cl - 1), data->m_data, _cmd, hashCopy);
|
data->m_chain->callNext(g_RehldsSvs->GetClient(_cl - 1), data->m_args, _cmd, hashCopy);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (g_RecheckerFuncs->GetResource()->GetPrevHash() == responseHash) {
|
if (g_RecheckerFuncs->GetResource()->GetPrevHash() == responseHash) {
|
||||||
|
@ -288,10 +288,10 @@ R callForward(size_t func, original_t original, f_args... args)
|
|||||||
template<typename T, typename A>
|
template<typename T, typename A>
|
||||||
struct hookdata_t
|
struct hookdata_t
|
||||||
{
|
{
|
||||||
hookdata_t(T chain, A data) : m_chain(chain), m_data(data) {}
|
hookdata_t(T chain, A args) : m_chain(chain), m_args(args) {}
|
||||||
|
|
||||||
T m_chain;
|
T m_chain;
|
||||||
A m_data;
|
A m_args;
|
||||||
};
|
};
|
||||||
|
|
||||||
// rehlds functions
|
// rehlds functions
|
||||||
@ -299,7 +299,18 @@ void SV_StartSound(IRehldsHook_SV_StartSound *chain, int recipients, edict_t *en
|
|||||||
void SV_DropClient(IRehldsHook_SV_DropClient *chain, IGameClient *cl, bool crash, const char *fmt);
|
void SV_DropClient(IRehldsHook_SV_DropClient *chain, IGameClient *cl, bool crash, const char *fmt);
|
||||||
void SV_ActivateServer(IRehldsHook_SV_ActivateServer *chain, int runPhysics);
|
void SV_ActivateServer(IRehldsHook_SV_ActivateServer *chain, int runPhysics);
|
||||||
void Cvar_DirectSet(IRehldsHook_Cvar_DirectSet *chain, cvar_t *var, const char *value);
|
void Cvar_DirectSet(IRehldsHook_Cvar_DirectSet *chain, cvar_t *var, const char *value);
|
||||||
void SV_WriteFullClientUpdate(IRehldsHook_SV_WriteFullClientUpdate *chain, IGameClient *client, char *info, size_t maxlen, sizebuf_t *sb, IGameClient *receiver);
|
|
||||||
|
struct SV_WriteFullClientUpdate_args_t
|
||||||
|
{
|
||||||
|
SV_WriteFullClientUpdate_args_t(sizebuf_t *msg, int size) : message(msg), maxlen(size) {}
|
||||||
|
|
||||||
|
sizebuf_t *message;
|
||||||
|
int maxlen;
|
||||||
|
};
|
||||||
|
|
||||||
|
using SV_WriteFullClientUpdate_t = hookdata_t<IRehldsHook_SV_WriteFullClientUpdate *, SV_WriteFullClientUpdate_args_t &>;
|
||||||
|
void SV_WriteFullClientUpdate_AMXX(SV_WriteFullClientUpdate_t *data, IGameClient *client, size_t buffer, IGameClient *receiver);
|
||||||
|
void SV_WriteFullClientUpdate(IRehldsHook_SV_WriteFullClientUpdate *chain, IGameClient *client, char *buffer, size_t maxlen, sizebuf_t *sb, IGameClient *receiver);
|
||||||
|
|
||||||
// regamedll functions
|
// regamedll functions
|
||||||
int GetForceCamera(IReGameHook_GetForceCamera *chain, CBasePlayer *pObserver);
|
int GetForceCamera(IReGameHook_GetForceCamera *chain, CBasePlayer *pObserver);
|
||||||
|
@ -69,13 +69,13 @@ struct regfunc
|
|||||||
|
|
||||||
int regfunc::current_cell = 1;
|
int regfunc::current_cell = 1;
|
||||||
|
|
||||||
#define ENG(h) { {}, {}, #h, "ReHLDS", [](){ return api_cfg.hasReHLDS(); }, ((!(RH_##h & (MAX_REGION_RANGE - 1)) ? regfunc::current_cell = 1, true : false) || (RH_##h & (MAX_REGION_RANGE - 1)) == regfunc::current_cell++) ? regfunc(h) : regfunc(#h), [](){ g_RehldsHookchains->##h##()->registerHook(&##h); }, [](){ g_RehldsHookchains->##h##()->unregisterHook(&##h); }}
|
#define ENG(h,...) { {}, {}, #h, "ReHLDS", [](){ return api_cfg.hasReHLDS(); }, ((!(RH_##h & (MAX_REGION_RANGE - 1)) ? regfunc::current_cell = 1, true : false) || (RH_##h & (MAX_REGION_RANGE - 1)) == regfunc::current_cell++) ? regfunc(h##__VA_ARGS__) : regfunc(#h#__VA_ARGS__), [](){ g_RehldsHookchains->##h##()->registerHook(&##h); }, [](){ g_RehldsHookchains->##h##()->unregisterHook(&##h); }}
|
||||||
hook_t hooklist_engine[] = {
|
hook_t hooklist_engine[] = {
|
||||||
ENG(SV_StartSound),
|
ENG(SV_StartSound),
|
||||||
ENG(SV_DropClient),
|
ENG(SV_DropClient),
|
||||||
ENG(SV_ActivateServer),
|
ENG(SV_ActivateServer),
|
||||||
ENG(Cvar_DirectSet),
|
ENG(Cvar_DirectSet),
|
||||||
ENG(SV_WriteFullClientUpdate)
|
ENG(SV_WriteFullClientUpdate, _AMXX)
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DLL(h) { {}, {}, #h, "ReGameDLL", [](){ return api_cfg.hasReGameDLL(); }, ((!(RG_##h & (MAX_REGION_RANGE - 1)) ? regfunc::current_cell = 1, true : false) || (RG_##h & (MAX_REGION_RANGE - 1)) == regfunc::current_cell++) ? regfunc(h) : regfunc(#h), [](){ g_ReGameHookchains->##h##()->registerHook(&##h); }, [](){ g_ReGameHookchains->##h##()->unregisterHook(&##h); }}
|
#define DLL(h) { {}, {}, #h, "ReGameDLL", [](){ return api_cfg.hasReGameDLL(); }, ((!(RG_##h & (MAX_REGION_RANGE - 1)) ? regfunc::current_cell = 1, true : false) || (RG_##h & (MAX_REGION_RANGE - 1)) == regfunc::current_cell++) ? regfunc(h) : regfunc(#h), [](){ g_ReGameHookchains->##h##()->registerHook(&##h); }, [](){ g_ReGameHookchains->##h##()->unregisterHook(&##h); }}
|
||||||
|
@ -129,8 +129,14 @@ cell AMX_NATIVE_CALL amx_get_key_value(AMX *amx, cell *params)
|
|||||||
{
|
{
|
||||||
enum args_e { arg_count, arg_buffer, arg_key, arg_value, arg_maxlen };
|
enum args_e { arg_count, arg_buffer, arg_key, arg_value, arg_maxlen };
|
||||||
|
|
||||||
char buffer[MAX_INFO_STRING], key[MAX_KV_LEN];
|
char *buffer = reinterpret_cast<char *>(params[arg_buffer]);
|
||||||
Q_strlcpy(buffer, getAmxString(amx, params[arg_buffer]));
|
if (!buffer)
|
||||||
|
{
|
||||||
|
MF_LogError(amx, AMX_ERR_NATIVE, "%s: Invalid buffer", __FUNCTION__);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
char key[MAX_KV_LEN];
|
||||||
Q_strlcpy(key, getAmxString(amx, params[arg_key]));
|
Q_strlcpy(key, getAmxString(amx, params[arg_key]));
|
||||||
|
|
||||||
return g_amxxapi.SetAmxString(amx, params[arg_value], g_engfuncs.pfnInfoKeyValue(buffer, key), params[arg_maxlen]);
|
return g_amxxapi.SetAmxString(amx, params[arg_value], g_engfuncs.pfnInfoKeyValue(buffer, key), params[arg_maxlen]);
|
||||||
@ -145,18 +151,33 @@ cell AMX_NATIVE_CALL amx_get_key_value(AMX *amx, cell *params)
|
|||||||
*
|
*
|
||||||
* @noreturn
|
* @noreturn
|
||||||
*
|
*
|
||||||
* native set_key_value(const pbuffer, const key[], const value[]);
|
* native set_key_value(const &pbuffer, const key[], const value[]);
|
||||||
*/
|
*/
|
||||||
cell AMX_NATIVE_CALL amx_set_key_value(AMX *amx, cell *params)
|
cell AMX_NATIVE_CALL amx_set_key_value(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
enum args_e { arg_count, arg_buffer, arg_key, arg_value };
|
enum args_e { arg_count, arg_buffer, arg_key, arg_value };
|
||||||
|
|
||||||
char buffer[MAX_INFO_STRING], key[MAX_KV_LEN], value[MAX_KV_LEN];
|
char *buffer = reinterpret_cast<char *>(params[arg_buffer]);
|
||||||
Q_strlcpy(buffer, getAmxString(amx, params[arg_buffer]));
|
if (!buffer)
|
||||||
|
{
|
||||||
|
MF_LogError(amx, AMX_ERR_NATIVE, "%s: Invalid buffer", __FUNCTION__);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
char key[MAX_KV_LEN], value[MAX_KV_LEN];
|
||||||
Q_strlcpy(key, getAmxString(amx, params[arg_key]));
|
Q_strlcpy(key, getAmxString(amx, params[arg_key]));
|
||||||
Q_strlcpy(value, getAmxString(amx, params[arg_value]));
|
Q_strlcpy(value, getAmxString(amx, params[arg_value]));
|
||||||
|
|
||||||
g_engfuncs.pfnSetKeyValue(buffer, key, value);
|
if (!key[0])
|
||||||
|
{
|
||||||
|
buffer[0] = '\0';
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info_SetValueForStarKey(buffer, key, value, MAX_INFO_STRING);
|
||||||
|
|
||||||
|
// TODO: this function doesn't let me sets another buffer
|
||||||
|
//g_engfuncs.pfnSetKeyValue(buffer, key, value);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
// AmxModX API
|
// AmxModX API
|
||||||
#include "amxxmodule.h"
|
#include "amxxmodule.h"
|
||||||
|
|
||||||
|
#include "info.h"
|
||||||
#include "com_client.h"
|
#include "com_client.h"
|
||||||
|
|
||||||
// reapi main
|
// reapi main
|
||||||
|
Loading…
x
Reference in New Issue
Block a user