diff --git a/dep/hlsdk/engine/usermsg.h b/dep/hlsdk/engine/usermsg.h index e3b0897..1623419 100644 --- a/dep/hlsdk/engine/usermsg.h +++ b/dep/hlsdk/engine/usermsg.h @@ -46,6 +46,7 @@ typedef struct _UserMsg } UserMsg; bool HookUserMsg(char *pszMsgName, pfnUserMsgHook pfn); +bool UnHookUserMsg(char *pszMsgName); extern UserMsg *g_pClientUserMsgs; extern std::map g_ClientUserMsgsMap; diff --git a/dep/hlsdk/pm_shared/pm_defs.h b/dep/hlsdk/pm_shared/pm_defs.h index 04bea26..a268fb1 100644 --- a/dep/hlsdk/pm_shared/pm_defs.h +++ b/dep/hlsdk/pm_shared/pm_defs.h @@ -188,5 +188,8 @@ typedef struct playermove_s void (*PM_PlaySound)(int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch); const char *(*PM_TraceTexture)(int ground, float *vstart, float *vend); void (*PM_PlaybackEventFull)(int flags, int clientindex, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2); + pmtrace_t (*PM_PlayerTraceEx)(float *start, float *end, int traceFlags, int (*pfnIgnore)(physent_t *pe)); + int (*PM_TestPlayerPositionEx)(float *pos, pmtrace_t *ptrace, int (*pfnIgnore)(physent_t *pe)); + struct pmtrace_s *(*PM_TraceLineEx)(float *start, float *end, int flags, int usehulll, int (*pfnIgnore)(physent_t *pe)); } playermove_t; diff --git a/hitboxtracker/client/src/cdll_int.cpp b/hitboxtracker/client/src/cdll_int.cpp index 275e2c5..9077ccb 100644 --- a/hitboxtracker/client/src/cdll_int.cpp +++ b/hitboxtracker/client/src/cdll_int.cpp @@ -44,44 +44,104 @@ int Initialize(cl_enginefunc_t *pEnginefuncs, int iVersion) void HUD_Init() { + g_pClientfuncs->pHudFrame = HUD_Frame; g_pClientfuncs->pPostRunCmd = HUD_PostRunCmd; - g_pClientfuncs->pProcessPlayerState = HUD_ProcessPlayerState; g_pClientfuncs->pStudioInterface = HUD_GetStudioModelInterface; + g_pClientfuncs->pDirectorMessage = HUD_DirectorMessage; gClientfuncs.pHudInitFunc(); gHUD.Init(); } -void HUD_WeaponsPostThink(local_state_t *from, local_state_t *to, usercmd_t *cmd, double time, unsigned int random_seed) +void HUD_Frame(double time) { - int flags = from->client.iuser3; + net_status_t st; + gEngfuncs.pNetAPI->Status(&st); - g_bHoldingKnife = (from->client.m_iId == WEAPON_KNIFE); - g_bHoldingShield = (flags & PLAYER_HOLDING_SHIELD) != 0; + const auto delay = 0.5; + if (st.connected == 1 && st.connection_time > (delay - 0.1) && st.connection_time < delay) + { + // tell the server that i want to sync + gEngfuncs.pfnServerCmd("__request_sync"); + } + + gClientfuncs.pHudFrame(time); } -void HUD_ProcessPlayerState(entity_state_t *dst, entity_state_t *src) +union split_double_t { - // save current values of fields from server-side - auto &sync = g_PlayerSyncInfo[src->number]; + split_double_t() : d (0.0) {} + split_double_t(double f) : d(f) {} - sync.yaw = src->vuser1[0]; - sync.gaityaw = src->vuser1[1]; - sync.gaitframe = src->vuser1[2]; + double d; + struct { + int32_t lo; + int32_t hi; + }; +}; - sync.gaitmovement = src->vuser2[0]; - sync.gaitsequence = src->vuser2[1]; - sync.pitch = src->vuser2[2]; +constexpr size_t DIRECTOR_UID = 0xabcdef00; - sync.prevgaitorigin[0] = src->maxs[0]; - sync.prevgaitorigin[1] = src->maxs[1]; - sync.prevgaitorigin[2] = src->maxs[2]; +void HUD_DirectorMessage(int iSize, void *pbuf) +{ + BEGIN_READ(pbuf, iSize); - sync.time = src->mins[0]; // m_clTime - sync.oldtime = src->mins[1]; // m_clOldTime - sync.frametime = src->mins[2]; // m_clTime - m_clOldTime? + auto cmd = READ_BYTE(); + if (cmd != DRC_CMD_TIMESCALE) + { + gClientfuncs.pDirectorMessage(iSize, pbuf); + return; + } - gClientfuncs.pProcessPlayerState(dst, src); + // make sure that this is our custom message + auto uid = READ_LONG(); + if (uid != DIRECTOR_UID) + { + gClientfuncs.pDirectorMessage(iSize, pbuf); + return; + } + + auto index = READ_BYTE(); + + // header packet + if (index == 0) + { + // parse time + split_double_t time, oldtime; + + time.lo = READ_LONG(); + time.hi = READ_LONG(); + + oldtime.lo = READ_LONG(); + oldtime.hi = READ_LONG(); + + sv.time = time.d; + sv.oldtime = oldtime.d; + sv.frametime = READ_FLOAT(); + } + else + { + auto &sync = g_PlayerSyncInfo[index]; + + // save current values of fields from server-side + sync.prevgaitorigin[0] = READ_FLOAT(); + sync.prevgaitorigin[1] = READ_FLOAT(); + sync.prevgaitorigin[2] = READ_FLOAT(); + + sync.yaw = READ_FLOAT(); + sync.pitch = READ_FLOAT(); + + sync.gaityaw = READ_FLOAT(); + sync.gaitframe = READ_FLOAT(); + sync.gaitmovement = READ_FLOAT(); + sync.gaitsequence = READ_LONG (); + } +} + +void HUD_WeaponsPostThink(local_state_t *from, local_state_t *to, usercmd_t *cmd, double time, unsigned int random_seed) +{ + g_bHoldingKnife = (from->client.m_iId == WEAPON_KNIFE); + g_bHoldingShield = (from->client.iuser3 & PLAYER_HOLDING_SHIELD) == PLAYER_HOLDING_SHIELD; } void R_ForceCVars(qboolean multiplayer) diff --git a/hitboxtracker/client/src/hud.cpp b/hitboxtracker/client/src/hud.cpp index bc6b586..a6a92ac 100644 --- a/hitboxtracker/client/src/hud.cpp +++ b/hitboxtracker/client/src/hud.cpp @@ -40,6 +40,7 @@ cvar_t *cl_minmodels; cvar_t *default_fov; cvar_t *sensitivity; +server_sync_t sv; player_sync_t g_PlayerSyncInfo [MAX_PLAYERS + 1]; extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS + 1]; // additional player info sent directly to the client dll diff --git a/hitboxtracker/client/src/hud.h b/hitboxtracker/client/src/hud.h index 81ff557..71f2abd 100644 --- a/hitboxtracker/client/src/hud.h +++ b/hitboxtracker/client/src/hud.h @@ -37,6 +37,13 @@ enum MAX_TEAM_NAME = 16, }; +struct server_sync_t +{ + double time; + double oldtime; + float frametime; +}; + struct player_sync_t { float yaw; @@ -45,9 +52,6 @@ struct player_sync_t float gaitframe; float gaitmovement; int gaitsequence; - float time; - float oldtime; - float frametime; Vector prevgaitorigin; }; @@ -72,7 +76,8 @@ struct extra_player_info_t }; // Macros to hook function calls into the HUD object -#define HOOK_MESSAGE(x) HookUserMsg(#x, __MsgFunc_##x) +#define HOOK_MESSAGE(x) HookUserMsg(#x, __MsgFunc_##x) +#define UNHOOK_MESSAGE(x) UnHookUserMsg(#x) #define DECLARE_MESSAGE(y, x)\ int __MsgFunc_##x(const char *pszName, int iSize, void *pbuf)\ @@ -113,6 +118,7 @@ private: extern CHud gHUD; +extern server_sync_t sv; extern player_sync_t g_PlayerSyncInfo [MAX_PLAYERS + 1]; extern extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS + 1]; diff --git a/hitboxtracker/client/src/modules/engine.cpp b/hitboxtracker/client/src/modules/engine.cpp index 01fa784..3311d42 100644 --- a/hitboxtracker/client/src/modules/engine.cpp +++ b/hitboxtracker/client/src/modules/engine.cpp @@ -97,9 +97,15 @@ bool CEngine::Init(const char *szModuleName, const char *pszFile) m_Software = !Q_stricmp(szModuleName, ENGINE_CLIENT_SOFT_LIB) ? true : false; - if (!LoadSecureClient_Init() || !LoadInSecureClient_Init()) + if (!LoadSecureClient_Init()) { - TraceLog("> %s: Not found ClientFuncs\n", __FUNCTION__); + TraceLog("> %s: Not found LoadSecureClient\n", __FUNCTION__); + return false; + } + + if (!LoadInSecureClient_Init()) + { + TraceLog("> %s: Not found LoadInSecureClient\n", __FUNCTION__); return false; } @@ -229,12 +235,11 @@ bool CEngine::StudioLightingInit() void R_StudioLighting(float *lv, int bone, int flags, const vec_t *normal) { - if (!pfnR_StudioLighting) { - *lv = 0.75f; - return; - } + *lv = 0.75f; - pfnR_StudioLighting(lv, bone, flags, normal); + if (pfnR_StudioLighting) { + pfnR_StudioLighting(lv, bone, flags, normal); + } if (g_EngineLib->IsSoftware()) { *lv = *lv / (USHRT_MAX + 1); diff --git a/hitboxtracker/client/src/studio/GameStudioModelRenderer.cpp b/hitboxtracker/client/src/studio/GameStudioModelRenderer.cpp index 9eb42ed..63cadcc 100644 --- a/hitboxtracker/client/src/studio/GameStudioModelRenderer.cpp +++ b/hitboxtracker/client/src/studio/GameStudioModelRenderer.cpp @@ -356,8 +356,6 @@ void CGameStudioModelRenderer::StudioSetupBones() && m_pCurrentEntity->curstate.sequence != ANIM_SWIM_1 && m_pCurrentEntity->curstate.sequence != ANIM_SWIM_2) { - bool bCopy = true; - if (m_pPlayerInfo->gaitsequence >= m_pStudioHeader->numseq || m_pPlayerInfo->gaitsequence < 0) m_pPlayerInfo->gaitsequence = 0; @@ -366,6 +364,7 @@ void CGameStudioModelRenderer::StudioSetupBones() panim = StudioGetAnim(m_pRenderModel, pseqdesc); StudioCalcRotations(pos2, q2, pseqdesc, panim, m_pPlayerInfo->gaitframe); + bool bCopy = true; for (int i = 0; i < m_pStudioHeader->numbones; i++) { if (!Q_strcmp(pbones[i].name, "Bip01 Spine")) @@ -418,7 +417,7 @@ void CGameStudioModelRenderer::StudioEstimateGait(entity_state_t *pplayer) float dt; if (m_pPlayerSync) { - dt = clamp(m_pPlayerSync->time - m_pPlayerSync->oldtime, 0.0f, 1.0f); + dt = clamp(sv.time - sv.oldtime, 0.0, 1.0); } else { @@ -513,7 +512,7 @@ void CGameStudioModelRenderer::StudioProcessGait(entity_state_t *pplayer) float dt; if (m_pPlayerSync) { - dt = clamp(m_pPlayerSync->time - m_pPlayerSync->oldtime, 0.0f, 1.0f); + dt = clamp(sv.time - sv.oldtime, 0.0, 1.0); } else { @@ -732,7 +731,7 @@ void CGameStudioModelRenderer::SetupClientAnimation(entity_state_t *pplayer) st->m_fSequenceLoops = ((GetSequenceFlags(pmodel, st) & STUDIO_LOOPING) != 0) ? TRUE : FALSE; StudioFrameAdvance(st, fr, dt); - // gEngfuncs.Con_Printf("gs %i frame %f\n", st->gaitsequence, st->frame); + //gEngfuncs.Con_Printf("gs %i frame %f\n", st->gaitsequence, st->frame); ent->angles = st->realangles; ent->curstate.angles = st->angles; @@ -809,7 +808,7 @@ int CGameStudioModelRenderer::StudioDrawPlayer(int flags, entity_state_t *pplaye // Call real draw function int iret = _StudioDrawPlayer(flags, pplayer); - if (iret && m_pCvarDrawEntities->value == 6) + if (iret && (m_pCvarDrawEntities->value == 6 || m_pCvarDrawEntities->value == 7)) { m_pPlayerSync = &g_PlayerSyncInfo[pplayer->number]; m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); @@ -982,7 +981,6 @@ int CGameStudioModelRenderer::_StudioDrawPlayer(int flags, entity_state_t *pplay if (m_pCurrentEntity->index > 0) { cl_entity_t *ent = gEngfuncs.GetEntityByIndex(m_pCurrentEntity->index); - Q_memcpy(ent->attachment, m_pCurrentEntity->attachment, sizeof(ent->attachment)); } } @@ -1157,9 +1155,9 @@ void CGameStudioModelRenderer::CalculatePitchBlend(entity_state_t *pplayer) StudioPlayerBlend(pseqdesc, &iBlend, &m_pCurrentEntity->angles[PITCH]); - m_pCurrentEntity->latched.prevangles[PITCH] = m_pCurrentEntity->angles[PITCH]; - m_pCurrentEntity->curstate.blending[1] = iBlend; - m_pCurrentEntity->latched.prevblending[1] = m_pCurrentEntity->curstate.blending[1]; + m_pCurrentEntity->latched.prevangles[PITCH] = m_pCurrentEntity->angles[PITCH]; + m_pCurrentEntity->curstate.blending[1] = iBlend; + m_pCurrentEntity->latched.prevblending[1] = m_pCurrentEntity->curstate.blending[1]; m_pCurrentEntity->latched.prevseqblending[1] = m_pCurrentEntity->curstate.blending[1]; } diff --git a/hitboxtracker/client/src/studio/StudioModelRenderer.cpp b/hitboxtracker/client/src/studio/StudioModelRenderer.cpp index f27d0c6..1f867da 100644 --- a/hitboxtracker/client/src/studio/StudioModelRenderer.cpp +++ b/hitboxtracker/client/src/studio/StudioModelRenderer.cpp @@ -46,14 +46,14 @@ int CStudioModelRenderer::m_boxpnt[6][4] = vec3_t CStudioModelRenderer::m_hullcolor[8] = { - { 1.0, 1.0, 1.0 }, - { 1.0, 0.5, 0.5 }, - { 0.5, 1.0, 0.5 }, - { 1.0, 1.0, 0.5 }, - { 0.5, 0.5, 1.0 }, - { 1.0, 0.5, 1.0 }, - { 0.5, 1.0, 1.0 }, - { 1.0, 1.0, 1.0 }, + { 1.0, 1.0, 1.0 }, // Shield : White + { 1.0, 0.5, 0.5 }, // Head : Light red + { 0.5, 1.0, 0.5 }, // Chest : Light green + { 1.0, 1.0, 0.5 }, // Stomach : Light yellow + { 0.5, 0.5, 1.0 }, // Leftarm : Light blue + { 1.0, 0.5, 1.0 }, // Rightarm: Pink + { 0.5, 1.0, 1.0 }, // Leftleg : Aqua + { 1.0, 1.0, 1.0 }, // Rightleg: White }; void CStudioModelRenderer::Init() @@ -63,7 +63,7 @@ void CStudioModelRenderer::Init() m_pCvarDeveloper = IEngineStudio.GetCvar("developer"); m_pCvarDrawEntities = IEngineStudio.GetCvar("r_drawentities"); m_pChromeSprite = IEngineStudio.GetChromeSprite(); - m_pWhiteSprite = IEngineStudio.Mod_ForName("sprites/white.spr", 1); + m_pWhiteSprite = IEngineStudio.Mod_ForName("sprites/white.spr", TRUE); IEngineStudio.GetModelCounters(&m_pStudioModelCount, &m_pModelsDrawn); @@ -690,7 +690,7 @@ void CStudioModelRenderer::StudioSetupBones() } panim = StudioGetAnim(m_pRenderModel, pseqdesc); - StudioCalcRotations(pos, q, pseqdesc, panim, (int)f); // TODO: CHECK ME cast from float to int and to float + StudioCalcRotations(pos, q, pseqdesc, panim, f); if (pseqdesc->numblends > 1) { @@ -834,9 +834,6 @@ void CStudioModelRenderer::StudioSetupBones() if (IEngineStudio.IsHardware()) { ConcatTransforms((*m_protationmatrix), bonematrix, (*m_pbonetransform)[i]); - - // MatrixCopy should be faster... - //ConcatTransforms((*m_protationmatrix), bonematrix, (*m_plighttransform)[i]); MatrixCopy((*m_pbonetransform)[i], (*m_plighttransform)[i]); } else @@ -1693,7 +1690,6 @@ void CStudioModelRenderer::StudioDrawAbsBBox() gEngfuncs.pTriAPI->Begin(TRI_QUADS); gEngfuncs.pTriAPI->Color4f(0.5f, 0.5f, 1.0f, 1.0f); - //gEngfuncs.pTriAPI->TexCoord2f(0.0f, 0.0f); for (j = 0; j < ARRAYSIZE(m_boxpnt); j++) { @@ -1720,22 +1716,28 @@ void CStudioModelRenderer::StudioRenderFinal_Software() if (m_pCvarDrawEntities->value == 2) { - //IEngineStudio.StudioDrawBones(); - StudioDrawBones(); // IEngineStudio.StudioDrawBones(); + /*IEngineStudio.*/StudioDrawBones(); } else if (m_pCvarDrawEntities->value == 3) { - StudioDrawHulls(); // IEngineStudio.StudioDrawHulls(); + /*IEngineStudio.*/StudioDrawHulls(); } else { if (m_pPlayerSync) { - if (m_pCurrentEntity->player && m_pCvarDrawEntities->value == 6) + if (m_pCurrentEntity->player) { - gEngfuncs.pTriAPI->RenderMode(kRenderTransAdd); - StudioDrawHulls(); - gEngfuncs.pTriAPI->RenderMode(kRenderNormal); + if (m_pCvarDrawEntities->value == 6) + { + gEngfuncs.pTriAPI->RenderMode(kRenderTransAdd); + StudioDrawHulls(); + gEngfuncs.pTriAPI->RenderMode(kRenderNormal); + } + else if (m_pCvarDrawEntities->value == 7) + { + StudioDrawHulls(); + } } } else @@ -1752,13 +1754,13 @@ void CStudioModelRenderer::StudioRenderFinal_Software() if (m_pCvarDrawEntities->value == 4) { gEngfuncs.pTriAPI->RenderMode(kRenderTransAdd); - StudioDrawHulls(); // IEngineStudio.StudioDrawHulls(); + /*IEngineStudio.*/StudioDrawHulls(); gEngfuncs.pTriAPI->RenderMode(kRenderNormal); } if (m_pCvarDrawEntities->value == 5) { - StudioDrawAbsBBox(); // IEngineStudio.StudioDrawAbsBBox(); + /*IEngineStudio.*/StudioDrawAbsBBox(); } IEngineStudio.RestoreRenderer(); @@ -1771,21 +1773,28 @@ void CStudioModelRenderer::StudioRenderFinal_Hardware() if (m_pCvarDrawEntities->value == 2) { - StudioDrawBones(); // IEngineStudio.StudioDrawBones(); + /*IEngineStudio.*/StudioDrawBones(); } else if (m_pCvarDrawEntities->value == 3) { - StudioDrawHulls(); // IEngineStudio.StudioDrawHulls(); + /*IEngineStudio.*/StudioDrawHulls(); } else { if (m_pPlayerSync) { - if (m_pCurrentEntity->player && m_pCvarDrawEntities->value == 6) + if (m_pCurrentEntity->player) { - gEngfuncs.pTriAPI->RenderMode(kRenderTransAdd); - StudioDrawHulls(); - gEngfuncs.pTriAPI->RenderMode(kRenderNormal); + if (m_pCvarDrawEntities->value == 6) + { + gEngfuncs.pTriAPI->RenderMode(kRenderTransAdd); + StudioDrawHulls(); + gEngfuncs.pTriAPI->RenderMode(kRenderNormal); + } + else if (m_pCvarDrawEntities->value == 7) + { + StudioDrawHulls(); + } } } else @@ -1811,13 +1820,13 @@ void CStudioModelRenderer::StudioRenderFinal_Hardware() if (m_pCvarDrawEntities->value == 4) { gEngfuncs.pTriAPI->RenderMode(kRenderTransAdd); - StudioDrawHulls(); // IEngineStudio.StudioDrawHulls(); + /*IEngineStudio.*/StudioDrawHulls(); gEngfuncs.pTriAPI->RenderMode(kRenderNormal); } if (m_pCvarDrawEntities->value == 5) { - StudioDrawAbsBBox(); // IEngineStudio.StudioDrawAbsBBox(); + /*IEngineStudio.*/StudioDrawAbsBBox(); } IEngineStudio.RestoreRenderer(); diff --git a/hitboxtracker/client/src/studio/studio_util.cpp b/hitboxtracker/client/src/studio/studio_util.cpp index db3c960..5c0dc37 100644 --- a/hitboxtracker/client/src/studio/studio_util.cpp +++ b/hitboxtracker/client/src/studio/studio_util.cpp @@ -157,7 +157,7 @@ void AngleQuaternion(float *angles, vec4_t quaternion) void QuaternionSlerp(vec4_t p, vec4_t q, float t, vec4_t qt) { int i; - float omega, cosom, sinom, sclp, sclq; + float omega, cosom, sinom, sclp, sclq; // decide if one of the quaternions is backwards float a = 0; @@ -168,6 +168,7 @@ void QuaternionSlerp(vec4_t p, vec4_t q, float t, vec4_t qt) a += (p[i] - q[i]) * (p[i] - q[i]); b += (p[i] + q[i]) * (p[i] + q[i]); } + if (a > b) { for (i = 0; i < 4; i++) @@ -176,7 +177,7 @@ void QuaternionSlerp(vec4_t p, vec4_t q, float t, vec4_t qt) } } - cosom = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] + p[3]*q[3]; + cosom = p[0] * q[0] + p[1] * q[1] + p[2] * q[2] + p[3] * q[3]; if ((1.0 + cosom) > 0.000001) { @@ -184,6 +185,7 @@ void QuaternionSlerp(vec4_t p, vec4_t q, float t, vec4_t qt) { omega = acos(cosom); sinom = sin(omega); + sclp = sin((1.0 - t) * omega) / sinom; sclq = sin(t * omega) / sinom; } @@ -201,11 +203,13 @@ void QuaternionSlerp(vec4_t p, vec4_t q, float t, vec4_t qt) else { qt[0] = -q[1]; - qt[1] = q[0]; + qt[1] = q[0]; qt[2] = -q[3]; - qt[3] = q[2]; + qt[3] = q[2]; + sclp = sin((1.0 - t) * (0.5 * M_PI)); sclq = sin(t * (0.5 * M_PI)); + for (i = 0; i < 3; i++) { qt[i] = sclp * p[i] + sclq * qt[i]; diff --git a/hitboxtracker/client/src/studio/studio_util.h b/hitboxtracker/client/src/studio/studio_util.h index 0595225..969896d 100644 --- a/hitboxtracker/client/src/studio/studio_util.h +++ b/hitboxtracker/client/src/studio/studio_util.h @@ -29,7 +29,7 @@ #pragma once #ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h +#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h #endif #define PITCH 0 // up / down diff --git a/hitboxtracker/client/src/usermsg.cpp b/hitboxtracker/client/src/usermsg.cpp index db2bc22..4a9d557 100644 --- a/hitboxtracker/client/src/usermsg.cpp +++ b/hitboxtracker/client/src/usermsg.cpp @@ -48,3 +48,21 @@ bool HookUserMsg(char *pszMsgName, pfnUserMsgHook pfn) return false; } + +bool UnHookUserMsg(char *pszMsgName) +{ + auto pClientUserMsgs = g_pClientUserMsgs; + while (pClientUserMsgs) + { + if (!Q_strcmp(pClientUserMsgs->szName, pszMsgName)) + { + pClientUserMsgs->pfn = g_ClientUserMsgsMap[pszMsgName]; + g_ClientUserMsgsMap[pszMsgName] = nullptr; + return true; + } + + pClientUserMsgs = pClientUserMsgs->next; + } + + return false; +} diff --git a/hitboxtracker/launcher/src/launcher.h b/hitboxtracker/launcher/src/launcher.h deleted file mode 100644 index 3f59c93..0000000 --- a/hitboxtracker/launcher/src/launcher.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once - diff --git a/hitboxtracker/server/src/dllapi.cpp b/hitboxtracker/server/src/dllapi.cpp index a42ee42..87d1dd7 100644 --- a/hitboxtracker/server/src/dllapi.cpp +++ b/hitboxtracker/server/src/dllapi.cpp @@ -18,16 +18,16 @@ DLL_FUNCTIONS g_DllFunctionTable_Post = NULL, // pfnRestoreGlobalState NULL, // pfnResetGlobalState NULL, // pfnClientConnect - NULL, // pfnClientDisconnect + &ClientDisconnect_Post, // pfnClientDisconnect NULL, // pfnClientKill NULL, // pfnClientPutInServer - NULL, // pfnClientCommand + &ClientCommand_Post, // pfnClientCommand NULL, // pfnClientUserInfoChanged &ServerActivate_Post, // pfnServerActivate NULL, // pfnServerDeactivate NULL, // pfnPlayerPreThink - NULL, // pfnPlayerPostThink - NULL, // pfnStartFrame + &PlayerPostThink_Post, // pfnPlayerPostThink + &StartFrame_Post, // pfnStartFrame NULL, // pfnParmsNewLevel NULL, // pfnParmsChangeLevel NULL, // pfnGetGameDescription @@ -41,7 +41,7 @@ DLL_FUNCTIONS g_DllFunctionTable_Post = NULL, // pfnPM_FindTextureType NULL, // pfnSetupVisibility NULL, // pfnUpdateClientData - &AddToFullPack_Post, // pfnAddToFullPack + NULL, // pfnAddToFullPack NULL, // pfnCreateBaseline NULL, // pfnRegisterEncoders NULL, // pfnGetWeaponData diff --git a/hitboxtracker/server/src/main.cpp b/hitboxtracker/server/src/main.cpp index 48346d1..b20b5de 100644 --- a/hitboxtracker/server/src/main.cpp +++ b/hitboxtracker/server/src/main.cpp @@ -30,39 +30,145 @@ server_t *sv; -int AddToFullPack_Post(entity_state_t *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet) +struct player_t { - if (ent->v.modelindex <= 0 || ent->v.modelindex >= MAX_MODELS) + struct player_info_t { - RETURN_META_VALUE(MRES_IGNORED, 0); + bool read_packet : 1; + bool request_sync : 1; + }; + + player_info_t &operator[](size_t i) { return m_data[i - 1]; } + player_info_t &operator[](edict_t *pEdict) { return m_data[ENTINDEX(pEdict) - 1]; } + player_info_t &operator[](CBasePlayer *pPlayer) { return m_data[pPlayer->entindex() - 1]; } + + player_info_t m_data[MAX_CLIENTS]; +}; + +player_t g_Players; +constexpr size_t DIRECTOR_UID = 0xabcdef00; + +void ClientCommand_Post(edict_t *pEdict) +{ + const auto cmd = CMD_ARGV(0); + if (!Q_strcmp(cmd, "__request_sync")) + { + // want sync + g_Players[pEdict].request_sync = true; } - // we need to call every time SV_StudioSetupBones - // to keep gaityaw and other synced on client-side - TraceResult tr; - TRACE_LINE(ent->v.origin - Vector(1, 1, 1), host->v.origin + Vector(1, 1, 1), 0, nullptr, &tr); + RETURN_META(MRES_IGNORED); +} - CBasePlayer *plr = UTIL_PlayerByIndexSafe(e); - if (plr) +void SendPlayerSyncInfo(CBasePlayer *pPlayer) +{ + for (int i = 1; i <= gpGlobals->maxClients; i++) { - state->vuser1[0] = plr->m_flYaw; - state->vuser1[1] = plr->m_flGaityaw; - state->vuser1[2] = plr->m_flGaitframe; + auto plr = UTIL_PlayerByIndex(i); + if (!plr) + continue; - state->vuser2[0] = plr->m_flGaitMovement; - state->vuser2[1] = plr->m_iGaitsequence; - state->vuser2[2] = plr->m_flPitch; + if (plr->IsDormant() || plr->has_disconnected) + continue; - state->maxs[0] = plr->m_prevgaitorigin[0]; - state->maxs[1] = plr->m_prevgaitorigin[0]; - state->maxs[2] = plr->m_prevgaitorigin[0]; + if (!plr->IsNetClient()) + continue; - state->mins[0] = sv->time; - state->mins[1] = sv->oldtime; - state->mins[2] = gpGlobals->frametime; + if (g_Players[plr].request_sync) + { + MESSAGE_BEGIN(MSG_ONE, SVC_DIRECTOR, nullptr, plr->pev); + WRITE_BYTE(42); // number of bytes this message + WRITE_BYTE(DRC_CMD_TIMESCALE); + WRITE_LONG(DIRECTOR_UID); // unique message id + WRITE_BYTE(pPlayer->entindex()); + WRITE_LONG(*(int *)&pPlayer->m_prevgaitorigin[0]); + WRITE_LONG(*(int *)&pPlayer->m_prevgaitorigin[1]); + WRITE_LONG(*(int *)&pPlayer->m_prevgaitorigin[2]); + WRITE_LONG(*(int *)&pPlayer->m_flYaw); + WRITE_LONG(*(int *)&pPlayer->m_flPitch); + WRITE_LONG(*(int *)&pPlayer->m_flGaityaw); + WRITE_LONG(*(int *)&pPlayer->m_flGaitframe); + WRITE_LONG(*(int *)&pPlayer->m_flGaitMovement); + WRITE_LONG(pPlayer->m_iGaitsequence); + MESSAGE_END(); + } + } +} + +void PlayerPostThink_Post(edict_t *pEdict) +{ + g_Players[pEdict].read_packet = true; + RETURN_META(MRES_IGNORED); +} + +void ClientDisconnect_Post(edict_t *pEdict) +{ + g_Players[pEdict].read_packet = false; + g_Players[pEdict].request_sync = false; + RETURN_META(MRES_IGNORED); +} + +union split_double_t +{ + split_double_t() : d (0.0) {} + split_double_t(double f) : d(f) {} + + double d; + struct { + int32_t lo; + int32_t hi; + }; +}; + +void StartFrame_Post() +{ + int count = 0; + CBasePlayer *plrList[MAX_CLIENTS]; + + for (int i = 1; i <= gpGlobals->maxClients; i++) + { + auto pPlayer = UTIL_PlayerByIndex(i); + if (!pPlayer) + continue; + + if (pPlayer->IsDormant() || pPlayer->has_disconnected) + continue; + + if (!pPlayer->IsAlive()) + continue; + + if (!g_Players[i].read_packet) + { + RETURN_META(MRES_IGNORED); + } + + g_Players[i].read_packet = false; + plrList[count++] = pPlayer; } - RETURN_META_VALUE(MRES_IGNORED, 0); + if (count > 0) + { + split_double_t time(sv->time), oldtime(sv->oldtime); + + MESSAGE_BEGIN(MSG_ALL, SVC_DIRECTOR); + WRITE_BYTE(26); // number of bytes this message + WRITE_BYTE(DRC_CMD_TIMESCALE); + WRITE_LONG(DIRECTOR_UID); // unique message id + WRITE_BYTE(0); + WRITE_LONG(time.lo); + WRITE_LONG(time.hi); + WRITE_LONG(oldtime.lo); + WRITE_LONG(oldtime.hi); + WRITE_LONG(*(int *)&gpGlobals->frametime); + MESSAGE_END(); + + // 26 + (42 * count) the total number of payload bytes + for (int i = 0; i < count; i++) { + SendPlayerSyncInfo(plrList[i]); + } + } + + RETURN_META(MRES_IGNORED); } void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax) diff --git a/hitboxtracker/server/src/main.h b/hitboxtracker/server/src/main.h index 11b5659..1f94318 100644 --- a/hitboxtracker/server/src/main.h +++ b/hitboxtracker/server/src/main.h @@ -28,7 +28,10 @@ #pragma once -#include "entity_state.h" +#include "hltv.h" -int AddToFullPack_Post(entity_state_t *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet); +void StartFrame_Post(); +void PlayerPostThink_Post(edict_t *pEdict); void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax); +void ClientDisconnect_Post(edict_t *pEdict); +void ClientCommand_Post(edict_t *pEdict);