From 74f1ab866b499b13f04e9049c7d558ee7cf3e014 Mon Sep 17 00:00:00 2001 From: jeefo Date: Mon, 23 Nov 2020 00:06:18 +0300 Subject: [PATCH 1/3] Fixed linux listenserver startup problems Fixed multiple buffer overruns and memory leaks. --- ext/crlib/cr-alloc.h | 93 ---------------------------------------- ext/crlib/cr-array.h | 31 +++++++------- ext/crlib/cr-basic.h | 5 ++- ext/crlib/cr-complete.h | 2 +- ext/crlib/cr-deque.h | 23 +++++----- ext/crlib/cr-detour.h | 63 ++++++++++++++------------- ext/crlib/cr-files.h | 8 ++-- ext/crlib/cr-hashmap.h | 10 +++-- ext/crlib/cr-lambda.h | 5 +-- ext/crlib/cr-library.h | 20 ++++++--- ext/crlib/cr-logger.h | 2 +- ext/crlib/cr-memory.h | 52 ++++++++++++++++++++++ ext/crlib/cr-override.h | 39 +++++++++++++++++ ext/crlib/cr-random.h | 2 +- ext/crlib/cr-string.h | 10 ++++- ext/crlib/cr-uniqueptr.h | 12 +++--- inc/control.h | 6 +-- inc/engine.h | 50 ++++++++++++++++----- inc/graph.h | 36 +++++++++++----- inc/yapb.h | 1 - src/android.cpp | 5 ++- src/botlib.cpp | 3 +- src/graph.cpp | 24 +++++------ src/linkage.cpp | 64 +++++++++++++++++++++++---- src/manager.cpp | 29 ++++++++----- src/module.cpp | 3 -- src/navigate.cpp | 10 ++--- vc/yapb.vcxproj | 8 ++-- vc/yapb.vcxproj.filters | 9 ++-- 29 files changed, 371 insertions(+), 254 deletions(-) delete mode 100644 ext/crlib/cr-alloc.h create mode 100644 ext/crlib/cr-memory.h create mode 100644 ext/crlib/cr-override.h diff --git a/ext/crlib/cr-alloc.h b/ext/crlib/cr-alloc.h deleted file mode 100644 index b3da32b..0000000 --- a/ext/crlib/cr-alloc.h +++ /dev/null @@ -1,93 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2020 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include -#include -#include - -// provide placment new to avoid stdc++ header -inline void *operator new (const size_t, void *ptr) noexcept { - return ptr; -} - -CR_NAMESPACE_BEGIN - -// default allocator for cr-objects -class Allocator : public Singleton { -public: - Allocator () = default; - ~Allocator () = default; - -public: - template T *allocate (const size_t length = 1) { - auto memory = reinterpret_cast (malloc (cr::max (1u, length * sizeof (T)))); - - if (!memory) { - plat.abort (); - } - return memory; - } - - template void deallocate (T *memory) { - free (memory); - memory = nullptr; - } - -public: - template void construct (T *memory, Args &&...args) { - new (memory) T (cr::forward (args)...); - } - - template void destruct (T *memory) { - memory->~T (); - } - -public: - template T *create (Args &&...args) { - auto memory = allocate (); - new (memory) T (cr::forward (args)...); - - return memory; - } - - template T *createArray (const size_t amount) { - auto memory = allocate (amount); - - for (size_t i = 0; i < amount; ++i) { - new (memory + i) T (); - } - return memory; - } - - - template void destroy (T *memory) { - if (memory) { - destruct (memory); - deallocate (memory); - } - } -}; - -CR_EXPOSE_GLOBAL_SINGLETON (Allocator, alloc); - -template class UniquePtr; - -// implment singleton with UniquePtr -template T &Singleton ::instance () { - static const UniquePtr instance_ { alloc.create () }; - return *instance_; -} - -// declare destructor for pure-virtual classes -#define CR_DECLARE_DESTRUCTOR() \ - void operator delete (void *ptr) { \ - alloc.deallocate (ptr); \ - } \ - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-array.h b/ext/crlib/cr-array.h index 976290e..05512ba 100644 --- a/ext/crlib/cr-array.h +++ b/ext/crlib/cr-array.h @@ -8,7 +8,7 @@ #pragma once #include -#include +#include #include #include @@ -61,20 +61,20 @@ public: private: void destructElements () noexcept { for (size_t i = 0; i < length_; ++i) { - alloc.destruct (&contents_[i]); + Memory::destruct (&contents_[i]); } } void transferElements (T *dest, T *src, size_t length) noexcept { for (size_t i = 0; i < length; ++i) { - alloc.construct (&dest[i], cr::move (src[i])); - alloc.destruct (&src[i]); + Memory::construct (&dest[i], cr::move (src[i])); + Memory::destruct (&src[i]); } } void destroy () { destructElements (); - alloc.deallocate (contents_); + Memory::release (contents_); } void reset () { @@ -83,7 +83,6 @@ private: length_ = 0; } - public: bool reserve (const size_t amount) { if (length_ + amount < capacity_) { @@ -99,11 +98,11 @@ public: else { capacity = amount + capacity_ + 1; } - auto data = alloc.allocate (capacity); + auto data = Memory::get (capacity); if (contents_) { transferElements (data, contents_, length_); - alloc.deallocate (contents_); + Memory::release (contents_); } contents_ = data; @@ -152,7 +151,7 @@ public: return false; } } - alloc.construct (&contents_[index], cr::forward (object)); + Memory::construct (&contents_[index], cr::forward (object)); if (index >= length_) { length_ = index + 1; @@ -176,7 +175,7 @@ public: if (index >= length_) { for (size_t i = 0; i < count; ++i) { - alloc.construct (&contents_[i + index], cr::forward (objects[i])); + Memory::construct (&contents_[i + index], cr::forward (objects[i])); } length_ = capacity; } @@ -187,7 +186,7 @@ public: contents_[i + count - 1] = cr::move (contents_[i - 1]); } for (i = 0; i < count; ++i) { - alloc.construct (&contents_[i + index], cr::forward (objects[i])); + Memory::construct (&contents_[i + index], cr::forward (objects[i])); } length_ += count; } @@ -206,7 +205,7 @@ public: return false; } for (size_t i = index; i < index + count; ++i) { - alloc.destruct (&contents_[i]); + Memory::destruct (&contents_[i]); } length_ -= count; @@ -232,7 +231,7 @@ public: if (!reserve (1)) { return false; } - alloc.construct (&contents_[length_], cr::forward (object)); + Memory::construct (&contents_[length_], cr::forward (object)); ++length_; return true; @@ -242,7 +241,7 @@ public: if (!reserve (1)) { return false; } - alloc.construct (&contents_[length_], cr::forward (args)...); + Memory::construct (&contents_[length_], cr::forward (args)...); ++length_; return true; @@ -310,10 +309,10 @@ public: return false; } - auto data = alloc.allocate (length_); + auto data = Memory::get (length_); transferElements (data, contents_, length_); - alloc.deallocate (contents_); + Memory::release (contents_); contents_ = data; capacity_ = length_; diff --git a/ext/crlib/cr-basic.h b/ext/crlib/cr-basic.h index 5562013..7bdb9b5 100644 --- a/ext/crlib/cr-basic.h +++ b/ext/crlib/cr-basic.h @@ -92,7 +92,10 @@ protected: { } public: - static T &instance (); // implemented in cr-alloc.h + static T &instance () { + static T __instance {}; + return __instance; + } public: T *operator -> () { diff --git a/ext/crlib/cr-complete.h b/ext/crlib/cr-complete.h index 5cfe3f5..ecea87c 100644 --- a/ext/crlib/cr-complete.h +++ b/ext/crlib/cr-complete.h @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include #include diff --git a/ext/crlib/cr-deque.h b/ext/crlib/cr-deque.h index ee92397..cd5a50a 100644 --- a/ext/crlib/cr-deque.h +++ b/ext/crlib/cr-deque.h @@ -7,8 +7,7 @@ #pragma once -#include -#include +#include #include CR_NAMESPACE_BEGIN @@ -16,8 +15,8 @@ CR_NAMESPACE_BEGIN template class Deque : private DenyCopying { private: size_t capacity_ {}; + T *contents_ {}; - UniquePtr contents_ {}; Twin index_ {}; private: @@ -56,7 +55,7 @@ private: void extendCapacity () { auto capacity = capacity_ ? capacity_ * 2 : 8; - auto contents = cr::makeUnique (sizeof (T) * capacity); + auto contents = Memory::get (sizeof (T) * capacity); if (index_.first < index_.second) { for (size_t i = 0; i < index_.second - index_.first; ++i) { @@ -76,14 +75,16 @@ private: index_.second = index_.second + (capacity_ - index_.first); index_.first = 0; } - contents_ = cr::move (contents); + Memory::release (contents_); + + contents_ = contents; capacity_ = capacity; } void destroy () { auto destruct = [&] (size_t start, size_t end) { for (size_t i = start; i < end; ++i) { - alloc.destruct (&contents_[i]); + Memory::destruct (&contents_[i]); } }; @@ -94,7 +95,7 @@ private: destruct (index_.first, capacity_); destruct (0, index_.second); } - contents_ = nullptr; + Memory::release (contents_); } void reset () { @@ -127,17 +128,17 @@ public: template void emplaceLast (Args &&...args) { auto rear = pickRearIndex (); - alloc.construct (&contents_[index_.second], cr::forward (args)...); + Memory::construct (&contents_[index_.second], cr::forward (args)...); index_.second = rear; } template void emplaceFront (Args &&...args) { index_.first = pickFrontIndex (); - alloc.construct (&contents_[index_.first], cr::forward (args)...); + Memory::construct (&contents_[index_.first], cr::forward (args)...); } void discardFront () { - alloc.destruct (&contents_[index_.first]); + Memory::destruct (&contents_[index_.first]); if (index_.first == capacity_ - 1) { index_.first = 0; @@ -154,7 +155,7 @@ public: else { index_.second--; } - alloc.destruct (&contents_[index_.second]); + Memory::destruct (&contents_[index_.second]); } T popFront () { diff --git a/ext/crlib/cr-detour.h b/ext/crlib/cr-detour.h index b7d3058..509b509 100644 --- a/ext/crlib/cr-detour.h +++ b/ext/crlib/cr-detour.h @@ -140,35 +140,10 @@ private: } public: + Detour () = default; + Detour (StringRef module, StringRef name, T *address) { - savedBytes_.resize (jmpBuffer_.length ()); - -#if !defined (CR_WINDOWS) - (void) module; - (void) name; - - auto search = reinterpret_cast (address); - - while (*reinterpret_cast (search) == 0x25ff) { - search = **reinterpret_cast (search + 2); - } - - original_ = search; - pageSize_ = static_cast (sysconf (_SC_PAGE_SIZE)); -#else - auto handle = GetModuleHandleA (module.chars ()); - - if (!handle) { - original_ = reinterpret_cast (address); - return; - } - original_ = reinterpret_cast (GetProcAddress (handle, name.chars ())); - - if (!original_) { - original_ = reinterpret_cast (address); - return; - } -#endif + initialize (module, name, address); } ~Detour () { @@ -194,7 +169,37 @@ private: }; public: - + void initialize (StringRef module, StringRef name, T *address) { + savedBytes_.resize (jmpBuffer_.length ()); + +#if !defined (CR_WINDOWS) + (void) module; + (void) name; + + auto ptr = reinterpret_cast (address); + + while (*reinterpret_cast (ptr) == 0x25ff) { + ptr = **reinterpret_cast (ptr + 2); + } + + original_ = ptr; + pageSize_ = static_cast (sysconf (_SC_PAGE_SIZE)); +#else + auto handle = GetModuleHandleA (module.chars ()); + + if (!handle) { + original_ = reinterpret_cast (address); + return; + } + original_ = reinterpret_cast (GetProcAddress (handle, name.chars ())); + + if (!original_) { + original_ = reinterpret_cast (address); + return; + } +#endif + } + void install (void *detour, const bool enable = false) { if (!original_) { return; diff --git a/ext/crlib/cr-files.h b/ext/crlib/cr-files.h index 7c1251a..88bd2a6 100644 --- a/ext/crlib/cr-files.h +++ b/ext/crlib/cr-files.h @@ -180,8 +180,8 @@ private: FreeFunction freeFun_ = nullptr; public: - inline MemFileStorage () = default; - inline ~MemFileStorage () = default; + explicit MemFileStorage () = default; + ~MemFileStorage () = default; public: void initizalize (LoadFunction loader, FreeFunction unloader) { @@ -212,14 +212,14 @@ public: return nullptr; } *size = static_cast (file.length ()); - auto data = alloc.allocate (*size); + auto data = Memory::get (*size); file.read (data, *size); return data; } static void defaultUnload (void *buffer) { - alloc.deallocate (buffer); + Memory::release (buffer); } static String loadToString (StringRef filename) { diff --git a/ext/crlib/cr-hashmap.h b/ext/crlib/cr-hashmap.h index 9622aca..fbdd467 100644 --- a/ext/crlib/cr-hashmap.h +++ b/ext/crlib/cr-hashmap.h @@ -36,11 +36,13 @@ template <> struct Hash { template <> struct Hash { uint32 operator () (int32 key) const noexcept { - key = ((key >> 16) ^ key) * 0x119de1f3; - key = ((key >> 16) ^ key) * 0x119de1f3; - key = (key >> 16) ^ key; + auto result = static_cast (key); - return key; + result = ((result >> 16) ^ result) * 0x119de1f3; + result = ((result >> 16) ^ result) * 0x119de1f3; + result = (result >> 16) ^ result; + + return result; } }; diff --git a/ext/crlib/cr-lambda.h b/ext/crlib/cr-lambda.h index a684cf2..20c858c 100644 --- a/ext/crlib/cr-lambda.h +++ b/ext/crlib/cr-lambda.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include CR_NAMESPACE_BEGIN @@ -31,9 +31,6 @@ private: virtual R invoke (Args &&...) = 0; virtual UniquePtr clone () const = 0; - - public: - CR_DECLARE_DESTRUCTOR (); }; template class LambdaFunctor : public LambdaFunctorWrapper { diff --git a/ext/crlib/cr-library.h b/ext/crlib/cr-library.h index cfaa8ad..974e97e 100644 --- a/ext/crlib/cr-library.h +++ b/ext/crlib/cr-library.h @@ -27,6 +27,7 @@ public: private: Handle handle_ = nullptr; + bool unloadable_ = true; public: explicit SharedLibrary () = default; @@ -43,22 +44,28 @@ public: } public: - bool load (StringRef file) noexcept { + bool load (StringRef file, bool unloadable = true) noexcept { if (*this) { unload (); } + unloadable_ = unloadable; #if defined (CR_WINDOWS) handle_ = LoadLibraryA (file.chars ()); -#elif defined (CR_OSX) - handle_ = dlopen (file.chars (), RTLD_NOW | RTLD_LOCAL); #else - handle_ = dlopen (file.chars (), RTLD_NOW | RTLD_DEEPBIND | RTLD_LOCAL); + auto loadFlags = RTLD_NOW | RTLD_LOCAL; + +#if defined (CR_LINUX) && !defined (__SANITIZE_ADDRESS__) + loadFlags |= RTLD_DEEPBIND; +#endif + handle_ = dlopen (file.chars (), loadFlags); #endif return handle_ != nullptr; } bool locate (Handle address) { + unloadable_ = false; + #if defined (CR_WINDOWS) MEMORY_BASIC_INFORMATION mbi; @@ -75,16 +82,17 @@ public: plat.bzero (&dli, sizeof (dli)); if (dladdr (address, &dli)) { - return load (dli.dli_fname); + return load (dli.dli_fname, false); } #endif return handle_ != nullptr; } void unload () noexcept { - if (!*this) { + if (!handle_ || !unloadable_) { return; } + #if defined (CR_WINDOWS) FreeLibrary (static_cast (handle_)); #else diff --git a/ext/crlib/cr-logger.h b/ext/crlib/cr-logger.h index d320e8f..ae52672 100644 --- a/ext/crlib/cr-logger.h +++ b/ext/crlib/cr-logger.h @@ -23,7 +23,7 @@ private: PrintFunction printFun_; public: - SimpleLogger () = default; + explicit SimpleLogger () = default; ~SimpleLogger () = default; public: diff --git a/ext/crlib/cr-memory.h b/ext/crlib/cr-memory.h new file mode 100644 index 0000000..1571fd3 --- /dev/null +++ b/ext/crlib/cr-memory.h @@ -0,0 +1,52 @@ +// +// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. +// Copyright © 2004-2020 YaPB Project . +// +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include +#include +#include + +// provide placment new to avoid stdc++ header +inline void *operator new (const size_t, void *ptr) noexcept { + return ptr; +} + +CR_NAMESPACE_BEGIN + +// internal memory manager +class Memory final { +public: + Memory () = default; + ~Memory () = default; + +public: + template static T *get (const size_t length = 1) { + auto memory = reinterpret_cast (malloc (cr::max (1u, length * sizeof (T)))); + + if (!memory) { + plat.abort (); + } + return memory; + } + + template static void release (T *memory) { + free (memory); + memory = nullptr; + } + +public: + template static void construct (T *memory, Args &&...args) { + new (memory) T (cr::forward (args)...); + } + + template static void destruct (T *memory) { + memory->~T (); + } +}; + +CR_NAMESPACE_END diff --git a/ext/crlib/cr-override.h b/ext/crlib/cr-override.h new file mode 100644 index 0000000..ace571d --- /dev/null +++ b/ext/crlib/cr-override.h @@ -0,0 +1,39 @@ +// +// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. +// Copyright © 2004-2020 YaPB Project . +// +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include +#include + +void *operator new (size_t size) noexcept { + return cr::Memory::get (size); +} + +void *operator new [] (size_t size) noexcept { + return cr::Memory::get (size); +} + +void operator delete (void *ptr) noexcept { + cr::Memory::release (ptr); +} + +void operator delete [] (void *ptr) noexcept { + cr::Memory::release (ptr); +} + +void operator delete (void *ptr, size_t) noexcept { + cr::Memory::release (ptr); +} + +void operator delete [] (void *ptr, size_t) noexcept { + cr::Memory::release (ptr); +} + +CR_LINKAGE_C void __cxa_pure_virtual () { + cr::plat.abort ("pure virtual function call"); +} \ No newline at end of file diff --git a/ext/crlib/cr-random.h b/ext/crlib/cr-random.h index 2f20232..97fad28 100644 --- a/ext/crlib/cr-random.h +++ b/ext/crlib/cr-random.h @@ -18,7 +18,7 @@ private: uint64 state_ { static_cast (time (nullptr)) }; public: - Random () = default; + explicit Random () = default; ~Random () = default; private: diff --git a/ext/crlib/cr-string.h b/ext/crlib/cr-string.h index 48cec3c..5b753e3 100644 --- a/ext/crlib/cr-string.h +++ b/ext/crlib/cr-string.h @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include @@ -420,7 +420,13 @@ public: length = calcLength (str, length); resize (length); - memcpy (&chars_[0], str, length); + + if (str) { + memcpy (&chars_[0], str, length); + } + else { + chars_[0] = kNullChar; + } length_ = length; chars_[length_] = kNullChar; diff --git a/ext/crlib/cr-uniqueptr.h b/ext/crlib/cr-uniqueptr.h index 0d46ae4..c998834 100644 --- a/ext/crlib/cr-uniqueptr.h +++ b/ext/crlib/cr-uniqueptr.h @@ -8,7 +8,7 @@ #pragma once #include -#include +#include #include CR_NAMESPACE_BEGIN @@ -53,7 +53,7 @@ public: private: void destroy () { - alloc.destroy (ptr_); + delete ptr_; ptr_ = nullptr; } @@ -129,7 +129,7 @@ public: private: void destroy () { - alloc.destroy (ptr_); + delete[] ptr_; ptr_ = nullptr; } @@ -156,6 +156,7 @@ public: T &operator [] (size_t index) { return ptr_[index]; } + const T &operator [] (size_t index) const { return ptr_[index]; } @@ -192,11 +193,12 @@ namespace detail { } template typename detail::UniqueIf ::SingleObject makeUnique (Args &&... args) { - return UniquePtr (alloc.create (cr::forward (args)...)); + return UniquePtr (new T (cr::forward (args)...)); } template typename detail::UniqueIf ::UnknownBound makeUnique (size_t size) { - return UniquePtr (alloc.createArray ::Type> (size)); + using Type = typename detail::ClearExtent ::Type; + return UniquePtr (new Type[size] ()); } template typename detail::UniqueIf ::KnownBound makeUnique (Args &&...) = delete; diff --git a/inc/control.h b/inc/control.h index 5b67b9b..88cb00a 100644 --- a/inc/control.h +++ b/inc/control.h @@ -33,7 +33,7 @@ public: Handler handler = nullptr; public: - BotCmd () = default; + explicit BotCmd () = default; BotCmd (StringRef name, StringRef format, StringRef help, Handler handler) : name (name), format (format), help (help), handler (cr::move (handler)) { } @@ -46,7 +46,7 @@ public: MenuHandler handler; public: - BotMenu (int ident, int slots, StringRef text, MenuHandler handler) : ident (ident), slots (slots), text (text), handler (cr::move (handler)) + explicit BotMenu (int ident, int slots, StringRef text, MenuHandler handler) : ident (ident), slots (slots), text (text), handler (cr::move (handler)) { } }; @@ -56,7 +56,7 @@ public: String text; public: - PrintQueue () = default; + explicit PrintQueue () = default; PrintQueue (int32 destination, StringRef text) : destination (destination), text (text) { } diff --git a/inc/engine.h b/inc/engine.h index fd1f52d..2254e3a 100644 --- a/inc/engine.h +++ b/inc/engine.h @@ -642,26 +642,29 @@ public: class EntityLinkage : public Singleton { private: #if defined (CR_WINDOWS) -# define DETOUR_FUNCTION GetProcAddress -# define DETOUR_RETURN FARPROC -# define DETOUR_HANDLE HMODULE +# define DLSYM_FUNCTION GetProcAddress +# define DLSYM_RETURN FARPROC +# define DLSYM_HANDLE HMODULE #else -# define DETOUR_FUNCTION dlsym -# define DETOUR_RETURN SharedLibrary::Handle -# define DETOUR_HANDLE SharedLibrary::Handle +# define DLSYM_FUNCTION dlsym +# define DLSYM_RETURN SharedLibrary::Handle +# define DLSYM_HANDLE SharedLibrary::Handle #endif private: + bool m_paused { false }; + + Detour m_dlsym; + HashMap m_exports; + SharedLibrary m_self; - Detour m_dlsym { "kernel32.dll", "GetProcAddress", DETOUR_FUNCTION }; - HashMap m_exports; public: EntityLinkage () = default; public: void initialize (); - DETOUR_RETURN lookup (SharedLibrary::Handle module, const char *function); + DLSYM_RETURN lookup (SharedLibrary::Handle module, const char *function); public: void callPlayerFunction (edict_t *ent) { @@ -673,7 +676,30 @@ public: } public: - static DETOUR_RETURN CR_STDCALL replacement (SharedLibrary::Handle module, const char *function) { + void enable () { + if (m_dlsym.detoured ()) { + return; + } + m_dlsym.detour (); + } + + void disable () { + if (!m_dlsym.detoured ()) { + return; + } + m_dlsym.restore (); + } + + void setPaused (bool what) { + m_paused = what; + } + + bool isPaused () const { + return m_paused; + } + +public: + static DLSYM_RETURN CR_STDCALL replacement (SharedLibrary::Handle module, const char *function) { return EntityLinkage::instance ().lookup (module, function); } @@ -681,6 +707,10 @@ public: void clearExportTable () { m_exports.clear (); } + + bool isWorkaroundNeeded () { + return !plat.win32 && !Game::instance ().isDedicated (); + } }; // expose globals diff --git a/inc/graph.h b/inc/graph.h index cb34ce3..97078d5 100644 --- a/inc/graph.h +++ b/inc/graph.h @@ -177,7 +177,9 @@ struct PODPath { class PathWalk final : public DenyCopying { private: size_t m_cursor = 0; - Array m_storage; + size_t m_length = 0; + + UniquePtr m_path; public: explicit PathWalk () = default; @@ -193,11 +195,11 @@ public: } int32 &last () { - return m_storage.last (); + return at (length () - 1); } int32 &at (size_t index) { - return m_storage.at (m_cursor + index); + return m_path[m_cursor + index]; } void shift () { @@ -205,31 +207,39 @@ public: } void reverse () { - m_storage.reverse (); + for (size_t i = 0; i < m_length / 2; ++i) { + cr::swap (m_path[i], m_path[m_length - 1 - i]); + } } size_t length () const { - if (m_cursor > m_storage.length ()) { + if (m_cursor >= m_length) { return 0; } - return m_storage.length () - m_cursor; + return m_length - m_cursor; } bool hasNext () const { - return m_cursor < m_storage.length (); + return length () > m_cursor; } bool empty () const { return !length (); } - void push (int node) { - m_storage.push (node); + void add (int32 node) { + m_path[m_length++] = node; } void clear () { m_cursor = 0; - m_storage.clear (); + m_length = 0; + + m_path[0] = 0; + } + + void init (size_t length) { + m_path = cr::makeUnique (length); } }; @@ -250,7 +260,7 @@ private: int m_lastJumpNode; int m_findWPIndex; int m_facingAtIndex; - int m_highestDamage[kGameTeamNum]; + int m_highestDamage[kGameTeamNum] {}; float m_timeJumpStarted; float m_autoPathDistance; @@ -373,6 +383,10 @@ public: const SmallArray &getNodesInBucket (const Vector &pos); public: + size_t getMaxRouteLength () const { + return m_paths.length () / 2; + } + int getHighestDamageForTeam (int team) const { return m_highestDamage[team]; } diff --git a/inc/yapb.h b/inc/yapb.h index 77569f5..228bdfb 100644 --- a/inc/yapb.h +++ b/inc/yapb.h @@ -453,7 +453,6 @@ constexpr int kMaxNodeLinks = 8; constexpr int kMaxPracticeDamageValue = 2040; constexpr int kMaxPracticeGoalValue = 2040; constexpr int kMaxNodes = 2048; -constexpr int kMaxRouteLength = kMaxNodes / 2; constexpr int kMaxWeapons = 32; constexpr int kNumWeapons = 26; constexpr int kMaxCollideMoves = 3; diff --git a/src/android.cpp b/src/android.cpp index 357cc8a..b7faea4 100644 --- a/src/android.cpp +++ b/src/android.cpp @@ -24,7 +24,7 @@ CR_EXPORT int Server_GetBlendingInterface (int version, struct sv_blending_inter return api_GetBlendingInterface (version, ppinterface, pstudio, rotationmatrix, bonetransform); } -void android_LinkEntity (EntityFunction &addr, const char *name, entvars_t *pev) { +void forwardEntity_helper (EntityFunction &addr, const char *name, entvars_t *pev) { if (!addr) { addr = game.lib ().resolve (name); } @@ -37,7 +37,7 @@ void android_LinkEntity (EntityFunction &addr, const char *name, entvars_t *pev) #define LINK_ENTITY(entityName) \ CR_EXPORT void entityName (entvars_t *pev) { \ static EntityFunction addr; \ - android_LinkEntity (addr, #entityName, pev); \ + forwardEntity_helper (addr, __FUNCTION__, pev); \ } #else #define LINK_ENTITY(entityName) @@ -142,6 +142,7 @@ LINK_ENTITY (game_team_master) LINK_ENTITY (game_team_set) LINK_ENTITY (game_text) LINK_ENTITY (game_zone_player) +LINK_ENTITY (gib) LINK_ENTITY (gibshooter) LINK_ENTITY (grenade) LINK_ENTITY (hostage_entity) diff --git a/src/botlib.cpp b/src/botlib.cpp index a860c3f..3fb0c57 100644 --- a/src/botlib.cpp +++ b/src/botlib.cpp @@ -193,7 +193,6 @@ void Bot::checkGrenadesThrow () { allowThrowing = false; continue; } - m_throw = graph[predict].origin; auto throwPos = calcThrow (getEyesPos (), m_throw); @@ -4068,7 +4067,7 @@ void Bot::followUser_ () { clearSearchNodes (); int destIndex = graph.getNearest (m_targetEntity->v.origin); - IntArray points = graph.searchRadius (200.0f, m_targetEntity->v.origin); + auto points = graph.searchRadius (200.0f, m_targetEntity->v.origin); for (auto &newIndex : points) { // if waypoint not yet used, assign it as dest diff --git a/src/graph.cpp b/src/graph.cpp index aee884c..d78a2bc 100644 --- a/src/graph.cpp +++ b/src/graph.cpp @@ -51,10 +51,10 @@ int BotGraph::clearConnections (int index) { } struct Connection { - int index; - int number; - int distance; - float angles; + int index {}; + int number {}; + int distance {}; + float angles {}; public: Connection () { @@ -514,7 +514,7 @@ IntArray BotGraph::searchRadius (float radius, const Vector &origin, int maxCoun if (bucket.empty ()) { result.push (getNearestNoBuckets (origin, radius)); - return cr::move (result); + return result; } radius = cr::square (radius); @@ -527,7 +527,7 @@ IntArray BotGraph::searchRadius (float radius, const Vector &origin, int maxCoun result.push (at); } } - return cr::move (result); + return result; } void BotGraph::add (int type, const Vector &pos) { @@ -2564,7 +2564,7 @@ bool BotGraph::checkNodes (bool teleportPlayer) { for (auto &visit : visited) { visit = false; } - walk.push (0); // always check from node number 0 + walk.add (0); // always check from node number 0 while (!walk.empty ()) { // pop a node from the stack @@ -2579,7 +2579,7 @@ bool BotGraph::checkNodes (bool teleportPlayer) { // skip this node as it's already visited if (exists (index) && !visited[index]) { visited[index] = true; - walk.push (index); + walk.add (index); } } } @@ -2612,7 +2612,7 @@ bool BotGraph::checkNodes (bool teleportPlayer) { visit = false; } walk.clear (); - walk.push (0); // always check from node number 0 + walk.add (0); // always check from node number 0 while (!walk.empty ()) { const int current = walk.first (); // pop a node from the stack @@ -2623,7 +2623,7 @@ bool BotGraph::checkNodes (bool teleportPlayer) { continue; // skip this node as it's already visited } visited[outgoing] = true; - walk.push (outgoing); + walk.add (outgoing); } } @@ -2756,7 +2756,7 @@ void BotGraph::eraseFromDisk () { // if we're delete graph, delete all corresponding to it files forErase.push (strings.format ("%spwf/%s.pwf", data, map)); // graph itself - forErase.push (strings.format ("%strain/%s.exp", data, map)); // corresponding to practice + forErase.push (strings.format ("%strain/%s.prc", data, map)); // corresponding to practice forErase.push (strings.format ("%strain/%s.vis", data, map)); // corresponding to vistable forErase.push (strings.format ("%strain/%s.pmx", data, map)); // corresponding to matrix forErase.push (strings.format ("%sgraph/%s.graph", data, map)); // new format graph @@ -2839,8 +2839,6 @@ void BotGraph::setSearchIndex (int index) { } BotGraph::BotGraph () { - plat.bzero (m_highestDamage, sizeof (m_highestDamage)); - m_endJumpPoint = false; m_needsVisRebuild = false; m_jumpLearnNode = false; diff --git a/src/linkage.cpp b/src/linkage.cpp index c57340f..53315f0 100644 --- a/src/linkage.cpp +++ b/src/linkage.cpp @@ -10,6 +10,7 @@ ConVar cv_version ("yb_version", product.version.chars (), Var::ReadOnly); gamefuncs_t dllapi; +newgamefuncs_t newapi; enginefuncs_t engfuncs; gamedll_funcs_t dllfuncs; @@ -499,6 +500,17 @@ CR_LINKAGE_C int GetEngineFunctions (enginefuncs_t *table, int *) { plat.bzero (table, sizeof (enginefuncs_t)); } + if (ents.isWorkaroundNeeded () && !game.is (GameFlags::Metamod)) { + table->pfnCreateNamedEntity = [] (int classname) -> edict_t * { + + if (ents.isPaused ()) { + ents.enable (); + ents.setPaused (false); + } + return engfuncs.pfnCreateNamedEntity (classname); + }; + } + table->pfnChangeLevel = [] (char *s1, char *s2) { // the purpose of this function is to ask the engine to shutdown the server and restart a // new one running the map whose name is s1. It is used ONLY IN SINGLE PLAYER MODE and is @@ -790,13 +802,33 @@ CR_EXPORT int GetNewDLLFunctions (newgamefuncs_t *table, int *interfaceVersion) // pass them too, else the DLL interfacing wouldn't be complete and the game possibly wouldn't // run properly. - auto api_GetNewDLLFunctions = game.lib ().resolve (__FUNCTION__); + plat.bzero (table, sizeof (newgamefuncs_t)); - if (!api_GetNewDLLFunctions || !api_GetNewDLLFunctions (table, interfaceVersion)) { - logger.error ("Could not resolve symbol \"%s\" in the game dll. Continuing...", __FUNCTION__); - return HLFalse; + if (!(game.is (GameFlags::Metamod))) { + auto api_GetEntityAPI = game.lib ().resolve (__FUNCTION__); + + // pass other DLLs engine callbacks to function table... + if (!api_GetEntityAPI || api_GetEntityAPI (&newapi, interfaceVersion) == 0) { + logger.error ("Could not resolve symbol \"%s\" in the game dll.", __FUNCTION__); + } + dllfuncs.newapi_table = &newapi; + + memcpy (table, &newapi, sizeof (newgamefuncs_t)); } - dllfuncs.newapi_table = table; + + table->pfnOnFreeEntPrivateData = [] (edict_t *ent) { + for (auto &bot : bots) { + if (bot->m_enemy == ent) { + bot->m_enemy = nullptr; + bot->m_lastEnemy = nullptr; + } + } + + if (game.is (GameFlags::Metamod)) { + RETURN_META (MRES_IGNORED); + } + newapi.pfnOnFreeEntPrivateData (ent); + }; return HLTrue; } @@ -851,7 +883,7 @@ CR_EXPORT int Meta_Attach (PLUG_LOADTIME now, metamod_funcs_t *functionTable, me GetEntityAPI_Post, // pfnGetEntityAPI_Post () nullptr, // pfnGetEntityAPI2 () nullptr, // pfnGetEntityAPI2_Post () - nullptr, // pfnGetNewDLLFunctions () + GetNewDLLFunctions, // pfnGetNewDLLFunctions () nullptr, // pfnGetNewDLLFunctions_Post () GetEngineFunctions, // pfnGetEngineFunctions () GetEngineFunctions_Post, // pfnGetEngineFunctions_Post () @@ -947,14 +979,23 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t api_GiveFnptrsToDll (functionTable, glob); } -DETOUR_RETURN EntityLinkage::lookup (SharedLibrary::Handle module, const char *function) { +DLSYM_RETURN EntityLinkage::lookup (SharedLibrary::Handle module, const char *function) { static const auto &gamedll = game.lib ().handle (); static const auto &self = m_self.handle (); const auto resolve = [&] (SharedLibrary::Handle handle) { - return reinterpret_cast (m_dlsym (static_cast (handle), function)); + return reinterpret_cast (m_dlsym (static_cast (handle), function)); }; + if (ents.isWorkaroundNeeded () && !strcmp (function, "CreateInterface")) { + ents.setPaused (true); + auto ret = resolve (module); + + ents.disable (); + + return ret; + } + // if requested module is yapb module, put in cache the looked up symbol if (self != module || (plat.win32 && (static_cast (reinterpret_cast (function) >> 16) & 0xffff) == 0)) { return resolve (module); @@ -979,13 +1020,18 @@ DETOUR_RETURN EntityLinkage::lookup (SharedLibrary::Handle module, const char *f } void EntityLinkage::initialize () { - if (plat.arm) { + if (plat.arm || game.is (GameFlags::Metamod)) { return; } + m_dlsym.initialize ("kernel32.dll", "GetProcAddress", DLSYM_FUNCTION); m_dlsym.install (reinterpret_cast (EntityLinkage::replacement), true); + m_self.locate (&engfuncs); } // add linkents for android #include "android.cpp" + +// override new/delete globally, need to be included in .cpp file +#include diff --git a/src/manager.cpp b/src/manager.cpp index 83d2dae..75b5d93 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -914,6 +914,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int skin) { // we're not initializing all the variables in bot class, so do an ugly thing... memset this plat.bzero (this, sizeof (*this)); + int clientIndex = game.indexOfEntity (bot); pev = &bot->v; @@ -1033,6 +1034,9 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int skin) { // just to be sure m_msgQueue.clear (); + // init path walker + m_pathWalk.init (graph.getMaxRouteLength ()); + // assign team and class m_wantedTeam = team; m_wantedSkin = skin; @@ -1104,18 +1108,18 @@ bool BotManager::isTeamStacked (int team) { void BotManager::erase (Bot *bot) { for (auto &e : m_bots) { - if (e.get () == bot) { - bot->showChaterIcon (false); - bot->markStale (); - - conf.clearUsedName (bot); // clear the bot name - - e.reset (); - m_bots.remove (e); // remove from bots array - - break; + if (e.get () != bot) { + continue; } + bot->markStale (); + + auto index = m_bots.index (e); + e.reset (); + + m_bots.erase (index, 1); // remove from bots array + break; } + } void BotManager::handleDeath (edict_t *killer, edict_t *victim) { @@ -1423,6 +1427,11 @@ void Bot::kick () { } void Bot::markStale () { + showChaterIcon (false); + + // clear the bot name + conf.clearUsedName (this); + // clear fakeclient bit pev->flags &= ~FL_FAKECLIENT; diff --git a/src/module.cpp b/src/module.cpp index 460dbcf..3a46c39 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -12,9 +12,6 @@ class YaPBModule : public IYaPBModule { public: virtual ~YaPBModule () override = default; -public: - CR_DECLARE_DESTRUCTOR (); - private: Bot *getBot (int index) { if (index < 1) { diff --git a/src/navigate.cpp b/src/navigate.cpp index a689c77..79ada7a 100644 --- a/src/navigate.cpp +++ b/src/navigate.cpp @@ -601,7 +601,7 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) { m_collStateIndex++; m_probeTime = game.time () + 0.5f; - if (m_collStateIndex > kMaxCollideMoves) { + if (m_collStateIndex >= kMaxCollideMoves) { m_navTimeset = game.time () - 5.0f; resetCollision (); } @@ -1181,7 +1181,7 @@ void Bot::findShortestPath (int srcIndex, int destIndex) { m_chosenGoalIndex = srcIndex; m_goalValue = 0.0f; - m_pathWalk.push (srcIndex); + m_pathWalk.add (srcIndex); while (srcIndex != destIndex) { srcIndex = (graph.m_matrix.data () + (srcIndex * graph.length ()) + destIndex)->index; @@ -1192,7 +1192,7 @@ void Bot::findShortestPath (int srcIndex, int destIndex) { return; } - m_pathWalk.push (srcIndex); + m_pathWalk.add (srcIndex); } } @@ -1406,7 +1406,7 @@ void Bot::findPath (int srcIndex, int destIndex, FindPath pathType /*= FindPath: int currentIndex = m_routeQue.pop ().first; // safes us from bad graph... - if (m_routeQue.length () >= kMaxRouteLength - 1) { + if (m_routeQue.length () >= graph.getMaxRouteLength () - 1) { logger.error ("A* Search for bot \"%s\" has tried to build path with at least %d nodes. Seems to be graph is broken.", pev->netname.chars (), m_routeQue.length ()); kick (); // kick the bot off... @@ -1418,7 +1418,7 @@ void Bot::findPath (int srcIndex, int destIndex, FindPath pathType /*= FindPath: // build the complete path do { - m_pathWalk.push (currentIndex); + m_pathWalk.add (currentIndex); currentIndex = m_routes[currentIndex].parent; } while (currentIndex != kInvalidNodeIndex); diff --git a/vc/yapb.vcxproj b/vc/yapb.vcxproj index 50abf9d..1fbb721 100644 --- a/vc/yapb.vcxproj +++ b/vc/yapb.vcxproj @@ -11,7 +11,6 @@ - @@ -26,7 +25,9 @@ + + @@ -97,8 +98,8 @@ DynamicLibrary false v142 - false false + false @@ -162,9 +163,8 @@ Level4 true - EditAndContinue Default - true + false false Default true diff --git a/vc/yapb.vcxproj.filters b/vc/yapb.vcxproj.filters index 6709171..b04ec55 100644 --- a/vc/yapb.vcxproj.filters +++ b/vc/yapb.vcxproj.filters @@ -75,9 +75,6 @@ inc\ext\hlsdk - - inc\ext\crlib - inc\ext\crlib @@ -147,6 +144,12 @@ inc + + inc\ext\crlib + + + inc\ext\crlib + From b75e1b8a23ff030776df25ef4e4df72f1515e3d9 Mon Sep 17 00:00:00 2001 From: jeefo Date: Mon, 23 Nov 2020 10:48:44 +0300 Subject: [PATCH 2/3] Fixed compiler warnings. --- .gitignore | 3 ++- ext/crlib/cr-override.h | 6 +++--- ext/crlib/cr-platform.h | 8 ++++---- inc/engine.h | 2 +- inc/message.h | 4 ++-- src/engine.cpp | 6 +++--- src/linkage.cpp | 2 +- src/manager.cpp | 6 +++++- src/support.cpp | 2 +- 9 files changed, 22 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 8108f3c..fb89a80 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,11 @@ *.dll *.so *.user +*.json vc/release vc/debug vc/.vs vc/enc_temp_folder -build/ \ No newline at end of file +build/ diff --git a/ext/crlib/cr-override.h b/ext/crlib/cr-override.h index ace571d..e30f5b5 100644 --- a/ext/crlib/cr-override.h +++ b/ext/crlib/cr-override.h @@ -10,11 +10,11 @@ #include #include -void *operator new (size_t size) noexcept { +void *operator new (size_t size) { return cr::Memory::get (size); } -void *operator new [] (size_t size) noexcept { +void *operator new [] (size_t size) { return cr::Memory::get (size); } @@ -36,4 +36,4 @@ void operator delete [] (void *ptr, size_t) noexcept { CR_LINKAGE_C void __cxa_pure_virtual () { cr::plat.abort ("pure virtual function call"); -} \ No newline at end of file +} diff --git a/ext/crlib/cr-platform.h b/ext/crlib/cr-platform.h index fde5311..51d2857 100644 --- a/ext/crlib/cr-platform.h +++ b/ext/crlib/cr-platform.h @@ -142,8 +142,8 @@ CR_NAMESPACE_BEGIN // helper struct for platform detection struct Platform : public Singleton { - bool win32 = false; - bool linux = false; + bool win = false; + bool nix = false; bool osx = false; bool android = false; bool hfp = false; @@ -154,7 +154,7 @@ struct Platform : public Singleton { Platform () { #if defined(CR_WINDOWS) - win32 = true; + win = true; #endif #if defined(CR_ANDROID) @@ -166,7 +166,7 @@ struct Platform : public Singleton { #endif #if defined(CR_LINUX) - linux = true; + nix = true; #endif #if defined(CR_OSX) diff --git a/inc/engine.h b/inc/engine.h index 2254e3a..010f79e 100644 --- a/inc/engine.h +++ b/inc/engine.h @@ -709,7 +709,7 @@ public: } bool isWorkaroundNeeded () { - return !plat.win32 && !Game::instance ().isDedicated (); + return !plat.win && !Game::instance ().isDedicated (); } }; diff --git a/inc/message.h b/inc/message.h index a9711cc..42fc07a 100644 --- a/inc/message.h +++ b/inc/message.h @@ -70,13 +70,13 @@ private: struct Args { union { float float_; - long long_; + int32 long_; const char *chars_; }; public: Args (float value) : float_ (value) { } - Args (int value) : long_ (value) { } + Args (int32 value) : long_ (value) { } Args (const char *value) : chars_ (value) { } }; diff --git a/src/engine.cpp b/src/engine.cpp index 1123e3b..2132130 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -571,7 +571,7 @@ bool Game::isSoftwareRenderer () { } // and on only windows version you can use software-render game. Linux, OSX always defaults to OpenGL - if (plat.win32) { + if (plat.win) { return plat.hasModule ("sw"); } return false; @@ -696,11 +696,11 @@ bool Game::loadCSBinary () { } StringArray libs; - if (plat.win32) { + if (plat.win) { libs.push ("mp.dll"); libs.push ("cs.dll"); } - else if (plat.linux) { + else if (plat.nix) { libs.push ("cs.so"); libs.push ("cs_i386.so"); } diff --git a/src/linkage.cpp b/src/linkage.cpp index 53315f0..9a5fa74 100644 --- a/src/linkage.cpp +++ b/src/linkage.cpp @@ -997,7 +997,7 @@ DLSYM_RETURN EntityLinkage::lookup (SharedLibrary::Handle module, const char *fu } // if requested module is yapb module, put in cache the looked up symbol - if (self != module || (plat.win32 && (static_cast (reinterpret_cast (function) >> 16) & 0xffff) == 0)) { + if (self != module || (plat.win && (static_cast (reinterpret_cast (function) >> 16) & 0xffff) == 0)) { return resolve (module); } diff --git a/src/manager.cpp b/src/manager.cpp index 75b5d93..bdc0b6a 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -770,7 +770,11 @@ float BotManager::getAverageTeamKPD (bool calcForBots) { } auto bot = bots[client.ent]; - if ((calcForBots && bot) || (!calcForBots && !bot)) { + if (calcForBots && bot) { + calc.first += client.ent->v.frags; + calc.second++; + } + else if (!calcForBots && !bot) { calc.first += client.ent->v.frags; calc.second++; } diff --git a/src/support.cpp b/src/support.cpp index 7ce6316..0fb35a6 100644 --- a/src/support.cpp +++ b/src/support.cpp @@ -650,7 +650,7 @@ void BotSupport::installSendTo () { } // enable only on modern games - if (game.is (GameFlags::Modern) && (plat.linux || plat.win32) && !plat.arm && !m_sendToDetour.detoured ()) { + if (game.is (GameFlags::Modern) && (plat.nix || plat.win) && !plat.arm && !m_sendToDetour.detoured ()) { m_sendToDetour.install (reinterpret_cast (BotSupport::sendTo), true); } } From 97b7a90bb990749f0eaecaf99ac1fa2785e55406 Mon Sep 17 00:00:00 2001 From: jeefo Date: Mon, 23 Nov 2020 13:11:28 +0300 Subject: [PATCH 3/3] Fix unitialized members. --- inc/manager.h | 18 +-- inc/yapb.h | 314 ++++++++++++++++++++++++------------------------- src/botlib.cpp | 2 +- 3 files changed, 167 insertions(+), 167 deletions(-) diff --git a/inc/manager.h b/inc/manager.h index d7e0aa1..7020218 100644 --- a/inc/manager.h +++ b/inc/manager.h @@ -61,20 +61,20 @@ private: float m_autoKillCheckTime; // time to kill all the bots ? float m_maintainTime; // time to maintain bot creation float m_quotaMaintainTime; // time to maintain bot quota - float m_grenadeUpdateTime; // time to update active grenades - float m_entityUpdateTime; // time to update intresting entities - float m_plantSearchUpdateTime; // time to update for searching planted bomb - float m_lastChatTime; // global chat time timestamp - float m_timeBombPlanted; // time the bomb were planted - float m_lastRadioTime[kGameTeamNum]; // global radio time + float m_grenadeUpdateTime {}; // time to update active grenades + float m_entityUpdateTime {}; // time to update intresting entities + float m_plantSearchUpdateTime {}; // time to update for searching planted bomb + float m_lastChatTime {}; // global chat time timestamp + float m_timeBombPlanted {}; // time the bomb were planted + float m_lastRadioTime[kGameTeamNum] {}; // global radio time int m_lastWinner; // the team who won previous round int m_lastDifficulty; // last bots difficulty int m_bombSayStatus; // some bot is issued whine about bomb - int m_lastRadio[kGameTeamNum]; // last radio message for team + int m_lastRadio[kGameTeamNum] {}; // last radio message for team - bool m_leaderChoosen[kGameTeamNum]; // is team leader choose theese round - bool m_economicsGood[kGameTeamNum]; // is team able to buy anything + bool m_leaderChoosen[kGameTeamNum] {}; // is team leader choose theese round + bool m_economicsGood[kGameTeamNum] {}; // is team able to buy anything bool m_bombPlanted; bool m_botsCanPause; bool m_roundOver; diff --git a/inc/yapb.h b/inc/yapb.h index 228bdfb..5089c4f 100644 --- a/inc/yapb.h +++ b/inc/yapb.h @@ -605,101 +605,101 @@ public: friend class BotManager; private: - uint32 m_states; // sensing bitstates - uint32 m_collideMoves[kMaxCollideMoves]; // sorted array of movements - uint32 m_collisionProbeBits; // bits of possible collision moves - uint32 m_collStateIndex; // index into collide moves - uint32 m_aimFlags; // aiming conditions - uint32 m_currentTravelFlags; // connection flags like jumping + uint32 m_states {}; // sensing bitstates + uint32 m_collideMoves[kMaxCollideMoves] {}; // sorted array of movements + uint32 m_collisionProbeBits {}; // bits of possible collision moves + uint32 m_collStateIndex {}; // index into collide moves + uint32 m_aimFlags {}; // aiming conditions + uint32 m_currentTravelFlags {}; // connection flags like jumping - int m_traceSkip[TraceChannel::Num]; // trace need to be skipped? - int m_messageQueue[32]; // stack for messages + int m_traceSkip[TraceChannel::Num] {}; // trace need to be skipped? + int m_messageQueue[32] {}; // stack for messages - int m_oldButtons; // our old buttons - int m_reloadState; // current reload state + int m_oldButtons {}; // our old buttons + int m_reloadState {}; // current reload state int m_voicePitch; // bot voice pitch - int m_loosedBombNodeIndex; // nearest to loosed bomb node - int m_plantedBombNodeIndex; // nearest to planted bomb node - int m_currentNodeIndex; // current node index - int m_travelStartIndex; // travel start index to double jump action - int m_previousNodes[5]; // previous node indices from node find - int m_pathFlags; // current node flags - int m_needAvoidGrenade; // which direction to strafe away - int m_campDirection; // camp Facing direction - int m_campButtons; // buttons to press while camping - int m_tryOpenDoor; // attempt's to open the door - int m_liftState; // state of lift handling - int m_radioSelect; // radio entry + int m_loosedBombNodeIndex {}; // nearest to loosed bomb node + int m_plantedBombNodeIndex {}; // nearest to planted bomb node + int m_currentNodeIndex {}; // current node index + int m_travelStartIndex {}; // travel start index to double jump action + int m_previousNodes[5] {}; // previous node indices from node find + int m_pathFlags {}; // current node flags + int m_needAvoidGrenade {}; // which direction to strafe away + int m_campDirection {}; // camp Facing direction + int m_campButtons {}; // buttons to press while camping + int m_tryOpenDoor {}; // attempt's to open the door + int m_liftState {}; // state of lift handling + int m_radioSelect {}; // radio entry - float m_headedTime; - float m_prevTime; // time previously checked movement speed + float m_headedTime {}; + float m_prevTime {}; // time previously checked movement speed float m_heavyTimestamp; // is it time to execute heavy-weight functions - float m_prevSpeed; // speed some frames before - float m_timeDoorOpen; // time to next door open check - float m_lastChatTime; // time bot last chatted - float m_timeLogoSpray; // time bot last spray logo - float m_knifeAttackTime; // time to rush with knife (at the beginning of the round) - float m_duckDefuseCheckTime; // time to check for ducking for defuse + float m_prevSpeed {}; // speed some frames before + float m_timeDoorOpen {}; // time to next door open check + float m_lastChatTime {}; // time bot last chatted + float m_timeLogoSpray {}; // time bot last spray logo + float m_knifeAttackTime {}; // time to rush with knife (at the beginning of the round) + float m_duckDefuseCheckTime {}; // time to check for ducking for defuse float m_frameInterval; // bot's frame interval float m_lastCommandTime; // time bot last thinked - float m_reloadCheckTime; // time to check reloading - float m_zoomCheckTime; // time to check zoom again - float m_shieldCheckTime; // time to check shiled drawing again - float m_grenadeCheckTime; // time to check grenade usage - float m_sniperStopTime; // bot switched to other weapon? - float m_lastEquipTime; // last time we equipped in buyzone - float m_duckTime; // time to duck - float m_jumpTime; // time last jump happened - float m_soundUpdateTime; // time to update the sound - float m_heardSoundTime; // last time noise is heard - float m_buttonPushTime; // time to push the button - float m_liftUsageTime; // time to use lift - float m_askCheckTime; // time to ask team - float m_collideTime; // time last collision - float m_firstCollideTime; // time of first collision - float m_probeTime; // time of probing different moves - float m_lastCollTime; // time until next collision check - float m_lookYawVel; // look yaw velocity - float m_lookPitchVel; // look pitch velocity - float m_lookUpdateTime; // lookangles update time - float m_aimErrorTime; // time to update error vector - float m_nextCampDirTime; // time next camp direction change - float m_lastFightStyleCheck; // time checked style - float m_strafeSetTime; // time strafe direction was set - float m_randomizeAnglesTime; // time last randomized location - float m_playerTargetTime; // time last targeting - float m_timeCamping; // time to camp - float m_lastUsedNodesTime; // last time bot followed nodes - float m_shootAtDeadTime; // time to shoot at dying players - float m_followWaitTime; // wait to follow time - float m_chatterTimes[Chatter::Count]; // chatter command timers - float m_navTimeset; // time node chosen by Bot - float m_moveSpeed; // current speed forward/backward - float m_strafeSpeed; // current speed sideways - float m_minSpeed; // minimum speed in normal mode - float m_oldCombatDesire; // holds old desire for filtering - float m_itemCheckTime; // time next search for items needs to be done + float m_reloadCheckTime {}; // time to check reloading + float m_zoomCheckTime {}; // time to check zoom again + float m_shieldCheckTime {}; // time to check shiled drawing again + float m_grenadeCheckTime {}; // time to check grenade usage + float m_sniperStopTime {}; // bot switched to other weapon? + float m_lastEquipTime {}; // last time we equipped in buyzone + float m_duckTime {}; // time to duck + float m_jumpTime {}; // time last jump happened + float m_soundUpdateTime {}; // time to update the sound + float m_heardSoundTime {}; // last time noise is heard + float m_buttonPushTime {}; // time to push the button + float m_liftUsageTime {}; // time to use lift + float m_askCheckTime {}; // time to ask team + float m_collideTime {}; // time last collision + float m_firstCollideTime {}; // time of first collision + float m_probeTime {}; // time of probing different moves + float m_lastCollTime {}; // time until next collision check + float m_lookYawVel {}; // look yaw velocity + float m_lookPitchVel {}; // look pitch velocity + float m_lookUpdateTime {}; // lookangles update time + float m_aimErrorTime {}; // time to update error vector + float m_nextCampDirTime {}; // time next camp direction change + float m_lastFightStyleCheck {}; // time checked style + float m_strafeSetTime {}; // time strafe direction was set + float m_randomizeAnglesTime {}; // time last randomized location + float m_playerTargetTime {}; // time last targeting + float m_timeCamping {}; // time to camp + float m_lastUsedNodesTime {}; // last time bot followed nodes + float m_shootAtDeadTime {}; // time to shoot at dying players + float m_followWaitTime {}; // wait to follow time + float m_chatterTimes[Chatter::Count] {}; // chatter command timers + float m_navTimeset {}; // time node chosen by Bot + float m_moveSpeed {}; // current speed forward/backward + float m_strafeSpeed {}; // current speed sideways + float m_minSpeed {}; // minimum speed in normal mode + float m_oldCombatDesire {}; // holds old desire for filtering + float m_itemCheckTime {}; // time next search for items needs to be done float m_joinServerTime; // time when bot joined the game float m_playServerTime; // time bot spent in the game - float m_changeViewTime; // timestamp to change look at while at freezetime + float m_changeViewTime {}; // timestamp to change look at while at freezetime - bool m_moveToGoal; // bot currently moving to goal?? - bool m_isStuck; // bot is stuck - bool m_isReloading; // bot is reloading a gun + bool m_moveToGoal {}; // bot currently moving to goal?? + bool m_isStuck {}; // bot is stuck + bool m_isReloading {}; // bot is reloading a gun bool m_forceRadio; // should bot use radio anyway? - bool m_defendedBomb; // defend action issued - bool m_defendHostage; // defend action issued - bool m_duckDefuse; // should or not bot duck to defuse bomb - bool m_checkKnifeSwitch; // is time to check switch to knife action - bool m_checkWeaponSwitch; // is time to check weapon switch - bool m_isUsingGrenade; // bot currently using grenade?? - bool m_bombSearchOverridden; // use normal node if applicable when near the bomb - bool m_wantsToFire; // bot needs consider firing - bool m_jumpFinished; // has bot finished jumping - bool m_isLeader; // bot is leader of his team - bool m_checkTerrain; // check for terrain - bool m_moveToC4; // ct is moving to bomb - bool m_grenadeRequested; // bot requested change to grenade + bool m_defendedBomb {}; // defend action issued + bool m_defendHostage {}; // defend action issued + bool m_duckDefuse {}; // should or not bot duck to defuse bomb + bool m_checkKnifeSwitch {}; // is time to check switch to knife action + bool m_checkWeaponSwitch {}; // is time to check weapon switch + bool m_isUsingGrenade {}; // bot currently using grenade?? + bool m_bombSearchOverridden {}; // use normal node if applicable when near the bomb + bool m_wantsToFire {}; // bot needs consider firing + bool m_jumpFinished {}; // has bot finished jumping + bool m_isLeader {}; // bot is leader of his team + bool m_checkTerrain {}; // check for terrain + bool m_moveToC4 {}; // ct is moving to bomb + bool m_grenadeRequested {}; // bot requested change to grenade Pickup m_pickupType; // type of entity which needs to be used/picked up PathWalk m_pathWalk; // pointer to current node from path @@ -707,15 +707,15 @@ private: Fight m_fightStyle; // combat style to use CollisionState m_collisionState; // collision State FindPath m_pathType; // which pathfinder to use - uint8 m_enemyParts; // visibility flags + uint8 m_enemyParts {}; // visibility flags TraceResult m_lastTrace[TraceChannel::Num]; // last trace result - edict_t *m_pickupItem; // pointer to entity of item to use/pickup - edict_t *m_itemIgnore; // pointer to entity to ignore for pickup - edict_t *m_liftEntity; // pointer to lift entity - edict_t *m_breakableEntity; // pointer to breakable entity - edict_t *m_targetEntity; // the entity that the bot is trying to reach - edict_t *m_avoidGrenade; // pointer to grenade entity to avoid + edict_t *m_pickupItem {}; // pointer to entity of item to use/pickup + edict_t *m_itemIgnore {}; // pointer to entity to ignore for pickup + edict_t *m_liftEntity {}; // pointer to lift entity + edict_t *m_breakableEntity {}; // pointer to breakable entity + edict_t *m_targetEntity {}; // the entity that the bot is trying to reach + edict_t *m_avoidGrenade {}; // pointer to grenade entity to avoid Vector m_liftTravelPos; // lift travel position Vector m_moveAngles; // bot move angles @@ -738,9 +738,9 @@ private: Array m_routes; // pointer BinaryHeap m_routeQue; - Path *m_path; // pointer to the current path node + Path *m_path {}; // pointer to the current path node String m_chatBuffer; // space for strings (say text...) - FrustumPlane m_frustum[FrustumSide::Num] {}; + FrustumPlane m_frustum[FrustumSide::Num] {}; private: int pickBestWeapon (int *vec, int count, int moneySave); @@ -933,89 +933,89 @@ public: int m_difficulty; // bots hard level int m_moneyAmount; // amount of money in bot's bank - float m_spawnTime; // time this bot spawned - float m_timeTeamOrder; // time of last radio command + float m_spawnTime {}; // time this bot spawned + float m_timeTeamOrder {}; // time of last radio command float m_slowFrameTimestamp; // time to per-second think - float m_nextBuyTime; // next buy time - float m_checkDarkTime; // check for darkness time - float m_preventFlashing; // bot turned away from flashbang - float m_flashLevel; // flashlight level - 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_fallDownTime; // time bot started to fall - float m_duckForJump; // is bot needed to duck for double jump + float m_nextBuyTime {}; // next buy time + float m_checkDarkTime {}; // check for darkness time + float m_preventFlashing {}; // bot turned away from flashbang + float m_flashLevel {}; // flashlight level + 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_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) float m_baseFearLevel; // base fear level (on initializing) float m_agressionLevel; // dynamic aggression level (in game) float m_fearLevel; // dynamic fear level (in game) float m_nextEmotionUpdate; // next time to sanitize emotions - float m_updateTime; // skip some frames in bot thinking - float m_updateInterval; // interval between frames - float m_goalValue; // ranking value for this node - float m_viewDistance; // current view distance - float m_maxViewDistance; // maximum view distance - float m_retreatTime; // time to retreat? - float m_enemyUpdateTime; // time to check for new enemies - float m_enemyReachableTimer; // time to recheck if enemy reachable - float m_enemyIgnoreTimer; // ignore enemy for some time - float m_seeEnemyTime; // time bot sees enemy - float m_enemySurpriseTime; // time of surprise - float m_idealReactionTime; // time of base reaction - float m_actualReactionTime; // time of current reaction time - float m_timeNextTracking; // time node index for tracking player is recalculated - float m_firePause; // time to pause firing - float m_shootTime; // time to shoot - float m_timeLastFired; // time to last firing - float m_difficultyChange; // time when auto-difficulty was last applied to this bot + float m_updateTime {}; // skip some frames in bot thinking + float m_updateInterval {}; // interval between frames + float m_goalValue {}; // ranking value for this node + float m_viewDistance {}; // current view distance + float m_maxViewDistance {}; // maximum view distance + float m_retreatTime {}; // time to retreat? + float m_enemyUpdateTime {}; // time to check for new enemies + float m_enemyReachableTimer {}; // time to recheck if enemy reachable + float m_enemyIgnoreTimer {}; // ignore enemy for some time + float m_seeEnemyTime {}; // time bot sees enemy + float m_enemySurpriseTime {}; // time of surprise + float m_idealReactionTime {}; // time of base reaction + float m_actualReactionTime {}; // time of current reaction time + float m_timeNextTracking {}; // time node index for tracking player is recalculated + float m_firePause {}; // time to pause firing + float m_shootTime {}; // time to shoot + float m_timeLastFired {}; // time to last firing + float m_difficultyChange {}; // time when auto-difficulty was last applied to this bot float m_kpdRatio; // kill per death ratio float m_healthValue; // clamped bot health int m_basePing; // base ping for bot - int m_numEnemiesLeft; // number of enemies alive left on map - int m_numFriendsLeft; // number of friend alive left on map + int m_numEnemiesLeft {}; // number of enemies alive left on map + int m_numFriendsLeft {}; // number of friend alive left on map int m_retryJoin; // retry count for chosing team/class int m_startAction; // team/class selection state - int m_voteKickIndex; // index of player to vote against - int m_lastVoteKick; // last index - int m_voteMap; // number of map to vote for + int m_voteKickIndex {}; // index of player to vote against + int m_lastVoteKick {}; // last index + int m_voteMap {}; // number of map to vote for int m_logotypeIndex; // index for logotype - int m_buyState; // current count in buying - int m_blindButton; // buttons bot press, when blind - int m_radioOrder; // actual command - int m_prevGoalIndex; // holds destination goal node - int m_chosenGoalIndex; // used for experience, same as above - int m_lastDamageType; // stores last damage - int m_team; // bot team + int m_buyState {}; // current count in buying + int m_blindButton {}; // buttons bot press, when blind + int m_radioOrder {}; // actual command + int m_prevGoalIndex {}; // holds destination goal node + int m_chosenGoalIndex {}; // used for experience, same as above + int m_lastDamageType {}; // stores last damage + int m_team {}; // bot team int m_currentWeapon; // one current weapon for each bot int m_weaponType; // current weapon type - int m_ammoInClip[kMaxWeapons]; // ammo in clip for each weapons - int m_ammo[MAX_AMMO_SLOTS]; // total ammo amounts + int m_ammoInClip[kMaxWeapons] {}; // ammo in clip for each weapons + int m_ammo[MAX_AMMO_SLOTS] {}; // total ammo amounts - bool m_isVIP; // bot is vip? + bool m_isVIP {}; // bot is vip? bool m_notKilled; // has the player been killed or has he just respawned bool m_notStarted; // team/class not chosen yet - bool m_ignoreBuyDelay; // when reaching buyzone in the middle of the round don't do pauses - bool m_inBombZone; // bot in the bomb zone or not - bool m_inBuyZone; // bot currently in buy zone - bool m_inVIPZone; // bot in the vip satefy zone - bool m_buyingFinished; // done with buying - bool m_buyPending; // bot buy is pending - bool m_hasDefuser; // does bot has defuser - bool m_hasNVG; // does bot has nightvision goggles - bool m_usesNVG; // does nightvision goggles turned on - bool m_hasC4; // does bot has c4 bomb - bool m_hasProgressBar; // has progress bar on a HUD - bool m_jumpReady; // is double jump ready - bool m_canChooseAimDirection; // can choose aiming direction - bool m_isEnemyReachable; // direct line to enemy + bool m_ignoreBuyDelay {}; // when reaching buyzone in the middle of the round don't do pauses + bool m_inBombZone {}; // bot in the bomb zone or not + bool m_inBuyZone {}; // bot currently in buy zone + bool m_inVIPZone {}; // bot in the vip satefy zone + bool m_buyingFinished {}; // done with buying + bool m_buyPending {}; // bot buy is pending + bool m_hasDefuser {}; // does bot has defuser + bool m_hasNVG {}; // does bot has nightvision goggles + bool m_usesNVG {}; // does nightvision goggles turned on + bool m_hasC4 {}; // does bot has c4 bomb + bool m_hasProgressBar {}; // has progress bar on a HUD + bool m_jumpReady {}; // is double jump ready + bool m_canChooseAimDirection {}; // can choose aiming direction + bool m_isEnemyReachable {}; // direct line to enemy - edict_t *m_doubleJumpEntity; // pointer to entity that request double jump - edict_t *m_radioEntity; // pointer to entity issuing a radio command - edict_t *m_enemy; // pointer to enemy entity - edict_t *m_lastEnemy; // pointer to last enemy entity - edict_t *m_lastVictim; // pointer to killed entity - edict_t *m_trackingEdict; // pointer to last tracked player when camping/hiding + edict_t *m_doubleJumpEntity {}; // pointer to entity that request double jump + edict_t *m_radioEntity {}; // pointer to entity issuing a radio command + edict_t *m_enemy {}; // pointer to enemy entity + edict_t *m_lastEnemy {}; // pointer to last enemy entity + edict_t *m_lastVictim {}; // pointer to killed entity + edict_t *m_trackingEdict {}; // pointer to last tracked player when camping/hiding Vector m_pathOrigin; // origin of node Vector m_destOrigin; // origin of move destination diff --git a/src/botlib.cpp b/src/botlib.cpp index 3fb0c57..2838f89 100644 --- a/src/botlib.cpp +++ b/src/botlib.cpp @@ -1243,7 +1243,7 @@ int Bot::pickBestWeapon (int *vec, int count, int moneySave) { union { unsigned int u; float f; - } cast; + } cast {}; cast.f = factor; return (static_cast ((cast.u >> 23) & 0xff) - 127) * 0.3010299956639812f;