2
0
mirror of https://github.com/rehlds/rehlds.git synced 2025-01-01 01:25:38 +03:00

Fixed crash in Q_UnicodeConvertT

Refactoring in SV_ExtractFrom
Added Steam_GSBUpdateUserData hook
Refactored and optimized calculateBytecount without hardcode
This commit is contained in:
asmodai 2016-01-16 23:52:17 +03:00
parent 4aad7ec954
commit 267c7eb327
8 changed files with 81 additions and 78 deletions

View File

@ -321,7 +321,8 @@ void CDeltaCheckJIT::iterateStrings(deltajitdata_t *jitdesc)
pushed_size += 8;
}
add(esp, pushed_size);
if (pushed_size)
add(esp, pushed_size);
}
class CDeltaClearMarkFieldsJIT : public jitasm::function<int, CDeltaClearMarkFieldsJIT, void*, void*, void*, void*>
@ -380,60 +381,36 @@ void CDeltaClearMarkFieldsJIT::calculateBytecount() {
mov(eax, dword_ptr[ebx + delta_markbits_offset]);
xor_(edx, edx);
// 0-7
// bits 0-7
test(al, al);
setnz(dl);
// 8-15
if (jitdesc->numFields > 7)
{
mov(esi, 2);
test(ah, ah);
cmovnz(edx, esi);
}
for (size_t i = 1; i < DELTAJIT_MAX_FIELDS / 8; i++) {
const int byteid = i & 3;
// 16-23
if (jitdesc->numFields > 15)
{
mov(ecx, 3);
test(eax, 0xFF0000);
cmovnz(edx, ecx);
}
if (byteid == 0)
mov(eax, dword_ptr[ebx + delta_markbits_offset + i]);
// 24-31
if (jitdesc->numFields > 23)
{
mov(esi, 4);
test(eax, 0xFF000000);
cmovnz(edx, esi);
}
auto reg = (i & 1) ? ecx : esi;
auto prev = (i & 1) ? esi : ecx;
if (jitdesc->numFields > 31)
{
mov(eax, dword_ptr[ebx + delta_markbits_offset + 4]);
if (jitdesc->numFields > i * 8 - 1) {
mov(reg, i + 1);
if(i != 1) cmovnz(edx, prev);
// 32-39
mov(ecx, 5);
test(al, al);
cmovnz(edx, ecx);
// 40-47
if (jitdesc->numFields > 39)
{
mov(esi, 6);
test(ah, ah);
cmovnz(edx, esi);
switch (byteid) {
case 0: test(al, al); break;
case 1: test(ah, ah); break;
default: test(eax, 0xFF << (byteid * 8));
}
}
// 48-55
if (jitdesc->numFields > 47)
{
mov(ecx, 7);
test(eax, 0xFF0000);
cmovnz(edx, ecx);
else if (jitdesc->numFields > unsigned(i * 8 - 9)) {
cmovnz(edx, prev);
break;
}
// maxfields is 56
}
if (jitdesc->numFields > DELTAJIT_MAX_FIELDS - 9) {
cmovnz(edx, (DELTAJIT_MAX_FIELDS / 8 & 1) ? esi : ecx);
}
size_t delta_masksize_offset = offsetof(CDeltaJit, markedFieldsMaskSize);
@ -513,7 +490,7 @@ CDeltaClearMarkFieldsJIT::Result CDeltaClearMarkFieldsJIT::main(Addr src, Addr d
CUniqueLabel no_markedbits("no_markedbits");
CUniqueLabel calculated("calculated");
test(edi, edi);
//test(edi, edi); // flags are already set
jz(no_markedbits);
calculateBytecount();
jmp(calculated);
@ -775,4 +752,4 @@ void CDeltaJitRegistry::Cleanup() {
cur = cur->next;
}
#endif
}
}

View File

@ -2411,7 +2411,11 @@ void EXT_FUNC SV_ConnectClient_internal(void)
bIsSecure = Steam_GSBSecure();
Netchan_OutOfBandPrint(NS_SERVER, adr, "%c %i \"%s\" %i %i", 66, host_client->userid, NET_AdrToString(host_client->netchan.remote_address), bIsSecure, build_number());
Log_Printf("\"%s<%i><%s><>\" connected, address \"%s\"\n", name, host_client->userid, SV_GetClientIDString(host_client), NET_AdrToString(host_client->netchan.remote_address));
#ifdef REHLDS_FIXES
Q_strncpy(host_client->userinfo, userinfo, MAX_INFO_STRING - 1);
#else
Q_strncpy(host_client->userinfo, userinfo, MAX_INFO_STRING);
#endif
host_client->userinfo[MAX_INFO_STRING - 1] = 0;
SV_ExtractFromUserinfo(host_client);
@ -4799,15 +4803,13 @@ void SV_ExtractFromUserinfo(client_t *cl)
const char *val;
int i;
char newname[MAX_NAME];
char rawname[MAX_NAME];
char *userinfo = cl->userinfo;
val = Info_ValueForKey(userinfo, "name");
Q_strncpy(rawname, val, sizeof(rawname) - 1);
rawname[sizeof(rawname) - 1] = 0;
Q_strncpy(newname, val, sizeof(newname) - 1);
newname[sizeof(newname) - 1] = '\0';
for (char *p = rawname; *p; p++)
for (char *p = newname; *p; p++)
{
if (*p == '%'
|| *p == '&'
@ -4819,10 +4821,9 @@ void SV_ExtractFromUserinfo(client_t *cl)
}
#ifdef REHLDS_FIXES
Q_strcpy(newname, rawname);
Q_StripUnprintableAndSpace(newname);
#else // REHLDS_FIXES
TrimSpace(rawname, newname);
TrimSpace(newname, newname);
#endif // REHLDS_FIXES
if (!Q_UnicodeValidate(newname))
@ -4831,9 +4832,9 @@ void SV_ExtractFromUserinfo(client_t *cl)
}
// Fix name to not start with '#', so it will not resemble userid
for (char *p = rawname; *p == '#'; p++) *p = ' ';
for (char *p = newname; *p == '#'; p++) *p = ' ';
if (newname[0] == 0 || !Q_stricmp(newname, "console")
if (newname[0] == '\0' || !Q_stricmp(newname, "console")
#ifdef REHLDS_FIXES
|| Q_strstr(newname, "..") != NULL)
#else // REHLDS_FIXES
@ -4854,7 +4855,7 @@ void SV_ExtractFromUserinfo(client_t *cl)
val = Info_ValueForKey(userinfo, "name");
Q_strncpy(cl->name, val, sizeof(cl->name) - 1);
cl->name[sizeof(cl->name) - 1] = 0;
cl->name[sizeof(cl->name) - 1] = '\0';
ISteamGameServer_BUpdateUserData(cl->network_userid.m_SteamID, cl->name, 0);
@ -7329,4 +7330,4 @@ NOXREF qboolean BIsValveGame(void)
return TRUE;
}
return FALSE;
}
}

View File

@ -467,7 +467,11 @@ void CSteam3Server::RunFrame()
if (!cl->active)
continue;
CRehldsPlatformHolder::get()->SteamGameServer()->BUpdateUserData(CSteamID(cl->network_userid.m_SteamID), cl->name, cl->edict->v.frags);
#ifdef REHLDS_FIXES
ISteamGameServer_BUpdateUserData(cl->network_userid.m_SteamID, cl->name, cl->edict->v.frags);
#else
CRehldsPlatformHolder::get()->SteamGameServer()->BUpdateUserData(cl->network_userid.m_SteamID, cl->name, cl->edict->v.frags);
#endif
}
if (CRehldsPlatformHolder::get()->SteamGameServer()->WasRestartRequested())
@ -647,6 +651,11 @@ uint64 ISteamGameServer_CreateUnauthenticatedUserConnection(void)
return CRehldsPlatformHolder::get()->SteamGameServer()->CreateUnauthenticatedUserConnection().ConvertToUint64();
}
bool Steam_GSBUpdateUserData(uint64 steamIDUser, const char *pchPlayerName, uint32 uScore)
{
return CRehldsPlatformHolder::get()->SteamGameServer()->BUpdateUserData(steamIDUser, pchPlayerName, uScore);
}
/* <f10a4> ../engine/sv_steam3.cpp:559 */
bool ISteamGameServer_BUpdateUserData(uint64 steamid, const char *netname, uint32 score)
{
@ -655,7 +664,7 @@ bool ISteamGameServer_BUpdateUserData(uint64 steamid, const char *netname, uint3
return false;
}
return CRehldsPlatformHolder::get()->SteamGameServer()->BUpdateUserData(steamid, netname, score);
return g_RehldsHookchains.m_Steam_GSBUpdateUserData.callChain(Steam_GSBUpdateUserData, steamid, netname, score);
}
/* <f10ef> ../engine/sv_steam3.cpp:566 */
@ -955,4 +964,4 @@ void Master_SetMaster_f(void)
void Steam_HandleIncomingPacket(byte *data, int len, int fromip, uint16 port)
{
CRehldsPlatformHolder::get()->SteamGameServer()->HandleIncomingPacket(data, len, fromip, port);
}
}

View File

@ -224,12 +224,12 @@ void TrimSpace(const char *source, char *dest)
if (length <= 0)
{
dest[0] = 0;
dest[0] = '\0';
}
else
{
Q_strncpy(dest, &source[start], length);
dest[length] = 0;
Q_memmove(dest, &source[start], length);
dest[length] = '\0';
}
}
@ -507,4 +507,4 @@ NOXREF client_textmessage_t *TextMessageGet(const char *pName)
return &gMessageTable[i];
}
return NULL;
}
}

View File

@ -624,12 +624,13 @@ template<
>
int Q_UnicodeConvertT(const T_IN* pIn, T_OUT *pOut, int nOutBytes, enum EStringConvertErrorPolicy ePolicy)
{
if (nOutBytes == 0)
return 0;
int nOut = 0;
if (pOut)
{
int nMaxOut = nOutBytes / sizeof(T_OUT) - 1;
if (nMaxOut <= 0)
return 0;
int nMaxOut = nOutBytes / sizeof(T_OUT) - 1; // print symbols count
while (*pIn)
{
@ -742,7 +743,7 @@ qboolean Q_StripUnprintableAndSpace(char *pch)
int cch = Q_strlen(pch);
int cubDest = (cch + 1) * sizeof(uchar16);
uchar16 *pwch_alloced = (uchar16*)malloc(cubDest);
uchar16 *pwch_alloced = (uchar16*)alloca(cubDest);
bStrippedAny = false;
bStrippedWhitespace = false;
int cwch = (unsigned int)Q_UTF8ToUTF16(pch, (uchar16 *)pwch_alloced, cubDest, _STRINGCONVERTFLAG_ASSERT) >> 1;
@ -751,6 +752,5 @@ qboolean Q_StripUnprintableAndSpace(char *pch)
if (bStrippedWhitespace || bStrippedAny)
Q_UTF16ToUTF8(pwch, pch, cch, STRINGCONVERT_ASSERT_REPLACE);
free(pwch_alloced);
return bStrippedAny;
}
}

View File

@ -35,7 +35,7 @@
#include "model.h"
#define REHLDS_API_VERSION_MAJOR 2
#define REHLDS_API_VERSION_MINOR 5
#define REHLDS_API_VERSION_MINOR 6
//Steam_NotifyClientConnect hook
typedef IHookChain<qboolean, IGameClient*, const void*, unsigned int> IRehldsHook_Steam_NotifyClientConnect;
@ -165,6 +165,11 @@ typedef IHookChainRegistry<uint64> IRehldsHookRegistry_Steam_GSGetSteamID;
typedef IHookChain<int> IRehldsHook_SV_TransferConsistencyInfo;
typedef IHookChainRegistry<int> IRehldsHookRegistry_SV_TransferConsistencyInfo;
//Steam_GSBUpdateUserData hook
typedef IHookChain<bool, uint64, const char *, uint32> IRehldsHook_Steam_GSBUpdateUserData;
typedef IHookChainRegistry<bool, uint64, const char *, uint32> IRehldsHookRegistry_Steam_GSBUpdateUserData;
//BUpdateUserData
class IRehldsHookchains {
public:
virtual ~IRehldsHookchains() { }
@ -201,6 +206,7 @@ public:
virtual IRehldsHookRegistry_SV_WriteVoiceCodec* SV_WriteVoiceCodec() = 0;
virtual IRehldsHookRegistry_Steam_GSGetSteamID* Steam_GSGetSteamID() = 0;
virtual IRehldsHookRegistry_SV_TransferConsistencyInfo* SV_TransferConsistencyInfo() = 0;
virtual IRehldsHookRegistry_Steam_GSBUpdateUserData* Steam_GSBUpdateUserData() = 0;
};
struct RehldsFuncs_t {
@ -261,4 +267,4 @@ public:
virtual IRehldsFlightRecorder* GetFlightRecorder() = 0;
};
#define VREHLDS_HLDS_API_VERSION "VREHLDS_HLDS_API_VERSION001"
#define VREHLDS_HLDS_API_VERSION "VREHLDS_HLDS_API_VERSION001"

View File

@ -346,7 +346,7 @@ IRehldsHookRegistry_SV_WriteVoiceCodec* CRehldsHookchains::SV_WriteVoiceCodec()
return &m_SV_WriteVoiceCodec;
}
CRehldsHookRegistry_Steam_GSGetSteamID* CRehldsHookchains::Steam_GSGetSteamID() {
IRehldsHookRegistry_Steam_GSGetSteamID* CRehldsHookchains::Steam_GSGetSteamID() {
return &m_Steam_GSGetSteamID;
}
@ -354,6 +354,10 @@ CRehldsHookRegistry_SV_TransferConsistencyInfo* CRehldsHookchains::SV_TransferCo
return &m_SV_TransferConsistencyInfo;
}
IRehldsHookRegistry_Steam_GSBUpdateUserData* CRehldsHookchains::Steam_GSBUpdateUserData() {
return &m_Steam_GSBUpdateUserData;
}
int EXT_FUNC CRehldsApi::GetMajorVersion()
{
return REHLDS_API_VERSION_MAJOR;
@ -386,4 +390,4 @@ IRehldsFlightRecorder* EXT_FUNC CRehldsApi::GetFlightRecorder() {
return g_FlightRecorder;
}
EXPOSE_SINGLE_INTERFACE(CRehldsApi, IRehldsApi, VREHLDS_HLDS_API_VERSION);
EXPOSE_SINGLE_INTERFACE(CRehldsApi, IRehldsApi, VREHLDS_HLDS_API_VERSION);

View File

@ -159,6 +159,10 @@ typedef IHookChainRegistryImpl<uint64> CRehldsHookRegistry_Steam_GSGetSteamID;
typedef IHookChainImpl<int> CRehldsHook_SV_TransferConsistencyInfo;
typedef IHookChainRegistryImpl<int> CRehldsHookRegistry_SV_TransferConsistencyInfo;
//Steam_GSBUpdateUserData hook
typedef IHookChainImpl<bool, uint64, const char *, uint32> CRehldsHook_Steam_GSBUpdateUserData;
typedef IHookChainRegistryImpl<bool, uint64, const char *, uint32> CRehldsHookRegistry_Steam_GSBUpdateUserData;
class CRehldsHookchains : public IRehldsHookchains {
public:
CRehldsHookRegistry_Steam_NotifyClientConnect m_Steam_NotifyClientConnect;
@ -193,6 +197,7 @@ public:
CRehldsHookRegistry_SV_WriteVoiceCodec m_SV_WriteVoiceCodec;
CRehldsHookRegistry_Steam_GSGetSteamID m_Steam_GSGetSteamID;
CRehldsHookRegistry_SV_TransferConsistencyInfo m_SV_TransferConsistencyInfo;
CRehldsHookRegistry_Steam_GSBUpdateUserData m_Steam_GSBUpdateUserData;
public:
virtual IRehldsHookRegistry_Steam_NotifyClientConnect* Steam_NotifyClientConnect();
@ -225,7 +230,8 @@ public:
virtual IRehldsHookRegistry_SV_DropClient* SV_DropClient();
virtual IRehldsHookRegistry_SV_ActivateServer* SV_ActivateServer();
virtual IRehldsHookRegistry_SV_WriteVoiceCodec* SV_WriteVoiceCodec();
virtual CRehldsHookRegistry_Steam_GSGetSteamID* Steam_GSGetSteamID();
virtual IRehldsHookRegistry_Steam_GSGetSteamID* Steam_GSGetSteamID();
virtual IRehldsHookRegistry_Steam_GSBUpdateUserData* Steam_GSBUpdateUserData();
virtual CRehldsHookRegistry_SV_TransferConsistencyInfo* SV_TransferConsistencyInfo();
};
@ -248,4 +254,4 @@ public:
extern sizebuf_t* GetNetMessage_api();
extern IGameClient* GetHostClient_api();
extern int* GetMsgReadCount_api();
extern int* GetMsgReadCount_api();