fix: crash with hl25 structs on xash3d again

fix: %t placeholder should return damage inflictor when used in team attack section of chat
fix: all arguments in bot commands are lowercased (resolves #680)
bot: disable threads when engine's timescale is active
bot: a little refactor for the code all over the places
linkage: resolved crash due to sse alignment on ancient engines (resolves #614)
utils move wave parse into crlib
practice: move loading practice to thread pool
build: allow to build with static linkents instead of hooking dlsym

Co-Authored-By: Max <161382234+dyspose@users.noreply.github.com>
This commit is contained in:
jeefo 2025-03-16 18:25:15 +03:00
commit 38c45aff9a
No known key found for this signature in database
GPG key ID: D696786B81B667C8
37 changed files with 348 additions and 304 deletions

View file

@ -436,81 +436,42 @@ StringRef BotSupport::weaponIdToAlias (int32_t id) {
return none;
}
// helper class for reading wave header
class WaveEndianessHelper final : public NonCopyable {
private:
#if defined (CR_ARCH_CPU_BIG_ENDIAN)
bool little { false };
#else
bool little { true };
#endif
float BotSupport::getWaveFileDuration (StringRef filename) {
constexpr auto kZeroLength = 0.0f;
public:
uint16_t read16 (uint16_t value) {
return little ? value : static_cast <uint16_t> ((value >> 8) | (value << 8));
}
uint32_t read32 (uint32_t value) {
return little ? value : (((value & 0x000000ff) << 24) | ((value & 0x0000ff00) << 8) | ((value & 0x00ff0000) >> 8) | ((value & 0xff000000) >> 24));
}
bool isWave (char *format) const {
if (little && memcmp (format, "WAVE", 4) == 0) {
return true;
}
return *reinterpret_cast <uint32_t *> (format) == 0x57415645;
}
};
float BotSupport::getWaveLength (StringRef filename) {
using WaveHeader = WaveHelper <>::Header;
auto filePath = strings.joinPath (cv_chatter_path.as <StringRef> (), strings.format ("%s.wav", filename));
MemFile fp (filePath);
// we're got valid handle?
if (!fp) {
return 0.0f;
return kZeroLength;
}
// else fuck with manual search
struct WavHeader {
char riff[4];
uint32_t chunkSize;
char wave[4];
char fmt[4];
uint32_t subchunk1Size;
uint16_t audioFormat;
uint16_t numChannels;
uint32_t sampleRate;
uint32_t byteRate;
uint16_t blockAlign;
uint16_t bitsPerSample;
char dataChunkId[4];
uint32_t dataChunkLength;
} header {};
WaveHeader hdr {};
static WaveHelper wh {};
static WaveEndianessHelper weh {};
if (fp.read (&header, sizeof (WavHeader)) == 0) {
logger.error ("Wave File %s - has wrong or unsupported format", filePath);
return 0.0f;
if (fp.read (&hdr, sizeof (WaveHeader)) == 0) {
logger.error ("WAVE %s - has wrong or unsupported format.", filePath);
return kZeroLength;
}
fp.close ();
if (!weh.isWave (header.wave)) {
logger.error ("Wave File %s - has wrong wave chunk id", filePath);
return 0.0f;
if (!wh.isWave (hdr.wave)) {
logger.error ("WAVE %s - has wrong wave chunk id.", filePath);
return kZeroLength;
}
if (weh.read32 (header.dataChunkLength) == 0) {
logger.error ("Wave File %s - has zero length!", filePath);
return 0.0f;
if (wh.read32 <uint32_t> (hdr.dataChunkLength) == 0) {
logger.error ("WAVE %s - has zero length!.", filePath);
return kZeroLength;
}
const auto length = static_cast <float> (weh.read32 (header.dataChunkLength));
const auto bps = static_cast <float> (weh.read16 (header.bitsPerSample)) / 8;
const auto channels = static_cast <float> (weh.read16 (header.numChannels));
const auto rate = static_cast <float> (weh.read32 (header.sampleRate));
const auto length = wh.read32 <float> (hdr.dataChunkLength);
const auto bps = wh.read16 <float> (hdr.bitsPerSample) / 8.0f;
const auto channels = wh.read16 <float> (hdr.numChannels);
const auto rate = wh.read32 <float> (hdr.sampleRate);
return length / bps / channels / rate;
}