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

@ -231,8 +231,14 @@ public:
void collectArgs () {
m_args.clear ();
for (int i = 0; i < engfuncs.pfnCmd_Argc (); ++i) {
m_args.emplace (String (engfuncs.pfnCmd_Argv (i)).lowercase ());
for (auto i = 0; i < engfuncs.pfnCmd_Argc (); ++i) {
String arg = engfuncs.pfnCmd_Argv (i);
// only make case-insensetive command itself and first argument
if (i < 2) {
arg = arg.lowercase ();
}
m_args.emplace (arg);
}
}

View file

@ -316,27 +316,27 @@ public:
}
// gets edict pointer out of entity index
edict_t *entityOfIndex (const int index) {
CR_FORCE_INLINE edict_t *entityOfIndex (const int index) {
return static_cast <edict_t *> (m_startEntity + index);
};
// gets edict pointer out of entity index (player)
edict_t *playerOfIndex (const int index) {
CR_FORCE_INLINE edict_t *playerOfIndex (const int index) {
return entityOfIndex (index) + 1;
};
// gets edict index out of it's pointer
int indexOfEntity (const edict_t *ent) {
CR_FORCE_INLINE int indexOfEntity (const edict_t *ent) {
return static_cast <int> (ent - m_startEntity);
};
// gets edict index of it's pointer (player)
int indexOfPlayer (const edict_t *ent) {
CR_FORCE_INLINE int indexOfPlayer (const edict_t *ent) {
return indexOfEntity (ent) - 1;
}
// verify entity isn't null
bool isNullEntity (const edict_t *ent) {
CR_FORCE_INLINE bool isNullEntity (const edict_t *ent) {
return !ent || !indexOfEntity (ent) || ent->free;
}

View file

@ -82,6 +82,7 @@ private:
private:
CountdownTimer m_recalcTime {};
PingBitMsg m_pbm {};
public:
explicit BotFakePingManager () = default;

View file

@ -189,11 +189,12 @@ public:
SmallArray <Path> m_paths {};
HashMap <int32_t, Array <int32_t>, EmptyHash <int32_t>> m_hashTable {};
String m_graphAuthor {};
String m_graphModified {};
ExtenHeader m_extenHeader {};
StorageHeader m_graphHeader {};
struct GraphInfo {
String author {};
String modified {};
ExtenHeader exten {};
StorageHeader header {};
} m_info {};
edict_t *m_editor {};
@ -270,11 +271,11 @@ public:
public:
StringRef getAuthor () const {
return m_graphAuthor;
return m_info.author;
}
StringRef getModifiedBy () const {
return m_graphModified;
return m_info.modified;
}
bool hasChanged () const {
@ -339,12 +340,12 @@ public:
// set exten header from binary storage
void setExtenHeader (ExtenHeader *hdr) {
memcpy (&m_extenHeader, hdr, sizeof (ExtenHeader));
memcpy (&m_info.exten, hdr, sizeof (ExtenHeader));
}
// set graph header from binary storage
void setGraphHeader (StorageHeader *hdr) {
memcpy (&m_graphHeader, hdr, sizeof (StorageHeader));
memcpy (&m_info.header, hdr, sizeof (StorageHeader));
}
// gets the node numbers

View file

@ -105,13 +105,13 @@ public:
}
public:
static int32_t CR_STDCALL sendTo (int socket, const void *message, size_t length, int flags, const struct sockaddr *dest, int destLength);
CR_FORCE_STACK_ALIGN static int32_t CR_STDCALL sendTo (int socket, const void *message, size_t length, int flags, const struct sockaddr *dest, int destLength);
};
// used for transit calls between game dll and engine without all needed functions on bot side
class DynamicLinkerHook : public Singleton <DynamicLinkerHook> {
private:
#if defined (CR_WINDOWS)
#if defined(CR_WINDOWS)
# define DLSYM_FUNCTION GetProcAddress
# define DLCLOSE_FUNCTION FreeLibrary
#else
@ -177,11 +177,11 @@ public:
}
public:
static SharedLibrary::Func CR_STDCALL lookupHandler (SharedLibrary::Handle module, const char *function) {
CR_FORCE_STACK_ALIGN static SharedLibrary::Func CR_STDCALL lookupHandler (SharedLibrary::Handle module, const char *function) {
return instance ().lookup (module, function);
}
static int CR_STDCALL closeHandler (SharedLibrary::Handle module) {
CR_FORCE_STACK_ALIGN static int CR_STDCALL closeHandler (SharedLibrary::Handle module) {
return instance ().close (module);
}
};

View file

@ -117,7 +117,7 @@ public:
void notifyBombDefuse ();
void execGameEntity (edict_t *ent);
void forEach (ForEachBot handler);
void erase (Bot *bot);
void disconnectBot (Bot *bot);
void handleDeath (edict_t *killer, edict_t *victim);
void setLastWinner (int winner);
void checkBotModel (edict_t *ent, char *infobuffer);

View file

@ -115,6 +115,9 @@ public:
void load ();
void save ();
private:
void syncLoad ();
public:
template <typename U = int32_t> U getHighestDamageForTeam (int32_t team) const {
return static_cast <U> (cr::max (1, m_teamHighestDamage[team]));

View file

@ -15,58 +15,59 @@
#include VERSION_HEADER
// compile time build string
#define CTS_BUILD_STR static inline constexpr StringRef
// simple class for bot internal information
class Product final : public Singleton <Product> {
static constexpr class Product final {
public:
explicit constexpr Product () = default;
~Product () = default;
public:
struct Build {
static constexpr StringRef hash { MODULE_COMMIT_COUNT };
static constexpr StringRef count { MODULE_COMMIT_HASH };
static constexpr StringRef author { MODULE_AUTHOR };
static constexpr StringRef machine { MODULE_MACHINE };
static constexpr StringRef compiler { MODULE_COMPILER };
static constexpr StringRef id { MODULE_BUILD_ID };
} build {};
static constexpr struct BuildInfo {
CTS_BUILD_STR hash { MODULE_COMMIT_HASH };
CTS_BUILD_STR count { MODULE_COMMIT_COUNT };
CTS_BUILD_STR author { MODULE_AUTHOR };
CTS_BUILD_STR machine { MODULE_MACHINE };
CTS_BUILD_STR compiler { MODULE_COMPILER };
CTS_BUILD_STR id { MODULE_BUILD_ID };
} bi {};
public:
static constexpr StringRef name { "YaPB" };
static constexpr StringRef nameLower { "yapb" };
static constexpr StringRef year { &__DATE__[7] };
static constexpr StringRef author { "YaPB Project" };
static constexpr StringRef email { "yapb@jeefo.net" };
static constexpr StringRef url { "https://yapb.jeefo.net/" };
static constexpr StringRef download { "yapb.jeefo.net" };
static constexpr StringRef upload { "yapb.jeefo.net/upload" };
static constexpr StringRef httpScheme { "http" };
static constexpr StringRef logtag { "YB" };
static constexpr StringRef dtime { __DATE__ " " __TIME__ };
static constexpr StringRef date { __DATE__ };
static constexpr StringRef version { MODULE_VERSION "." MODULE_COMMIT_COUNT };
static constexpr StringRef cmdPri { "yb" };
static constexpr StringRef cmdSec { "yapb" };
};
CTS_BUILD_STR name { "YaPB" };
CTS_BUILD_STR nameLower { "yapb" };
CTS_BUILD_STR year { &__DATE__[7] };
CTS_BUILD_STR author { "YaPB Project" };
CTS_BUILD_STR email { "yapb@jeefo.net" };
CTS_BUILD_STR url { "https://yapb.jeefo.net/" };
CTS_BUILD_STR download { "yapb.jeefo.net" };
CTS_BUILD_STR upload { "yapb.jeefo.net/upload" };
CTS_BUILD_STR httpScheme { "http" };
CTS_BUILD_STR logtag { "YB" };
CTS_BUILD_STR dtime { __DATE__ " " __TIME__ };
CTS_BUILD_STR date { __DATE__ };
CTS_BUILD_STR version { MODULE_VERSION "." MODULE_COMMIT_COUNT };
CTS_BUILD_STR cmdPri { "yb" };
CTS_BUILD_STR cmdSec { "yapb" };
} product {};
class Folders final : public Singleton <Folders> {
static constexpr class Folders final {
public:
explicit constexpr Folders () = default;
~Folders () = default;
public:
static constexpr StringRef bot { "yapb" };
static constexpr StringRef addons { "addons" };
static constexpr StringRef config { "conf" };
static constexpr StringRef data { "data" };
static constexpr StringRef lang { "lang" };
static constexpr StringRef logs { "logs" };
static constexpr StringRef train { "train" };
static constexpr StringRef graph { "graph" };
static constexpr StringRef podbot { "pwf" };
static constexpr StringRef ebot { "ewp" };
};
CTS_BUILD_STR bot { "yapb" };
CTS_BUILD_STR addons { "addons" };
CTS_BUILD_STR config { "conf" };
CTS_BUILD_STR data { "data" };
CTS_BUILD_STR lang { "lang" };
CTS_BUILD_STR logs { "logs" };
CTS_BUILD_STR train { "train" };
CTS_BUILD_STR graph { "graph" };
CTS_BUILD_STR podbot { "pwf" };
CTS_BUILD_STR ebot { "ewp" };
} folders {};
// expose product info
CR_EXPOSE_GLOBAL_SINGLETON (Product, product);
CR_EXPOSE_GLOBAL_SINGLETON (Folders, folders);
#undef CTS_BUILD_STR

View file

@ -103,7 +103,7 @@ public:
}
};
#if !defined (BOT_STORAGE_EXPLICIT_INSTANTIATIONS)
#if !defined(BOT_STORAGE_EXPLICIT_INSTANTIATIONS)
# define BOT_STORAGE_EXPLICIT_INSTANTIATIONS
# include "../src/storage.cpp"
#endif

View file

@ -80,7 +80,7 @@ public:
StringRef getFakeSteamId (edict_t *ent);
// get's the wave length
float getWaveLength (StringRef filename);
float getWaveFileDuration (StringRef filename);
// set custom cvar descriptions
void setCustomCvarDescriptions ();

View file

@ -10,7 +10,7 @@
// fallback if no git or custom build
#define MODULE_COMMIT_COUNT "0"
#define MODULE_COMMIT_HASH "0"
#define MODULE_AUTHOR "default@mail.net"
#define MODULE_AUTHOR "yapb-local@jeefo.net"
#define MODULE_MACHINE "localhost"
#define MODULE_COMPILER "default"
#define MODULE_VERSION "4.5"

View file

@ -617,7 +617,7 @@ public:
float m_preventFlashing {}; // bot turned away from flashbang
float m_blindTime {}; // time when bot is blinded
float m_blindMoveSpeed {}; // mad speeds when bot is blind
float m_blindSidemoveSpeed {}; // mad side move speeds when bot is blind
float m_blindSideMoveSpeed {}; // mad side move speeds when bot is blind
float m_fallDownTime {}; // time bot started to fall
float m_duckForJump {}; // is bot needed to duck for double jump
float m_baseAgressionLevel {}; // base aggression level (on initializing)
@ -720,11 +720,7 @@ public:
public:
Bot (edict_t *bot, int difficulty, int personality, int team, int skin);
// need to wait until all threads will finish it's work before terminating bot object
~Bot () {
MutexScopedLock lock1 (m_pathFindLock);
}
~Bot () = default;
public:
void logic (); /// the things that can be executed while skipping frames