diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cfa836fee..b4e807929 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -58,14 +58,13 @@ jobs: move msvc\${{ env.buildRelease }}\mp.pdb publish\debug\mp.pdb - name: Deploy artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v3.1.1 with: name: win32 path: publish/* testdemos: - if: false # TODO: FIXME!! - name: 'Test demos (FIXME)' + name: 'Test demos' runs-on: ubuntu-20.04 container: s1lentq/testdemos:latest needs: [windows] @@ -73,6 +72,7 @@ jobs: env: WINEDEBUG: -all WINEDLLOVERRIDES: mshtml= + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true defaults: run: @@ -81,7 +81,7 @@ jobs: steps: - name: Deploying windows artifacts - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: win32 @@ -146,12 +146,11 @@ jobs: run: | sudo dpkg --add-architecture i386 sudo apt-get update - sudo apt-get install -y clang sudo apt-get install -y gcc-multilib g++-multilib - name: Build and Run unittests run: | - rm -rf build && CC=clang CXX=clang++ cmake -DCMAKE_BUILD_TYPE=Unittests -B build && cmake --build build -j8 + rm -rf build && CC=gcc CXX=g++ cmake -DCMAKE_BUILD_TYPE=Unittests -B build && cmake --build build -j8 retVal=0 ./build/regamedll/cs 2> /dev/null > result.log || retVal=$? while read line; do @@ -172,9 +171,9 @@ jobs: fi shell: bash - - name: Build using Clang C++ Compiler + - name: Build run: | - rm -rf build && CC=clang CXX=clang++ cmake -B build && cmake --build build -j8 + rm -rf build && CC=gcc CXX=g++ cmake -B build && cmake --build build -j8 - name: Prepare CSSDK run: | @@ -200,7 +199,7 @@ jobs: shell: bash - name: Deploy artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v3.1.1 id: upload-job with: name: linux32 @@ -219,12 +218,12 @@ jobs: steps: - name: Deploying linux artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v3 with: name: linux32 - name: Deploying windows artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v3 with: name: win32 diff --git a/README.md b/README.md index 6a41158c8..0ca8b1536 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ This means that plugins that do binary code analysis (Orpheu for example) probab | swapteams | Swap the teams and restart the game (1 sec delay to restart by default).
Args:
`0` - swap teams without restart.
`>0.001` - time delay in seconds to restart the round after swap. | | give | Give weapon command.
Args:

Usage:
`give weapon_ak47`
`give weapon_usp`

NOTE: `sv_cheats 1` required. | | impulse 255 | Give all weapons.

NOTE: `sv_cheats 1` required. | +| impulse 200 | Noclip with air acceleration.

NOTE: `sv_cheats 1` required. | ## Configuration (cvars)
@@ -120,6 +121,8 @@ This means that plugins that do binary code analysis (Orpheu for example) probab | mp_item_respawn_time | 30 | 0.0 | - | The respawn time for items (such as health packs, armor, etc.). | | mp_weapon_respawn_time | 20 | 0.0 | - | The respawn time for weapons. | | mp_ammo_respawn_time | 20 | 0.0 | - | The respawn time for ammunition. | +| mp_vote_flags | km | 0 | - | Vote systems enabled in server.
`0` voting disabled
`k` votekick enabled via `vote` command
`m` votemap enabled via `votemap` command | +| mp_votemap_min_time | 180 | 0.0 | - | Minimum seconds that must elapse on map before `votemap` command can be used. | | mp_scoreboard_fix | 0 | 0 | 1 | Enable ReGameDLL scoreboard bug fix(Dead players could see the bomb or defuse kit).
`0` disabled
`1` enabled
`NOTE`: Absolutely cannot fix it in "CNCS😂" |
diff --git a/dist/game.cfg b/dist/game.cfg index e5db27cf1..6d6f76972 100644 --- a/dist/game.cfg +++ b/dist/game.cfg @@ -607,6 +607,21 @@ mp_weapon_respawn_time "20" // Default value: "20" mp_ammo_respawn_time "20" +// Vote systems enabled in server +// +// k - votekick enabled via vote command +// m - votemap enabled via votemap command +// +// Set to "0" to disable voting systems +// +// Default value: "km" +mp_vote_flags "km" + +// Minimum seconds that must elapse on map before votemap command can be used +// +// Default value: "180" +mp_votemap_min_time "180" + // Enable ReGameDLL scoreboard bug fix(Dead players could see the bomb or defuse kit) // 0 - disable // 1 - enabled diff --git a/regamedll/CMakeLists.txt b/regamedll/CMakeLists.txt index ffae23827..bc0a990e9 100644 --- a/regamedll/CMakeLists.txt +++ b/regamedll/CMakeLists.txt @@ -348,6 +348,7 @@ target_compile_definitions(regamedll PRIVATE _strnicmp=strncasecmp _strdup=strdup _unlink=unlink + _snprintf=snprintf _vsnprintf=vsnprintf _write=write _close=close diff --git a/regamedll/dlls/bot/cs_bot_init.cpp b/regamedll/dlls/bot/cs_bot_init.cpp index a6503e901..1bf7aec00 100644 --- a/regamedll/dlls/bot/cs_bot_init.cpp +++ b/regamedll/dlls/bot/cs_bot_init.cpp @@ -332,7 +332,7 @@ void CCSBot::SpawnBot() TheCSBots()->ValidateMapData(); ResetValues(); - Q_strcpy(m_name, STRING(pev->netname)); + Q_strlcpy(m_name, STRING(pev->netname)); SetState(&m_buyState); SetTouch(&CCSBot::BotTouch); diff --git a/regamedll/dlls/bot/cs_bot_learn.cpp b/regamedll/dlls/bot/cs_bot_learn.cpp index 76edded7a..3cf041e31 100644 --- a/regamedll/dlls/bot/cs_bot_learn.cpp +++ b/regamedll/dlls/bot/cs_bot_learn.cpp @@ -477,14 +477,14 @@ void CCSBot::StartSaveProcess() void CCSBot::UpdateSaveProcess() { - char filename[256]; char msg[256]; char cmd[128]; - GET_GAME_DIR(filename); + char gd[64]{}; + GET_GAME_DIR(gd); - Q_strcat(filename, "\\"); - Q_strcat(filename, TheBots->GetNavMapFilename()); + char filename[MAX_OSPATH]; + Q_snprintf(filename, sizeof(filename), "%s\\%s", gd, TheBots->GetNavMapFilename()); HintMessageToAllPlayers("Saving..."); SaveNavigationMap(filename); diff --git a/regamedll/dlls/bot/cs_bot_manager.cpp b/regamedll/dlls/bot/cs_bot_manager.cpp index b4391be7f..730805bbf 100644 --- a/regamedll/dlls/bot/cs_bot_manager.cpp +++ b/regamedll/dlls/bot/cs_bot_manager.cpp @@ -578,14 +578,16 @@ void CCSBotManager::ServerCommand(const char *pcmd) } else if (FStrEq(pcmd, "bot_nav_save")) { - GET_GAME_DIR(buffer); - Q_strcat(buffer, "\\"); - Q_strcat(buffer, CBotManager::GetNavMapFilename()); + char gd[64]{}; + GET_GAME_DIR(gd); - if (SaveNavigationMap(buffer)) - CONSOLE_ECHO("Navigation map '%s' saved.\n", buffer); + char filename[MAX_OSPATH]; + Q_snprintf(filename, sizeof(filename), "%s\\%s", gd, CBotManager::GetNavMapFilename()); + + if (SaveNavigationMap(filename)) + CONSOLE_ECHO("Navigation map '%s' saved.\n", filename); else - CONSOLE_ECHO("ERROR: Cannot save navigation map '%s'.\n", buffer); + CONSOLE_ECHO("ERROR: Cannot save navigation map '%s'.\n", filename); } else if (FStrEq(pcmd, "bot_nav_load")) { @@ -1211,6 +1213,13 @@ void CCSBotManager::ValidateMapData() found = true; isLegacy = false; } + else if (FClassnameIs(pEntity->pev, "func_escapezone")) + { + m_gameScenario = SCENARIO_ESCAPE; + found = true; + isLegacy = false; + } + if (found) { diff --git a/regamedll/dlls/bot/cs_bot_manager.h b/regamedll/dlls/bot/cs_bot_manager.h index 1faea5461..9552c6978 100644 --- a/regamedll/dlls/bot/cs_bot_manager.h +++ b/regamedll/dlls/bot/cs_bot_manager.h @@ -85,7 +85,8 @@ class CCSBotManager: public CBotManager SCENARIO_DEATHMATCH, SCENARIO_DEFUSE_BOMB, SCENARIO_RESCUE_HOSTAGES, - SCENARIO_ESCORT_VIP + SCENARIO_ESCORT_VIP, + SCENARIO_ESCAPE }; GameScenarioType GetScenario() const diff --git a/regamedll/dlls/bot/states/cs_bot_idle.cpp b/regamedll/dlls/bot/states/cs_bot_idle.cpp index e38bde885..4bfcd7cc0 100644 --- a/regamedll/dlls/bot/states/cs_bot_idle.cpp +++ b/regamedll/dlls/bot/states/cs_bot_idle.cpp @@ -773,6 +773,93 @@ void IdleState::OnUpdate(CCSBot *me) } break; } + case CCSBotManager::SCENARIO_ESCAPE: + { + if (me->m_iTeam == TERRORIST) + { + // if early in round, pick a random zone, otherwise pick closest zone + const float earlyTime = 20.0f; + const CCSBotManager::Zone *zone = nullptr; + + if (TheCSBots()->GetElapsedRoundTime() < earlyTime) + { + // pick random zone + zone = TheCSBots()->GetRandomZone(); + } + else + { + // pick closest zone + zone = TheCSBots()->GetClosestZone(me->GetLastKnownArea(), PathCost(me)); + } + + if (zone) + { + // pick a random spot within the escape zone + const Vector *pos = TheCSBots()->GetRandomPositionInZone(zone); + if (pos) + { + // move to escape zone + // me->SetTask(CCSBot::VIP_ESCAPE); + me->Run(); + me->MoveTo(pos); + return; + } + } + } + // CT + else + { + if (me->IsSniper()) + { + if (RANDOM_FLOAT(0, 100) <= defenseSniperCampChance) + { + // snipe escape zone(s) + const CCSBotManager::Zone *zone = TheCSBots()->GetRandomZone(); + if (zone) + { + CNavArea *area = TheCSBots()->GetRandomAreaInZone(zone); + if (area) + { + me->SetTask(CCSBot::MOVE_TO_SNIPER_SPOT); + me->Hide(area, -1.0, sniperHideRange); + me->SetDisposition(CCSBot::OPPORTUNITY_FIRE); + me->PrintIfWatched("Sniping near escape zone\n"); + return; + } + } + } + } + + // rogues just hunt, unless they want to snipe + // if the whole team has decided to rush, hunt + if (me->IsRogue() || TheCSBots()->IsDefenseRushing()) + break; + + // the lower our morale gets, the more we want to camp the escape zone(s) + float guardEscapeZoneChance = -34.0f * me->GetMorale(); + + if (RANDOM_FLOAT(0.0f, 100.0f) < guardEscapeZoneChance) + { + // guard escape zone(s) + const CCSBotManager::Zone *zone = TheCSBots()->GetRandomZone(); + if (zone) + { + CNavArea *area = TheCSBots()->GetRandomAreaInZone(zone); + if (area) + { + // guard the escape zone - stay closer if our morale is low + //me->SetTask(CCSBot::GUARD_VIP_ESCAPE_ZONE); + me->PrintIfWatched("I'm guarding an escape zone\n"); + + float escapeGuardRange = 750.0f + 250.0f * (me->GetMorale() + 3); + me->Hide(area, -1.0, escapeGuardRange); + me->SetDisposition(CCSBot::OPPORTUNITY_FIRE); + return; + } + } + } + } + } // deathmatch default: { diff --git a/regamedll/dlls/cbase.cpp b/regamedll/dlls/cbase.cpp index ebfd2fdc2..5be847bdc 100644 --- a/regamedll/dlls/cbase.cpp +++ b/regamedll/dlls/cbase.cpp @@ -1598,6 +1598,30 @@ void OnFreeEntPrivateData(edict_t *pEnt) if (!pEntity) return; +#ifdef REGAMEDLL_FIXES + // FIXED: Ensure this item will be removed from the owner player's inventory 'm_rgpPlayerItems[]' + // to avoid dangling pointers + CBasePlayerItem *pItem = dynamic_cast(pEntity); + if (pItem) + { + CBasePlayer *pOwner = GET_PRIVATE(pItem->pev->owner); + if (pOwner && pOwner->IsPlayer()) + { + if (pOwner->m_pActiveItem == pItem && pItem->IsWeapon()) + ((CBasePlayerWeapon *)pItem)->RetireWeapon(); + + if (pOwner->RemovePlayerItem(pItem)) + { + // Ammo must be dropped, otherwise grenades cannot be buy or picked up + if (IsGrenadeWeapon(pItem->m_iId) || pItem->m_iId == WEAPON_C4) + pOwner->m_rgAmmo[pItem->PrimaryAmmoIndex()] = 0; + + pOwner->pev->weapons &= ~(1 << pItem->m_iId); + } + } + } +#endif + #ifdef REGAMEDLL_API pEntity->OnDestroy(); #endif diff --git a/regamedll/dlls/cdll_dll.h b/regamedll/dlls/cdll_dll.h index da6cd36df..6e495368d 100644 --- a/regamedll/dlls/cdll_dll.h +++ b/regamedll/dlls/cdll_dll.h @@ -74,6 +74,7 @@ const int DEFAULT_FOV = 90; // the default field of view #define PLAYER_PREVENT_DUCK BIT(4) #define PLAYER_PREVENT_CLIMB BIT(5) // The player can't climb ladder #define PLAYER_PREVENT_JUMP BIT(6) +#define PLAYER_PREVENT_DDUCK BIT(7) #define MENU_KEY_1 BIT(0) #define MENU_KEY_2 BIT(1) diff --git a/regamedll/dlls/client.cpp b/regamedll/dlls/client.cpp index 961175644..5e37071d2 100644 --- a/regamedll/dlls/client.cpp +++ b/regamedll/dlls/client.cpp @@ -133,6 +133,7 @@ static entity_field_alias_t custom_entity_field_alias[] = { "animtime", 0 }, }; +edict_t *g_pEdicts = nullptr; bool g_bServerActive = false; bool g_bItemCreatedByBuying = false; PLAYERPVSSTATUS g_PVSStatus[MAX_CLIENTS]; @@ -464,7 +465,7 @@ NOXREF int CountTeams() void ListPlayers(CBasePlayer *current) { - char message[120] = "", cNumber[12]; + char message[120]{}; CBaseEntity *pEntity = nullptr; while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player"))) @@ -478,12 +479,7 @@ void ListPlayers(CBasePlayer *current) CBasePlayer *pPlayer = GetClassPtr((CBasePlayer *)pEntity->pev); int iUserID = GETPLAYERUSERID(ENT(pPlayer->pev)); - Q_sprintf(cNumber, "%d", iUserID); - Q_strcpy(message, "\n"); - Q_strcat(message, cNumber); - Q_strcat(message, " : "); - Q_strcat(message, STRING(pPlayer->pev->netname)); - + Q_snprintf(message, sizeof(message), "\n%d : %s", iUserID, STRING(pPlayer->pev->netname)); ClientPrint(current->pev, HUD_PRINTCONSOLE, message); } @@ -737,8 +733,8 @@ void EXT_FUNC ClientPutInServer(edict_t *pEntity) pPlayer->m_iJoiningState = SHOWLTEXT; - static char sName[128]; - Q_strcpy(sName, STRING(pPlayer->pev->netname)); + char sName[128]; + Q_strlcpy(sName, STRING(pPlayer->pev->netname)); for (char *pApersand = sName; pApersand && *pApersand != '\0'; pApersand++) { @@ -796,12 +792,12 @@ void Host_Say(edict_t *pEntity, BOOL teamonly) { if (CMD_ARGC_() >= 2) { - Q_sprintf(szTemp, "%s %s", pcmd, CMD_ARGS()); + Q_snprintf(szTemp, sizeof(szTemp), "%s %s", pcmd, CMD_ARGS()); } else { // Just a one word command, use the first word...sigh - Q_sprintf(szTemp, "%s", pcmd); + Q_snprintf(szTemp, sizeof(szTemp), "%s", pcmd); } p = szTemp; @@ -966,8 +962,8 @@ void Host_Say(edict_t *pEntity, BOOL teamonly) } } - Q_strcat(text, p); - Q_strcat(text, "\n"); + Q_strlcat(text, p); + Q_strlcat(text, "\n"); // loop through all players // Start with the first player. @@ -2638,6 +2634,15 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa return; } +#ifdef REGAMEDLL_ADD + static const int flagKick = UTIL_ReadFlags("k"); + if ((flagKick & UTIL_ReadFlags(vote_flags.string)) == 0) + { + ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Command_Not_Available"); + return; + } +#endif + pPlayer->m_flNextVoteTime = gpGlobals->time + 3; if (pPlayer->m_iTeam != UNASSIGNED) @@ -2719,11 +2724,20 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa return; } +#ifdef REGAMEDLL_ADD + static const int flagMap = UTIL_ReadFlags("m"); + if ((flagMap & UTIL_ReadFlags(vote_flags.string)) == 0) + { + ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Command_Not_Available"); + return; + } +#endif + pPlayer->m_flNextVoteTime = gpGlobals->time + 3; if (pPlayer->m_iTeam != UNASSIGNED) { - if (gpGlobals->time < 180) + if (gpGlobals->time < CGameRules::GetVotemapMinElapsedTime()) { ClientPrint(pPlayer->pev, HUD_PRINTCONSOLE, "#Cannot_Vote_Map"); return; @@ -3292,6 +3306,26 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa } } #endif + +#ifdef REGAMEDLL_ADD + // Request from client for the given version of player movement control, if any + else if (FStrEq(pcmd, "cl_pmove_version")) + { + // cl_pmove_version + if (CMD_ARGC_() < 2) + return; // invalid + + PlayerMovementVersion &playerMovementVersion = pPlayer->CSPlayer()->m_MovementVersion; + playerMovementVersion.Set(parg1); + + // If the client's requested movement version is newer, enforce it to the available one + if (playerMovementVersion.IsGreaterThan(PM_VERSION)) + { + playerMovementVersion.Set(PM_VERSION); // reset to available version + CLIENT_COMMAND(pEntity, "cl_pmove_version %s\n", playerMovementVersion.ToString()); + } + } +#endif else { if (g_pGameRules->ClientCommand_DeadOrAlive(GetClassPtr((CBasePlayer *)pev), pcmd)) @@ -3720,6 +3754,22 @@ void EXT_FUNC ServerDeactivate() void EXT_FUNC ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) { + g_pEdicts = pEdictList; + +#ifdef REGAMEDLL_ADD + // + // Tells clients which version of player movement (pmove) the server is using + // + // In GoldSrc, both the server and clients handle player movement using shared code. + // If the server changes how movement works, due to improvements or bugfixes, it can mess up + // the client's movement prediction, causing desync. To avoid this, the server can tell clients what + // version of the movement code it's using. Clients that don't recognize or respond to this version + // will be treated as using the previous behavior, and the server will handle them accordingly. + // Clients that do recognize it will let the server know, so everything stays in sync. + // + SET_KEY_VALUE(GET_INFO_BUFFER(pEdictList), "pmove", PM_ServerVersion()); +#endif + int i; CBaseEntity *pClass; @@ -4949,7 +4999,7 @@ void EXT_FUNC UpdateClientData(const edict_t *ent, int sendweapons, struct clien cd->flSwimTime = pev->flSwimTime; cd->waterjumptime = int(pev->teleport_time); - Q_strcpy(cd->physinfo, ENGINE_GETPHYSINFO(ent)); + Q_strlcpy(cd->physinfo, ENGINE_GETPHYSINFO(ent)); cd->maxspeed = pev->maxspeed; cd->fov = pev->fov; @@ -5160,8 +5210,10 @@ int EXT_FUNC InconsistentFile(const edict_t *pEdict, const char *filename, char if (!CVAR_GET_FLOAT("mp_consistency")) return 0; + const int BufferLen = 256; + // Default behavior is to kick the player - Q_sprintf(disconnect_message, "Server is enforcing file consistency for %s\n", filename); + Q_snprintf(disconnect_message, BufferLen, "Server is enforcing file consistency for %s\n", filename); // Kick now with specified disconnect message. return 1; diff --git a/regamedll/dlls/debug.cpp b/regamedll/dlls/debug.cpp index 82d50d71d..81605143d 100644 --- a/regamedll/dlls/debug.cpp +++ b/regamedll/dlls/debug.cpp @@ -27,7 +27,7 @@ NOXREF void UTIL_DPrintf(DebugOutputType outputType, char *pszMsg, ...) { va_list argptr; va_start(argptr, pszMsg); - vsprintf(theDebugBuffer, pszMsg, argptr); + Q_vsnprintf(theDebugBuffer, sizeof(theDebugBuffer), pszMsg, argptr); va_end(argptr); SERVER_PRINT(theDebugBuffer); @@ -41,7 +41,7 @@ void UTIL_DPrintf(char *pszMsg, ...) va_list argptr; va_start(argptr, pszMsg); - vsprintf(theDebugBuffer, pszMsg, argptr); + Q_vsnprintf(theDebugBuffer, sizeof(theDebugBuffer), pszMsg, argptr); va_end(argptr); SERVER_PRINT(theDebugBuffer); @@ -130,7 +130,7 @@ NOXREF void UTIL_BotDPrintf(char *pszMsg, ...) { va_list argptr; va_start(argptr, pszMsg); - vsprintf(theDebugBuffer, pszMsg, argptr); + Q_vsnprintf(theDebugBuffer, sizeof(theDebugBuffer), pszMsg, argptr); va_end(argptr); SERVER_PRINT(theDebugBuffer); @@ -146,7 +146,7 @@ void UTIL_CareerDPrintf(char *pszMsg, ...) { va_list argptr; va_start(argptr, pszMsg); - vsprintf(theDebugBuffer, pszMsg, argptr); + Q_vsnprintf(theDebugBuffer, sizeof(theDebugBuffer), pszMsg, argptr); va_end(argptr); SERVER_PRINT(theDebugBuffer); @@ -162,7 +162,7 @@ NOXREF void UTIL_TutorDPrintf(char *pszMsg, ...) { va_list argptr; va_start(argptr, pszMsg); - vsprintf(theDebugBuffer, pszMsg, argptr); + Q_vsnprintf(theDebugBuffer, sizeof(theDebugBuffer), pszMsg, argptr); va_end(argptr); SERVER_PRINT(theDebugBuffer); @@ -178,7 +178,7 @@ NOXREF void UTIL_StatsDPrintf(char *pszMsg, ...) { va_list argptr; va_start(argptr, pszMsg); - vsprintf(theDebugBuffer, pszMsg, argptr); + Q_vsnprintf(theDebugBuffer, sizeof(theDebugBuffer), pszMsg, argptr); va_end(argptr); SERVER_PRINT(theDebugBuffer); @@ -194,7 +194,7 @@ NOXREF void UTIL_HostageDPrintf(char *pszMsg, ...) { va_list argptr; va_start(argptr, pszMsg); - vsprintf(theDebugBuffer, pszMsg, argptr); + Q_vsnprintf(theDebugBuffer, sizeof(theDebugBuffer), pszMsg, argptr); va_end(argptr); SERVER_PRINT(theDebugBuffer); diff --git a/regamedll/dlls/explode.cpp b/regamedll/dlls/explode.cpp index 104d84720..6d1c7ccd4 100644 --- a/regamedll/dlls/explode.cpp +++ b/regamedll/dlls/explode.cpp @@ -201,7 +201,7 @@ void ExplosionCreate(const Vector ¢er, Vector &angles, edict_t *pOwner, int CBaseEntity *pExplosion = CBaseEntity::Create("env_explosion", center, angles, pOwner); - Q_sprintf(buf, "%3d", magnitude); + Q_snprintf(buf, sizeof(buf), "%3d", magnitude); kvd.szKeyName = "iMagnitude"; kvd.szValue = buf; diff --git a/regamedll/dlls/game.cpp b/regamedll/dlls/game.cpp index 964286ea6..d3947fb76 100644 --- a/regamedll/dlls/game.cpp +++ b/regamedll/dlls/game.cpp @@ -185,6 +185,9 @@ cvar_t item_respawn_time = { "mp_item_respawn_time", "30", FCVAR_SERVER, 3 cvar_t weapon_respawn_time = { "mp_weapon_respawn_time", "20", FCVAR_SERVER, 20.0f, nullptr }; cvar_t ammo_respawn_time = { "mp_ammo_respawn_time", "20", FCVAR_SERVER, 20.0f, nullptr }; +cvar_t vote_flags = { "mp_vote_flags", "km", 0, 0.0f, nullptr }; +cvar_t votemap_min_time = { "mp_votemap_min_time", "180", 0, 180.0f, nullptr }; + cvar_t scoreboard_fix = { "mp_scoreboard_fix", "0", FCVAR_SERVER, 0.0f, nullptr }; void GameDLL_Version_f() @@ -455,8 +458,11 @@ void EXT_FUNC GameDLLInit() CVAR_REGISTER(&item_respawn_time); CVAR_REGISTER(&weapon_respawn_time); CVAR_REGISTER(&ammo_respawn_time); - - CVAR_REGISTER(&scoreboard_fix); + + CVAR_REGISTER(&vote_flags); + CVAR_REGISTER(&votemap_min_time); + + CVAR_REGISTER(&scoreboard_fix); // print version CONSOLE_ECHO("ReGameDLL version: " APP_VERSION "\n"); diff --git a/regamedll/dlls/game.h b/regamedll/dlls/game.h index 843f12fd6..af147d855 100644 --- a/regamedll/dlls/game.h +++ b/regamedll/dlls/game.h @@ -203,10 +203,11 @@ extern cvar_t freezetime_jump; extern cvar_t defuser_allocation; extern cvar_t location_area_info; extern cvar_t chat_loc_fallback; - extern cvar_t item_respawn_time; extern cvar_t weapon_respawn_time; extern cvar_t ammo_respawn_time; +extern cvar_t vote_flags; +extern cvar_t votemap_min_time; extern cvar_t scoreboard_fix; diff --git a/regamedll/dlls/gamerules.cpp b/regamedll/dlls/gamerules.cpp index 45210e212..3d9f14182 100644 --- a/regamedll/dlls/gamerules.cpp +++ b/regamedll/dlls/gamerules.cpp @@ -8,8 +8,8 @@ CGameRules::CGameRules() m_bBombDropped = FALSE; m_bGameOver = false; - m_GameDesc = new char[sizeof("Counter-Strike")]; - Q_strcpy(m_GameDesc, AreRunningCZero() ? "Condition Zero" : "Counter-Strike"); + const char *pszGameDesc = AreRunningCZero() ? "Condition Zero" : "Counter-Strike"; + m_GameDesc = CloneString(pszGameDesc); } CGameRules::~CGameRules() diff --git a/regamedll/dlls/gamerules.h b/regamedll/dlls/gamerules.h index cc6e9ec8f..220e09556 100644 --- a/regamedll/dlls/gamerules.h +++ b/regamedll/dlls/gamerules.h @@ -31,28 +31,29 @@ #include "game_shared/voice_gamemgr.h" #include "cmdhandler.h" -const int MAX_RULE_BUFFER = 1024; -const int MAX_VOTE_MAPS = 100; -const int MAX_VIP_QUEUES = 5; -const int MAX_MONEY_THRESHOLD = 999999; // allowable money limit in the game that can be drawn on the HUD - -const int MAX_MOTD_CHUNK = 60; -const int MAX_MOTD_LENGTH = 1536; // (MAX_MOTD_CHUNK * 4) - -const float ITEM_RESPAWN_TIME = 30.0f; -const float WEAPON_RESPAWN_TIME = 20.0f; -const float AMMO_RESPAWN_TIME = 20.0f; -const float ROUND_RESPAWN_TIME = 20.0f; -const float ROUND_BEGIN_DELAY = 5.0f; // delay before beginning new round -const float ITEM_KILL_DELAY = 300.0f; -const float RADIO_TIMEOUT = 1.5f; +const int MAX_RULE_BUFFER = 1024; +const int MAX_VOTE_MAPS = 100; +const int MAX_VIP_QUEUES = 5; +const int MAX_MONEY_THRESHOLD = 999999; // allowable money limit in the game that can be drawn on the HUD + +const int MAX_MOTD_CHUNK = 60; +const int MAX_MOTD_LENGTH = 1536; // (MAX_MOTD_CHUNK * 4) + +const float ITEM_RESPAWN_TIME = 30.0f; +const float WEAPON_RESPAWN_TIME = 20.0f; +const float AMMO_RESPAWN_TIME = 20.0f; +const float ROUND_RESPAWN_TIME = 20.0f; +const float ROUND_BEGIN_DELAY = 5.0f; // delay before beginning new round +const float ITEM_KILL_DELAY = 300.0f; +const float RADIO_TIMEOUT = 1.5f; const float DEATH_ANIMATION_TIME = 3.0f; +const float VOTEMAP_MIN_TIME = 180.0f; -const int MAX_INTERMISSION_TIME = 120; // longest the intermission can last, in seconds +const int MAX_INTERMISSION_TIME = 120; // longest the intermission can last, in seconds // when we are within this close to running out of entities, items // marked with the ITEM_FLAG_LIMITINWORLD will delay their respawn -const int ENTITY_INTOLERANCE = 100; +const int ENTITY_INTOLERANCE = 100; enum { @@ -381,6 +382,7 @@ class CGameRules static float GetItemKillDelay(); static float GetRadioTimeout(); static float GetDyingTime(); + static float GetVotemapMinElapsedTime(); public: BOOL m_bFreezePeriod; // TRUE at beginning of round, set to FALSE when the period expires @@ -986,6 +988,15 @@ inline float CGameRules::GetDyingTime() #endif } +inline float CGameRules::GetVotemapMinElapsedTime() +{ +#ifdef REGAMEDLL_ADD + return votemap_min_time.value; +#else + return VOTEMAP_MIN_TIME; +#endif +} + bool IsBotSpeaking(); void SV_Continue_f(); void SV_Tutor_Toggle_f(); @@ -998,5 +1009,4 @@ char *GetTeam(int team); void DestroyMapCycle(mapcycle_t *cycle); int ReloadMapCycleFile(char *filename, mapcycle_t *cycle); int CountPlayers(); -void ExtractCommandString(char *s, char *szCommand); int GetMapCount(); diff --git a/regamedll/dlls/hostage/hostage_improv.cpp b/regamedll/dlls/hostage/hostage_improv.cpp index 9cdba7777..6932d2185 100644 --- a/regamedll/dlls/hostage/hostage_improv.cpp +++ b/regamedll/dlls/hostage/hostage_improv.cpp @@ -1605,9 +1605,9 @@ void CHostageImprov::Afraid() int which = RANDOM_LONG(0, 100) % 3 + 1; - Q_sprintf(animInto, "cower_into_%d", which); - Q_sprintf(animLoop, "cower_loop_%d", which); - Q_sprintf(animExit, "cower_exit_%d", which); + Q_snprintf(animInto, sizeof(animInto), "cower_into_%d", which); + Q_snprintf(animLoop, sizeof(animLoop), "cower_loop_%d", which); + Q_snprintf(animExit, sizeof(animExit), "cower_exit_%d", which); m_animateState.AddSequence(this, animInto); m_animateState.AddSequence(this, animLoop, RANDOM_FLOAT(3, 10)); diff --git a/regamedll/dlls/items.cpp b/regamedll/dlls/items.cpp index 03620e362..ba138e044 100644 --- a/regamedll/dlls/items.cpp +++ b/regamedll/dlls/items.cpp @@ -237,7 +237,7 @@ BOOL CItemBattery::MyTouch(CBasePlayer *pPlayer) pct--; char szcharge[64]; - Q_sprintf(szcharge, "!HEV_%1dP", pct); + Q_snprintf(szcharge, sizeof(szcharge), "!HEV_%1dP", pct); pPlayer->SetSuitUpdate(szcharge, SUIT_SENTENCE, SUIT_NEXT_IN_30SEC); return TRUE; diff --git a/regamedll/dlls/lights.cpp b/regamedll/dlls/lights.cpp index d44cddcc1..aa8629ea0 100644 --- a/regamedll/dlls/lights.cpp +++ b/regamedll/dlls/lights.cpp @@ -129,11 +129,11 @@ void CEnvLight::KeyValue(KeyValueData *pkvd) pkvd->fHandled = TRUE; char szColor[64]; - Q_sprintf(szColor, "%d", r); + Q_snprintf(szColor, sizeof(szColor), "%d", r); CVAR_SET_STRING("sv_skycolor_r", szColor); - Q_sprintf(szColor, "%d", g); + Q_snprintf(szColor, sizeof(szColor), "%d", g); CVAR_SET_STRING("sv_skycolor_g", szColor); - Q_sprintf(szColor, "%d", b); + Q_snprintf(szColor, sizeof(szColor), "%d", b); CVAR_SET_STRING("sv_skycolor_b", szColor); } else @@ -147,13 +147,13 @@ void CEnvLight::Spawn() char szVector[64]; UTIL_MakeAimVectors(pev->angles); - Q_sprintf(szVector, "%f", gpGlobals->v_forward.x); + Q_snprintf(szVector, sizeof(szVector), "%f", gpGlobals->v_forward.x); CVAR_SET_STRING("sv_skyvec_x", szVector); - Q_sprintf(szVector, "%f", gpGlobals->v_forward.y); + Q_snprintf(szVector, sizeof(szVector), "%f", gpGlobals->v_forward.y); CVAR_SET_STRING("sv_skyvec_y", szVector); - Q_sprintf(szVector, "%f", gpGlobals->v_forward.z); + Q_snprintf(szVector, sizeof(szVector), "%f", gpGlobals->v_forward.z); CVAR_SET_STRING("sv_skyvec_z", szVector); CLight::Spawn(); diff --git a/regamedll/dlls/multiplay_gamerules.cpp b/regamedll/dlls/multiplay_gamerules.cpp index e1b8a7e4e..7a84afd46 100644 --- a/regamedll/dlls/multiplay_gamerules.cpp +++ b/regamedll/dlls/multiplay_gamerules.cpp @@ -178,15 +178,12 @@ bool CCStrikeGameMgrHelper::GetCanHearPlayer(CBasePlayer* pListener, CBasePlayer void Broadcast(const char *sentence) { - char text[32]; + char text[128]; if (!sentence) - { return; - } - Q_strcpy(text, "%!MRAD_"); - Q_strcat(text, UTIL_VarArgs("%s", sentence)); + Q_snprintf(text, sizeof(text), "%%!MRAD_%s", sentence); MESSAGE_BEGIN(MSG_BROADCAST, gmsgSendAudio); WRITE_BYTE(0); @@ -507,7 +504,7 @@ CHalfLifeMultiplay::CHalfLifeMultiplay() char szCommand[256]; ALERT(at_console, "Executing listen server config file\n"); - Q_sprintf(szCommand, "exec %s\n", lservercfgfile); + Q_snprintf(szCommand, sizeof(szCommand), "exec %s\n", lservercfgfile); SERVER_COMMAND(szCommand); } } @@ -4293,7 +4290,7 @@ int CHalfLifeMultiplay::ItemShouldRespawn(CItem *pItem) // At what time in the future may this Item respawn? float CHalfLifeMultiplay::FlItemRespawnTime(CItem *pItem) { -#ifdef REGAMEDLL_ADD; +#ifdef REGAMEDLL_ADD return gpGlobals->time + item_respawn_time.value; #else return gpGlobals->time + ITEM_RESPAWN_TIME; @@ -4554,12 +4551,7 @@ int ReloadMapCycleFile(char *filename, mapcycle_t *cycle) if (Q_strlen(pToken) <= 0) break; -#ifdef REGAMEDLL_FIXES - Q_strncpy(szMap, pToken, sizeof(szMap) - 1); - szMap[sizeof(szMap) - 1] = '\0'; -#else - Q_strcpy(szMap, pToken); -#endif + Q_strlcpy(szMap, pToken); // Any more tokens on this line? if (SharedTokenWaiting(pFileList)) @@ -4568,7 +4560,7 @@ int ReloadMapCycleFile(char *filename, mapcycle_t *cycle) if (Q_strlen(pToken) > 0) { hasBuffer = true; - Q_strcpy(szBuffer, pToken); + Q_strlcpy(szBuffer, pToken); } } @@ -4580,7 +4572,7 @@ int ReloadMapCycleFile(char *filename, mapcycle_t *cycle) item = new mapcycle_item_s; - Q_strcpy(item->mapname, szMap); + Q_strlcpy(item->mapname, szMap); item->minplayers = 0; item->maxplayers = 0; @@ -4610,7 +4602,7 @@ int ReloadMapCycleFile(char *filename, mapcycle_t *cycle) REMOVE_KEY_VALUE(szBuffer, "minplayers"); REMOVE_KEY_VALUE(szBuffer, "maxplayers"); - Q_strcpy(item->rulebuffer, szBuffer); + Q_strlcpy(item->rulebuffer, szBuffer); } item->next = cycle->items; @@ -4675,7 +4667,7 @@ int CountPlayers() } // Parse commands/key value pairs to issue right after map xxx command is issued on server level transition -void ExtractCommandString(char *s, char *szCommand) +void ExtractCommandString(char *s, char *szCommand, size_t len) { // Now make rules happen char pkey[512]; @@ -4744,13 +4736,13 @@ void ExtractCommandString(char *s, char *szCommand) *c = '\0'; - Q_strcat(szCommand, pkey); + Q_strlcat(szCommand, pkey, len); if (Q_strlen(value) > 0) { - Q_strcat(szCommand, " "); - Q_strcat(szCommand, value); + Q_strlcat(szCommand, " ", len); + Q_strlcat(szCommand, value, len); } - Q_strcat(szCommand, "\n"); + Q_strlcat(szCommand, "\n", len); /*if (!*s) { @@ -4937,10 +4929,10 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(ChangeLevel)() #ifdef REGAMEDLL_FIXES // the absolute default level is de_dust - Q_strcpy(szFirstMapInList, "de_dust"); + Q_strlcpy(szFirstMapInList, "de_dust"); #else // the absolute default level is hldm1 - Q_strcpy(szFirstMapInList, "hldm1"); + Q_strlcpy(szFirstMapInList, "hldm1"); #endif int curplayers; @@ -4958,7 +4950,7 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(ChangeLevel)() // Has the map cycle filename changed? if (Q_stricmp(mapcfile, szPreviousMapCycleFile) != 0) { - Q_strcpy(szPreviousMapCycleFile, mapcfile); + Q_strlcpy(szPreviousMapCycleFile, mapcfile); DestroyMapCycle(&mapcycle); @@ -4976,8 +4968,8 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(ChangeLevel)() mapcycle_item_s *item; // Assume current map - Q_strcpy(szNextMap, STRING(gpGlobals->mapname)); - Q_strcpy(szFirstMapInList, STRING(gpGlobals->mapname)); + Q_strlcpy(szNextMap, STRING(gpGlobals->mapname)); + Q_strlcpy(szFirstMapInList, STRING(gpGlobals->mapname)); // Traverse list for (item = mapcycle.next_item; item->next != mapcycle.next_item; item = item->next) @@ -5030,14 +5022,14 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(ChangeLevel)() mapcycle.next_item = item->next; // Perform logic on current item - Q_strcpy(szNextMap, item->mapname); - ExtractCommandString(item->rulebuffer, szCommands); - Q_strcpy(szRules, item->rulebuffer); + Q_strlcpy(szNextMap, item->mapname); + ExtractCommandString(item->rulebuffer, szCommands, sizeof(szCommands)); + Q_strlcpy(szRules, item->rulebuffer); } if (!IS_MAP_VALID(szNextMap)) { - Q_strcpy(szNextMap, szFirstMapInList); + Q_strlcpy(szNextMap, szFirstMapInList); } m_bGameOver = true; @@ -5077,17 +5069,7 @@ void CHalfLifeMultiplay::SendMOTDToClient(edict_t *client) while (pFileList && *pFileList && char_count < MAX_MOTD_LENGTH) { char chunk[MAX_MOTD_CHUNK + 1]; - - if (Q_strlen(pFileList) < sizeof(chunk)) - { - Q_strcpy(chunk, pFileList); - } - else - { - Q_strncpy(chunk, pFileList, sizeof(chunk) - 1); - // Q_strncpy doesn't always append the null terminator - chunk[sizeof(chunk) - 1] = '\0'; - } + Q_strlcpy(chunk, pFileList); char_count += Q_strlen(chunk); diff --git a/regamedll/dlls/observer.cpp b/regamedll/dlls/observer.cpp index 4b3521a6c..3ccefc433 100644 --- a/regamedll/dlls/observer.cpp +++ b/regamedll/dlls/observer.cpp @@ -480,14 +480,14 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Observer_SetMode)(int iMode) { #ifdef REGAMEDLL_FIXES m_hObserverTarget = Observer_IsValidTarget( ENTINDEX(m_hObserverTarget->edict()), forcecamera != CAMERA_MODE_SPEC_ANYONE ); -#else +#else CBasePlayer *pTarget = m_hObserverTarget; - if (pTarget == this - || !pTarget - || pTarget->has_disconnected - || pTarget->GetObserverMode() != OBS_NONE - || (pTarget->pev->effects & EF_NODRAW) + if (pTarget == this + || !pTarget + || pTarget->has_disconnected + || pTarget->GetObserverMode() != OBS_NONE + || (pTarget->pev->effects & EF_NODRAW) || (forcecamera != CAMERA_MODE_SPEC_ANYONE && pTarget->m_iTeam != m_iTeam)) m_hObserverTarget = nullptr; #endif @@ -534,7 +534,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Observer_SetMode)(int iMode) // print spepctaor mode on client screen char modemsg[16]; - Q_sprintf(modemsg, "#Spec_Mode%i", pev->iuser1); + Q_snprintf(modemsg, sizeof(modemsg), "#Spec_Mode%i", pev->iuser1); ClientPrint(pev, HUD_PRINTCENTER, modemsg); m_iObserverLastMode = iMode; @@ -548,4 +548,4 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Observer_Think)() Observer_HandleButtons(); Observer_CheckTarget(); Observer_CheckProperties(); -} \ No newline at end of file +} diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp index d56f02545..d1783dfb3 100644 --- a/regamedll/dlls/player.cpp +++ b/regamedll/dlls/player.cpp @@ -569,13 +569,20 @@ LINK_HOOK_CLASS_VOID_CHAIN2(CBasePlayer, DeathSound) void EXT_FUNC CBasePlayer::__API_HOOK(DeathSound)() { +#if REGAMEDLL_FIXES + // FIXED: Don't interrupt pain sounds with death sound, use any available channel instead + const int channel = CHAN_AUTO; +#else + const int channel = CHAN_VOICE; +#endif + // temporarily using pain sounds for death sounds switch (RANDOM_LONG(1, 4)) { - case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/die1.wav", VOL_NORM, ATTN_NORM); break; - case 2: EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/die2.wav", VOL_NORM, ATTN_NORM); break; - case 3: EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/die3.wav", VOL_NORM, ATTN_NORM); break; - case 4: EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/death6.wav", VOL_NORM, ATTN_NORM); break; + case 1: EMIT_SOUND(ENT(pev), channel, "player/die1.wav", VOL_NORM, ATTN_NORM); break; + case 2: EMIT_SOUND(ENT(pev), channel, "player/die2.wav", VOL_NORM, ATTN_NORM); break; + case 3: EMIT_SOUND(ENT(pev), channel, "player/die3.wav", VOL_NORM, ATTN_NORM); break; + case 4: EMIT_SOUND(ENT(pev), channel, "player/death6.wav", VOL_NORM, ATTN_NORM); break; } } @@ -2556,11 +2563,19 @@ BOOL CBasePlayer::IsBombGuy() LINK_HOOK_CLASS_VOID_CHAIN(CBasePlayer, SetAnimation, (PLAYER_ANIM playerAnim), playerAnim) +int CBasePlayer::GetAnimDesired(const char *szAnim, AnimationType type) +{ + const char *refAnim = (type == ANIM_CROUCH && (pev->flags & FL_DUCKING)) ? "crouch_" : "ref_"; + + char szAnimConstruct[128]; + Q_snprintf(szAnimConstruct, sizeof(szAnimConstruct), "%s%s_%s", refAnim, szAnim, m_szAnimExtention); + return LookupSequence(szAnimConstruct); +} + void EXT_FUNC CBasePlayer::__API_HOOK(SetAnimation)(PLAYER_ANIM playerAnim) { int animDesired; float speed; - char szAnim[64]; int hopSeq; int leapSeq; @@ -2696,16 +2711,17 @@ void EXT_FUNC CBasePlayer::__API_HOOK(SetAnimation)(PLAYER_ANIM playerAnim) if (m_Activity == m_IdealActivity) return; + const char *refAnim; + switch (m_Activity) { - case ACT_RANGE_ATTACK1: Q_strcpy(szAnim, "ref_shoot_"); break; - case ACT_RANGE_ATTACK2: Q_strcpy(szAnim, "ref_shoot2_"); break; - case ACT_RELOAD: Q_strcpy(szAnim, "ref_reload_"); break; - default: Q_strcpy(szAnim, "ref_aim_"); break; + case ACT_RANGE_ATTACK1: refAnim = "shoot"; break; + case ACT_RANGE_ATTACK2: refAnim = "shoot2"; break; + case ACT_RELOAD: refAnim = "reload"; break; + default: refAnim = "aim"; break; } - Q_strcat(szAnim, m_szAnimExtention); - animDesired = LookupSequence(szAnim); + animDesired = GetAnimDesired(refAnim, ANIM_NORMAL); if (animDesired == -1) animDesired = 0; @@ -2727,13 +2743,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(SetAnimation)(PLAYER_ANIM playerAnim) { m_flLastFired = gpGlobals->time; - if (pev->flags & FL_DUCKING) - Q_strcpy(szAnim, "crouch_shoot_"); - else - Q_strcpy(szAnim, "ref_shoot_"); - - Q_strcat(szAnim, m_szAnimExtention); - animDesired = LookupSequence(szAnim); + animDesired = GetAnimDesired("shoot", ANIM_CROUCH); if (animDesired == -1) animDesired = 0; @@ -2748,13 +2758,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(SetAnimation)(PLAYER_ANIM playerAnim) { m_flLastFired = gpGlobals->time; - if (pev->flags & FL_DUCKING) - Q_strcpy(szAnim, "crouch_shoot2_"); - else - Q_strcpy(szAnim, "ref_shoot2_"); - - Q_strcat(szAnim, m_szAnimExtention); - animDesired = LookupSequence(szAnim); + animDesired = GetAnimDesired("shoot2", ANIM_CROUCH); if (animDesired == -1) animDesired = 0; @@ -2767,13 +2771,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(SetAnimation)(PLAYER_ANIM playerAnim) } case ACT_RELOAD: { - if (pev->flags & FL_DUCKING) - Q_strcpy(szAnim, "crouch_reload_"); - else - Q_strcpy(szAnim, "ref_reload_"); - - Q_strcat(szAnim, m_szAnimExtention); - animDesired = LookupSequence(szAnim); + animDesired = GetAnimDesired("reload", ANIM_CROUCH); if (animDesired == -1) animDesired = 0; @@ -2788,13 +2786,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(SetAnimation)(PLAYER_ANIM playerAnim) } case ACT_HOLDBOMB: { - if (pev->flags & FL_DUCKING) - Q_strcpy(szAnim, "crouch_aim_"); - else - Q_strcpy(szAnim, "ref_aim_"); - - Q_strcat(szAnim, m_szAnimExtention); - animDesired = LookupSequence(szAnim); + animDesired = GetAnimDesired("aim", ANIM_CROUCH); if (animDesired == -1) animDesired = 0; @@ -2811,13 +2803,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(SetAnimation)(PLAYER_ANIM playerAnim) { if (speed <= 135.0f || m_flLastFired + 4.0 >= gpGlobals->time) { - if (pev->flags & FL_DUCKING) - Q_strcpy(szAnim, "crouch_aim_"); - else - Q_strcpy(szAnim, "ref_aim_"); - - Q_strcat(szAnim, m_szAnimExtention); - animDesired = LookupSequence(szAnim); + animDesired = GetAnimDesired("aim", ANIM_CROUCH); if (animDesired == -1) animDesired = 0; @@ -2825,18 +2811,10 @@ void EXT_FUNC CBasePlayer::__API_HOOK(SetAnimation)(PLAYER_ANIM playerAnim) } else { - Q_strcpy(szAnim, "run_"); - Q_strcat(szAnim, m_szAnimExtention); - animDesired = LookupSequence(szAnim); + animDesired = GetAnimDesired("run", ANIM_NORMAL); if (animDesired == -1) { - if (pev->flags & FL_DUCKING) - Q_strcpy(szAnim, "crouch_aim_"); - else - Q_strcpy(szAnim, "ref_aim_"); - - Q_strcat(szAnim, m_szAnimExtention); - animDesired = LookupSequence(szAnim); + animDesired = GetAnimDesired("aim", ANIM_CROUCH); if (animDesired == -1) animDesired = 0; @@ -3086,20 +3064,9 @@ void EXT_FUNC CBasePlayer::__API_HOOK(SetAnimation)(PLAYER_ANIM playerAnim) { if (m_Activity != ACT_FLINCH && m_Activity != ACT_LARGE_FLINCH) { - Q_strcpy(szAnim, "run_"); - Q_strcat(szAnim, m_szAnimExtention); - - animDesired = LookupSequence(szAnim); + animDesired = GetAnimDesired("run", ANIM_NORMAL); if (animDesired == -1) - { - if (pev->flags & FL_DUCKING) - Q_strcpy(szAnim, "crouch_aim_"); - else - Q_strcpy(szAnim, "ref_aim_"); - - Q_strcat(szAnim, m_szAnimExtention); - animDesired = LookupSequence(szAnim); - } + animDesired = GetAnimDesired("aim", ANIM_CROUCH); else pev->gaitsequence = animDesired; @@ -4248,11 +4215,15 @@ void CBasePlayer::PlayerUse() } } + int caps; + int iClosestCaps = 0; + if (!pClosest) { while ((pObject = UTIL_FindEntityInSphere(pObject, pev->origin, MAX_PLAYER_USE_RADIUS))) { - if (pObject->ObjectCaps() & (FCAP_IMPULSE_USE | FCAP_CONTINUOUS_USE | FCAP_ONOFF_USE)) + caps = pObject->ObjectCaps(); + if (caps & (FCAP_IMPULSE_USE | FCAP_CONTINUOUS_USE | FCAP_ONOFF_USE)) { // TODO: PERFORMANCE- should this check be done on a per case basis AFTER we've determined that // this object is actually usable? This dot is being done for every object within PLAYER_SEARCH_RADIUS @@ -4267,11 +4238,21 @@ void CBasePlayer::PlayerUse() { flMaxDot = flDot; pClosest = pObject; +#ifdef REGAMEDLL_FIXES + iClosestCaps = caps; +#endif } } } } +#ifdef REGAMEDLL_FIXES + else // catch new hostages caps + { + iClosestCaps = pClosest->ObjectCaps(); + } + caps = iClosestCaps; +#endif pObject = pClosest; // Found an object @@ -4280,8 +4261,9 @@ void CBasePlayer::PlayerUse() if (!useNewHostages || CanSeeUseable(this, pObject)) { // TODO: traceline here to prevent +USEing buttons through walls +#ifndef REGAMEDLL_FIXES int caps = pObject->ObjectCaps(); - +#endif if (m_afButtonPressed & IN_USE) EMIT_SOUND(ENT(pev), CHAN_ITEM, "common/wpn_select.wav", 0.4, ATTN_NORM); @@ -4295,7 +4277,12 @@ void CBasePlayer::PlayerUse() } // UNDONE: Send different USE codes for ON/OFF. Cache last ONOFF_USE object to send 'off' if you turn away // BUGBUG This is an "off" use - else if ((m_afButtonReleased & IN_USE) && (pObject->ObjectCaps() & FCAP_ONOFF_USE)) + else if ((m_afButtonReleased & IN_USE) +#ifdef REGAMEDLL_FIXES + && (caps & FCAP_ONOFF_USE)) +#else + && (pObject->ObjectCaps() & FCAP_ONOFF_USE)) +#endif { pObject->Use(this, this, USE_SET, 0); } @@ -5027,8 +5014,7 @@ void CBasePlayer::CheckSuitUpdate() { // play sentence number char sentence[MAX_SENTENCE_NAME + 1]; - Q_strcpy(sentence, "!"); - Q_strcat(sentence, gszallsentencenames[isentence]); + Q_snprintf(sentence, sizeof(sentence), "!%s", gszallsentencenames[isentence]); EMIT_SOUND_SUIT(ENT(pev), sentence); } else @@ -5354,11 +5340,6 @@ BOOL IsSpawnPointValid(CBaseEntity *pPlayer, CBaseEntity *pSpot) if (!pSpot->IsTriggered(pPlayer)) return FALSE; -#ifdef REGAMEDLL_ADD - if (!kill_filled_spawn.value) - return TRUE; -#endif - CBaseEntity *pEntity = nullptr; while ((pEntity = UTIL_FindEntityInSphere(pEntity, pSpot->pev->origin, MAX_PLAYER_USE_RADIUS))) { @@ -6778,6 +6759,26 @@ void CBasePlayer::CheatImpulseCommands(int iImpulse) break; } +#ifdef REGAMEDLL_ADD + // noclip with air acceleration + case 200: + { + if (pev->movetype == MOVETYPE_WALK) + { + pev->movetype = MOVETYPE_NOCLIP; + pev->fuser3 = MAX_PLAYER_RUN_MODIFIER_SPEED; // air acceleration increases xN times + ALERT(at_console, "noclip ON\n"); + } + else + { + pev->movetype = MOVETYPE_WALK; + pev->fuser3 = 0; + ALERT(at_console, "noclip OFF\n"); + } + + break; + } +#endif case 202: { // Random blood splatter @@ -8049,7 +8050,7 @@ void CBasePlayer::UpdateStatusBar() char sbuf0[MAX_SBAR_STRING]; Q_memset(newSBarState, 0, sizeof(newSBarState)); - Q_strcpy(sbuf0, m_SbarString0); + Q_strlcpy(sbuf0, m_SbarString0); // Find an ID Target TraceResult tr; @@ -8079,9 +8080,9 @@ void CBasePlayer::UpdateStatusBar() if (sameTeam || GetObserverMode() != OBS_NONE) { if (playerid.value != PLAYERID_MODE_OFF || GetObserverMode() != OBS_NONE) - Q_strcpy(sbuf0, "1 %c1: %p2\n2 %h: %i3%%"); + Q_strlcpy(sbuf0, "1 %c1: %p2\n2 %h: %i3%%"); else - Q_strcpy(sbuf0, " "); + Q_strlcpy(sbuf0, " "); newSBarState[SBAR_ID_TARGETHEALTH] = int((pEntity->pev->health / pEntity->pev->max_health) * 100); @@ -8094,9 +8095,9 @@ void CBasePlayer::UpdateStatusBar() else if (GetObserverMode() == OBS_NONE) { if (playerid.value != PLAYERID_MODE_TEAMONLY && playerid.value != PLAYERID_MODE_OFF) - Q_strcpy(sbuf0, "1 %c1: %p2"); + Q_strlcpy(sbuf0, "1 %c1: %p2"); else - Q_strcpy(sbuf0, " "); + Q_strlcpy(sbuf0, " "); if (!(m_flDisplayHistory & DHF_ENEMY_SEEN)) { @@ -8110,9 +8111,9 @@ void CBasePlayer::UpdateStatusBar() else if (pEntity->Classify() == CLASS_HUMAN_PASSIVE) { if (playerid.value != PLAYERID_MODE_OFF || GetObserverMode() != OBS_NONE) - Q_strcpy(sbuf0, "1 %c1 %h: %i3%%"); + Q_strlcpy(sbuf0, "1 %c1 %h: %i3%%"); else - Q_strcpy(sbuf0, " "); + Q_strlcpy(sbuf0, " "); newSBarState[SBAR_ID_TARGETTYPE] = SBAR_TARGETTYPE_HOSTAGE; newSBarState[SBAR_ID_TARGETHEALTH] = int((pEntity->pev->health / pEntity->pev->max_health) * 100); @@ -8154,7 +8155,7 @@ void CBasePlayer::UpdateStatusBar() WRITE_STRING(sbuf0); MESSAGE_END(); - Q_strcpy(m_SbarString0, sbuf0); + Q_strlcpy(m_SbarString0, sbuf0); // make sure everything's resent bForceResend = true; @@ -9345,14 +9346,10 @@ void CBasePlayer::AddAutoBuyData(const char *str) { if (len > 0) { - Q_strncat(m_autoBuyString, " ", len); + Q_strlcat(m_autoBuyString, " "); } -#ifndef REGAMEDLL_FIXES - Q_strncat(m_autoBuyString, str, sizeof(m_autoBuyString) - Q_strlen(m_autoBuyString)); -#else - Q_strncat(m_autoBuyString, str, sizeof(m_autoBuyString) - Q_strlen(m_autoBuyString) - 1); -#endif + Q_strlcat(m_autoBuyString, str); } } @@ -9369,9 +9366,7 @@ void CBasePlayer::InitRebuyData(const char *str) m_rebuyString = nullptr; } - m_rebuyString = new char[Q_strlen(str) + 1]; - Q_strcpy(m_rebuyString, str); - m_rebuyString[Q_strlen(str)] = '\0'; + m_rebuyString = CloneString(str); } void CBasePlayer::AutoBuy() @@ -9399,7 +9394,7 @@ void CBasePlayer::AutoBuy() if (c) { - Q_strcpy(prioritizedString, c); + Q_strlcpy(prioritizedString, c); PrioritizeAutoBuyString(prioritizedString, m_autoBuyString); ParseAutoBuyString(prioritizedString, boughtPrimary, boughtSecondary); @@ -9409,7 +9404,7 @@ void CBasePlayer::AutoBuy() if (c) { - Q_strcpy(prioritizedString, c); + Q_strlcpy(prioritizedString, c); PrioritizeAutoBuyString(prioritizedString, m_autoBuyString); ParseAutoBuyString(prioritizedString, boughtPrimary, boughtSecondary); @@ -9557,11 +9552,11 @@ const char *CBasePlayer::PickPrimaryCareerTaskWeapon() CCareerTask *pTask = taskVector[i]; if (IsPrimaryWeaponId(pTask->GetWeaponId())) - Q_strncat(buf, WeaponIDToAlias(pTask->GetWeaponId()), sizeof(buf) - Q_strlen(buf) - 1); + Q_strlcat(buf, WeaponIDToAlias(pTask->GetWeaponId())); else - Q_strncat(buf, GetBuyStringForWeaponClass(pTask->GetWeaponClassId()), sizeof(buf) - Q_strlen(buf) - 1); + Q_strlcat(buf, GetBuyStringForWeaponClass(pTask->GetWeaponClassId())); - Q_strncat(buf, " ", sizeof(buf) - Q_strlen(buf) - 1); + Q_strlcat(buf, " "); } return buf; @@ -9632,11 +9627,11 @@ const char *CBasePlayer::PickSecondaryCareerTaskWeapon() CCareerTask *pTask = taskVector[i]; if (IsSecondaryWeaponId(pTask->GetWeaponId())) - Q_strncat(buf, WeaponIDToAlias(pTask->GetWeaponId()), sizeof(buf) - Q_strlen(buf) - 1); + Q_strlcat(buf, WeaponIDToAlias(pTask->GetWeaponId())); else - Q_strncat(buf, GetBuyStringForWeaponClass(pTask->GetWeaponClassId()), sizeof(buf) - Q_strlen(buf) - 1); + Q_strlcat(buf, GetBuyStringForWeaponClass(pTask->GetWeaponClassId())); - Q_strncat(buf, " ", sizeof(buf) - Q_strlen(buf) - 1); + Q_strlcat(buf, " "); } return buf; @@ -9685,7 +9680,7 @@ const char *CBasePlayer::PickGrenadeKillWeaponString() } // PostAutoBuyCommandProcessing - reorders the tokens in autobuyString based on the order of tokens in the priorityString. -void CBasePlayer::PrioritizeAutoBuyString(char *autobuyString, const char *priorityString) +void CBasePlayer::PrioritizeAutoBuyString(char (&autobuyString)[MAX_AUTOBUY_LENGTH], const char *priorityString) { char newString[MAX_AUTOBUY_LENGTH]; int newStringPos = 0; @@ -9758,7 +9753,7 @@ void CBasePlayer::PrioritizeAutoBuyString(char *autobuyString, const char *prior // terminate the string. Trailing spaces shouldn't matter. newString[newStringPos] = '\0'; - Q_sprintf(autobuyString, "%s", newString); + Q_snprintf(autobuyString, sizeof(autobuyString), "%s", newString); } void CBasePlayer::ParseAutoBuyString(const char *string, bool &boughtPrimary, bool &boughtSecondary) diff --git a/regamedll/dlls/player.h b/regamedll/dlls/player.h index d3d37d3ea..b13c2c820 100644 --- a/regamedll/dlls/player.h +++ b/regamedll/dlls/player.h @@ -58,9 +58,10 @@ const int MAX_BUFFER_MENU_BRIEFING = 50; const float SUIT_UPDATE_TIME = 3.5f; const float SUIT_FIRST_UPDATE_TIME = 0.1f; -const float MAX_PLAYER_FATAL_FALL_SPEED = 1100.0f; -const float MAX_PLAYER_SAFE_FALL_SPEED = 500.0f; -const float MAX_PLAYER_USE_RADIUS = 64.0f; +const float MAX_PLAYER_FATAL_FALL_SPEED = 1100.0f; +const float MAX_PLAYER_SAFE_FALL_SPEED = 500.0f; +const float MAX_PLAYER_USE_RADIUS = 64.0f; +const float MAX_PLAYER_RUN_MODIFIER_SPEED = 10.0f; // x10 speed run when IN_RUN button is pressed const float ARMOR_RATIO = 0.5f; // Armor Takes 50% of the damage const float ARMOR_BONUS = 0.5f; // Each Point of Armor is work 1/x points of health @@ -521,7 +522,9 @@ class CBasePlayer: public CBaseMonster { void UpdatePlayerSound(); void DeathSound(); void SetAnimation(PLAYER_ANIM playerAnim); - void SetWeaponAnimType(const char *szExtention) { Q_strcpy(m_szAnimExtention, szExtention); } + enum AnimationType { ANIM_NORMAL, ANIM_CROUCH }; + int GetAnimDesired(const char *szAnim, AnimationType type); + void SetWeaponAnimType(const char *szExtention) { Q_strlcpy(m_szAnimExtention, szExtention); } void CheatImpulseCommands(int iImpulse); void StartDeathCam(); void StartObserver(Vector &vecPosition, Vector &vecViewAngle); @@ -601,7 +604,7 @@ class CBasePlayer: public CBaseMonster { void AddAutoBuyData(const char *str); void AutoBuy(); void ClientCommand(const char *cmd, const char *arg1 = nullptr, const char *arg2 = nullptr, const char *arg3 = nullptr); - void PrioritizeAutoBuyString(char *autobuyString, const char *priorityString); + void PrioritizeAutoBuyString(char (&autobuyString)[MAX_AUTOBUY_LENGTH], const char *priorityString); const char *PickPrimaryCareerTaskWeapon(); const char *PickSecondaryCareerTaskWeapon(); const char *PickFlashKillWeaponString(); diff --git a/regamedll/dlls/saverestore.cpp b/regamedll/dlls/saverestore.cpp index a3a55c7f6..897452c4f 100644 --- a/regamedll/dlls/saverestore.cpp +++ b/regamedll/dlls/saverestore.cpp @@ -962,8 +962,8 @@ void CGlobalState::EntityAdd(string_t globalname, string_t mapName, GLOBALESTATE pNewEntity->pNext = m_pList; m_pList = pNewEntity; - Q_strcpy(pNewEntity->name, STRING(globalname)); - Q_strcpy(pNewEntity->levelName, STRING(mapName)); + Q_strlcpy(pNewEntity->name, STRING(globalname)); + Q_strlcpy(pNewEntity->levelName, STRING(mapName)); pNewEntity->state = state; m_listCount++; @@ -1068,7 +1068,7 @@ void CGlobalState::EntityUpdate(string_t globalname, string_t mapname) globalentity_t *pEnt = Find(globalname); if (pEnt) { - Q_strcpy(pEnt->levelName, STRING(mapname)); + Q_strlcpy(pEnt->levelName, STRING(mapname)); } } diff --git a/regamedll/dlls/skill.cpp b/regamedll/dlls/skill.cpp index 87fd4468f..3c0bfe0d3 100644 --- a/regamedll/dlls/skill.cpp +++ b/regamedll/dlls/skill.cpp @@ -10,7 +10,7 @@ NOXREF float GetSkillCvar(char *pName) float flValue; char szBuffer[64]; - iCount = Q_sprintf(szBuffer, "%s%d", pName, gSkillData.iSkillLevel); + iCount = Q_snprintf(szBuffer, sizeof(szBuffer), "%s%d", pName, gSkillData.iSkillLevel); flValue = CVAR_GET_FLOAT(szBuffer); if (flValue <= 0.0f) diff --git a/regamedll/dlls/sound.cpp b/regamedll/dlls/sound.cpp index baf5353cc..a4dc0a7d6 100644 --- a/regamedll/dlls/sound.cpp +++ b/regamedll/dlls/sound.cpp @@ -1040,11 +1040,10 @@ void USENTENCEG_InitLRU(unsigned char *plru, int count) // ipick is passed in as the requested sentence ordinal. // ipick 'next' is returned. // return of -1 indicates an error. -int USENTENCEG_PickSequential(int isentenceg, char *szfound, int ipick, int freset) +int USENTENCEG_PickSequential(int isentenceg, char (&szfound)[64], int ipick, int freset) { char *szgroupname; unsigned char count; - char sznum[12]; if (!fSentencesInit) return -1; @@ -1061,10 +1060,7 @@ int USENTENCEG_PickSequential(int isentenceg, char *szfound, int ipick, int fres if (ipick >= count) ipick = count - 1; - Q_strcpy(szfound, "!"); - Q_strcat(szfound, szgroupname); - Q_snprintf(sznum, sizeof(sznum), "%d", ipick); - Q_strcat(szfound, sznum); + Q_snprintf(szfound, sizeof(szfound), "!%s%d", szgroupname, ipick); if (ipick >= count) { @@ -1084,13 +1080,12 @@ int USENTENCEG_PickSequential(int isentenceg, char *szfound, int ipick, int fres // rest of the lru filled with -1. The first integer in the lru is // actually the size of the list. Returns ipick, the ordinal // of the picked sentence within the group. -int USENTENCEG_Pick(int isentenceg, char *szfound) +int USENTENCEG_Pick(int isentenceg, char (&szfound)[64]) { char *szgroupname; unsigned char *plru; unsigned char i; unsigned char count; - char sznum[12]; unsigned char ipick = 0xFF; BOOL ffound = FALSE; @@ -1119,11 +1114,7 @@ int USENTENCEG_Pick(int isentenceg, char *szfound) if (ffound) { - Q_strcpy(szfound, "!"); - Q_strcat(szfound, szgroupname); - Q_snprintf(sznum, sizeof(sznum), "%d", ipick); - Q_strcat(szfound, sznum); - + Q_snprintf(szfound, sizeof(szfound), "!%s%d", szgroupname, ipick); return ipick; } else @@ -1168,8 +1159,6 @@ int SENTENCEG_PlayRndI(edict_t *entity, int isentenceg, float volume, float atte if (!fSentencesInit) return -1; - name[0] = '\0'; - ipick = USENTENCEG_Pick(isentenceg, name); #ifndef REGAMEDLL_FIXES @@ -1194,8 +1183,6 @@ int SENTENCEG_PlayRndSz(edict_t *entity, const char *szgroupname, float volume, if (!fSentencesInit) return -1; - name[0] = '\0'; - isentenceg = SENTENCEG_GetIndex(szgroupname); if (isentenceg < 0) { @@ -1223,8 +1210,6 @@ int SENTENCEG_PlaySequentialSz(edict_t *entity, const char *szgroupname, float v if (!fSentencesInit) return -1; - name[0] = '\0'; - isentenceg = SENTENCEG_GetIndex(szgroupname); if (isentenceg < 0) return -1; @@ -1323,7 +1308,7 @@ void SENTENCEG_Init() ALERT(at_warning, "Sentence %s longer than %d letters\n", pString, MAX_SENTENCE_NAME - 1); } - Q_strcpy(gszallsentencenames[gcallsentences++], pString); + Q_strlcpy(gszallsentencenames[gcallsentences++], pString); if (--j <= i) continue; @@ -1354,10 +1339,10 @@ void SENTENCEG_Init() break; } - Q_strcpy(rgsentenceg[isentencegs].szgroupname, &(buffer[i])); + Q_strlcpy(rgsentenceg[isentencegs].szgroupname, &(buffer[i])); rgsentenceg[isentencegs].count = 1; - Q_strcpy(szgroup, &(buffer[i])); + Q_strlcpy(szgroup, &(buffer[i])); continue; } @@ -1385,9 +1370,8 @@ void SENTENCEG_Init() } // convert sentence (sample) name to !sentencenum, return !sentencenum -int SENTENCEG_Lookup(const char *sample, char *sentencenum) +int SENTENCEG_Lookup(const char *sample, char (&sentencenum)[32]) { - char sznum[12]; int i; // this is a sentence name; lookup sentence number @@ -1398,9 +1382,7 @@ int SENTENCEG_Lookup(const char *sample, char *sentencenum) { if (sentencenum) { - Q_strcpy(sentencenum, "!"); - Q_snprintf(sznum, sizeof(sznum), "%d", i); - Q_strcat(sentencenum, sznum); + Q_snprintf(sentencenum, sizeof(sentencenum), "!%d", i); } return i; @@ -1580,7 +1562,7 @@ void TEXTURETYPE_Init() j = Q_min(j, MAX_TEXTURENAME_LENGHT - 1 + i); buffer[j] = '\0'; - Q_strcpy(&(grgszTextureName[gcTextures++][0]), &(buffer[i])); + Q_strlcpy(grgszTextureName[gcTextures++], &(buffer[i])); } FREE_FILE(pMemFile); @@ -1616,7 +1598,7 @@ float TEXTURETYPE_PlaySound(TraceResult *ptr, Vector vecSrc, Vector vecEnd, int char chTextureType; float fvol; float fvolbar; - char szBuffer[64]; + char szBuffer[MAX_TEXTURENAME_LENGHT]; const char *pTextureName; float rgfl1[3]; float rgfl2[3]; @@ -1666,8 +1648,7 @@ float TEXTURETYPE_PlaySound(TraceResult *ptr, Vector vecSrc, Vector vecEnd, int pTextureName++; // '}}' - Q_strcpy(szBuffer, pTextureName); - szBuffer[MAX_TEXTURENAME_LENGHT - 1] = '\0'; + Q_strlcpy(szBuffer, pTextureName); // get texture type chTextureType = TEXTURETYPE_Find(szBuffer); diff --git a/regamedll/dlls/sound.h b/regamedll/dlls/sound.h index d2f0b41a7..b4e716fbc 100644 --- a/regamedll/dlls/sound.h +++ b/regamedll/dlls/sound.h @@ -170,15 +170,13 @@ class CSpeaker: public CBaseEntity BOOL FEnvSoundInRange(entvars_t *pev, entvars_t *pevTarget, float *pflRange); void USENTENCEG_InitLRU(unsigned char *plru, int count); -int USENTENCEG_PickSequential(int isentenceg, char *szfound, int ipick, int freset); -int USENTENCEG_Pick(int isentenceg, char *szfound); int SENTENCEG_GetIndex(const char *szgroupname); int SENTENCEG_PlayRndI(edict_t *entity, int isentenceg, float volume, float attenuation, int flags, int pitch); int SENTENCEG_PlayRndSz(edict_t *entity, const char *szgroupname, float volume, float attenuation, int flags, int pitch); int SENTENCEG_PlaySequentialSz(edict_t *entity, const char *szgroupname, float volume, float attenuation, int flags, int pitch, int ipick, int freset); void SENTENCEG_Stop(edict_t *entity, int isentenceg, int ipick); void SENTENCEG_Init(); -int SENTENCEG_Lookup(const char *sample, char *sentencenum); +int SENTENCEG_Lookup(const char *sample, char (&sentencenum)[32]); void EMIT_SOUND_DYN(edict_t *entity, int channel, const char *sample, float volume, float attenuation, int flags, int pitch); void EMIT_SOUND_SUIT(edict_t *entity, const char *sample); void EMIT_GROUPID_SUIT(edict_t *entity, int isentenceg); diff --git a/regamedll/dlls/triggers.cpp b/regamedll/dlls/triggers.cpp index 82bf6907a..1bfd85b94 100644 --- a/regamedll/dlls/triggers.cpp +++ b/regamedll/dlls/triggers.cpp @@ -645,7 +645,7 @@ void PlayCDTrack(edict_t *pClient, int iTrack) CLIENT_COMMAND(pClient, UTIL_VarArgs("mp3 play %s\n", g_szMP3trackFileMap[iTrack])); #else char string[64]; - Q_sprintf(string, "cd play %3d\n", iTrack); + Q_snprintf(string, sizeof(string), "cd play %3d\n", iTrack); CLIENT_COMMAND(pClient, string); #endif } @@ -1214,7 +1214,7 @@ void CChangeLevel::KeyValue(KeyValueData *pkvd) ALERT(at_error, "Map name '%s' too long (32 chars)\n", pkvd->szValue); } - Q_strcpy(m_szMapName, pkvd->szValue); + Q_strlcpy(m_szMapName, pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "landmark")) @@ -1224,7 +1224,7 @@ void CChangeLevel::KeyValue(KeyValueData *pkvd) ALERT(at_error, "Landmark name '%s' too long (32 chars)\n", pkvd->szValue); } - Q_strcpy(m_szLandmarkName, pkvd->szValue); + Q_strlcpy(m_szLandmarkName, pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "changetarget")) @@ -1356,7 +1356,7 @@ void CChangeLevel::ChangeLevelNow(CBaseEntity *pActivator) } // This object will get removed in the call to CHANGE_LEVEL, copy the params into "safe" memory - Q_strcpy(st_szNextMap, m_szMapName); + Q_strlcpy(st_szNextMap, m_szMapName); m_hActivator = pActivator; SUB_UseTargets(pActivator, USE_TOGGLE, 0); @@ -1369,7 +1369,7 @@ void CChangeLevel::ChangeLevelNow(CBaseEntity *pActivator) if (!FNullEnt(pentLandmark)) { - Q_strcpy(st_szNextSpot, m_szLandmarkName); + Q_strlcpy(st_szNextSpot, m_szLandmarkName); gpGlobals->vecLandmarkOffset = VARS(pentLandmark)->origin; } @@ -1415,8 +1415,8 @@ int CChangeLevel::AddTransitionToList(LEVELLIST *pLevelList, int listCount, cons } } - Q_strcpy(pLevelList[listCount].mapName, pMapName); - Q_strcpy(pLevelList[listCount].landmarkName, pLandmarkName); + Q_strlcpy(pLevelList[listCount].mapName, pMapName); + Q_strlcpy(pLevelList[listCount].landmarkName, pLandmarkName); pLevelList[listCount].pentLandmark = pentLandmark; pLevelList[listCount].vecLandmarkOrigin = VARS(pentLandmark)->origin; @@ -1591,12 +1591,12 @@ NOXREF void NextLevel() { gpGlobals->mapname = ALLOC_STRING("start"); pChange = GetClassPtr((CChangeLevel *)nullptr); - Q_strcpy(pChange->m_szMapName, "start"); + Q_strlcpy(pChange->m_szMapName, "start"); } else pChange = GetClassPtr((CChangeLevel *)VARS(pent)); - Q_strcpy(st_szNextMap, pChange->m_szMapName); + Q_strlcpy(st_szNextMap, pChange->m_szMapName); g_pGameRules->SetGameOver(); if (pChange->pev->nextthink < gpGlobals->time) diff --git a/regamedll/dlls/tutor_base_tutor.cpp b/regamedll/dlls/tutor_base_tutor.cpp index 2268d18b7..a44ef4728 100644 --- a/regamedll/dlls/tutor_base_tutor.cpp +++ b/regamedll/dlls/tutor_base_tutor.cpp @@ -68,12 +68,10 @@ void TutorMessageEvent::AddParameter(char *str) TutorMessageEventParam *param = new TutorMessageEventParam; param->m_next = nullptr; - param->m_data = new char[Q_strlen(str) + 1]; + param->m_data = CloneString(str); if (param->m_data) { - Q_strcpy(param->m_data, str); - param->m_data[Q_strlen(str)] = '\0'; m_numParameters++; if (m_paramList) @@ -101,11 +99,7 @@ char *TutorMessageEvent::GetNextParameter(char *buf, int buflen) m_numParameters--; m_paramList = param->m_next; - Q_strncpy(buf, param->m_data, buflen); - -#ifdef REGAMEDLL_FIXES - buf[buflen - 1] = '\0'; -#endif + Q_strlcpy(buf, param->m_data, buflen); delete param; return buf; diff --git a/regamedll/dlls/tutor_cs_tutor.cpp b/regamedll/dlls/tutor_cs_tutor.cpp index 18e5d2b67..aa6bdd4bc 100644 --- a/regamedll/dlls/tutor_cs_tutor.cpp +++ b/regamedll/dlls/tutor_cs_tutor.cpp @@ -213,7 +213,7 @@ void ParseMessageParameters(char *&messageData, TutorMessage *ret) if (!Q_stricmp(token, "String")) { messageData = SharedParse((char *)messageData); - ret->m_text = Q_strdup(SharedGetToken()); + ret->m_text = CloneString(SharedGetToken()); } else if (!Q_stricmp(token, "Duration")) { @@ -832,7 +832,7 @@ TutorMessageEvent *CCSTutor::CreateTutorMessageEvent(TutorMessageID mid, CBaseEn { numtasks = TheCareerTasks->GetNumRemainingTasks(); } - Q_sprintf(numLeftStr, "%d", numtasks); + Q_snprintf(numLeftStr, sizeof(numLeftStr), "%d", numtasks); event->AddParameter(numLeftStr); break; } @@ -2820,8 +2820,7 @@ void CCSTutor::ConstructRecentDeathsList(TeamName team, char *buf, int buflen, T if (!buf || !buflen) return; - char scratch[32]; - buf[0] = '\0'; + int len = 0; for (int i = 1; i <= gpGlobals->maxClients; i++) { @@ -2837,10 +2836,7 @@ void CCSTutor::ConstructRecentDeathsList(TeamName team, char *buf, int buflen, T if (pPlayer->m_iTeam != team) continue; - Q_strcat(buf, " %n"); - Q_sprintf(scratch, "%d\n", i); - Q_strcat(buf, scratch); - + len += Q_snprintf(&buf[len], buflen - len, " %%n%d\n", i); m_playerDeathInfo[i].m_event = event; } } diff --git a/regamedll/dlls/util.cpp b/regamedll/dlls/util.cpp index 7841b006b..de6159469 100644 --- a/regamedll/dlls/util.cpp +++ b/regamedll/dlls/util.cpp @@ -690,10 +690,7 @@ void UTIL_Log(const char *fmt, ...) Q_vsnprintf(string, sizeof(string), fmt, ap); va_end(ap); - if (Q_strlen(string) < sizeof(string) - 2) - Q_strcat(string, "\n"); - else - string[Q_strlen(string) - 1] = '\n'; + Q_strlcat(string, "\n"); FILE *fp = fopen("regamedll.log", "at"); if (fp) @@ -717,10 +714,7 @@ void UTIL_ServerPrint(const char *fmt, ...) Q_vsnprintf(string, sizeof(string), fmt, ap); va_end(ap); - if (Q_strlen(string) < sizeof(string) - 2) - Q_strcat(string, "\n"); - else - string[Q_strlen(string) - 1] = '\n'; + Q_strlcat(string, "\n"); SERVER_PRINT(string); } @@ -738,10 +732,7 @@ void UTIL_PrintConsole(edict_t *pEdict, const char *fmt, ...) Q_vsnprintf(string, sizeof(string), fmt, ap); va_end(ap); - if (Q_strlen(string) < sizeof(string) - 2) - Q_strcat(string, "\n"); - else - string[Q_strlen(string) - 1] = '\n'; + Q_strlcat(string, "\n"); ClientPrint(pEntity->pev, HUD_PRINTCONSOLE, string); } @@ -759,10 +750,7 @@ void UTIL_SayText(edict_t *pEdict, const char *fmt, ...) Q_vsnprintf(string, sizeof(string), fmt, ap); va_end(ap); - if (Q_strlen(string) < sizeof(string) - 2) - Q_strcat(string, "\n"); - else - string[Q_strlen(string) - 1] = '\n'; + Q_strlcat(string, "\n"); MESSAGE_BEGIN(MSG_ONE, gmsgSayText, nullptr, pEntity->edict()); WRITE_BYTE(pEntity->entindex()); @@ -781,28 +769,28 @@ void UTIL_SayTextAll(const char *pText, CBaseEntity *pEntity) char *UTIL_dtos1(int d) { static char buf[12]; - Q_sprintf(buf, "%d", d); + Q_snprintf(buf, sizeof(buf), "%d", d); return buf; } char *UTIL_dtos2(int d) { static char buf[12]; - Q_sprintf(buf, "%d", d); + Q_snprintf(buf, sizeof(buf), "%d", d); return buf; } NOXREF char *UTIL_dtos3(int d) { static char buf[12]; - Q_sprintf(buf, "%d", d); + Q_snprintf(buf, sizeof(buf), "%d", d); return buf; } NOXREF char *UTIL_dtos4(int d) { static char buf[12]; - Q_sprintf(buf, "%d", d); + Q_snprintf(buf, sizeof(buf), "%d", d); return buf; } @@ -991,7 +979,7 @@ char *UTIL_VarArgs(char *format, ...) static char string[1024]; va_start(argptr, format); - vsprintf(string, format, argptr); + Q_vsnprintf(string, sizeof(string), format, argptr); va_end(argptr); return string; @@ -1561,7 +1549,7 @@ void UTIL_LogPrintf(const char *fmt, ...) static char string[1024]; va_start(argptr, fmt); - vsprintf(string, fmt, argptr); + Q_vsnprintf(string, sizeof(string), fmt, argptr); va_end(argptr); ALERT(at_logged, "%s", string); @@ -1580,7 +1568,7 @@ char UTIL_TextureHit(TraceResult *ptr, Vector vecSrc, Vector vecEnd) float rgfl1[3]; float rgfl2[3]; const char *pTextureName; - char szbuffer[64]; + char szbuffer[MAX_TEXTURENAME_LENGHT]; CBaseEntity *pEntity = CBaseEntity::Instance(ptr->pHit); #ifdef REGAMEDLL_FIXES @@ -1606,8 +1594,8 @@ char UTIL_TextureHit(TraceResult *ptr, Vector vecSrc, Vector vecEnd) if (*pTextureName == '{' || *pTextureName == '!' || *pTextureName == '~' || *pTextureName == ' ') pTextureName++; - Q_strcpy(szbuffer, pTextureName); - szbuffer[16] = '\0'; + Q_strlcpy(szbuffer, pTextureName); + chTextureType = TEXTURETYPE_Find(szbuffer); } else diff --git a/regamedll/dlls/weapons.cpp b/regamedll/dlls/weapons.cpp index 9f1765418..47a77c6fc 100644 --- a/regamedll/dlls/weapons.cpp +++ b/regamedll/dlls/weapons.cpp @@ -652,11 +652,11 @@ void CBasePlayerWeapon::SetPlayerShieldAnim() if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) { - Q_strcpy(m_pPlayer->m_szAnimExtention, "shield"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shield"); } else { - Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgun"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgun"); } } @@ -666,7 +666,7 @@ void CBasePlayerWeapon::ResetPlayerShieldAnim() { if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) { - Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgun"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgun"); } } } @@ -697,7 +697,7 @@ bool CBasePlayerWeapon::ShieldSecondaryFire(int iUpAnim, int iDownAnim) { m_iWeaponState &= ~WPNSTATE_SHIELD_DRAWN; SendWeaponAnim(iDownAnim, UseDecrement() != FALSE); - Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgun"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgun"); m_fMaxSpeed = 250.0f; m_pPlayer->m_bShieldDrawn = false; } @@ -705,7 +705,7 @@ bool CBasePlayerWeapon::ShieldSecondaryFire(int iUpAnim, int iDownAnim) { m_iWeaponState |= WPNSTATE_SHIELD_DRAWN; SendWeaponAnim(iUpAnim, UseDecrement() != FALSE); - Q_strcpy(m_pPlayer->m_szAnimExtention, "shielded"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shielded"); m_fMaxSpeed = 180.0f; m_pPlayer->m_bShieldDrawn = true; } @@ -724,6 +724,41 @@ LINK_HOOK_CLASS_VOID_CHAIN(CBasePlayerWeapon, KickBack, (float up_base, float la void EXT_FUNC CBasePlayerWeapon::__API_HOOK(KickBack)(float up_base, float lateral_base, float up_modifier, float lateral_modifier, float up_max, float lateral_max, int direction_change) { +#ifdef REGAMEDLL_ADD + real_t flKickUp = up_base; + float flKickLateral = lateral_base; + + if (m_iShotsFired > 1) // consider == 0 case + { + flKickUp += m_iShotsFired * up_modifier; + flKickLateral += m_iShotsFired * lateral_modifier; + } + + if (up_max == 0.0f) // boundaryless vertical kick + { + m_pPlayer->pev->punchangle.x -= flKickUp; + } + else if (m_pPlayer->pev->punchangle.x > -up_max) // do not kick when already out of boundaries + { + m_pPlayer->pev->punchangle.x = Q_max(m_pPlayer->pev->punchangle.x - flKickUp, -up_max); + } + + if (lateral_max == 0.0f) // boundaryless horizontal kick + { + m_pPlayer->pev->punchangle.y += flKickLateral * (m_iDirection * 2 - 1); + } + else if (Q_fabs(m_pPlayer->pev->punchangle.y) < lateral_max) // do not kick when already out of boundaries + { + m_pPlayer->pev->punchangle.y = (m_iDirection == 1) ? + Q_min(m_pPlayer->pev->punchangle.y + flKickLateral, lateral_max) : + Q_max(m_pPlayer->pev->punchangle.y - flKickLateral, -lateral_max); + } + + if (direction_change > 0 && !RANDOM_LONG(0, direction_change)) // be sure to not waste RNG consumption + { + m_iDirection = !m_iDirection; + } +#else real_t flKickUp; float flKickLateral; @@ -764,6 +799,7 @@ void EXT_FUNC CBasePlayerWeapon::__API_HOOK(KickBack)(float up_base, float later { m_iDirection = !m_iDirection; } +#endif } void CBasePlayerWeapon::FireRemaining(int &shotsFired, float &shootTime, BOOL bIsGlock) @@ -1455,7 +1491,7 @@ BOOL EXT_FUNC CBasePlayerWeapon::__API_HOOK(DefaultDeploy)(char *szViewModel, ch m_pPlayer->pev->weaponmodel = MAKE_STRING(szWeaponModel); #endif model_name = m_pPlayer->pev->viewmodel; - Q_strcpy(m_pPlayer->m_szAnimExtention, szAnimExt); + Q_strlcpy(m_pPlayer->m_szAnimExtention, szAnimExt); SendWeaponAnim(iAnim, skiplocal); m_pPlayer->m_flNextAttack = 0.75f; @@ -1635,6 +1671,10 @@ void CBasePlayerWeapon::Holster(int skiplocal) m_fInReload = FALSE; m_pPlayer->pev->viewmodel = 0; m_pPlayer->pev->weaponmodel = 0; + +#ifdef REGAMEDLL_FIXES + m_fInSpecialReload = 0; +#endif } // called by the new item with the existing item as parameter diff --git a/regamedll/dlls/world.cpp b/regamedll/dlls/world.cpp index 55147af09..cc4a3de55 100644 --- a/regamedll/dlls/world.cpp +++ b/regamedll/dlls/world.cpp @@ -216,7 +216,7 @@ void CWorld::Spawn() Precache(); g_szMapBriefingText[0] = '\0'; - Q_sprintf(szMapBriefingFile, "maps/%s.txt", STRING(gpGlobals->mapname)); + Q_snprintf(szMapBriefingFile, sizeof(szMapBriefingFile), "maps/%s.txt", STRING(gpGlobals->mapname)); int flength = 0; char *pFile = (char *)LOAD_FILE_FOR_ME(szMapBriefingFile, &flength); diff --git a/regamedll/dlls/wpn_shared/wpn_awp.cpp b/regamedll/dlls/wpn_shared/wpn_awp.cpp index 0e31bd548..3cf4e437e 100644 --- a/regamedll/dlls/wpn_shared/wpn_awp.cpp +++ b/regamedll/dlls/wpn_shared/wpn_awp.cpp @@ -189,7 +189,11 @@ void CAWP::AWPFire(float flSpread, float flCycleTime, BOOL fUseAutoAim) } m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0f; +#ifdef REGAMEDLL_ADD + KickBack(2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0); +#else m_pPlayer->pev->punchangle.x -= 2.0f; +#endif } void CAWP::Reload() diff --git a/regamedll/dlls/wpn_shared/wpn_deagle.cpp b/regamedll/dlls/wpn_shared/wpn_deagle.cpp index 7dbed0c6b..f04ab55d6 100644 --- a/regamedll/dlls/wpn_shared/wpn_deagle.cpp +++ b/regamedll/dlls/wpn_shared/wpn_deagle.cpp @@ -177,7 +177,11 @@ void CDEAGLE::DEAGLEFire(float flSpread, float flCycleTime, BOOL fUseSemi) } m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.8f; +#ifdef REGAMEDLL_ADD + KickBack(2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0); +#else m_pPlayer->pev->punchangle.x -= 2; +#endif ResetPlayerShieldAnim(); } @@ -200,11 +204,23 @@ void CDEAGLE::WeaponIdle() if (m_flTimeWeaponIdle <= UTIL_WeaponTimeBase()) { - m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 20.0f; +#ifdef REGAMEDLL_FIXES + if (m_pPlayer->HasShield()) +#endif + { + m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 20.0f; - if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) + if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) + { + SendWeaponAnim(DEAGLE_SHIELD_IDLE_UP, UseDecrement() != FALSE); + } + } +#ifdef REGAMEDLL_FIXES + else if (m_iClip) { - SendWeaponAnim(DEAGLE_SHIELD_IDLE_UP, UseDecrement() != FALSE); + m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 3.0625f; + SendWeaponAnim(DEAGLE_IDLE1, UseDecrement() != FALSE); } +#endif } } diff --git a/regamedll/dlls/wpn_shared/wpn_elite.cpp b/regamedll/dlls/wpn_shared/wpn_elite.cpp index 05428d8ed..845b5f278 100644 --- a/regamedll/dlls/wpn_shared/wpn_elite.cpp +++ b/regamedll/dlls/wpn_shared/wpn_elite.cpp @@ -200,7 +200,11 @@ void CELITE::ELITEFire(float flSpread, float flCycleTime, BOOL fUseSemi) } m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0f; +#ifdef REGAMEDLL_ADD + KickBack(2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0); +#else m_pPlayer->pev->punchangle.x -= 2.0f; +#endif } void CELITE::Reload() diff --git a/regamedll/dlls/wpn_shared/wpn_fiveseven.cpp b/regamedll/dlls/wpn_shared/wpn_fiveseven.cpp index 31f211f08..4f07b840e 100644 --- a/regamedll/dlls/wpn_shared/wpn_fiveseven.cpp +++ b/regamedll/dlls/wpn_shared/wpn_fiveseven.cpp @@ -176,7 +176,11 @@ void CFiveSeven::FiveSevenFire(float flSpread, float flCycleTime, BOOL fUseSemi) } m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0f; +#ifdef REGAMEDLL_ADD + KickBack(2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0); +#else m_pPlayer->pev->punchangle.x -= 2.0f; +#endif ResetPlayerShieldAnim(); } diff --git a/regamedll/dlls/wpn_shared/wpn_flashbang.cpp b/regamedll/dlls/wpn_shared/wpn_flashbang.cpp index 0443353e8..bbebb8ebf 100644 --- a/regamedll/dlls/wpn_shared/wpn_flashbang.cpp +++ b/regamedll/dlls/wpn_shared/wpn_flashbang.cpp @@ -114,7 +114,7 @@ bool CFlashbang::ShieldSecondaryFire(int iUpAnim, int iDownAnim) m_iWeaponState &= ~WPNSTATE_SHIELD_DRAWN; SendWeaponAnim(iDownAnim, UseDecrement() != FALSE); - Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); m_fMaxSpeed = FLASHBANG_MAX_SPEED; m_pPlayer->m_bShieldDrawn = false; @@ -124,7 +124,7 @@ bool CFlashbang::ShieldSecondaryFire(int iUpAnim, int iDownAnim) m_iWeaponState |= WPNSTATE_SHIELD_DRAWN; SendWeaponAnim(iUpAnim, UseDecrement() != FALSE); - Q_strcpy(m_pPlayer->m_szAnimExtention, "shielded"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shielded"); m_fMaxSpeed = FLASHBANG_MAX_SPEED_SHIELD; m_pPlayer->m_bShieldDrawn = true; @@ -151,9 +151,9 @@ void CFlashbang::SetPlayerShieldAnim() return; if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) - Q_strcpy(m_pPlayer->m_szAnimExtention, "shield"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shield"); else - Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); } void CFlashbang::ResetPlayerShieldAnim() @@ -163,7 +163,7 @@ void CFlashbang::ResetPlayerShieldAnim() if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) { - Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); } } diff --git a/regamedll/dlls/wpn_shared/wpn_g3sg1.cpp b/regamedll/dlls/wpn_shared/wpn_g3sg1.cpp index 5351d0f78..b7e36b09f 100644 --- a/regamedll/dlls/wpn_shared/wpn_g3sg1.cpp +++ b/regamedll/dlls/wpn_shared/wpn_g3sg1.cpp @@ -185,8 +185,15 @@ void CG3SG1::G3SG1Fire(float flSpread, float flCycleTime, BOOL fUseAutoAim) m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.8f; +#ifdef REGAMEDLL_ADD + m_iDirection = 1; // force positive Y addition + KickBack(UTIL_SharedRandomFloat(m_pPlayer->random_seed + 4, 0.75, 1.75) + m_pPlayer->pev->punchangle.x * 0.25f, + UTIL_SharedRandomFloat(m_pPlayer->random_seed + 5, -0.75, 0.75), + 0.0, 0.0, 0.0, 0.0, 0); +#else m_pPlayer->pev->punchangle.x -= UTIL_SharedRandomFloat(m_pPlayer->random_seed + 4, 0.75, 1.75) + m_pPlayer->pev->punchangle.x * 0.25f; m_pPlayer->pev->punchangle.y += UTIL_SharedRandomFloat(m_pPlayer->random_seed + 5, -0.75, 0.75); +#endif } void CG3SG1::Reload() diff --git a/regamedll/dlls/wpn_shared/wpn_glock18.cpp b/regamedll/dlls/wpn_shared/wpn_glock18.cpp index c2f5399d5..b879ef858 100644 --- a/regamedll/dlls/wpn_shared/wpn_glock18.cpp +++ b/regamedll/dlls/wpn_shared/wpn_glock18.cpp @@ -253,6 +253,9 @@ void CGLOCK18::GLOCK18Fire(float flSpread, float flCycleTime, BOOL bFireBurst) m_flGlock18Shoot = gpGlobals->time + 0.1f; } +#ifdef REGAMEDLL_ADD + KickBack(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0); // dummy call, API useful +#endif ResetPlayerShieldAnim(); } diff --git a/regamedll/dlls/wpn_shared/wpn_hegrenade.cpp b/regamedll/dlls/wpn_shared/wpn_hegrenade.cpp index 49d8eb7a8..ca2c63adb 100644 --- a/regamedll/dlls/wpn_shared/wpn_hegrenade.cpp +++ b/regamedll/dlls/wpn_shared/wpn_hegrenade.cpp @@ -117,7 +117,7 @@ bool CHEGrenade::ShieldSecondaryFire(int iUpAnim, int iDownAnim) { m_iWeaponState &= ~WPNSTATE_SHIELD_DRAWN; SendWeaponAnim(iDownAnim, UseDecrement() != FALSE); - Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); m_fMaxSpeed = HEGRENADE_MAX_SPEED; m_pPlayer->m_bShieldDrawn = false; @@ -126,7 +126,7 @@ bool CHEGrenade::ShieldSecondaryFire(int iUpAnim, int iDownAnim) { m_iWeaponState |= WPNSTATE_SHIELD_DRAWN; SendWeaponAnim(iUpAnim, UseDecrement() != FALSE); - Q_strcpy(m_pPlayer->m_szAnimExtention, "shielded"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shielded"); m_fMaxSpeed = HEGRENADE_MAX_SPEED_SHIELD; m_pPlayer->m_bShieldDrawn = true; @@ -153,9 +153,9 @@ void CHEGrenade::SetPlayerShieldAnim() return; if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) - Q_strcpy(m_pPlayer->m_szAnimExtention, "shield"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shield"); else - Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); } void CHEGrenade::ResetPlayerShieldAnim() @@ -165,7 +165,7 @@ void CHEGrenade::ResetPlayerShieldAnim() if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) { - Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); } } diff --git a/regamedll/dlls/wpn_shared/wpn_knife.cpp b/regamedll/dlls/wpn_shared/wpn_knife.cpp index fcbf2d949..43a2f28f2 100644 --- a/regamedll/dlls/wpn_shared/wpn_knife.cpp +++ b/regamedll/dlls/wpn_shared/wpn_knife.cpp @@ -180,7 +180,7 @@ void CKnife::SetPlayerShieldAnim() if (!m_pPlayer->HasShield()) return; - Q_strcpy(m_pPlayer->m_szAnimExtention, (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) != 0 ? "shield" : "shieldknife"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) != 0 ? "shield" : "shieldknife"); } void CKnife::ResetPlayerShieldAnim() @@ -190,7 +190,7 @@ void CKnife::ResetPlayerShieldAnim() if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) { - Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldknife"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldknife"); } } @@ -207,7 +207,7 @@ bool CKnife::ShieldSecondaryFire(int iUpAnim, int iDownAnim) SendWeaponAnim(iDownAnim, UseDecrement() != FALSE); - Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldknife"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldknife"); m_fMaxSpeed = KNIFE_MAX_SPEED; m_pPlayer->m_bShieldDrawn = false; @@ -217,7 +217,7 @@ bool CKnife::ShieldSecondaryFire(int iUpAnim, int iDownAnim) m_iWeaponState |= WPNSTATE_SHIELD_DRAWN; SendWeaponAnim(iUpAnim, UseDecrement() != FALSE); - Q_strcpy(m_pPlayer->m_szAnimExtention, "shielded"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shielded"); m_fMaxSpeed = KNIFE_MAX_SPEED_SHIELD; m_pPlayer->m_bShieldDrawn = true; @@ -339,14 +339,14 @@ BOOL CKnife::Swing(BOOL fFirst) m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0f; // play wiff or swish sound - EMIT_SOUND_DYN(m_pPlayer->edict(), - CHAN_WEAPON, - RANDOM_LONG(0, 1) ? + EMIT_SOUND_DYN(m_pPlayer->edict(), + CHAN_WEAPON, + RANDOM_LONG(0, 1) ? "weapons/knife_slash1.wav" : - "weapons/knife_slash2.wav", - VOL_NORM, - ATTN_NORM, - 0, + "weapons/knife_slash2.wav", + VOL_NORM, + ATTN_NORM, + 0, 94); // player "shoot" animation @@ -390,10 +390,10 @@ BOOL CKnife::Swing(BOOL fFirst) m_pPlayer->SetAnimation(PLAYER_ATTACK1); ClearMultiDamage(); - pEntity->TraceAttack(m_pPlayer->pev, + pEntity->TraceAttack(m_pPlayer->pev, KnifeSwingDamage(m_flNextPrimaryAttack + 0.4f < UTIL_WeaponTimeBase()), - gpGlobals->v_forward, - &tr, + gpGlobals->v_forward, + &tr, (DMG_NEVERGIB | DMG_BULLET)); ApplyMultiDamage(m_pPlayer->pev, m_pPlayer->pev); @@ -402,7 +402,7 @@ BOOL CKnife::Swing(BOOL fFirst) if (pEntity) // -V595 #endif { - if (pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE + if (pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE #ifdef REGAMEDLL_FIXES && pEntity->Classify() != CLASS_VEHICLE #endif @@ -518,14 +518,14 @@ BOOL CKnife::Stab(BOOL fFirst) m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.0f; // play wiff or swish sound - EMIT_SOUND_DYN(m_pPlayer->edict(), - CHAN_WEAPON, - RANDOM_LONG(0, 1) ? - "weapons/knife_slash1.wav" : - "weapons/knife_slash2.wav", - VOL_NORM, - ATTN_NORM, - 0, + EMIT_SOUND_DYN(m_pPlayer->edict(), + CHAN_WEAPON, + RANDOM_LONG(0, 1) ? + "weapons/knife_slash1.wav" : + "weapons/knife_slash2.wav", + VOL_NORM, + ATTN_NORM, + 0, 94); // player "shoot" animation @@ -586,7 +586,7 @@ BOOL CKnife::Stab(BOOL fFirst) if (pEntity) // -V595 #endif { - if (pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE + if (pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE #ifdef REGAMEDLL_FIXES && pEntity->Classify() != CLASS_VEHICLE #endif diff --git a/regamedll/dlls/wpn_shared/wpn_m3.cpp b/regamedll/dlls/wpn_shared/wpn_m3.cpp index 3251ae9a1..64ad7c5f0 100644 --- a/regamedll/dlls/wpn_shared/wpn_m3.cpp +++ b/regamedll/dlls/wpn_shared/wpn_m3.cpp @@ -167,10 +167,17 @@ void CM3::PrimaryAttack() m_fInSpecialReload = 0; +#ifdef REGAMEDLL_ADD + if (m_pPlayer->pev->flags & FL_ONGROUND) + KickBack(UTIL_SharedRandomLong(m_pPlayer->random_seed + 1, 4, 6), 0.0, 0.0, 0.0, 0.0, 0.0, 0); + else + KickBack(UTIL_SharedRandomLong(m_pPlayer->random_seed + 1, 8, 11), 0.0, 0.0, 0.0, 0.0, 0.0, 0); +#else if (m_pPlayer->pev->flags & FL_ONGROUND) m_pPlayer->pev->punchangle.x -= UTIL_SharedRandomLong(m_pPlayer->random_seed + 1, 4, 6); else m_pPlayer->pev->punchangle.x -= UTIL_SharedRandomLong(m_pPlayer->random_seed + 1, 8, 11); +#endif m_pPlayer->m_flEjectBrass = gpGlobals->time + 0.45f; } diff --git a/regamedll/dlls/wpn_shared/wpn_m4a1.cpp b/regamedll/dlls/wpn_shared/wpn_m4a1.cpp index 89ea81b5b..e9bb062e2 100644 --- a/regamedll/dlls/wpn_shared/wpn_m4a1.cpp +++ b/regamedll/dlls/wpn_shared/wpn_m4a1.cpp @@ -82,13 +82,13 @@ void CM4A1::SecondaryAttack() { m_iWeaponState &= ~WPNSTATE_M4A1_SILENCED; SendWeaponAnim(M4A1_DETACH_SILENCER, UseDecrement() != FALSE); - Q_strcpy(m_pPlayer->m_szAnimExtention, "rifle"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "rifle"); } else { m_iWeaponState |= WPNSTATE_M4A1_SILENCED; SendWeaponAnim(M4A1_ATTACH_SILENCER, UseDecrement() != FALSE); - Q_strcpy(m_pPlayer->m_szAnimExtention, "rifle"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "rifle"); } m_flTimeWeaponIdle = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 2.0f; diff --git a/regamedll/dlls/wpn_shared/wpn_p228.cpp b/regamedll/dlls/wpn_shared/wpn_p228.cpp index b64f5fcf3..1343671cb 100644 --- a/regamedll/dlls/wpn_shared/wpn_p228.cpp +++ b/regamedll/dlls/wpn_shared/wpn_p228.cpp @@ -176,7 +176,11 @@ void CP228::P228Fire(float flSpread, float flCycleTime, BOOL fUseSemi) } m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0f; +#ifdef REGAMEDLL_ADD + KickBack(2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0); +#else m_pPlayer->pev->punchangle.x -= 2; +#endif ResetPlayerShieldAnim(); } diff --git a/regamedll/dlls/wpn_shared/wpn_scout.cpp b/regamedll/dlls/wpn_shared/wpn_scout.cpp index fd9456624..ec7c1a196 100644 --- a/regamedll/dlls/wpn_shared/wpn_scout.cpp +++ b/regamedll/dlls/wpn_shared/wpn_scout.cpp @@ -181,7 +181,11 @@ void CSCOUT::SCOUTFire(float flSpread, float flCycleTime, BOOL fUseAutoAim) } m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.8f; +#ifdef REGAMEDLL_ADD + KickBack(2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0); +#else m_pPlayer->pev->punchangle.x -= 2.0f; +#endif } void CSCOUT::Reload() diff --git a/regamedll/dlls/wpn_shared/wpn_sg550.cpp b/regamedll/dlls/wpn_shared/wpn_sg550.cpp index 8263e98a8..efad9e082 100644 --- a/regamedll/dlls/wpn_shared/wpn_sg550.cpp +++ b/regamedll/dlls/wpn_shared/wpn_sg550.cpp @@ -188,8 +188,15 @@ void CSG550::SG550Fire(float flSpread, float flCycleTime, BOOL fUseAutoAim) m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.8f; +#ifdef REGAMEDLL_ADD + m_iDirection = 1; // force positive Y addition + KickBack(UTIL_SharedRandomFloat(m_pPlayer->random_seed + 4, 0.75, 1.75) + m_pPlayer->pev->punchangle.x * 0.25, + UTIL_SharedRandomFloat(m_pPlayer->random_seed + 5, -0.75, 0.75), + 0.0, 0.0, 0.0, 0.0, 0); +#else m_pPlayer->pev->punchangle.x -= UTIL_SharedRandomFloat(m_pPlayer->random_seed + 4, 0.75, 1.25) + m_pPlayer->pev->punchangle.x * 0.25; m_pPlayer->pev->punchangle.y += UTIL_SharedRandomFloat(m_pPlayer->random_seed + 5, -0.75, 0.75); +#endif } void CSG550::Reload() diff --git a/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp b/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp index ae13158b4..56c5e27bc 100644 --- a/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp +++ b/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp @@ -117,7 +117,7 @@ bool CSmokeGrenade::ShieldSecondaryFire(int iUpAnim, int iDownAnim) m_iWeaponState &= ~WPNSTATE_SHIELD_DRAWN; SendWeaponAnim(iDownAnim, UseDecrement() != FALSE); - Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); m_fMaxSpeed = SMOKEGRENADE_MAX_SPEED; m_pPlayer->m_bShieldDrawn = false; @@ -127,7 +127,7 @@ bool CSmokeGrenade::ShieldSecondaryFire(int iUpAnim, int iDownAnim) m_iWeaponState |= WPNSTATE_SHIELD_DRAWN; SendWeaponAnim(iUpAnim, UseDecrement() != FALSE); - Q_strcpy(m_pPlayer->m_szAnimExtention, "shielded"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shielded"); m_fMaxSpeed = SMOKEGRENADE_MAX_SPEED_SHIELD; m_pPlayer->m_bShieldDrawn = true; @@ -154,9 +154,9 @@ void CSmokeGrenade::SetPlayerShieldAnim() return; if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) - Q_strcpy(m_pPlayer->m_szAnimExtention, "shield"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shield"); else - Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); } void CSmokeGrenade::ResetPlayerShieldAnim() @@ -166,7 +166,7 @@ void CSmokeGrenade::ResetPlayerShieldAnim() if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) { - Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgren"); } } diff --git a/regamedll/dlls/wpn_shared/wpn_usp.cpp b/regamedll/dlls/wpn_shared/wpn_usp.cpp index 0d830d690..de823f30e 100644 --- a/regamedll/dlls/wpn_shared/wpn_usp.cpp +++ b/regamedll/dlls/wpn_shared/wpn_usp.cpp @@ -98,14 +98,14 @@ void CUSP::SecondaryAttack() m_iWeaponState &= ~WPNSTATE_USP_SILENCED; SendWeaponAnim(USP_DETACH_SILENCER, UseDecrement() != FALSE); - Q_strcpy(m_pPlayer->m_szAnimExtention, "onehanded"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "onehanded"); } else { m_iWeaponState |= WPNSTATE_USP_SILENCED; SendWeaponAnim(USP_ATTACH_SILENCER, UseDecrement() != FALSE); - Q_strcpy(m_pPlayer->m_szAnimExtention, "onehanded"); + Q_strlcpy(m_pPlayer->m_szAnimExtention, "onehanded"); } m_flNextSecondaryAttack = m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + USP_ADJUST_SIL_TIME; @@ -239,7 +239,11 @@ void CUSP::USPFire(float flSpread, float flCycleTime, BOOL fUseSemi) } m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0f; +#ifdef REGAMEDLL_ADD + KickBack(2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0); +#else m_pPlayer->pev->punchangle.x -= 2.0f; +#endif ResetPlayerShieldAnim(); } diff --git a/regamedll/dlls/wpn_shared/wpn_xm1014.cpp b/regamedll/dlls/wpn_shared/wpn_xm1014.cpp index ec7a01dee..a4e4304eb 100644 --- a/regamedll/dlls/wpn_shared/wpn_xm1014.cpp +++ b/regamedll/dlls/wpn_shared/wpn_xm1014.cpp @@ -166,10 +166,17 @@ void CXM1014::PrimaryAttack() m_fInSpecialReload = 0; +#ifdef REGAMEDLL_ADD + if (m_pPlayer->pev->flags & FL_ONGROUND) + KickBack(UTIL_SharedRandomLong(m_pPlayer->random_seed + 1, 3, 5), 0.0, 0.0, 0.0, 0.0, 0.0, 0); + else + KickBack(UTIL_SharedRandomLong(m_pPlayer->random_seed + 1, 7, 10), 0.0, 0.0, 0.0, 0.0, 0.0, 0); +#else if (m_pPlayer->pev->flags & FL_ONGROUND) m_pPlayer->pev->punchangle.x -= UTIL_SharedRandomLong(m_pPlayer->random_seed + 1, 3, 5); else m_pPlayer->pev->punchangle.x -= UTIL_SharedRandomLong(m_pPlayer->random_seed + 1, 7, 10); +#endif } void CXM1014::Reload() diff --git a/regamedll/game_shared/bot/bot.cpp b/regamedll/game_shared/bot/bot.cpp index 0f19e81f4..52d1f4db7 100644 --- a/regamedll/game_shared/bot/bot.cpp +++ b/regamedll/game_shared/bot/bot.cpp @@ -486,11 +486,11 @@ NOXREF void CBot::Print(char *format, ...) const char buffer[1024]; // prefix the message with the bot's name - Q_sprintf(buffer, "%s: ", STRING(pev->netname)); + Q_snprintf(buffer, sizeof(buffer), "%s: ", STRING(pev->netname)); SERVER_PRINT(buffer); va_start(varg, format); - vsprintf(buffer, format, varg); + Q_vsnprintf(buffer, sizeof(buffer), format, varg); va_end(varg); SERVER_PRINT(buffer); @@ -509,12 +509,12 @@ void CBot::PrintIfWatched(char *format, ...) const // prefix the message with the bot's name (this can be NULL if bot was just added) const char *name = pev ? STRING(pev->netname) : "(NULL pev)"; - Q_sprintf(buffer, "%s: ", name ? name : "(NULL netname)"); + Q_snprintf(buffer, sizeof(buffer), "%s: ", name ? name : "(NULL netname)"); SERVER_PRINT(buffer); va_start(varg, format); - vsprintf(buffer, format, varg); + Q_vsnprintf(buffer, sizeof(buffer), format, varg); va_end(varg); SERVER_PRINT(buffer); diff --git a/regamedll/game_shared/bot/bot_manager.cpp b/regamedll/game_shared/bot/bot_manager.cpp index 7ccd32814..3fa121ba7 100644 --- a/regamedll/game_shared/bot/bot_manager.cpp +++ b/regamedll/game_shared/bot/bot_manager.cpp @@ -213,7 +213,7 @@ void CBotManager::StartFrame() const char *CBotManager::GetNavMapFilename() const { static char filename[256]; - Q_sprintf(filename, "maps\\%s.nav", STRING(gpGlobals->mapname)); + Q_snprintf(filename, sizeof(filename), "maps\\%s.nav", STRING(gpGlobals->mapname)); return filename; } diff --git a/regamedll/game_shared/bot/bot_profile.cpp b/regamedll/game_shared/bot/bot_profile.cpp index c025f903b..76cb37a10 100644 --- a/regamedll/game_shared/bot/bot_profile.cpp +++ b/regamedll/game_shared/bot/bot_profile.cpp @@ -178,9 +178,10 @@ void BotProfileManager::Init(const char *filename, unsigned int *checksum) m_skins[m_nextSkin] = CloneString(decoratedName); // construct the model filename + int SkinLen = Q_strlen(token) * 2 + Q_strlen("models/player//.mdl"); m_skinModelnames[m_nextSkin] = CloneString(token); - m_skinFilenames[m_nextSkin] = new char[Q_strlen(token) * 2 + Q_strlen("models/player//.mdl") + 1]; - Q_sprintf(m_skinFilenames[m_nextSkin], "models/player/%s/%s.mdl", token, token); + m_skinFilenames[m_nextSkin] = new char[SkinLen + 1]; + Q_snprintf(m_skinFilenames[m_nextSkin], SkinLen + 1, "models/player/%s/%s.mdl", token, token); m_nextSkin++; } @@ -304,7 +305,7 @@ void BotProfileManager::Init(const char *filename, unsigned int *checksum) // found attribute name - keep it char attributeName[64]; - Q_strcpy(attributeName, token); + Q_strlcpy(attributeName, token); // eat '=' dataFile = SharedParse(dataFile); diff --git a/regamedll/game_shared/bot/bot_util.cpp b/regamedll/game_shared/bot/bot_util.cpp index 449b7e373..4d694b318 100644 --- a/regamedll/game_shared/bot/bot_util.cpp +++ b/regamedll/game_shared/bot/bot_util.cpp @@ -560,7 +560,7 @@ void CONSOLE_ECHO(const char *pszMsg, ...) static char szStr[1024]; va_start(argptr, pszMsg); - vsprintf(szStr, pszMsg, argptr); + Q_vsnprintf(szStr, sizeof(szStr), pszMsg, argptr); va_end(argptr); SERVER_PRINT(szStr); @@ -572,7 +572,7 @@ void CONSOLE_ECHO_LOGGED(const char *pszMsg, ...) static char szStr[1024]; va_start(argptr, pszMsg); - vsprintf(szStr, pszMsg, argptr); + Q_vsnprintf(szStr, sizeof(szStr), pszMsg, argptr); va_end(argptr); SERVER_PRINT(szStr); diff --git a/regamedll/game_shared/bot/nav_area.cpp b/regamedll/game_shared/bot/nav_area.cpp index 8e4baf0da..6c5960517 100644 --- a/regamedll/game_shared/bot/nav_area.cpp +++ b/regamedll/game_shared/bot/nav_area.cpp @@ -3819,9 +3819,9 @@ void EditNavAreas(NavEditCmdType cmd) name = TheNavAreaGrid.IDToName(area->GetPlace()); if (name) - Q_strcpy(locName, name); + Q_strlcpy(locName, name); else - Q_strcpy(locName, "ERROR"); + Q_strlcpy(locName, "ERROR"); } else { diff --git a/regamedll/game_shared/bot/nav_file.cpp b/regamedll/game_shared/bot/nav_file.cpp index c9f206fd9..5c6d65c38 100644 --- a/regamedll/game_shared/bot/nav_file.cpp +++ b/regamedll/game_shared/bot/nav_file.cpp @@ -632,12 +632,15 @@ bool SaveNavigationMap(const char *filename) void LoadLocationFile(const char *filename) { char locFilename[256]; - Q_strcpy(locFilename, filename); + Q_strlcpy(locFilename, filename); - char *dot = Q_strchr(locFilename, '.'); + char *dot = Q_strrchr(locFilename, '.'); if (dot) { - Q_strcpy(dot, ".loc"); + int dotlen = dot - locFilename; + size_t remaining_size = sizeof(locFilename) - dotlen; + if (remaining_size > 0) + Q_snprintf(dot, remaining_size, ".loc"); int locDataLength; char *locDataFile = (char *)LOAD_FILE_FOR_ME(const_cast(locFilename), &locDataLength); @@ -771,7 +774,7 @@ NavErrorType LoadNavigationMap() // nav filename is derived from map filename char filename[256]; - Q_sprintf(filename, "maps\\%s.nav", STRING(gpGlobals->mapname)); + Q_snprintf(filename, sizeof(filename), "maps\\%s.nav", STRING(gpGlobals->mapname)); // free previous navigation map data DestroyNavigationMap(); diff --git a/regamedll/msvc/ReGameDLL.vcxproj b/regamedll/msvc/ReGameDLL.vcxproj index 57e09e917..f33cfa3dc 100644 --- a/regamedll/msvc/ReGameDLL.vcxproj +++ b/regamedll/msvc/ReGameDLL.vcxproj @@ -809,6 +809,9 @@ + + + {70A2B904-B7DB-4C48-8DE0-AF567360D572} ReGameDLL diff --git a/regamedll/msvc/ReGameDLL.vcxproj.filters b/regamedll/msvc/ReGameDLL.vcxproj.filters index ef2017ae4..bfc6d6256 100644 --- a/regamedll/msvc/ReGameDLL.vcxproj.filters +++ b/regamedll/msvc/ReGameDLL.vcxproj.filters @@ -1070,4 +1070,9 @@ public\tier0 + + + regamedll + + \ No newline at end of file diff --git a/regamedll/pm_shared/pm_defs.h b/regamedll/pm_shared/pm_defs.h index 8606c587d..75fba5076 100644 --- a/regamedll/pm_shared/pm_defs.h +++ b/regamedll/pm_shared/pm_defs.h @@ -91,6 +91,74 @@ typedef struct physent_s } physent_t; +#define PM_VERSION_MAJOR 1 +#define PM_VERSION_MINOR 0 +#define PM_VERSION_PATCH 0 +#define PM_VERSION PM_VERSION_MAJOR, PM_VERSION_MINOR, PM_VERSION_PATCH + +#define PM_VERSION_STRINGIZE(x) #x +#define PM_VERSION_STRING(major,minor,patch) \ + (patch == 0 ?\ + PM_VERSION_STRINGIZE(major) "." PM_VERSION_STRINGIZE(minor) :\ + PM_VERSION_STRINGIZE(major) "." PM_VERSION_STRINGIZE(minor) "." PM_VERSION_STRINGIZE(patch)) + +// Control version of the player movement system +struct PlayerMovementVersion { + uint8_t major, minor, patch; + uint32_t u32; + + PlayerMovementVersion() { + Set(0, 0, 0); + } + + PlayerMovementVersion(uint32_t majorVersion, uint32_t minorVersion, uint32_t patchVersion = 0) { + Set(majorVersion, minorVersion, patchVersion); + } + + inline void Set(uint32_t majorVersion, uint32_t minorVersion, uint32_t patchVersion = 0) + { + major = majorVersion; + minor = minorVersion; + patch = patchVersion; + u32 = (major << 16) | (minor << 8) | patch; + } + + inline void Set(const char *version) + { + if (!version) + return; + + major = minor = patch = u32 = 0; + int result = sscanf(version, "%hhu.%hhu.%hhu", &major, &minor, &patch); + if (result < 1) + return; // major invalid + + u32 = (major << 16) | (minor << 8) | patch; + } + + // Compares if the current version is less than the given version + inline bool IsLessThan(uint32_t major, uint32_t minor, uint32_t patch = 0) const { + return u32 < ((major << 16) | (minor << 8) | patch); + } + + // Compares if the current version is greater than the given version + inline bool IsGreaterThan(uint32_t major, uint32_t minor, uint32_t patch = 0) const { + return u32 > ((major << 16) | (minor << 8) | patch); + } + + // Compares if the current version is greater than or equal to the given version + inline bool IsAtLeast(uint32_t major, uint32_t minor, uint32_t patch = 0) const { + return !IsLessThan(major, minor, patch); + } + + const char *ToString() const { + static char string[14]; + int len = Q_snprintf(string, sizeof(string), "%u.%u.%u", major, minor, patch); + if (patch == 0 && len > 2) string[len - 2] = '\0'; + return string; + } +}; + typedef struct playermove_s { int player_index; // So we don't try to run the PM_CheckStuck nudging too quickly. @@ -111,7 +179,7 @@ typedef struct playermove_s qboolean bInDuck; // In process of ducking or ducked already? int flTimeStepSound; // For walking/falling // Next time we can play a step sound - int iStepLeft; + qboolean iStepLeft; float flFallVelocity; vec3_t punchangle; float flSwimTime; diff --git a/regamedll/pm_shared/pm_shared.cpp b/regamedll/pm_shared/pm_shared.cpp index b40495569..e9efb3763 100644 --- a/regamedll/pm_shared/pm_shared.cpp +++ b/regamedll/pm_shared/pm_shared.cpp @@ -123,7 +123,7 @@ void PM_InitTextureTypes() j = Q_min(j, MAX_TEXTURENAME_LENGHT - 1 + i); buffer[j] = '\0'; - Q_strcpy(&(pm_grgszTextureName[pm_gcTextures++][0]), &(buffer[i])); + Q_strlcpy(pm_grgszTextureName[pm_gcTextures++], &(buffer[i])); } // Must use engine to free since we are in a .dll @@ -364,8 +364,7 @@ void PM_CatagorizeTextureType() if (*pTextureName == '{' || *pTextureName == '!' || *pTextureName == '~' || *pTextureName == ' ') pTextureName++; - Q_strcpy(pmove->sztexturename, pTextureName); - pmove->sztexturename[MAX_TEXTURENAME_LENGHT - 1] = '\0'; + Q_strlcpy(pmove->sztexturename, pTextureName, MAX_TEXTURENAME_LENGHT); // get texture type pmove->chtexturetype = PM_FindTextureType(pmove->sztexturename); @@ -870,7 +869,7 @@ void PM_WalkMove() vec3_t wishvel; real_t spd; - float fmove, smove; + float fmove, smove, maxspeed; vec3_t wishdir; real_t wishspeed; @@ -882,6 +881,7 @@ void PM_WalkMove() pmtrace_t trace; + // jump penalty if (pmove->fuser2 > 0.0) { real_t flRatio = (100 - pmove->fuser2 * 0.001 * 19) * 0.01; @@ -893,6 +893,17 @@ void PM_WalkMove() // Copy movement amounts fmove = pmove->cmd.forwardmove; smove = pmove->cmd.sidemove; + maxspeed = pmove->maxspeed; + +#ifdef REGAMEDLL_ADD + // Player can speed up the run if '+speed' button is pressed + if ((pmove->cmd.buttons & IN_RUN) && pmove->fuser3 > 0) + { + fmove *= pmove->fuser3; + smove *= pmove->fuser3; + maxspeed *= 2.0f; // increase speed cap to x2 when running + } +#endif // Zero out z components of movement vectors pmove->forward[2] = 0; @@ -916,10 +927,10 @@ void PM_WalkMove() wishspeed = VectorNormalize(wishdir); // Clamp to server defined max speed - if (wishspeed > pmove->maxspeed) + if (wishspeed > maxspeed) { - VectorScale(wishvel, pmove->maxspeed / wishspeed, wishvel); - wishspeed = pmove->maxspeed; + VectorScale(wishvel, maxspeed / wishspeed, wishvel); + wishspeed = maxspeed; } // Set pmove velocity @@ -1438,7 +1449,7 @@ void PM_CategorizePosition() // Do not stick to the ground of an OBSERVER or NOCLIP mode #ifdef REGAMEDLL_FIXES - if (pmove->movetype == MOVETYPE_NOCLIP || pmove->movetype == MOVETYPE_NONE) + if (pmoveplayer->m_MovementVersion.IsAtLeast(1, 0) && (pmove->movetype == MOVETYPE_NOCLIP || pmove->movetype == MOVETYPE_NONE)) { pmove->onground = -1; return; @@ -1636,7 +1647,7 @@ void PM_SpectatorMove() real_t accelspeed; int i; vec3_t wishvel; - float fmove, smove; + float fmove, smove, spectatormaxspeed; vec3_t wishdir; real_t wishspeed; @@ -1688,6 +1699,19 @@ void PM_SpectatorMove() fmove = pmove->cmd.forwardmove; smove = pmove->cmd.sidemove; + spectatormaxspeed = pmove->movevars->spectatormaxspeed; + +#ifdef REGAMEDLL_ADD + // Observer can accelerate in air if '+speed' button is pressed + if (pmove->cmd.buttons & IN_RUN) + { + float flAirAccelerate = (pmove->fuser3 > 0.0f) ? pmove->fuser3 : max(pmove->movevars->airaccelerate / 100.0f, 7.0f); + fmove *= flAirAccelerate; + smove *= flAirAccelerate; + spectatormaxspeed *= 2.0f; // increase speed cap to x2 when accelerating + } +#endif + VectorNormalize(pmove->forward); VectorNormalize(pmove->right); @@ -1702,29 +1726,36 @@ void PM_SpectatorMove() wishspeed = VectorNormalize(wishdir); // clamp to server defined max speed - if (wishspeed > pmove->movevars->spectatormaxspeed) + if (wishspeed > spectatormaxspeed) { - VectorScale(wishvel, pmove->movevars->spectatormaxspeed / wishspeed, wishvel); - wishspeed = pmove->movevars->spectatormaxspeed; + VectorScale(wishvel, spectatormaxspeed / wishspeed, wishvel); + wishspeed = spectatormaxspeed; } currentspeed = DotProduct(pmove->velocity, wishdir); addspeed = wishspeed - currentspeed; + if (addspeed <= 0) { - return; +#ifdef REGAMEDLL_FIXES + if (pmoveplayer->m_MovementVersion.IsLessThan(1, 0)) +#endif + return; } - accelspeed = pmove->movevars->accelerate * pmove->frametime * wishspeed; - if (accelspeed > addspeed) + if (addspeed > 0) { - accelspeed = addspeed; - } + accelspeed = pmove->movevars->accelerate * pmove->frametime * wishspeed; + if (accelspeed > addspeed) + { + accelspeed = addspeed; + } - for (i = 0; i < 3; i++) - { - pmove->velocity[i] += accelspeed * wishdir[i]; + for (i = 0; i < 3; i++) + { + pmove->velocity[i] += accelspeed * wishdir[i]; + } } // move @@ -1815,7 +1846,7 @@ LINK_HOOK_VOID_CHAIN2(PM_UnDuck) void EXT_FUNC __API_HOOK(PM_UnDuck)() { #ifdef REGAMEDLL_ADD - if (unduck_method.value) + if (unduck_method.value || (pmove->iuser3 & PLAYER_PREVENT_DDUCK)) #endif { #ifdef REGAMEDLL_FIXES @@ -1902,8 +1933,8 @@ void EXT_FUNC __API_HOOK(PM_Duck)() } #ifdef REGAMEDLL_ADD - if ((pmove->iuser3 & PLAYER_PREVENT_DUCK) == PLAYER_PREVENT_DUCK // Prevent ducking if the iuser3 variable is contain PLAYER_PREVENT_DUCK - || freezetime_duck.value == 0.0f && CSGameRules()->IsFreezePeriod()) // Prevent ducking during freezetime if the freezetime_duck cvar is 0 + if ((pmove->iuser3 & PLAYER_PREVENT_DUCK) == PLAYER_PREVENT_DUCK // Prevent ducking if the iuser3 variable is contain PLAYER_PREVENT_DUCK + || (freezetime_duck.value == 0.0f && CSGameRules()->IsFreezePeriod())) // Prevent ducking during freezetime if the freezetime_duck cvar is 0 { // Try to unduck if (pmove->flags & FL_DUCKING) @@ -2334,6 +2365,16 @@ void PM_NoClip() fmove = pmove->cmd.forwardmove; smove = pmove->cmd.sidemove; +#ifdef REGAMEDLL_ADD + // Player with noclip can accelerate in air if '+speed' button is pressed + if ((pmove->cmd.buttons & IN_RUN) && pmove->fuser3 > 0) + { + float flAirAccelerate = pmove->fuser3; + fmove *= flAirAccelerate; + smove *= flAirAccelerate; + } +#endif + VectorNormalize(pmove->forward); VectorNormalize(pmove->right); @@ -2458,8 +2499,8 @@ void EXT_FUNC __API_HOOK(PM_Jump)() } #ifdef REGAMEDLL_ADD - if ((pmove->iuser3 & PLAYER_PREVENT_JUMP) == PLAYER_PREVENT_JUMP // Prevent jumping if the iuser3 variable is contain PLAYER_PREVENT_JUMP - || freezetime_jump.value == 0.0f && CSGameRules()->IsFreezePeriod()) // Prevent jumping during freezetime if the freezetime_jump cvar is 0 + if ((pmove->iuser3 & PLAYER_PREVENT_JUMP) == PLAYER_PREVENT_JUMP // Prevent jumping if the iuser3 variable is contain PLAYER_PREVENT_JUMP + || (freezetime_jump.value == 0.0f && CSGameRules()->IsFreezePeriod())) // Prevent jumping during freezetime if the freezetime_jump cvar is 0 { return; } @@ -3340,3 +3381,8 @@ void EXT_FUNC __API_HOOK(PM_Init)(struct playermove_s *ppmove) pm_shared_initialized = TRUE; } + +const char *PM_ServerVersion() +{ + return PM_VERSION_STRING(PM_VERSION_MAJOR, PM_VERSION_MINOR, PM_VERSION_PATCH); +} diff --git a/regamedll/pm_shared/pm_shared.h b/regamedll/pm_shared/pm_shared.h index 2c0385f40..50550c696 100644 --- a/regamedll/pm_shared/pm_shared.h +++ b/regamedll/pm_shared/pm_shared.h @@ -96,4 +96,6 @@ void PM_AirAccelerate_OrigFunc(vec_t *wishdir, float wishspeed, float accel); void PM_AirMove(int playerIndex = 0); #endif +const char *PM_ServerVersion(); + extern struct playermove_s *pmove; diff --git a/regamedll/public/regamedll/API/CSPlayer.h b/regamedll/public/regamedll/API/CSPlayer.h index 90c55e2ab..e0b73fe6d 100644 --- a/regamedll/public/regamedll/API/CSPlayer.h +++ b/regamedll/public/regamedll/API/CSPlayer.h @@ -187,6 +187,9 @@ class CCSPlayer: public CCSMonster { int m_iGibDamageThreshold; // negative health to reach to gib player usercmd_t m_LastCmd; + + // Player movement version control + PlayerMovementVersion m_MovementVersion; }; // Inlines diff --git a/regamedll/public/regamedll/regamedll_api.h b/regamedll/public/regamedll/regamedll_api.h index d655ee656..74879aa42 100644 --- a/regamedll/public/regamedll/regamedll_api.h +++ b/regamedll/public/regamedll/regamedll_api.h @@ -38,7 +38,7 @@ #include #define REGAMEDLL_API_VERSION_MAJOR 5 -#define REGAMEDLL_API_VERSION_MINOR 27 +#define REGAMEDLL_API_VERSION_MINOR 28 // CBasePlayer::Spawn hook typedef IHookChainClass IReGameHook_CBasePlayer_Spawn; diff --git a/regamedll/public/strtools.h b/regamedll/public/strtools.h index 5cdf8c41d..11279c76e 100644 --- a/regamedll/public/strtools.h +++ b/regamedll/public/strtools.h @@ -156,40 +156,48 @@ inline char *Q_strlcpy(char *dest, const char *src, size_t size) { // a safe variant of strcpy that truncates the result to fit in the destination buffer template char *Q_strlcpy(char (&dest)[size], const char *src) { - return Q_strlcpy(dest, src, size); + return Q_strlcpy(static_cast(dest), src, size); } // safely concatenate two strings. // a variant of strcat that truncates the result to fit in the destination buffer -template -size_t Q_strlcat(char (&dest)[size], const char *src) +inline size_t Q_strlcat(char *dest, const char *src, size_t maxDestSize) { size_t srclen; // Length of source string size_t dstlen; // Length of destination string // Figure out how much room is left - dstlen = Q_strlen(dest); - size_t length = size - dstlen + 1; + dstlen = strlen(dest); + size_t unRemainingSize = maxDestSize - dstlen - 1; + + // Sanity check in case dest doesn't contain a null termination + if (dstlen > (maxDestSize - 1)) + dstlen = maxDestSize - 1; - if (!length) { - // No room, return immediately - return dstlen; + if (unRemainingSize <= 0 || unRemainingSize > maxDestSize) + { + dest[dstlen] = '\0'; + return dstlen; // No room, return immediately } // Figure out how much room is needed - srclen = Q_strlen(src); + srclen = strlen(src); // Copy the appropriate amount - if (srclen > length) { - srclen = length; - } + if (srclen > unRemainingSize) + srclen = unRemainingSize; Q_memcpy(dest + dstlen, src, srclen); dest[dstlen + srclen] = '\0'; - return dstlen + srclen; } +template +inline size_t Q_strlcat(char (&dest)[size], const char *src) +{ + return Q_strlcat(static_cast(dest), src, size); +} + // Force slashes of either type to be = separator character inline void Q_FixSlashes(char *pname, char separator = CORRECT_PATH_SEPARATOR) { diff --git a/regamedll/public/tier0/dbg.cpp b/regamedll/public/tier0/dbg.cpp index 35c99fe38..b9bade819 100644 --- a/regamedll/public/tier0/dbg.cpp +++ b/regamedll/public/tier0/dbg.cpp @@ -141,7 +141,7 @@ SpewRetval_t _SpewMessageV(SpewType_t spewType, int level, const char *pMsgForma assert(len < sizeof(szTempBuffer)); // Add \n for warning and assert - if ((spewType == SPEW_ASSERT)) + if (spewType == SPEW_ASSERT) { len += Q_snprintf(&szTempBuffer[len], sizeof(szTempBuffer) - len, "\n"); Plat_OutputDebugString(szTempBuffer); diff --git a/regamedll/regamedll/types.natvis b/regamedll/regamedll/types.natvis new file mode 100644 index 000000000..4dc313c65 --- /dev/null +++ b/regamedll/regamedll/types.natvis @@ -0,0 +1,107 @@ + + + + + + {{ { pev->pContainingEntity - g_pEdicts }, { pev->classname }, { pev->health }, { m_iTeam }, { m_iModelName } }} + + + + + + { *m_pContainingEntity } + + + + + {{ { pev->pContainingEntity - g_pEdicts }, { pev->classname } }} + + + m_pNext + m_pNext + (*this) + + + + + + + {{ { pev->pContainingEntity - g_pEdicts }, { pev->classname }, { pev->model } }} + + + + + {{ {this - g_pEdicts}, { v.classname }, { v.model } }} + + + + + {{ { pContainingEntity - g_pEdicts }, { classname }, { model } }} + + + + + { &gpGlobals->pStringBase[m_string],s } + + + + + allocator + + ($T1 *)m_pMemory + m_nAllocationCount + m_nGrowSize + + + + + + {{ size = { m_Size } }} + + + m_Size + (ElemType_t *)m_Memory.m_pMemory + + + + + + + {{ size = { m_Tree.m_NumElements } }} + + m_Tree.m_NumElements + m_Tree.m_Elements + + + + ((CTree::Node_t *)m_Tree.m_Elements.m_pMemory)[iMap].m_Data.elem + iMap++ + + + + + + + + {{ size = { $T2 } }} + + + $T2 + ($T1 *)&m_Memory[0] + + + + + + + + m_NumElements + m_Elements + + m_NumElements + ((Node_t *)m_Elements.m_pMemory)[$i].m_Data + + + + + diff --git a/regamedll/unittests/mathfun_tests.cpp b/regamedll/unittests/mathfun_tests.cpp index 6cb36eca5..7d39cb3b7 100644 --- a/regamedll/unittests/mathfun_tests.cpp +++ b/regamedll/unittests/mathfun_tests.cpp @@ -32,10 +32,10 @@ TEST(SinCosPrecision, SseMathFun, 10000) double sse_sin = _mm_cvtss_f32(s); double sse_cos = _mm_cvtss_f32(c); - sprintf(localbuf, "sin precision failure for angle=%f", i); + Q_snprintf(localbuf, sizeof(localbuf), "sin precision failure for angle=%f", i); DOUBLES_EQUAL(localbuf, x87_sin, sse_sin, 0.000001); - sprintf(localbuf, "cos precision failure for angle=%f", i); + Q_snprintf(localbuf, sizeof(localbuf), "cos precision failure for angle=%f", i); DOUBLES_EQUAL(localbuf, x87_cos, sse_cos, 0.000001); } } diff --git a/regamedll/version/version.h b/regamedll/version/version.h index fc64686b4..62c33001b 100644 --- a/regamedll/version/version.h +++ b/regamedll/version/version.h @@ -6,5 +6,5 @@ #pragma once #define VERSION_MAJOR 5 -#define VERSION_MINOR 27 +#define VERSION_MINOR 28 #define VERSION_MAINTENANCE 0