commit
aae3008576
101
CHANGELOG.md
101
CHANGELOG.md
@ -4,8 +4,29 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.3.0/).
|
The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.3.0/).
|
||||||
|
|
||||||
|
## r4246 - 2023-05-03
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add to the iw4x-rawfiles common_scripts\utility GSC script `setPing` & `getPing` for backward compatibility.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix bug with Steam Proxy (#991)
|
||||||
|
- Fix bug with the `say` GSC notify in regards to hidden commands (#989)
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- SetPing GSC method (#998)
|
||||||
|
|
||||||
|
### Known issues
|
||||||
|
|
||||||
|
- Sound issue fix is experimental as the bug is not fully understood.
|
||||||
|
|
||||||
## r4226 - 2023-04-26
|
## r4226 - 2023-04-26
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
- Chat system will go back to using `SV_CMD_CAN_IGNORE` commands (#972)
|
- Chat system will go back to using `SV_CMD_CAN_IGNORE` commands (#972)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
@ -44,13 +65,22 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- `sv_mapRotationCurrent` supports `exec` directive for executing cfg scripts from the `game_settings` folder (#916)
|
- `sv_mapRotationCurrent` supports `exec` directive for executing cfg scripts from the `game_settings` folder (#916)
|
||||||
- `SetPing` GSC method is now deprecated.
|
- `SetPing` GSC method is now deprecated (#903)
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- Fix DOS exploit in the network protocol of the game (#942)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- `sv_privatePassword` will work as intended (#908)
|
- `sv_privatePassword` will work as intended (#908)
|
||||||
- Fix crash when loading bots.txt file (#927)
|
- Fix crash when loading bots.txt file (#927)
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Remove `GetIp` GSC method (#903)
|
||||||
|
- Remove `GetPing` GSC method (#903)
|
||||||
|
|
||||||
### Known issues
|
### Known issues
|
||||||
|
|
||||||
- Sound issue fix is experimental as the bug is not fully understood.
|
- Sound issue fix is experimental as the bug is not fully understood.
|
||||||
@ -112,7 +142,6 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
|
|
||||||
- Servers can no longer modify client Dvars that are saved in the client's config (#694)
|
- Servers can no longer modify client Dvars that are saved in the client's config (#694)
|
||||||
- `banClient` and `muteClient` server commands do not apply to bots anymore (#730)
|
- `banClient` and `muteClient` server commands do not apply to bots anymore (#730)
|
||||||
- Remove `zb_prefer_disk_assets` Dvar (#772)
|
|
||||||
- The max value of `perk_extendedMeleeRange` Dvar was increased (#782)
|
- The max value of `perk_extendedMeleeRange` Dvar was increased (#782)
|
||||||
- Test Clients will receive names from the Xlabs Patreon website in addition to the names from the bots.txt file (#771)
|
- Test Clients will receive names from the Xlabs Patreon website in addition to the names from the bots.txt file (#771)
|
||||||
|
|
||||||
@ -126,6 +155,10 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
- Fix bug where `FileRead` GSC function could return buffers that are too big (#767)
|
- Fix bug where `FileRead` GSC function could return buffers that are too big (#767)
|
||||||
- Fix bug where the `OnPlayerSay` GSC function would cause issues (#776)
|
- Fix bug where the `OnPlayerSay` GSC function would cause issues (#776)
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Remove `zb_prefer_disk_assets` Dvar (#772)
|
||||||
|
|
||||||
### Known issues
|
### Known issues
|
||||||
|
|
||||||
- Sound issue fix is experimental as the bug is not fully understood.
|
- Sound issue fix is experimental as the bug is not fully understood.
|
||||||
@ -169,6 +202,10 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
- Static models are now lit correctly depending on their position and ground lighting.
|
- Static models are now lit correctly depending on their position and ground lighting.
|
||||||
- New map porting utility ports sounds and effects properly.
|
- New map porting utility ports sounds and effects properly.
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Remove `HttpGet`& `HttpCancel` (#603)
|
||||||
|
|
||||||
### Known issues
|
### Known issues
|
||||||
|
|
||||||
- HTTPS is not supported for fast downloads at the moment.
|
- HTTPS is not supported for fast downloads at the moment.
|
||||||
@ -190,7 +227,6 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Remove non-existent menus from code (#483)
|
|
||||||
- Change font and colour of the external console (#477)
|
- Change font and colour of the external console (#477)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
@ -200,6 +236,7 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
- Fix party server not receiving packets (#500)
|
- Fix party server not receiving packets (#500)
|
||||||
- Fix crash caused by server thread issues (#561)
|
- Fix crash caused by server thread issues (#561)
|
||||||
- Fix hours spent playing IW4x not counting towards the hours spent playing MW2 on Steam (#573)
|
- Fix hours spent playing IW4x not counting towards the hours spent playing MW2 on Steam (#573)
|
||||||
|
- Remove non-existent menus from code (#483)
|
||||||
|
|
||||||
### Known issues
|
### Known issues
|
||||||
|
|
||||||
@ -224,9 +261,12 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Steam status is no longer set to busy (#417)
|
- Steam status is no longer set to busy (#417)
|
||||||
- `HttpGet`& `HttpCancel` are disabled for security reasons (#449)
|
|
||||||
- `g_allowVote` is a replicated Dvar (#457)
|
- `g_allowVote` is a replicated Dvar (#457)
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- Disable `HttpGet`& `HttpCancel` (#449)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed `startSingleplayer` command (#404)
|
- Fixed `startSingleplayer` command (#404)
|
||||||
@ -246,19 +286,14 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
- Add `EnableWeaponPickup` GSC method (#329)
|
- Add `EnableWeaponPickup` GSC method (#329)
|
||||||
- Add `protect-saved-dvars` command line argument (#335)
|
- Add `protect-saved-dvars` command line argument (#335)
|
||||||
- Add `clanName` dvar. Can be edited in the `barracks` menu (#361)
|
- Add `clanName` dvar. Can be edited in the `barracks` menu (#361)
|
||||||
- Add DLC9 containing classic maps from CoD4: Backlot, Chinatown, Winter Crash, Pipeline and Downpour
|
- Add DLC9 containing classic maps from CoD4: Backlot, Chinatown, Winter Crash, Pipeline and Downpour.
|
||||||
|
- Add to the iw4x-rawfiles `common_scripts\iw4x_utility` GSC script, it contains the scripts-based solution for the removed GSC built-in methods.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- `sv_mapRotationCurrent` functionality has been restored for backwards compatibility (#328)
|
- `sv_mapRotationCurrent` functionality has been restored for backward compatibility (#328)
|
||||||
- GSC IO Functions are restricted to the `scriptdata` folder (#322)
|
- GSC IO Functions are restricted to the `scriptdata` folder (#322)
|
||||||
- `scriptablehttp` command line argument is no longer needed (#322)
|
- `scriptablehttp` command line argument is no longer needed (#322)
|
||||||
- Removed `noclip` built-in GSC method. Replaced with script-based solution (#387)
|
|
||||||
- Removed `ufo` built-in GSC method. Replaced with script-based solution (#387)
|
|
||||||
- Removed `god` built-in GSC method. Replaced with script-based solution (#388)
|
|
||||||
- Removed `demiGod` built-in GSC method. Replaced with script-based solution (#388)
|
|
||||||
- Removed `noTarget` built-in GSC method. Replaced with script-based solution (#388)
|
|
||||||
- Added to the iw4x-rawfiles `common_scripts\iw4x_utility` GSC script, it contains the scripts-based solution for the removed GSC built-in methods
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
@ -272,6 +307,14 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
- Fixed issue where grenades and projectiles had no bounce sounds (#368)
|
- Fixed issue where grenades and projectiles had no bounce sounds (#368)
|
||||||
- Fixed issue that could cause the game to crash when loading CoD4 maps (#372)
|
- Fixed issue that could cause the game to crash when loading CoD4 maps (#372)
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Remove `noclip` built-in GSC method. Replaced with script-based solution (#387)
|
||||||
|
- Remove `ufo` built-in GSC method. Replaced with script-based solution (#387)
|
||||||
|
- Remove `god` built-in GSC method. Replaced with script-based solution (#388)
|
||||||
|
- Remove `demiGod` built-in GSC method. Replaced with script-based solution (#388)
|
||||||
|
- Remove `noTarget` built-in GSC method. Replaced with script-based solution (#388)
|
||||||
|
|
||||||
### Known issues
|
### Known issues
|
||||||
|
|
||||||
- HTTPS is not supported for fast downloads at the moment.
|
- HTTPS is not supported for fast downloads at the moment.
|
||||||
@ -292,9 +335,12 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- `openLink` command was removed for security reasons (#286)
|
|
||||||
- `sv_mapRotationCurrent` is not being used anymore (#302)
|
- `sv_mapRotationCurrent` is not being used anymore (#302)
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- Remove `openLink` command (#286)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fix font generation (#277)
|
- Fix font generation (#277)
|
||||||
@ -369,12 +415,12 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Added controller support (#75)
|
- Add controller support (#75)
|
||||||
- Added aim assist for controllers (#75)
|
- Add aim assist for controllers (#75)
|
||||||
- Unlock camera_thirdPersonCrosshairOffset Dvar (#68)
|
- Unlock camera_thirdPersonCrosshairOffset Dvar (#68)
|
||||||
- Added support for building custom Fonts with Zonebuilder (#88)
|
- Add support for building custom Fonts with Zonebuilder (#88)
|
||||||
- Added colorblind friendly team colors (#101)
|
- Add colorblind friendly team colors (#101)
|
||||||
- Added emojis based on titlecards and emblems to use in the chat and server names Example: `:nuke:` (#130)
|
- Add emojis based on titlecards and emblems to use in the chat and server names Example: `:nuke:` (#130)
|
||||||
- Upon leaving a server 'archive' dvars (saved in the config file) will be reset to the value they had prior to joining the server (#134)
|
- Upon leaving a server 'archive' dvars (saved in the config file) will be reset to the value they had prior to joining the server (#134)
|
||||||
- Implement muteClient command for the game chat (#159)
|
- Implement muteClient command for the game chat (#159)
|
||||||
- Implement unmute command for the game chat (#159)
|
- Implement unmute command for the game chat (#159)
|
||||||
@ -455,13 +501,12 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
- Add r_specularCustomMaps Dvar (#36)
|
- Add r_specularCustomMaps Dvar (#36)
|
||||||
- Unlock safeArea_horizontal and safeArea_vertical Dvars (#42)
|
- Unlock safeArea_horizontal and safeArea_vertical Dvars (#42)
|
||||||
- Unlock cg_fovscale Dvar (#47)
|
- Unlock cg_fovscale Dvar (#47)
|
||||||
- Added g_antilag Dvar (#61)
|
- Add g_antilag Dvar (#61)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Stats are now separate for each mod (#6). Player stats are copied to `fs_game` folder if no stats exist for this mod yet. Keep in mind this also means that level, XP and classes will not be synchronized with the main stats file after this point.
|
- Stats are now separate for each mod (#6). Player stats are copied to `fs_game` folder if no stats exist for this mod yet. Keep in mind this also means that level, XP and classes will not be synchronized with the main stats file after this point.
|
||||||
- Reduced duration of toasts (#48)
|
- Reduced duration of toasts (#48)
|
||||||
- Removed old updater functionality (#54)
|
|
||||||
- Use old bot names if bots.txt is not found (#46)
|
- Use old bot names if bots.txt is not found (#46)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
@ -472,6 +517,10 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
- Fixed an issue causing the game to crash when Steam was running in the background (#56)
|
- Fixed an issue causing the game to crash when Steam was running in the background (#56)
|
||||||
- Fixed slow download speed when using fast download
|
- Fixed slow download speed when using fast download
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Removed old updater functionality (#54)
|
||||||
|
|
||||||
### Known issues
|
### Known issues
|
||||||
|
|
||||||
- HTTPS is not supported for fast downloads at the moment.
|
- HTTPS is not supported for fast downloads at the moment.
|
||||||
@ -556,8 +605,6 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
|
|
||||||
- Show friend avatars when they play IW4x (request).
|
- Show friend avatars when they play IW4x (request).
|
||||||
- Rewrite and optimize the entire node system.
|
- Rewrite and optimize the entire node system.
|
||||||
- Remove syncnode command for node system.
|
|
||||||
- Remove steam start.
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
@ -567,6 +614,11 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
- Fix crashes caused by a bug in file/data compression.
|
- Fix crashes caused by a bug in file/data compression.
|
||||||
- Improve overall stability.
|
- Improve overall stability.
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Remove syncnode command for node system.
|
||||||
|
- Remove steam start.
|
||||||
|
|
||||||
## [0.5.0] - 2017-06-04
|
## [0.5.0] - 2017-06-04
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
@ -646,7 +698,6 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
- Disabled big minidump message box.
|
- Disabled big minidump message box.
|
||||||
- Limit dedicated servers to 15 instances per IP.
|
- Limit dedicated servers to 15 instances per IP.
|
||||||
- Move build number location.
|
- Move build number location.
|
||||||
- Remove news ticker and friends button from theater.
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
@ -660,6 +711,10 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
|
|||||||
- Fix weapon crash issue.
|
- Fix weapon crash issue.
|
||||||
- Potentially fix no-ammo bug.
|
- Potentially fix no-ammo bug.
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Remove news ticker and friends button from theater.
|
||||||
|
|
||||||
## [0.3.2] - 2017-02-12
|
## [0.3.2] - 2017-02-12
|
||||||
|
|
||||||
This is the third public Beta version.
|
This is the third public Beta version.
|
||||||
|
2
deps/iw4-open-formats
vendored
2
deps/iw4-open-formats
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 1bc514d4c981532d1195b420a8fc0ce809c65944
|
Subproject commit 266165d21d77dadfe2adb01b7f1bf0fe64832479
|
3
deps/premake/mongoose.lua
vendored
3
deps/premake/mongoose.lua
vendored
@ -20,8 +20,7 @@ function mongoose.project()
|
|||||||
|
|
||||||
mongoose.includes()
|
mongoose.includes()
|
||||||
|
|
||||||
files
|
files {
|
||||||
{
|
|
||||||
path.join(mongoose.source, "mongoose.c"),
|
path.join(mongoose.source, "mongoose.c"),
|
||||||
path.join(mongoose.source, "mongoose.h"),
|
path.join(mongoose.source, "mongoose.h"),
|
||||||
}
|
}
|
||||||
|
2
deps/premake/udis86.lua
vendored
2
deps/premake/udis86.lua
vendored
@ -3,7 +3,7 @@ udis86 = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function udis86.import()
|
function udis86.import()
|
||||||
links {"udis86"}
|
links "udis86"
|
||||||
|
|
||||||
udis86.includes()
|
udis86.includes()
|
||||||
end
|
end
|
||||||
|
2
deps/protobuf
vendored
2
deps/protobuf
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 53a1c5c1d8b61984899b6877e491e5117ad486ba
|
Subproject commit 5a3dac894157bf3618b2c906a8b9073b4cad62b6
|
2
deps/zlib
vendored
2
deps/zlib
vendored
@ -1 +1 @@
|
|||||||
Subproject commit b8a8373ec195c8d286fe7e81e78b4a6d31bd859f
|
Subproject commit 48c3741002aca9dae84e9f2288ca149af14c9128
|
@ -71,7 +71,7 @@ namespace Components
|
|||||||
TokenContainer.cancel = false;
|
TokenContainer.cancel = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Auth::SendConnectDataStub(Game::netsrc_t sock, Game::netadr_t adr, const char* format, int len)
|
void Auth::SendConnectDataStub(Game::netsrc_t sock, Game::netadr_t adr, const char* format, int len)
|
||||||
{
|
{
|
||||||
// Ensure our certificate is loaded
|
// Ensure our certificate is loaded
|
||||||
@ -88,7 +88,7 @@ namespace Components
|
|||||||
Logger::Error(Game::ERR_SERVERDISCONNECT, "Your online profile is invalid. A new key has been generated.");
|
Logger::Error(Game::ERR_SERVERDISCONNECT, "Your online profile is invalid. A new key has been generated.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string connectString(format, len);
|
std::string connectString(format, len);
|
||||||
Game::SV_Cmd_TokenizeString(connectString.data());
|
Game::SV_Cmd_TokenizeString(connectString.data());
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ namespace Components
|
|||||||
// Have only one instance of IW4x read/write the file
|
// Have only one instance of IW4x read/write the file
|
||||||
std::unique_lock<Utils::NamedMutex> Bans::Lock()
|
std::unique_lock<Utils::NamedMutex> Bans::Lock()
|
||||||
{
|
{
|
||||||
static Utils::NamedMutex mutex{"iw4x-ban-list-lock"};
|
static Utils::NamedMutex mutex{ "iw4x-ban-list-lock" };
|
||||||
std::unique_lock lock{mutex};
|
std::unique_lock lock{mutex};
|
||||||
return lock;
|
return lock;
|
||||||
}
|
}
|
||||||
|
@ -272,9 +272,6 @@ namespace Components
|
|||||||
g_botai[entref.entnum].right = static_cast<int8_t>(rightInt);
|
g_botai[entref.entnum].right = static_cast<int8_t>(rightInt);
|
||||||
g_botai[entref.entnum].active = true;
|
g_botai[entref.entnum].active = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
GSC::Script::AddMethod("SetPing", []([[maybe_unused]] const Game::scr_entref_t entref)
|
|
||||||
{});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bots::BotAiAction(Game::client_t* cl)
|
void Bots::BotAiAction(Game::client_t* cl)
|
||||||
|
@ -137,14 +137,13 @@ namespace Components
|
|||||||
pop eax
|
pop eax
|
||||||
|
|
||||||
cmp eax, 0
|
cmp eax, 0
|
||||||
jz OriginalTitle
|
jz originalTitle
|
||||||
|
|
||||||
pop ecx
|
pop ecx
|
||||||
mov ecx, DWORD ptr[esi + 4]
|
mov ecx, dword ptr[esi + 4]
|
||||||
retn
|
retn
|
||||||
|
|
||||||
OriginalTitle:
|
originalTitle:
|
||||||
|
|
||||||
mov eax, [esi + 50h]
|
mov eax, [esi + 50h]
|
||||||
cmp eax, 3
|
cmp eax, 3
|
||||||
|
|
||||||
@ -173,8 +172,7 @@ namespace Components
|
|||||||
list.append(std::format("\\{}\\{}", i, playerTitle));
|
list.append(std::format("\\{}\\{}", i, playerTitle));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto* command = Utils::String::Format("{:c} customTitles \"{}\"", 21, list);
|
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} customTitles \"{}\"", 21, list));
|
||||||
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, command);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardTitles::ParseCustomTitles(const char* msg)
|
void CardTitles::ParseCustomTitles(const char* msg)
|
||||||
|
@ -24,7 +24,7 @@ namespace Components
|
|||||||
// Have only one instance of IW4x read/write the file
|
// Have only one instance of IW4x read/write the file
|
||||||
std::unique_lock<Utils::NamedMutex> Chat::Lock()
|
std::unique_lock<Utils::NamedMutex> Chat::Lock()
|
||||||
{
|
{
|
||||||
static Utils::NamedMutex mutex{"iw4x-mute-list-lock"};
|
static Utils::NamedMutex mutex{ "iw4x-mute-list-lock" };
|
||||||
std::unique_lock lock{mutex};
|
std::unique_lock lock{mutex};
|
||||||
return lock;
|
return lock;
|
||||||
}
|
}
|
||||||
@ -51,6 +51,7 @@ namespace Components
|
|||||||
if (text[msgIndex] == '/')
|
if (text[msgIndex] == '/')
|
||||||
{
|
{
|
||||||
SendChat = false;
|
SendChat = false;
|
||||||
|
++msgIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsMuted(player))
|
if (IsMuted(player))
|
||||||
@ -65,13 +66,14 @@ namespace Components
|
|||||||
Game::SV_GameSendServerCommand(player - Game::g_entities, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"Chat is disabled\"", 0x65));
|
Game::SV_GameSendServerCommand(player - Game::g_entities, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"Chat is disabled\"", 0x65));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Message might be empty after the special characters
|
// Message might be empty after the special characters or '/'
|
||||||
if (text[msgIndex] == '\0')
|
if (text[msgIndex] == '\0')
|
||||||
{
|
{
|
||||||
SendChat = false;
|
SendChat = false;
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextRenderer::StripMaterialTextIcons(text, text, std::strlen(text) + 1);
|
||||||
Logger::Print("{}: {}\n", Game::svs_clients[player - Game::g_entities].name, (text + msgIndex));
|
Logger::Print("{}: {}\n", Game::svs_clients[player - Game::g_entities].name, (text + msgIndex));
|
||||||
|
|
||||||
for (const auto& callback : SayCallbacks)
|
for (const auto& callback : SayCallbacks)
|
||||||
@ -82,8 +84,6 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextRenderer::StripMaterialTextIcons(text, text, std::strlen(text) + 1);
|
|
||||||
|
|
||||||
Game::Scr_AddEntity(player);
|
Game::Scr_AddEntity(player);
|
||||||
Game::Scr_AddString(text + msgIndex);
|
Game::Scr_AddString(text + msgIndex);
|
||||||
Game::Scr_NotifyLevel(static_cast<std::uint16_t>(Game::SL_GetString("say", 0)), 2);
|
Game::Scr_NotifyLevel(static_cast<std::uint16_t>(Game::SL_GetString("say", 0)), 2);
|
||||||
@ -351,7 +351,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
catch (const std::exception& ex)
|
catch (const std::exception& ex)
|
||||||
{
|
{
|
||||||
Logger::PrintError(Game::CON_CHANNEL_ERROR, "Json Parse Error: {}\n", ex.what());
|
Logger::PrintError(Game::CON_CHANNEL_ERROR, "JSON Parse Error: {}\n", ex.what());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,7 +386,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
if (!Dedicated::IsRunning())
|
if (!Dedicated::IsRunning())
|
||||||
{
|
{
|
||||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Server is not running.\n");
|
Logger::Print("Server is not running.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,7 +409,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
if (!Dedicated::IsRunning())
|
if (!Dedicated::IsRunning())
|
||||||
{
|
{
|
||||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Server is not running.\n");
|
Logger::Print("Server is not running.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,7 +450,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
if (!Dedicated::IsRunning())
|
if (!Dedicated::IsRunning())
|
||||||
{
|
{
|
||||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Server is not running.\n");
|
Logger::Print("Server is not running.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,12 +462,12 @@ namespace Components
|
|||||||
if (!name.empty())
|
if (!name.empty())
|
||||||
{
|
{
|
||||||
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"{}: {}\"", 0x68, name, message));
|
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"{}: {}\"", 0x68, name, message));
|
||||||
Logger::Print(Game::CON_CHANNEL_SERVER, "{}: {}\n", name, message);
|
Logger::Print("{}: {}\n", name, message);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"Console: {}\"", 0x68, message));
|
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"Console: {}\"", 0x68, message));
|
||||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Console: {}\n", message);
|
Logger::Print("Console: {}\n", message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -475,7 +475,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
if (!Dedicated::IsRunning())
|
if (!Dedicated::IsRunning())
|
||||||
{
|
{
|
||||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Server is not running.\n");
|
Logger::Print("Server is not running.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,12 +490,12 @@ namespace Components
|
|||||||
if (!name.empty())
|
if (!name.empty())
|
||||||
{
|
{
|
||||||
Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"{}: {}\"", 0x68, name.data(), message));
|
Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"{}: {}\"", 0x68, name.data(), message));
|
||||||
Logger::Print(Game::CON_CHANNEL_SERVER, "{} -> {}: {}\n", name, clientNum, message);
|
Logger::Print("{} -> {}: {}\n", name, clientNum, message);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"Console: {}\"", 0x68, message));
|
Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"Console: {}\"", 0x68, message));
|
||||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Console -> {}: {}\n", clientNum, message);
|
Logger::Print("Console -> {}: {}\n", clientNum, message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -503,7 +503,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
if (!Dedicated::IsRunning())
|
if (!Dedicated::IsRunning())
|
||||||
{
|
{
|
||||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Server is not running.\n");
|
Logger::Print("Server is not running.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,14 +511,14 @@ namespace Components
|
|||||||
|
|
||||||
const auto message = params->join(1);
|
const auto message = params->join(1);
|
||||||
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"{}\"", 0x68, message));
|
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"{}\"", 0x68, message));
|
||||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Raw: {}\n", message);
|
Logger::Print("Raw: {}\n", message);
|
||||||
});
|
});
|
||||||
|
|
||||||
Command::AddSV("tellraw", [](Command::Params* params)
|
Command::AddSV("tellraw", [](Command::Params* params)
|
||||||
{
|
{
|
||||||
if (!Dedicated::IsRunning())
|
if (!Dedicated::IsRunning())
|
||||||
{
|
{
|
||||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Server is not running.\n");
|
Logger::Print("Server is not running.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,7 +529,7 @@ namespace Components
|
|||||||
|
|
||||||
const auto message = params->join(2);
|
const auto message = params->join(2);
|
||||||
Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"{}\"", 0x68, message));
|
Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"{}\"", 0x68, message));
|
||||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Raw -> {}: {}\n", clientNum, message);
|
Logger::Print("Raw -> {}: {}\n", clientNum, message);
|
||||||
});
|
});
|
||||||
|
|
||||||
sv_sayName = Dvar::Register<const char*>("sv_sayName", "^7Console", Game::DVAR_NONE, "The alias of the server when broadcasting a chat message");
|
sv_sayName = Dvar::Register<const char*>("sv_sayName", "^7Console", Game::DVAR_NONE, "The alias of the server when broadcasting a chat message");
|
||||||
|
@ -86,7 +86,7 @@ namespace Components
|
|||||||
auto curChar = CL_FilterChar(static_cast<unsigned char>(currentName[i]));
|
auto curChar = CL_FilterChar(static_cast<unsigned char>(currentName[i]));
|
||||||
if (curChar > 0)
|
if (curChar > 0)
|
||||||
{
|
{
|
||||||
*saneName++ = (curChar & 0xFF);
|
*saneName++ = curChar & 0xFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,7 +233,7 @@ namespace Components
|
|||||||
|
|
||||||
ClanTags::ClanTags()
|
ClanTags::ClanTags()
|
||||||
{
|
{
|
||||||
Events::OnClientInit([]
|
Events::OnDvarInit([]
|
||||||
{
|
{
|
||||||
ClanName = Game::Dvar_RegisterString("clanName", "", Game::DVAR_ARCHIVE, "Your clan abbreviation");
|
ClanName = Game::Dvar_RegisterString("clanName", "", Game::DVAR_ARCHIVE, "Your clan abbreviation");
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include <STDInclude.hpp>
|
#include <STDInclude.hpp>
|
||||||
#include "Console.hpp"
|
#include "Console.hpp"
|
||||||
#include "TextRenderer.hpp"
|
#include "TextRenderer.hpp"
|
||||||
|
|
||||||
@ -56,6 +56,8 @@ namespace Components
|
|||||||
|
|
||||||
Game::SafeArea Console::OriginalSafeArea;
|
Game::SafeArea Console::OriginalSafeArea;
|
||||||
|
|
||||||
|
bool Console::isCommand;
|
||||||
|
|
||||||
const char** Console::GetAutoCompleteFileList(const char* path, const char* extension, Game::FsListBehavior_e behavior, int* numfiles, int allocTrackType)
|
const char** Console::GetAutoCompleteFileList(const char* path, const char* extension, Game::FsListBehavior_e behavior, int* numfiles, int allocTrackType)
|
||||||
{
|
{
|
||||||
if (path == reinterpret_cast<char*>(0xBAADF00D) || path == reinterpret_cast<char*>(0xCDCDCDCD) || ::Utils::Memory::IsBadReadPtr(path)) return nullptr;
|
if (path == reinterpret_cast<char*>(0xBAADF00D) || path == reinterpret_cast<char*>(0xCDCDCDCD) || ::Utils::Memory::IsBadReadPtr(path)) return nullptr;
|
||||||
@ -807,6 +809,20 @@ namespace Components
|
|||||||
return reinterpret_cast<Game::Dvar_RegisterVec4_t>(0x471500)(dvarName, r, g, b, a, min, max, flags, description);
|
return reinterpret_cast<Game::Dvar_RegisterVec4_t>(0x471500)(dvarName, r, g, b, a, min, max, flags, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Console::Con_IsDvarCommand_Stub(const char* cmd)
|
||||||
|
{
|
||||||
|
isCommand = Game::Con_IsDvarCommand(cmd);
|
||||||
|
return isCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::Cmd_ForEach_Stub(void(*callback)(const char* str))
|
||||||
|
{
|
||||||
|
if (!isCommand)
|
||||||
|
{
|
||||||
|
Game::Cmd_ForEach(callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Console::Con_ToggleConsole()
|
void Console::Con_ToggleConsole()
|
||||||
{
|
{
|
||||||
Game::Field_Clear(Game::g_consoleField);
|
Game::Field_Clear(Game::g_consoleField);
|
||||||
@ -885,6 +901,10 @@ namespace Components
|
|||||||
// Don't resize the console
|
// Don't resize the console
|
||||||
Utils::Hook(0x64DC6B, 0x64DCC2, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x64DC6B, 0x64DCC2, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
|
// Con_DrawInput
|
||||||
|
Utils::Hook(0x5A45BD, Con_IsDvarCommand_Stub, HOOK_CALL).install()->quick();
|
||||||
|
Utils::Hook(0x5A466C, Cmd_ForEach_Stub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
AddConsoleCommand();
|
AddConsoleCommand();
|
||||||
#endif
|
#endif
|
||||||
|
@ -49,6 +49,8 @@ namespace Components
|
|||||||
|
|
||||||
static Game::SafeArea OriginalSafeArea;
|
static Game::SafeArea OriginalSafeArea;
|
||||||
|
|
||||||
|
static bool isCommand;
|
||||||
|
|
||||||
static void ShowPrompt();
|
static void ShowPrompt();
|
||||||
static void RefreshStatus();
|
static void RefreshStatus();
|
||||||
static void RefreshOutput();
|
static void RefreshOutput();
|
||||||
@ -75,6 +77,9 @@ namespace Components
|
|||||||
static void AddConsoleCommand();
|
static void AddConsoleCommand();
|
||||||
|
|
||||||
static Game::dvar_t* RegisterConColor(const char* dvarName, float r, float g, float b, float a, float min, float max, unsigned __int16 flags, const char* description);
|
static Game::dvar_t* RegisterConColor(const char* dvarName, float r, float g, float b, float a, float min, float max, unsigned __int16 flags, const char* description);
|
||||||
|
|
||||||
|
static bool Con_IsDvarCommand_Stub(const char* cmd);
|
||||||
|
static void Cmd_ForEach_Stub(void(*callback)(const char* str));
|
||||||
|
|
||||||
static LRESULT CALLBACK ConWndProc(HWND hWnd, UINT Msg, WPARAM wParam, unsigned int lParam);
|
static LRESULT CALLBACK ConWndProc(HWND hWnd, UINT Msg, WPARAM wParam, unsigned int lParam);
|
||||||
static ATOM CALLBACK RegisterClassHook(WNDCLASSA* lpWndClass);
|
static ATOM CALLBACK RegisterClassHook(WNDCLASSA* lpWndClass);
|
||||||
|
@ -172,7 +172,7 @@ namespace Components
|
|||||||
|
|
||||||
Network::Address master(Utils::String::VA("%s:%u", masterServerName, masterPort));
|
Network::Address master(Utils::String::VA("%s:%u", masterServerName, masterPort));
|
||||||
|
|
||||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Sending heartbeat to master: {}:{}\n", masterServerName, masterPort);
|
Logger::Print("Sending heartbeat to master: {}:{}\n", masterServerName, masterPort);
|
||||||
Network::SendCommand(master, "heartbeat", "IW4");
|
Network::SendCommand(master, "heartbeat", "IW4");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,10 +122,12 @@ namespace Components
|
|||||||
{
|
{
|
||||||
Game::Com_PrintMessage(Game::CON_CHANNEL_DONT_FILTER, i->data(), 0);
|
Game::Com_PrintMessage(Game::CON_CHANNEL_DONT_FILTER, i->data(), 0);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
if (!IsConsoleReady())
|
if (!IsConsoleReady())
|
||||||
{
|
{
|
||||||
OutputDebugStringA(i->data());
|
OutputDebugStringA(i->data());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
i = MessageQueue.erase(i);
|
i = MessageQueue.erase(i);
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,7 @@ namespace Components
|
|||||||
|
|
||||||
if (svMapname.empty())
|
if (svMapname.empty())
|
||||||
{
|
{
|
||||||
Logger::Print(Game::CON_CHANNEL_SERVER, "mapname dvar is empty! Defaulting to mp_afghan\n");
|
Logger::Print(Game::CON_CHANNEL_SERVER, "{} dvar is empty! Defaulting to mp_afghan\n", (*Game::sv_mapname)->name);
|
||||||
svMapname = "mp_afghan"s;
|
svMapname = "mp_afghan"s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,18 +813,6 @@ namespace Components
|
|||||||
Utils::Hook::Set<DWORD>(0x64A029, 0x1C200000); // 450 MiB
|
Utils::Hook::Set<DWORD>(0x64A029, 0x1C200000); // 450 MiB
|
||||||
Utils::Hook::Set<DWORD>(0x64A057, 0x1C200000);
|
Utils::Hook::Set<DWORD>(0x64A057, 0x1C200000);
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
// Hunk debugging
|
|
||||||
Utils::Hook::Set<BYTE>(0x4FF57B, 0xCC);
|
|
||||||
Utils::Hook::Nop(0x4FF57C, 4);
|
|
||||||
#else
|
|
||||||
// Temporarily disable distortion warnings
|
|
||||||
Utils::Hook::Nop(0x50DBFF, 5);
|
|
||||||
Utils::Hook::Nop(0x50DC4F, 5);
|
|
||||||
Utils::Hook::Nop(0x50DCA3, 5);
|
|
||||||
Utils::Hook::Nop(0x50DCFE, 5);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Intercept BSP name resolving
|
// Intercept BSP name resolving
|
||||||
Utils::Hook(0x4C5979, Maps::GetBSPName, HOOK_CALL).install()->quick();
|
Utils::Hook(0x4C5979, Maps::GetBSPName, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ namespace Components
|
|||||||
SendStats();
|
SendStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Stats::SaveStats(char* dest, const char* folder, const char* buffer, size_t length)
|
int Stats::SaveStats(char* dest, const char* folder, const char* buffer, int size)
|
||||||
{
|
{
|
||||||
assert(*Game::fs_gameDirVar);
|
assert(*Game::fs_gameDirVar);
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ namespace Components
|
|||||||
folder = (*Game::fs_gameDirVar)->current.string;
|
folder = (*Game::fs_gameDirVar)->current.string;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Utils::Hook::Call<int(char*, const char*, const char*, size_t)>(0x426450)(dest, folder, buffer, length);
|
return Utils::Hook::Call<int(char*, const char*, const char*, int)>(0x426450)(dest, folder, buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stats::AddScriptFunctions()
|
void Stats::AddScriptFunctions()
|
||||||
@ -175,7 +175,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
if (params->size() < 2)
|
if (params->size() < 2)
|
||||||
{
|
{
|
||||||
Logger::PrintError(Game::CON_CHANNEL_SERVER, "statget usage: statget <index>\n");
|
Logger::Print("statget usage: statget <index>\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ namespace Components
|
|||||||
static void UpdateClasses([[maybe_unused]] const UIScript::Token& token, [[maybe_unused]] const Game::uiInfo_s* info);
|
static void UpdateClasses([[maybe_unused]] const UIScript::Token& token, [[maybe_unused]] const Game::uiInfo_s* info);
|
||||||
|
|
||||||
static void SendStats();
|
static void SendStats();
|
||||||
static int SaveStats(char* dest, const char* folder, const char* buffer, size_t length);
|
static int SaveStats(char* dest, const char* folder, const char* buffer, int size);
|
||||||
|
|
||||||
static std::int64_t* GetStatsID();
|
static std::int64_t* GetStatsID();
|
||||||
|
|
||||||
|
@ -940,7 +940,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto materialNameLen = static_cast<uint8_t>(*text);
|
const auto materialNameLen = static_cast<uint8_t>(*text);
|
||||||
text++;
|
++text;
|
||||||
|
|
||||||
for (auto i = 0u; i < materialNameLen; i++)
|
for (auto i = 0u; i < materialNameLen; i++)
|
||||||
{
|
{
|
||||||
@ -954,8 +954,10 @@ namespace Components
|
|||||||
text += materialNameLen;
|
text += materialNameLen;
|
||||||
|
|
||||||
auto* material = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, materialName.data()).material;
|
auto* material = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, materialName.data()).material;
|
||||||
if (material == nullptr || material->techniqueSet == nullptr || material->techniqueSet->name == nullptr || strcmp(material->techniqueSet->name, "2d") != 0)
|
if (material == nullptr || material->techniqueSet == nullptr || material->techniqueSet->name == nullptr || std::strcmp(material->techniqueSet->name, "2d") != 0)
|
||||||
|
{
|
||||||
material = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, "default").material;
|
material = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, "default").material;
|
||||||
|
}
|
||||||
|
|
||||||
const auto yy = y - (h + yScale * static_cast<float>(font->pixelHeight)) * 0.5f;
|
const auto yy = y - (h + yScale * static_cast<float>(font->pixelHeight)) * 0.5f;
|
||||||
|
|
||||||
@ -1091,7 +1093,7 @@ namespace Components
|
|||||||
if (renderFlags & Game::TEXT_RENDERFLAG_PADDING)
|
if (renderFlags & Game::TEXT_RENDERFLAG_PADDING)
|
||||||
xa += xScale * padding;
|
xa += xScale * padding;
|
||||||
++count;
|
++count;
|
||||||
maxLengthRemaining--;
|
--maxLengthRemaining;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1111,7 +1113,7 @@ namespace Components
|
|||||||
if (renderFlags & Game::TEXT_RENDERFLAG_PADDING)
|
if (renderFlags & Game::TEXT_RENDERFLAG_PADDING)
|
||||||
xa += xScale * padding;
|
xa += xScale * padding;
|
||||||
count += (fontIconEnd - curText) + 1;
|
count += (fontIconEnd - curText) + 1;
|
||||||
maxLengthRemaining--;
|
--maxLengthRemaining;
|
||||||
curText = fontIconEnd;
|
curText = fontIconEnd;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1222,8 +1224,8 @@ namespace Components
|
|||||||
if (renderFlags & Game::TEXT_RENDERFLAG_PADDING)
|
if (renderFlags & Game::TEXT_RENDERFLAG_PADDING)
|
||||||
xa += xScale * padding;
|
xa += xScale * padding;
|
||||||
|
|
||||||
count++;
|
++count;
|
||||||
maxLengthRemaining--;
|
--maxLengthRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderFlags & Game::TEXT_RENDERFLAG_CURSOR && count == cursorPos)
|
if (renderFlags & Game::TEXT_RENDERFLAG_CURSOR && count == cursorPos)
|
||||||
@ -1240,10 +1242,14 @@ namespace Components
|
|||||||
auto maxWidth = 0;
|
auto maxWidth = 0;
|
||||||
|
|
||||||
if (maxChars <= 0)
|
if (maxChars <= 0)
|
||||||
|
{
|
||||||
maxChars = std::numeric_limits<int>::max();
|
maxChars = std::numeric_limits<int>::max();
|
||||||
|
}
|
||||||
|
|
||||||
if (text == nullptr)
|
if (text == nullptr)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
auto count = 0;
|
auto count = 0;
|
||||||
while (text && *text && count < maxChars)
|
while (text && *text && count < maxChars)
|
||||||
@ -1259,7 +1265,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
if (*text >= COLOR_FIRST_CHAR && *text <= COLOR_LAST_CHAR)
|
if (*text >= COLOR_FIRST_CHAR && *text <= COLOR_LAST_CHAR)
|
||||||
{
|
{
|
||||||
text++;
|
++text;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1309,7 +1315,8 @@ namespace Components
|
|||||||
{
|
{
|
||||||
maxWidth = lineWidth;
|
maxWidth = lineWidth;
|
||||||
}
|
}
|
||||||
count++;
|
|
||||||
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1328,7 +1335,7 @@ namespace Components
|
|||||||
if (!in || !out) return;
|
if (!in || !out) return;
|
||||||
|
|
||||||
max--;
|
max--;
|
||||||
size_t current = 0;
|
std::size_t current = 0;
|
||||||
while (*in != 0 && current < max)
|
while (*in != 0 && current < max)
|
||||||
{
|
{
|
||||||
const char index = *(in + 1);
|
const char index = *(in + 1);
|
||||||
@ -1345,6 +1352,7 @@ namespace Components
|
|||||||
|
|
||||||
++in;
|
++in;
|
||||||
}
|
}
|
||||||
|
|
||||||
*out = '\0';
|
*out = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1352,7 +1360,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
char buffer[1024]{}; // 1024 is a lucky number in the engine
|
char buffer[1024]{}; // 1024 is a lucky number in the engine
|
||||||
StripColors(in.data(), buffer, sizeof(buffer));
|
StripColors(in.data(), buffer, sizeof(buffer));
|
||||||
return {buffer};
|
return std::string{ buffer };
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextRenderer::StripMaterialTextIcons(const char* in, char* out, std::size_t max)
|
void TextRenderer::StripMaterialTextIcons(const char* in, char* out, std::size_t max)
|
||||||
@ -1399,6 +1407,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*out = '\0';
|
*out = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1406,7 +1415,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
char buffer[1000]{}; // Should be more than enough
|
char buffer[1000]{}; // Should be more than enough
|
||||||
StripAllTextIcons(in.data(), buffer, sizeof(buffer));
|
StripAllTextIcons(in.data(), buffer, sizeof(buffer));
|
||||||
return {buffer};
|
return std::string{ buffer };
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextRenderer::StripAllTextIcons(const char* in, char* out, std::size_t max)
|
void TextRenderer::StripAllTextIcons(const char* in, char* out, std::size_t max)
|
||||||
@ -1414,7 +1423,7 @@ namespace Components
|
|||||||
if (!in || !out) return;
|
if (!in || !out) return;
|
||||||
|
|
||||||
--max;
|
--max;
|
||||||
size_t current = 0;
|
std::size_t current = 0;
|
||||||
while (*in != 0 && current < max)
|
while (*in != 0 && current < max)
|
||||||
{
|
{
|
||||||
if (*in == '^' && (in[1] == '\x01' || in[1] == '\x02'))
|
if (*in == '^' && (in[1] == '\x01' || in[1] == '\x02'))
|
||||||
@ -1422,18 +1431,25 @@ namespace Components
|
|||||||
in += 2;
|
in += 2;
|
||||||
|
|
||||||
if (*in) // width
|
if (*in) // width
|
||||||
in++;
|
{
|
||||||
|
++in;
|
||||||
|
}
|
||||||
|
|
||||||
if (*in) // height
|
if (*in) // height
|
||||||
in++;
|
{
|
||||||
|
++in;
|
||||||
|
}
|
||||||
|
|
||||||
if (*in) // material name length + material name characters
|
if (*in) // material name length + material name characters
|
||||||
{
|
{
|
||||||
const auto materialNameLength = *in;
|
const auto materialNameLength = *in;
|
||||||
in++;
|
++in;
|
||||||
for (auto i = 0; i < materialNameLength; i++)
|
for (auto i = 0; i < materialNameLength; i++)
|
||||||
{
|
{
|
||||||
if (*in)
|
if (*in)
|
||||||
in++;
|
{
|
||||||
|
++in;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1486,16 +1502,16 @@ namespace Components
|
|||||||
|
|
||||||
if (c == '^' && *curText >= COLOR_FIRST_CHAR && *curText <= COLOR_LAST_CHAR && !(cursorPos > count && cursorPos < count + 2))
|
if (c == '^' && *curText >= COLOR_FIRST_CHAR && *curText <= COLOR_LAST_CHAR && !(cursorPos > count && cursorPos < count + 2))
|
||||||
{
|
{
|
||||||
curText++;
|
++curText;
|
||||||
count++;
|
++count;
|
||||||
}
|
}
|
||||||
else if(c != '\r' && c != '\n')
|
else if(c != '\r' && c != '\n')
|
||||||
{
|
{
|
||||||
len++;
|
++len;
|
||||||
}
|
}
|
||||||
|
|
||||||
count++;
|
++count;
|
||||||
lenWithInvisibleTail++;
|
++lenWithInvisibleTail;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lenWithInvisibleTail;
|
return lenWithInvisibleTail;
|
||||||
@ -1524,17 +1540,17 @@ namespace Components
|
|||||||
{
|
{
|
||||||
Utils::Hook::Set<char>(0x535629, limit); // DrawText2d
|
Utils::Hook::Set<char>(0x535629, limit); // DrawText2d
|
||||||
Utils::Hook::Set<char>(0x4C1BE4, limit); // SEH_PrintStrlen
|
Utils::Hook::Set<char>(0x4C1BE4, limit); // SEH_PrintStrlen
|
||||||
Utils::Hook::Set<char>(0x4863DD, limit); // No idea :P
|
Utils::Hook::Set<char>(0x4863DD, limit); // No idea
|
||||||
Utils::Hook::Set<char>(0x486429, limit); // No idea :P
|
Utils::Hook::Set<char>(0x486429, limit); // No idea
|
||||||
Utils::Hook::Set<char>(0x49A5A8, limit); // No idea :P
|
Utils::Hook::Set<char>(0x49A5A8, limit); // No idea
|
||||||
Utils::Hook::Set<char>(0x505721, limit); // R_TextWidth
|
Utils::Hook::Set<char>(0x505721, limit); // R_TextWidth
|
||||||
Utils::Hook::Set<char>(0x505801, limit); // No idea :P
|
Utils::Hook::Set<char>(0x505801, limit); // No idea
|
||||||
Utils::Hook::Set<char>(0x50597F, limit); // No idea :P
|
Utils::Hook::Set<char>(0x50597F, limit); // No idea
|
||||||
Utils::Hook::Set<char>(0x5815DB, limit); // No idea :P
|
Utils::Hook::Set<char>(0x5815DB, limit); // No idea
|
||||||
Utils::Hook::Set<char>(0x592ED0, limit); // No idea :P
|
Utils::Hook::Set<char>(0x592ED0, limit); // No idea
|
||||||
Utils::Hook::Set<char>(0x5A2E2E, limit); // No idea :P
|
Utils::Hook::Set<char>(0x5A2E2E, limit); // No idea
|
||||||
|
|
||||||
Utils::Hook::Set<char>(0x5A2733, static_cast<char>(ColorIndexForChar(limit))); // No idea :P
|
Utils::Hook::Set<char>(0x5A2733, static_cast<char>(ColorIndexForChar(limit))); // No idea
|
||||||
}
|
}
|
||||||
|
|
||||||
// Patches team overhead normally
|
// Patches team overhead normally
|
||||||
@ -1573,8 +1589,8 @@ namespace Components
|
|||||||
{
|
{
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
push[esp + 8h]
|
push [esp + 8h]
|
||||||
push[esp + 8h]
|
push [esp + 8h]
|
||||||
call TextRenderer::Dvar_GetUnpackedColorByName
|
call TextRenderer::Dvar_GetUnpackedColorByName
|
||||||
add esp, 8h
|
add esp, 8h
|
||||||
|
|
||||||
@ -1654,7 +1670,7 @@ namespace Components
|
|||||||
fontIconLookup.emplace(std::make_pair(entry.iconName, entry));
|
fontIconLookup.emplace(std::make_pair(entry.iconName, entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(fontIconList.begin(), fontIconList.end(), [](const FontIconTableEntry& a, const FontIconTableEntry& b)
|
std::ranges::sort(fontIconList, [](const FontIconTableEntry& a, const FontIconTableEntry& b) -> bool
|
||||||
{
|
{
|
||||||
return a.iconName < b.iconName;
|
return a.iconName < b.iconName;
|
||||||
});
|
});
|
||||||
|
@ -3407,10 +3407,10 @@ namespace Components
|
|||||||
constexpr auto fileCountMultiplier = 8;
|
constexpr auto fileCountMultiplier = 8;
|
||||||
constexpr auto maxFileCount = 8191 * fileCountMultiplier;
|
constexpr auto maxFileCount = 8191 * fileCountMultiplier;
|
||||||
|
|
||||||
int RelocateFileCount(std::uint32_t dwSize, int unk1, int unk2, int unk3)
|
Game::HunkUser* Hunk_UserCreate_Stub(int maxSize, const char* name, bool fixed, int type)
|
||||||
{
|
{
|
||||||
dwSize *= fileCountMultiplier;
|
maxSize *= fileCountMultiplier;
|
||||||
return Utils::Hook::Call<int(std::uint32_t, int, int, int)>(0x430E90)(dwSize, unk1, unk2, unk3);
|
return Utils::Hook::Call<Game::HunkUser*(int, const char*, bool, int)>(0x430E90)(maxSize, name, fixed, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Zones::LoadMaterialAsset(Game::Material** asset)
|
void Zones::LoadMaterialAsset(Game::Material** asset)
|
||||||
@ -3554,8 +3554,8 @@ namespace Components
|
|||||||
Utils::Hook::Set<std::uint32_t>(0x64AF78, maxFileCount);
|
Utils::Hook::Set<std::uint32_t>(0x64AF78, maxFileCount);
|
||||||
Utils::Hook::Set<std::uint32_t>(0x64B04F, maxFileCount);
|
Utils::Hook::Set<std::uint32_t>(0x64B04F, maxFileCount);
|
||||||
Utils::Hook::Set<std::uint32_t>(0x45A8CE, maxFileCount);
|
Utils::Hook::Set<std::uint32_t>(0x45A8CE, maxFileCount);
|
||||||
Utils::Hook(0x45A806, RelocateFileCount, HOOK_CALL).install()->quick();
|
Utils::Hook(0x45A806, Hunk_UserCreate_Stub, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x45A6A0, RelocateFileCount, HOOK_CALL).install()->quick();
|
Utils::Hook(0x45A6A0, Hunk_UserCreate_Stub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
// Ignore missing soundaliases for now
|
// Ignore missing soundaliases for now
|
||||||
@ -3662,4 +3662,4 @@ namespace Components
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma optimize( "", on )
|
#pragma optimize( "", on )
|
||||||
|
@ -4,7 +4,6 @@ namespace Main
|
|||||||
{
|
{
|
||||||
void Initialize()
|
void Initialize()
|
||||||
{
|
{
|
||||||
Utils::SetEnvironment();
|
|
||||||
Utils::Cryptography::Initialize();
|
Utils::Cryptography::Initialize();
|
||||||
Components::Loader::Initialize();
|
Components::Loader::Initialize();
|
||||||
|
|
||||||
@ -70,6 +69,7 @@ BOOL APIENTRY DllMain(HINSTANCE /*hinstDLL*/, DWORD fdwReason, LPVOID /*lpvReser
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Utils::SetEnvironment();
|
||||||
Steam::Proxy::RunMod();
|
Steam::Proxy::RunMod();
|
||||||
// Install entry point hook
|
// Install entry point hook
|
||||||
Utils::Hook(0x6BAC0F, Main::EntryPoint, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x6BAC0F, Main::EntryPoint, HOOK_JUMP).install()->quick();
|
||||||
|
@ -25,10 +25,12 @@ namespace Game
|
|||||||
Cmd_AddCommand_t Cmd_AddCommand = Cmd_AddCommand_t(0x470090);
|
Cmd_AddCommand_t Cmd_AddCommand = Cmd_AddCommand_t(0x470090);
|
||||||
Cmd_AddServerCommand_t Cmd_AddServerCommand = Cmd_AddServerCommand_t(0x4DCE00);
|
Cmd_AddServerCommand_t Cmd_AddServerCommand = Cmd_AddServerCommand_t(0x4DCE00);
|
||||||
Cmd_ExecuteSingleCommand_t Cmd_ExecuteSingleCommand = Cmd_ExecuteSingleCommand_t(0x609540);
|
Cmd_ExecuteSingleCommand_t Cmd_ExecuteSingleCommand = Cmd_ExecuteSingleCommand_t(0x609540);
|
||||||
|
Cmd_ForEach_t Cmd_ForEach = Cmd_ForEach_t(0x45D680);
|
||||||
|
|
||||||
Con_DrawMiniConsole_t Con_DrawMiniConsole = Con_DrawMiniConsole_t(0x464F30);
|
Con_DrawMiniConsole_t Con_DrawMiniConsole = Con_DrawMiniConsole_t(0x464F30);
|
||||||
Con_DrawSolidConsole_t Con_DrawSolidConsole = Con_DrawSolidConsole_t(0x5A5040);
|
Con_DrawSolidConsole_t Con_DrawSolidConsole = Con_DrawSolidConsole_t(0x5A5040);
|
||||||
Con_CancelAutoComplete_t Con_CancelAutoComplete = Con_CancelAutoComplete_t(0x435580);
|
Con_CancelAutoComplete_t Con_CancelAutoComplete = Con_CancelAutoComplete_t(0x435580);
|
||||||
|
Con_IsDvarCommand_t Con_IsDvarCommand = Con_IsDvarCommand_t(0x5A3FF0);
|
||||||
|
|
||||||
DB_AllocStreamPos_t DB_AllocStreamPos = DB_AllocStreamPos_t(0x418380);
|
DB_AllocStreamPos_t DB_AllocStreamPos = DB_AllocStreamPos_t(0x418380);
|
||||||
DB_PushStreamPos_t DB_PushStreamPos = DB_PushStreamPos_t(0x458A20);
|
DB_PushStreamPos_t DB_PushStreamPos = DB_PushStreamPos_t(0x458A20);
|
||||||
|
@ -60,7 +60,10 @@ namespace Game
|
|||||||
typedef void(*Cmd_ExecuteSingleCommand_t)(int localClientNum, int controllerIndex, const char* cmd);
|
typedef void(*Cmd_ExecuteSingleCommand_t)(int localClientNum, int controllerIndex, const char* cmd);
|
||||||
extern Cmd_ExecuteSingleCommand_t Cmd_ExecuteSingleCommand;
|
extern Cmd_ExecuteSingleCommand_t Cmd_ExecuteSingleCommand;
|
||||||
|
|
||||||
typedef char* (*Con_DrawMiniConsole_t)(int localClientNum, int xPos, int yPos, float alpha);
|
typedef void(*Cmd_ForEach_t)(void(*callback)(const char* str));
|
||||||
|
extern Cmd_ForEach_t Cmd_ForEach;
|
||||||
|
|
||||||
|
typedef char*(*Con_DrawMiniConsole_t)(int localClientNum, int xPos, int yPos, float alpha);
|
||||||
extern Con_DrawMiniConsole_t Con_DrawMiniConsole;
|
extern Con_DrawMiniConsole_t Con_DrawMiniConsole;
|
||||||
|
|
||||||
typedef void (*Con_DrawSolidConsole_t)();
|
typedef void (*Con_DrawSolidConsole_t)();
|
||||||
@ -69,6 +72,9 @@ namespace Game
|
|||||||
typedef bool(*Con_CancelAutoComplete_t)();
|
typedef bool(*Con_CancelAutoComplete_t)();
|
||||||
extern Con_CancelAutoComplete_t Con_CancelAutoComplete;
|
extern Con_CancelAutoComplete_t Con_CancelAutoComplete;
|
||||||
|
|
||||||
|
typedef bool(*Con_IsDvarCommand_t)(const char* cmd);
|
||||||
|
extern Con_IsDvarCommand_t Con_IsDvarCommand;
|
||||||
|
|
||||||
typedef bool(*Encode_Init_t)(const char* );
|
typedef bool(*Encode_Init_t)(const char* );
|
||||||
extern Encode_Init_t Encode_Init;
|
extern Encode_Init_t Encode_Init;
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ namespace Steam
|
|||||||
|
|
||||||
if (this->getMethodData(*vftbl, &name, ¶ms) && name == method)
|
if (this->getMethodData(*vftbl, &name, ¶ms) && name == method)
|
||||||
{
|
{
|
||||||
return{ vftbl->data, params };
|
return { vftbl->data, params };
|
||||||
}
|
}
|
||||||
|
|
||||||
++vftbl;
|
++vftbl;
|
||||||
@ -164,7 +164,7 @@ namespace Steam
|
|||||||
clientUtils.invoke<void>("SetAppIDForCurrentPipe", Proxy::AppId, false);
|
clientUtils.invoke<void>("SetAppIDForCurrentPipe", Proxy::AppId, false);
|
||||||
|
|
||||||
char ourPath[MAX_PATH]{};
|
char ourPath[MAX_PATH]{};
|
||||||
GetModuleFileNameA(GetModuleHandle(nullptr), ourPath, sizeof(ourPath));
|
GetModuleFileNameA(GetModuleHandleA(nullptr), ourPath, sizeof(ourPath));
|
||||||
|
|
||||||
char ourDirectory[MAX_PATH]{};
|
char ourDirectory[MAX_PATH]{};
|
||||||
GetCurrentDirectoryA(sizeof(ourDirectory), ourDirectory);
|
GetCurrentDirectoryA(sizeof(ourDirectory), ourDirectory);
|
||||||
|
@ -19,13 +19,13 @@ namespace Utils
|
|||||||
std::string Rand::GenerateChallenge()
|
std::string Rand::GenerateChallenge()
|
||||||
{
|
{
|
||||||
char buffer[512]{};
|
char buffer[512]{};
|
||||||
int buffer_pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
buffer_pos += sprintf_s(&buffer[buffer_pos], sizeof(buffer) - buffer_pos, "%X", GenerateInt());
|
pos += sprintf_s(&buffer[pos], sizeof(buffer) - pos, "%X", GenerateInt());
|
||||||
buffer_pos += sprintf_s(&buffer[buffer_pos], sizeof(buffer) - buffer_pos, "%X", ~timeGetTime() ^ GenerateInt());
|
pos += sprintf_s(&buffer[pos], sizeof(buffer) - pos, "%X", ~timeGetTime() ^ GenerateInt());
|
||||||
buffer_pos += sprintf_s(&buffer[buffer_pos], sizeof(buffer) - buffer_pos, "%X", GenerateInt());
|
pos += sprintf_s(&buffer[pos], sizeof(buffer) - pos, "%X", GenerateInt());
|
||||||
|
|
||||||
return std::string(buffer, static_cast<std::size_t>(buffer_pos));
|
return std::string(buffer, static_cast<std::size_t>(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint32_t Rand::GenerateInt()
|
std::uint32_t Rand::GenerateInt()
|
||||||
|
Loading…
Reference in New Issue
Block a user