diff --git a/ext/crlib/cr-array.h b/ext/crlib/cr-array.h deleted file mode 100644 index 59c57d2..0000000 --- a/ext/crlib/cr-array.h +++ /dev/null @@ -1,408 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include -#include -#include -#include - -#include - -// policy to reserve memory -CR_DECLARE_SCOPED_ENUM (ReservePolicy, - Multiple, - Single, -) - -CR_NAMESPACE_BEGIN - -// simple array class like std::vector -template class Array : public DenyCopying { -private: - T *contents_ {}; - size_t capacity_ {}; - size_t length_ {}; - -public: - explicit Array () { - if (fix (S > 0)) { - reserve (S); - } - } - - Array (const size_t amount) { - reserve (amount); - } - - Array (Array &&rhs) noexcept { - contents_ = rhs.contents_; - length_ = rhs.length_; - capacity_ = rhs.capacity_; - - rhs.reset (); - } - - Array (const std::initializer_list &list) { - for (const auto &elem : list) { - push (elem); - } - } - - ~Array () { - destroy (); - } - -private: - void destructElements () noexcept { - for (size_t i = 0; i < length_; ++i) { - Memory::destruct (&contents_[i]); - } - } - - void transferElements (T *dest, T *src, size_t length) noexcept { - for (size_t i = 0; i < length; ++i) { - Memory::construct (&dest[i], cr::move (src[i])); - Memory::destruct (&src[i]); - } - } - - void destroy () { - destructElements (); - Memory::release (contents_); - } - - void reset () { - contents_ = nullptr; - capacity_ = 0; - length_ = 0; - } - -public: - bool reserve (const size_t amount) { - if (length_ + amount < capacity_) { - return true; - } - auto capacity = capacity_ ? capacity_ : 12; - - if (cr::fix (R == ReservePolicy::Multiple)) { - while (length_ + amount > capacity) { - capacity *= 2; - } - } - else { - capacity = amount + capacity_ + 1; - } - auto data = Memory::get (capacity); - - if (contents_) { - transferElements (data, contents_, length_); - Memory::release (contents_); - } - - contents_ = data; - capacity_ = capacity; - - return true; - } - - bool resize (const size_t amount) { - if (amount < length_) { - while (amount < length_) { - discard (); - } - } - else if (amount > length_) { - if (!ensure (amount)) { - return false; - } - size_t resizeLength = amount - length_; - - while (resizeLength--) { - emplace (); - } - } - return true; - } - - bool ensure (const size_t amount) { - if (amount <= length_) { - return true; - } - return reserve (amount - length_); - } - - template U length () const { - return static_cast (length_); - } - - size_t capacity () const { - return capacity_; - } - - template bool set (size_t index, U &&object) { - if (index >= capacity_) { - if (!reserve (index + 1)) { - return false; - } - } - Memory::construct (&contents_[index], cr::forward (object)); - - if (index >= length_) { - length_ = index + 1; - } - return true; - } - - template bool insert (size_t index, U &&object) { - return insert (index, &object, 1); - } - - template bool insert (size_t index, U *objects, size_t count = 1) { - if (!objects || !count) { - return false; - } - const size_t capacity = (length_ > index ? length_ : index) + count; - - if (capacity >= capacity_ && !reserve (capacity)) { - return false; - } - - if (index >= length_) { - for (size_t i = 0; i < count; ++i) { - Memory::construct (&contents_[i + index], cr::forward (objects[i])); - } - length_ = capacity; - } - else { - size_t i = 0; - - for (i = length_; i > index; --i) { - contents_[i + count - 1] = cr::move (contents_[i - 1]); - } - for (i = 0; i < count; ++i) { - Memory::construct (&contents_[i + index], cr::forward (objects[i])); - } - length_ += count; - } - return true; - } - - bool insert (size_t at, const Array &rhs) { - if (&rhs == this) { - return false; - } - return insert (at, &rhs.contents_[0], rhs.length_); - } - - bool erase (const size_t index, const size_t count) { - if (index + count > capacity_) { - return false; - } - for (size_t i = index; i < index + count; ++i) { - Memory::destruct (&contents_[i]); - } - length_ -= count; - - for (size_t i = index; i < length_; ++i) { - contents_[i] = cr::move (contents_[i + count]); - } - return true; - } - - bool shift () { - return erase (0, 1); - } - - template bool unshift (U &&object) { - return insert (0, &object); - } - - bool remove (const T &object) { - return erase (index (object), 1); - } - - template bool push (U &&object) { - if (!reserve (1)) { - return false; - } - Memory::construct (&contents_[length_], cr::forward (object)); - ++length_; - - return true; - } - - template bool emplace (Args &&...args) { - if (!reserve (1)) { - return false; - } - Memory::construct (&contents_[length_], cr::forward (args)...); - ++length_; - - return true; - } - - T pop () { - auto object = cr::move (contents_[length_ - 1]); - discard (); - - return object; - } - - void discard () { - erase (length_ - 1, 1); - } - - size_t index (const T &object) const { - return &object - &contents_[0]; - } - - void shuffle () { - int32 shuffleLength = length (); - - for (int32 i = shuffleLength; i >= 1; --i) { - cr::swap (contents_[i - 1], contents_[rg.get (i, shuffleLength - 2)]); - } - } - - void reverse () { - for (size_t i = 0; i < length_ / 2; ++i) { - cr::swap (contents_[i], contents_[length_ - 1 - i]); - } - } - - template bool extend (U &&rhs) { - if (length_ == 0) { - *this = cr::move (rhs); - } - else { - for (size_t i = 0; i < rhs.length (); ++i) { - if (!push (cr::move (rhs[i]))) { - return false; - } - } - } - return true; - } - - template bool assign (U &&rhs) { - clear (); - return extend (cr::move (rhs)); - } - - void clear () { - destructElements (); - length_ = 0; - } - - bool empty () const { - return length_ == 0; - } - - bool shrink () { - if (length_ == capacity_ || !length_) { - return false; - } - - auto data = Memory::get (length_); - transferElements (data, contents_, length_); - - Memory::release (contents_); - - contents_ = data; - capacity_ = length_; - - return true; - } - - const T &at (size_t index) const { - return contents_[index]; - } - - T &at (size_t index) { - return contents_[index]; - } - - const T &first () const { - return contents_[0]; - } - - T &first () { - return contents_[0]; - } - - T &last () { - return contents_[length_ - 1]; - } - - const T &last () const { - return contents_[length_ - 1]; - } - - const T &random () const { - return contents_[rg.get (0, length () - 1)]; - } - - T &random () { - return contents_[rg.get (0, length () - 1)]; - } - - T *data () { - return contents_; - } - - T *data () const { - return contents_; - } - -public: - Array &operator = (Array &&rhs) noexcept { - if (this != &rhs) { - destroy (); - - contents_ = rhs.contents_; - length_ = rhs.length_; - capacity_ = rhs.capacity_; - - rhs.reset (); - } - return *this; - } - -public: - const T &operator [] (size_t index) const { - return at (index); - } - - T &operator [] (size_t index) { - return at (index); - } - - // for range-based loops -public: - T *begin () { - return contents_; - } - - T *begin () const { - return contents_; - } - - T *end () { - return contents_ + length_; - } - - T *end () const { - return contents_ + length_; - } -}; - -// small array (with minimal reserve policy, something like fixed array, but still able to grow, by default allocates 64 elements) -template using SmallArray = Array ; - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-basic.h b/ext/crlib/cr-basic.h deleted file mode 100644 index f727bcd..0000000 --- a/ext/crlib/cr-basic.h +++ /dev/null @@ -1,130 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -// our global namaespace -#define CR_NAMESPACE_BEGIN namespace cr { -#define CR_NAMESPACE_END } - -#include -#include -#include - -#include -#include - -CR_NAMESPACE_BEGIN -// -// some useful type definitions -// -namespace types { - using int8 = signed char; - using int16 = signed short; - using int32 = signed int; - using uint8 = unsigned char; - using uint16 = unsigned short; - using uint32 = unsigned int; - using uint64 = unsigned long long; -} - -// make types available for our own use -using namespace cr::types; - -// -// global helper stuff -// -template constexpr size_t bufsize (const T (&)[N]) { - return N - 1; -} - -template constexpr T abs (const T &a) { - return a > 0 ? a : -a; -} - -template constexpr T bit (const T &a) { - return static_cast (1ULL << a); -} - -template constexpr T min (const T &a, const T &b) { - return a < b ? a : b; -} - -template constexpr T max (const T &a, const T &b) { - return a > b ? a : b; -} - -template constexpr T square (const T &value) { - return value * value; -} - -template constexpr T clamp (const T &x, const T &a, const T &b) { - return min (max (x, a), b); -} - -template const T &fix (const T &type) { - return type; -} - -// -// base classes -// - -// simple non-copying base class -class DenyCopying { -protected: - explicit DenyCopying () = default; - ~DenyCopying () = default; - -public: - DenyCopying (const DenyCopying &) = delete; - DenyCopying &operator = (const DenyCopying &) = delete; -}; - -// singleton for objects -template class Singleton : public DenyCopying { -protected: - Singleton () - { } - -public: - static T &instance () { - static T __instance {}; - return __instance; - } - -public: - T *operator -> () { - return &instance (); - } -}; - -// simple scoped enum, instaed of enum class -#define CR_DECLARE_SCOPED_ENUM_TYPE(enumName, enumType, ...) \ - CR_NAMESPACE_BEGIN \ - namespace enums { \ - struct _##enumName : protected DenyCopying { \ - enum Type : enumType { \ - __VA_ARGS__ \ - }; \ - }; \ - } \ - CR_NAMESPACE_END \ - using enumName = ::cr::enums::_##enumName::Type; \ - -// same as above, but with int32 type -#define CR_DECLARE_SCOPED_ENUM(enumName, ...) \ - CR_DECLARE_SCOPED_ENUM_TYPE(enumName, int32, __VA_ARGS__) \ - -// exposes global variable from class singleton -#define CR_EXPOSE_GLOBAL_SINGLETON(className, variable) \ - static auto &variable { className::instance () } \ - -CR_NAMESPACE_END - -// platform-dependant-stuff -#include diff --git a/ext/crlib/cr-binheap.h b/ext/crlib/cr-binheap.h deleted file mode 100644 index a23c38c..0000000 --- a/ext/crlib/cr-binheap.h +++ /dev/null @@ -1,151 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include - -CR_NAMESPACE_BEGIN - -// simple priority queue -template class BinaryHeap final : public DenyCopying { -private: - Array contents_; - -public: - explicit BinaryHeap () = default; - - BinaryHeap (BinaryHeap &&rhs) noexcept : contents_ (cr::move (rhs.contents_)) - { } - - ~BinaryHeap () = default; - -public: - template bool push (U &&item) { - if (!contents_.push (cr::move (item))) { - return false; - } - const size_t length = contents_.length (); - - if (length > 1) { - percolateUp (length - 1); - } - return true; - } - - template bool emplace (Args &&...args) { - if (!contents_.emplace (cr::forward (args)...)) { - return false; - } - const size_t length = contents_.length (); - - if (length > 1) { - percolateUp (length - 1); - } - return true; - } - - const T &top () const { - return contents_[0]; - } - - T pop () { - if (contents_.length () == 1) { - return contents_.pop (); - } - auto key (cr::move (contents_[0])); - - contents_[0] = cr::move (contents_.last ()); - contents_.discard (); - - percolateDown (0); - return key; - } - -public: - size_t length () const { - return contents_.length (); - } - - bool empty () const { - return !contents_.length (); - } - - void clear () { - contents_.clear (); - } - -private: - void percolateUp (size_t index) { - while (index != 0) { - const size_t parentIndex = parent (index); - - if (contents_[parentIndex] > contents_[index]) { - cr::swap (contents_[index], contents_[parentIndex]); - index = parentIndex; - } - else { - break; - } - } - } - - void percolateDown (size_t index) { - while (hasLeft (index)) { - size_t bestIndex = left (index); - - if (hasRight (index)) { - const size_t rightIndex = right (index); - - if (contents_[rightIndex] < contents_[bestIndex]) { - bestIndex = rightIndex; - } - } - - if (contents_[index] > contents_[bestIndex]) { - cr::swap (contents_[index], contents_[bestIndex]); - - index = bestIndex; - bestIndex = left (index); - } - else { - break; - } - } - } - -private: - BinaryHeap &operator = (BinaryHeap &&rhs) noexcept { - if (this != &rhs) { - contents_ = cr::move (rhs.contents_); - } - return *this; - } - -private: - static constexpr size_t parent (size_t index) { - return (index - 1) / 2; - } - - static constexpr size_t left (size_t index) { - return (index * 2) + 1; - } - - static constexpr size_t right (size_t index) { - return (index * 2) + 2; - } - - bool hasLeft (size_t index) const { - return left (index) < contents_.length (); - } - - bool hasRight (size_t index) const { - return right (index) < contents_.length (); - } -}; - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-color.h b/ext/crlib/cr-color.h deleted file mode 100644 index c5756ca..0000000 --- a/ext/crlib/cr-color.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include - -CR_NAMESPACE_BEGIN - -// simple color holder -class Color final { -public: - int32 red = 0, green = 0, blue = 0; - -public: - Color (int32 r, int32 g, int32 b) : red (r), green (g), blue (b) { } - - explicit Color () = default; - ~Color () = default; - -public: - void reset () { - red = green = blue = 0; - } - - int32 avg () const { - return sum () / (sizeof (Color) / sizeof (int32)); - } - - int32 sum () const { - return red + green + blue; - } -}; - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-complete.h b/ext/crlib/cr-complete.h deleted file mode 100644 index d1a991a..0000000 --- a/ext/crlib/cr-complete.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -CR_NAMESPACE_BEGIN - -namespace types { - using StringArray = Array ; - using IntArray = Array ; -} - -using namespace cr::types; - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-deque.h b/ext/crlib/cr-deque.h deleted file mode 100644 index 305501b..0000000 --- a/ext/crlib/cr-deque.h +++ /dev/null @@ -1,230 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include -#include - -CR_NAMESPACE_BEGIN - -template class Deque : private DenyCopying { -private: - size_t capacity_ {}; - T *contents_ {}; - - Twin index_ {}; - -private: - size_t pickFrontIndex () { - if (index_.first == 0) { - if (capacity_ && index_.second != capacity_ - 1) { - return capacity_ - 1; - } - } - else if (index_.first - 1 != index_.second) { - return index_.first - 1; - } - extendCapacity (); - - return capacity_ - 1; - } - - size_t pickRearIndex () { - if (index_.second < index_.first) { - if (index_.second + 1 != index_.first) { - return index_.second + 1; - } - } - else { - if (index_.second + 1 < capacity_) { - return index_.second + 1; - } - if (index_.first != 0) { - return 0; - } - } - extendCapacity (); - - return index_.second + 1; - } - - void extendCapacity () { - auto capacity = capacity_ ? capacity_ * 2 : 8; - auto contents = Memory::get (sizeof (T) * capacity); - - auto transfer = [] (T &dst, T &src) { - Memory::construct (&dst, cr::move (src)); - Memory::destruct (&src); - }; - - if (index_.first < index_.second) { - for (size_t i = 0; i < index_.second - index_.first; ++i) { - transfer (contents[i], contents_[index_.first + i]); - } - index_.second = index_.second - index_.first; - index_.first = 0; - } - else { - for (size_t i = 0; i < capacity_ - index_.first; ++i) { - transfer (contents[i], contents_[index_.first + i]); - } - - for (size_t i = 0; i < index_.second; ++i) { - transfer (contents[capacity_ - index_.first + i], contents_[i]); - } - index_.second = index_.second + (capacity_ - index_.first); - index_.first = 0; - } - 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) { - Memory::destruct (&contents_[i]); - } - }; - - if (index_.first <= index_.second) { - destruct (index_.first, index_.second); - } - else { - destruct (index_.first, capacity_); - destruct (0, index_.second); - } - Memory::release (contents_); - } - - void reset () { - contents_ = nullptr; - capacity_ = 0; - - clear (); - } - -public: - explicit Deque () : capacity_ (0), contents_ (nullptr) - { } - - Deque (Deque &&rhs) : contents_ (rhs.contents_), capacity_ (rhs.capacity_) { - index_.first (rhs.index_.first); - index_.second (rhs.index_.second); - - rhs.reset (); - } - - ~Deque () { - destroy (); - } - -public: - bool empty () const { - return index_.first == index_.second; - } - - template void emplaceLast (Args &&...args) { - auto rear = pickRearIndex (); - - Memory::construct (&contents_[index_.second], cr::forward (args)...); - index_.second = rear; - } - - template void emplaceFront (Args &&...args) { - index_.first = pickFrontIndex (); - Memory::construct (&contents_[index_.first], cr::forward (args)...); - } - - void discardFront () { - Memory::destruct (&contents_[index_.first]); - - if (index_.first == capacity_ - 1) { - index_.first = 0; - } - else { - index_.first++; - } - } - - void discardLast () { - if (index_.second == 0) { - index_.second = capacity_ - 1; - } - else { - index_.second--; - } - Memory::destruct (&contents_[index_.second]); - } - - T popFront () { - auto object (front ()); - discardFront (); - - return object; - } - - T popLast () { - auto object (last ()); - discardLast (); - - return object; - } - -public: - const T &front () const { - return contents_[index_.first]; - } - - const T &last () const { - if (index_.second == 0) { - return contents_[capacity_ - 1]; - } - return contents_[index_.second - 1]; - } - - T &front () { - return contents_[index_.first]; - } - - T &last () { - if (index_.second == 0) { - return contents_[capacity_ - 1]; - } - return contents_[index_.second - 1]; - } - - size_t length () const { - if (index_.first == index_.second) { - return 0; - } - return index_.first < index_.second ? index_.second - index_.first : index_.second + (capacity_ - index_.first); - } - - void clear () { - index_.first = 0; - index_.second = 0; - } - -public: - Deque &operator = (Deque &&rhs) { - destroy (); - - contents_ = rhs.contents_; - capacity_ = rhs.capacity_; - - index_.first = rhs.index_.first; - index_.second = rhs.index_.second; - - rhs.reset (); - return *this; - } -}; - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-detour.h b/ext/crlib/cr-detour.h deleted file mode 100644 index 2a7976f..0000000 --- a/ext/crlib/cr-detour.h +++ /dev/null @@ -1,249 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include - -#if !defined (CR_WINDOWS) -# include -# include -#endif - -CR_NAMESPACE_BEGIN - -// simple wrapper for critical sections -class CriticalSection final : public DenyCopying { -private: -#if defined (CR_WINDOWS) - CRITICAL_SECTION cs_; -#else - pthread_mutex_t mutex_; -#endif - -public: - CriticalSection () { -#if defined (CR_WINDOWS) - InitializeCriticalSection (&cs_); -#else - pthread_mutex_init (&mutex_, nullptr); -#endif - } - ~CriticalSection () { -#if defined (CR_WINDOWS) - DeleteCriticalSection (&cs_); -#else - pthread_mutex_destroy (&mutex_); -#endif - } - - void lock () { -#if defined (CR_WINDOWS) - EnterCriticalSection (&cs_); -#else - pthread_mutex_lock (&mutex_); -#endif - } - - void unlock () { -#if defined (CR_WINDOWS) - LeaveCriticalSection (&cs_); -#else - pthread_mutex_unlock (&mutex_); -#endif - } -}; - -// simple autolock wrapper -class AutoLock final : public DenyCopying { -private: - CriticalSection *cs_; - -public: - AutoLock (CriticalSection *cs) : cs_ (cs) { - cs_->lock (); - } - - ~AutoLock () { - cs_->unlock (); - } -}; - -// simple detour class for x86/x64 -template class Detour final : public DenyCopying { -private: - enum : uint32 { - PtrSize = sizeof (void *), - -#if defined (CR_ARCH_X64) - Offset = 2 -#else - Offset = 1 -#endif - }; - -#if defined (CR_ARCH_X64) - using uintptr = uint64; -#else - using uintptr = uint32; -#endif - -private: - CriticalSection cs_; - - void *original_ = nullptr; - void *detour_ = nullptr; - - Array savedBytes_ { }; - Array jmpBuffer_ - -#ifdef CR_ARCH_X64 - { 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0 }; -#else - { 0xb8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0 }; -#endif - -#if !defined (CR_WINDOWS) - unsigned long pageSize_ { 0 }; - uintptr pageStart_ { 0 }; -#endif - - bool overwritten_ { false }; - -private: - bool overwriteMemory (const Array &to, const bool overwritten) noexcept { - overwritten_ = overwritten; - - AutoLock lock (&cs_); -#if defined (CR_WINDOWS) - unsigned long oldProtect {}; - - if (VirtualProtect (original_, to.length (), PAGE_EXECUTE_READWRITE, &oldProtect)) { - memcpy (original_, to.data (), to.length ()); - - // restore protection - return VirtualProtect (original_, to.length (), oldProtect, &oldProtect); - } -#else - if (mprotect (reinterpret_cast (pageStart_), pageSize_, PROT_READ | PROT_WRITE | PROT_EXEC) != -1) { - memcpy (original_, to.data (), to.length ()); - - // restore protection - return mprotect (reinterpret_cast (pageStart_), pageSize_, PROT_READ | PROT_EXEC) != -1; - } -#endif - return false; - } - -public: - Detour () = default; - - Detour (StringRef module, StringRef name, T *address) { - initialize (module, name, address); - } - - ~Detour () { - restore (); - - original_ = nullptr; - detour_ = nullptr; - } - -private: - class DetourSwitch final { - private: - Detour *detour_; - - public: - DetourSwitch (Detour *detour) : detour_ (detour) { - detour_->restore (); - } - - ~DetourSwitch () { - detour_->detour (); - } - }; - -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; - } - detour_ = detour; - -#if !defined (CR_WINDOWS) - pageStart_ = reinterpret_cast (original_) & -pageSize_; -#endif - - memcpy (savedBytes_.data (), original_, savedBytes_.length ()); - memcpy (reinterpret_cast (reinterpret_cast (jmpBuffer_.data ()) + Offset), &detour_, PtrSize); - - if (enable) { - this->detour (); - } - } - - bool valid () const { - return original_ && detour_; - } - - bool detoured () const { - return overwritten_; - } - - bool detour () { - if (!valid ()) { - return false; - } - return overwriteMemory (jmpBuffer_, true); - } - - bool restore () { - if (!valid ()) { - return false; - } - return overwriteMemory (savedBytes_, false); - } - - template decltype (auto) operator () (Args &&...args) { - DetourSwitch sw (this); - return reinterpret_cast (original_) (args...); - } -}; - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-files.h b/ext/crlib/cr-files.h deleted file mode 100644 index 3f31fd1..0000000 --- a/ext/crlib/cr-files.h +++ /dev/null @@ -1,389 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include - -#include -#include - -CR_NAMESPACE_BEGIN - -// simple stdio file wrapper -class File final : private DenyCopying { -private: - FILE *handle_ = nullptr; - size_t length_ {}; - -public: - explicit File () = default; - - File (StringRef file, StringRef mode = "rt") { - open (file, mode); - } - - ~File () { - close (); - } - -public: - bool open (StringRef file, StringRef mode) { - if (!openFile (file, mode)) { - return false; - } - fseek (handle_, 0L, SEEK_END); - length_ = ftell (handle_); - fseek (handle_, 0L, SEEK_SET); - - return true; - } - - void close () { - if (handle_ != nullptr) { - fclose (handle_); - handle_ = nullptr; - } - length_ = 0; - } - - bool eof () const { - return !!feof (handle_); - } - - bool flush () const { - return !!fflush (handle_); - } - - int get () const { - return fgetc (handle_); - } - - char *getString (char *buffer, int count) const { - return fgets (buffer, count, handle_); - } - - bool getLine (String &line) { - int ch = 0; - SmallArray data (255); - - line.clear (); - - while ((ch = get ()) != EOF && !eof ()) { - data.push (static_cast (ch)); - - if (ch == '\n') { - break; - } - } - if (!data.empty ()) { - line.assign (data.data (), data.length ()); - } - return !line.empty (); - } - - template size_t puts (const char *fmt, Args &&...args) { - if (!*this) { - return 0; - } - return fputs (strings.format (fmt, cr::forward (args)...), handle_); - } - - bool puts (const char *buffer) { - if (!*this) { - return 0; - } - if (fputs (buffer, handle_) < 0) { - return false; - } - return true; - } - - int putChar (int ch) { - return fputc (ch, handle_); - } - - size_t read (void *buffer, size_t size, size_t count = 1) { - return fread (buffer, size, count, handle_); - } - - size_t write (void *buffer, size_t size, size_t count = 1) { - return fwrite (buffer, size, count, handle_); - } - - bool seek (long offset, int origin) { - if (fseek (handle_, offset, origin) != 0) { - return false; - } - return true; - } - - void rewind () { - ::rewind (handle_); - } - - size_t length () const { - return length_; - } - -public: - explicit operator bool () const { - return handle_ != nullptr; - } - -public: - static inline bool exists (StringRef file) { - File fp; - - if (fp.open (file, "rb")) { - fp.close (); - return true; - } - return false; - } - - static inline void createPath (const char *path) { - for (auto str = const_cast (path) + 1; *str; ++str) { - if (*str == '/') { - *str = 0; - plat.createDirectory (path); - *str = '/'; - } - } - plat.createDirectory (path); - } - -private: - bool openFile (StringRef filename, StringRef mode) { - if (*this) { - close (); - } - -#if defined (CR_WINDOWS) - fopen_s (&handle_, filename.chars (), mode.chars ()); -#else - handle_ = fopen (filename.chars (), mode.chars ()); -#endif - return handle_ != nullptr; - } -}; - -// wrapper for memory file for loading data into the memory -class MemFileStorage : public Singleton { -private: - using LoadFunction = Lambda ; - using FreeFunction = Lambda ; - -private: - LoadFunction loadFun_ = nullptr; - FreeFunction freeFun_ = nullptr; - -public: - explicit MemFileStorage () = default; - ~MemFileStorage () = default; - -public: - void initizalize (LoadFunction loader, FreeFunction unloader) { - loadFun_ = cr::move (loader); - freeFun_ = cr::move (unloader); - } - -public: - uint8 *load (StringRef file, int *size) { - if (loadFun_) { - return loadFun_ (file.chars (), size); - } - return nullptr; - } - - void unload (void *buffer) { - if (freeFun_) { - freeFun_ (buffer); - } - } - -public: - static uint8 *defaultLoad (const char *path, int *size) { - File file (path, "rb"); - - if (!file) { - *size = 0; - return nullptr; - } - *size = static_cast (file.length ()); - auto data = Memory::get (*size); - - file.read (data, *size); - return data; - } - - static void defaultUnload (void *buffer) { - Memory::release (buffer); - } - - static String loadToString (StringRef filename) { - int32 result = 0; - auto buffer = defaultLoad (filename.chars (), &result); - - if (result > 0 && buffer) { - String data (reinterpret_cast (buffer), result); - defaultUnload (buffer); - - return data; - } - return ""; - } -}; - -class MemFile final : public DenyCopying { -private: - enum : char { - Eof = static_cast (-1) - }; - -private: - uint8 *contents_ = nullptr; - size_t length_ {}; - size_t seek_ {}; - -public: - explicit MemFile () = default; - - MemFile (StringRef file) { - open (file); - } - - ~MemFile () { - close (); - } - -public: - bool open (StringRef file) { - length_ = 0; - seek_ = 0; - contents_ = MemFileStorage::instance ().load (file.chars (), reinterpret_cast (&length_)); - - if (!contents_) { - return false; - } - return true; - } - - void close () { - MemFileStorage::instance ().unload (contents_); - - length_ = 0; - seek_ = 0; - contents_ = nullptr; - } - - char get () { - if (!contents_ || seek_ >= length_) { - return Eof; - } - return static_cast (contents_[seek_++]); - } - - char *getString (char *buffer, size_t count) { - if (!contents_ || seek_ >= length_) { - return nullptr; - } - size_t index = 0; - buffer[0] = 0; - - for (; index < count - 1;) { - if (seek_ < length_) { - buffer[index] = contents_[seek_++]; - - if (buffer[index++] == '\n') { - break; - } - } - else { - break; - } - } - buffer[index] = 0; - return index ? buffer : nullptr; - } - - bool getLine (String &line) { - char ch; - SmallArray data (255); - - line.clear (); - - while ((ch = get ()) != Eof && !eof ()) { - data.push (ch); - - if (ch == '\n') { - break; - } - } - - if (!data.empty ()) { - line.assign (data.data (), data.length ()); - } - return !line.empty (); - } - - size_t read (void *buffer, size_t size, size_t count = 1) { - if (!contents_ || length_ <= seek_ || !buffer || !size || !count) { - return 0; - } - size_t blocksRead = size * count <= length_ - seek_ ? size * count : length_ - seek_; - - memcpy (buffer, &contents_[seek_], blocksRead); - seek_ += blocksRead; - - return blocksRead / size; - } - - bool seek (size_t offset, int origin) { - if (!contents_ || seek_ >= length_) { - return false; - } - if (origin == SEEK_SET) { - if (offset >= length_) { - return false; - } - seek_ = offset; - } - else if (origin == SEEK_END) { - if (offset >= length_) { - return false; - } - seek_ = length_ - offset; - } - else { - if (seek_ + offset >= length_) { - return false; - } - seek_ += offset; - } - return true; - } - - size_t length () const { - return length_; - } - - bool eof () const { - return seek_ >= length_; - } - - void rewind () { - seek_ = 0; - } - -public: - explicit operator bool () const { - return !!contents_ && length_ > 0; - } -}; - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-hashmap.h b/ext/crlib/cr-hashmap.h deleted file mode 100644 index b693c46..0000000 --- a/ext/crlib/cr-hashmap.h +++ /dev/null @@ -1,236 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include -#include -#include -#include - -CR_NAMESPACE_BEGIN - -template struct Hash; - -template <> struct Hash { - uint32 operator () (const String &key) const noexcept { - return key.hash (); - } -}; - -template <> struct Hash { - uint32 operator () (const StringRef &key) const noexcept { - return key.hash (); - } -}; - -template <> struct Hash { - uint32 operator () (const char *key) const noexcept { - return StringRef::fnv1a32 (key); - } -}; - -template <> struct Hash { - uint32 operator () (int32 key) const noexcept { - auto result = static_cast (key); - - result = ((result >> 16) ^ result) * 0x119de1f3; - result = ((result >> 16) ^ result) * 0x119de1f3; - result = (result >> 16) ^ result; - - return result; - } -}; - -template struct EmptyHash { - uint32 operator () (T key) const noexcept { - return static_cast (key); - } -}; - -namespace detail { - template struct HashEntry final : DenyCopying { - public: - K key {}; - V value {}; - bool used { false }; - - public: - HashEntry () = default; - ~HashEntry () = default; - - public: - HashEntry (HashEntry &&rhs) noexcept : used (rhs.used), key (cr::move (rhs.key)), value (cr::move (rhs.value)) - { } - - public: - HashEntry &operator = (HashEntry &&rhs) noexcept { - if (this != &rhs) { - key = cr::move (rhs.key); - value = cr::move (rhs.value); - used = rhs.used; - } - return *this; - } - }; -} - -template > class HashMap final : public DenyCopying { -public: - using Entries = detail::HashEntry []; - -private: - size_t capacity_ {}; - size_t length_ {}; - H hash_; - - UniquePtr contents_; - -public: - explicit HashMap (const size_t capacity = 3) : capacity_ (capacity), length_ (0) { - contents_ = cr::makeUnique (capacity); - } - - HashMap (HashMap &&rhs) noexcept : contents_ (cr::move (rhs.contents_)), hash_ (cr::move (rhs.hash_)), capacity_ (rhs.capacity_), length_ (rhs.length_) - { } - - ~HashMap () = default; - -private: - size_t getIndex (const K &key, size_t length) const { - return hash_ (key) % length; - } - - void rehash (size_t targetCapacity) { - if (length_ + targetCapacity < capacity_) { - return; - } - auto capacity = capacity_ ? capacity_ : 3; - - while (length_ + targetCapacity > capacity) { - capacity *= 2; - } - auto contents = cr::makeUnique (capacity); - - for (size_t i = 0; i < capacity_; ++i) { - if (contents_[i].used) { - auto result = put (contents_[i].key, contents, capacity); - contents[result.second].value = cr::move (contents_[i].value); - } - } - contents_ = cr::move (contents); - capacity_ = capacity; - } - - Twin put (const K &key, UniquePtr &contents, const size_t capacity) { - size_t index = getIndex (key, capacity); - - for (size_t i = 0; i < capacity; ++i) { - if (!contents[index].used) { - contents[index].key = key; - contents[index].used = true; - - return { true, index }; - } - - if (contents[index].key == key) { - return { false, index }; - } - index++; - - if (index == capacity) { - index = 0; - } - } - return { false, 0 }; - } - -public: - bool empty () const { - return !length_; - } - - size_t length () const { - return length_; - } - - bool has (const K &key) const { - if (empty ()) { - return false; - } - size_t index = getIndex (key, capacity_); - - for (size_t i = 0; i < capacity_; ++i) { - if (contents_[index].used && contents_[index].key == key) { - return true; - } - if (++index == capacity_) { - break; - } - } - return false; - } - - void erase (const K &key) { - size_t index = getIndex (key, capacity_); - - for (size_t i = 0; i < capacity_; ++i) { - if (contents_[index].used && contents_[index].key == key) { - contents_[index].used = false; - --length_; - - break; - } - if (++index == capacity_) { - break; - } - } - } - - void clear () { - length_ = 0; - - for (size_t i = 0; i < capacity_; ++i) { - contents_[i].used = false; - } - rehash (0); - } - - void foreach (Lambda callback) { - for (size_t i = 0; i < capacity_; ++i) { - if (contents_[i].used) { - callback (contents_[i].key, contents_[i].value); - } - } - } - -public: - V &operator [] (const K &key) { - if (length_ >= capacity_) { - rehash (length_ << 1); - } - auto result = put (key, contents_, capacity_); - - if (result.first) { - ++length_; - } - return contents_[result.second].value; - } - - HashMap &operator = (HashMap &&rhs) noexcept { - if (this != &rhs) { - contents_ = cr::move (rhs.contents_); - hash_ = cr::move (rhs.hash_); - - length_ = rhs.length_; - capacity_ = rhs.capacity_; - } - return *this; - } -}; - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-http.h b/ext/crlib/cr-http.h deleted file mode 100644 index c0e7d2c..0000000 --- a/ext/crlib/cr-http.h +++ /dev/null @@ -1,515 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include - -#include -#include -#include -#include -#include -#include -#include - -#if defined (CR_LINUX) || defined (CR_OSX) -# include -# include -# include -# include -# include -# include -# include -# include -# include -#elif defined (CR_WINDOWS) -# include -# include -#endif - -// status codes for http client -CR_DECLARE_SCOPED_ENUM (HttpClientResult, - Continue = 100, - SwitchingProtocol = 101, - Processing = 102, - EarlyHints = 103, - - Ok = 200, - Created = 201, - Accepted = 202, - NonAuthoritativeInformation = 203, - NoContent = 204, - ResetContent = 205, - PartialContent = 206, - MultiStatus = 207, - AlreadyReported = 208, - ImUsed = 226, - - MultipleChoice = 300, - MovedPermanently = 301, - Found = 302, - SeeOther = 303, - NotModified = 304, - UseProxy = 305, - TemporaryRedirect = 307, - PermanentRedirect = 308, - - BadRequest = 400, - Unauthorized = 401, - PaymentRequired = 402, - Forbidden = 403, - NotFound = 404, - MethodNotAllowed = 405, - NotAcceptable = 406, - ProxyAuthenticationRequired = 407, - RequestTimeout = 408, - Conflict = 409, - Gone = 410, - LengthRequired = 411, - PreconditionFailed = 412, - PayloadTooLarge = 413, - UriTooLong = 414, - UnsupportedMediaType = 415, - RangeNotSatisfiable = 416, - ExpectationFailed = 417, - ImaTeapot = 418, - MisdirectedRequest = 421, - UnprocessableEntity = 422, - Locked = 423, - FailedDependency = 424, - TooEarly = 425, - UpgradeRequired = 426, - PreconditionRequired = 428, - TooManyRequests = 429, - RequestHeaderFieldsTooLarge = 431, - UnavailableForLegalReasons = 451, - - InternalServerError = 500, - NotImplemented = 501, - BadGateway = 502, - ServiceUnavailable = 503, - GatewayTimeout = 504, - HttpVersionNotSupported = 505, - VariantAlsoNegotiates = 506, - InsufficientStorage = 507, - LoopDetected = 508, - NotExtended = 510, - NetworkAuthenticationRequired = 511, - - SocketError = -1, - ConnectError = -2, - HttpOnly = -3, - Undefined = -4, - NoLocalFile = -5, - LocalFileExists = -6 -) - -CR_NAMESPACE_BEGIN - -namespace detail { - - // simple http uri omitting query-string and port - struct HttpUri { - String path, protocol, host; - - public: - static HttpUri parse (StringRef uri) { - HttpUri result; - - if (uri.empty ()) { - return result; - } - size_t protocol = uri.find ("://"); - - if (protocol != String::InvalidIndex) { - result.protocol = uri.substr (0, protocol); - - size_t hostIndex = uri.find ("/", protocol + 3); - - if (hostIndex != String::InvalidIndex) { - result.path = uri.substr (hostIndex + 1); - result.host = uri.substr (protocol + 3, hostIndex - protocol - 3); - - return result; - } - } - return result; - } - }; - - struct SocketInit { - public: - static void start () { -#if defined(CR_WINDOWS) - WSADATA wsa; - - if (WSAStartup (MAKEWORD (2, 2), &wsa) != 0) { - logger.error ("Unable to inialize sockets."); - } -#endif - } - }; -} - -class Socket final : public DenyCopying { -private: - int32 socket_; - uint32 timeout_; - -public: - Socket () : socket_ (-1), timeout_ (2) - { } - - ~Socket () { - disconnect (); - } - -public: - bool connect (StringRef hostname) { - addrinfo hints {}, *result = nullptr; - plat.bzero (&hints, sizeof (hints)); - - constexpr auto NumericServ = 0x00000008; - - hints.ai_flags = NumericServ; - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - - if (getaddrinfo (hostname.chars (), "80", &hints, &result) != 0) { - return false; - } - socket_ = static_cast (socket (result->ai_family, result->ai_socktype, 0)); - - if (socket_ < 0) { - freeaddrinfo (result); - return false; - } - - auto getTimeouts = [&]() -> Twin { -#if defined (CR_WINDOWS) - DWORD tv = timeout_ * 1000; -#else - timeval tv { static_cast (timeout_), 0 }; -#endif - return { reinterpret_cast (&tv), static_cast (sizeof (tv)) }; - }; - auto timeouts = getTimeouts (); - - if (setsockopt (socket_, SOL_SOCKET, SO_RCVTIMEO, timeouts.first, timeouts.second) == -1) { - logger.message ("Unable to set SO_RCVTIMEO."); - } - - if (setsockopt (socket_, SOL_SOCKET, SO_SNDTIMEO, timeouts.first, timeouts.second) == -1) { - logger.message ("Unable to set SO_SNDTIMEO."); - } - - if (::connect (socket_, result->ai_addr, static_cast (result->ai_addrlen)) == -1) { - disconnect (); - freeaddrinfo (result); - - return false; - } - freeaddrinfo (result); - - return true; - } - - void setTimeout (uint32 timeout) { - timeout_ = timeout; - } - - void disconnect () { -#if defined(CR_WINDOWS) - if (socket_ != -1) { - closesocket (socket_); - } -#else - if (socket_ != -1) - close (socket_); -#endif - } - -public: - template int32 send (const U *buffer, int32 length) const { - return ::send (socket_, reinterpret_cast (buffer), length, 0); - } - - template int32 recv (U *buffer, int32 length) { - return ::recv (socket_, reinterpret_cast (buffer), length, 0); - } - -public: - static int32 CR_STDCALL sendto (int socket, const void *message, size_t length, int flags, const struct sockaddr *dest, int32 destLength) { -#if defined (CR_WINDOWS) - WSABUF buffer = { static_cast (length), const_cast (reinterpret_cast (message)) }; - DWORD sendLength = 0; - - if (WSASendTo (socket, &buffer, 1, &sendLength, flags, dest, destLength, NULL, NULL) == SOCKET_ERROR) { - errno = WSAGetLastError (); - return -1; - } - return static_cast (sendLength); -#else - iovec iov = { const_cast (message), length }; - msghdr msg {}; - - msg.msg_name = reinterpret_cast (const_cast (dest)); - msg.msg_namelen = destLength; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - - return sendmsg (socket, &msg, flags); -#endif - } -}; - -// simple http client for downloading/uploading files only -class HttpClient final : public Singleton { -private: - enum : int32 { - MaxReceiveErrors = 12, - DefaultSocketTimeout = 32 - }; - -private: - String userAgent_ = "crlib"; - HttpClientResult statusCode_ = HttpClientResult::Undefined; - int32 chunkSize_ = 4096; - bool initialized_ = false; - -public: - HttpClient () = default; - ~HttpClient () = default; - -private: - HttpClientResult parseResponseHeader (Socket *socket, uint8 *buffer) { - bool isFinished = false; - int32 pos = 0, symbols = 0, errors = 0; - - // prase response header - while (!isFinished && pos < chunkSize_) { - if (socket->recv (&buffer[pos], 1) < 1) { - if (++errors > MaxReceiveErrors) { - isFinished = true; - } - else { - continue; - } - } - - switch (buffer[pos]) { - case '\r': - break; - - case '\n': - isFinished = (symbols == 0); - symbols = 0; - break; - - default: - ++symbols; - break; - } - ++pos; - } - String response { reinterpret_cast (buffer) }; - size_t responseCodeStart = response.find ("HTTP/1.1"); - - if (responseCodeStart != String::InvalidIndex) { - String respCode = response.substr (responseCodeStart + 9, 3); - respCode.trim (); - - return static_cast (respCode.int_ ()); - } - return HttpClientResult::NotFound; - } - -public: - void startup () { - detail::SocketInit::start (); - initialized_ = true; - } - - // simple blocked download - bool downloadFile (StringRef url, StringRef localPath, int32 timeout = DefaultSocketTimeout) { - if (plat.win && !initialized_) { - plat.abort ("Sockets not initialized."); - } - - if (File::exists (localPath)) { - statusCode_ = HttpClientResult::LocalFileExists; - return false; - } - auto uri = detail::HttpUri::parse (url); - auto socket = cr::makeUnique (); - - // no https... - if (uri.protocol == "https") { - statusCode_ = HttpClientResult::HttpOnly; - return false; - } - socket->setTimeout (timeout); - - // unable to connect... - if (!socket->connect (uri.host)) { - statusCode_ = HttpClientResult::ConnectError; - return false; - } - - String request; - request.appendf ("GET /%s HTTP/1.1\r\n", uri.path); - request.append ("Accept: */*\r\n"); - request.append ("Connection: close\r\n"); - request.append ("Keep-Alive: 115\r\n"); - request.appendf ("User-Agent: %s\r\n", userAgent_); - request.appendf ("Host: %s\r\n\r\n", uri.host); - - if (socket->send (request.chars (), static_cast (request.length ())) < 1) { - statusCode_ = HttpClientResult::SocketError; - - return false; - } - SmallArray buffer (chunkSize_); - statusCode_ = parseResponseHeader (socket.get (), buffer.data ()); - - if (statusCode_ != HttpClientResult::Ok) { - return false; - } - - // receive the file - File file (localPath, "wb"); - - if (!file) { - statusCode_ = HttpClientResult::Undefined; - return false; - } - int32 length = 0; - int32 errors = 0; - - for (;;) { - length = socket->recv (buffer.data (), chunkSize_); - - if (length > 0) { - file.write (buffer.data (), length); - } - else if (++errors > 12) { - break; - } - } - statusCode_ = HttpClientResult::Ok; - - return true; - } - - bool uploadFile (StringRef url, StringRef localPath, const int32 timeout = DefaultSocketTimeout) { - if (plat.win && !initialized_) { - plat.abort ("Sockets not initialized."); - } - - if (!File::exists (localPath)) { - statusCode_ = HttpClientResult::NoLocalFile; - return false; - } - auto uri = detail::HttpUri::parse (url); - auto socket = cr::makeUnique (); - - // no https... - if (uri.protocol == "https") { - statusCode_ = HttpClientResult::HttpOnly; - return false; - } - socket->setTimeout (timeout); - - // unable to connect... - if (!socket->connect (uri.host)) { - statusCode_ = HttpClientResult::ConnectError; - return false; - } - - // receive the file - File file (localPath, "rb"); - - if (!file) { - statusCode_ = HttpClientResult::Undefined; - return false; - } - String boundaryName = localPath; - size_t boundarySlash = localPath.findLastOf ("\\/"); - - if (boundarySlash != String::InvalidIndex) { - boundaryName = localPath.substr (boundarySlash + 1); - } - StringRef boundaryLine = strings.format ("---crlib_upload_boundary_%d%d%d%d", rg.get (0, 9), rg.get (0, 9), rg.get (0, 9), rg.get (0, 9)); - - String request, start, end; - start.appendf ("--%s\r\n", boundaryLine); - start.appendf ("Content-Disposition: form-data; name='file'; filename='%s'\r\n", boundaryName); - start.append ("Content-Type: application/octet-stream\r\n\r\n"); - - end.appendf ("\r\n--%s--\r\n\r\n", boundaryLine); - - request.appendf ("POST /%s HTTP/1.1\r\n", uri.path); - request.appendf ("Host: %s\r\n", uri.host); - request.appendf ("User-Agent: %s\r\n", userAgent_); - request.appendf ("Content-Type: multipart/form-data; boundary=%s\r\n", boundaryLine); - request.appendf ("Content-Length: %d\r\n\r\n", file.length () + start.length () + end.length ()); - - // send the main request - if (socket->send (request.chars (), static_cast (request.length ())) < 1) { - statusCode_ = HttpClientResult::SocketError; - return false; - } - - // send boundary start - if (socket->send (start.chars (), static_cast (start.length ())) < 1) { - statusCode_ = HttpClientResult::SocketError; - - return false; - } - SmallArray buffer (chunkSize_); - int32 length = 0; - - for (;;) { - length = static_cast (file.read (buffer.data (), 1, chunkSize_)); - - if (length > 0) { - socket->send (buffer.data (), length); - } - else { - break; - } - } - - // send boundary end - if (socket->send (end.chars (), static_cast (end.length ())) < 1) { - statusCode_ = HttpClientResult::SocketError; - return false; - } - statusCode_ = parseResponseHeader (socket.get (), buffer.data ()); - - return statusCode_ == HttpClientResult::Ok; - } - -public: - void setUserAgent (StringRef ua) { - userAgent_ = ua; - } - - HttpClientResult getLastStatusCode () { - return statusCode_; - } - - void setChunkSize (int32 chunkSize) { - chunkSize_ = chunkSize; - } -}; - -// expose global http client -CR_EXPOSE_GLOBAL_SINGLETON (HttpClient, http); - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-lambda.h b/ext/crlib/cr-lambda.h deleted file mode 100644 index e3e48e4..0000000 --- a/ext/crlib/cr-lambda.h +++ /dev/null @@ -1,169 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include -#include - -CR_NAMESPACE_BEGIN - -template class Lambda; -template class Lambda { -private: - enum : uint32 { - LamdaSmallBufferLength = sizeof (void *) * 16 - }; - -private: - class LambdaFunctorWrapper { - public: - LambdaFunctorWrapper () = default; - virtual ~LambdaFunctorWrapper () = default; - - public: - virtual void move (uint8 *to) = 0; - virtual void small (uint8 *to) const = 0; - - virtual R invoke (Args &&...) = 0; - virtual UniquePtr clone () const = 0; - }; - - template class LambdaFunctor : public LambdaFunctorWrapper { - private: - T callable_; - - public: - LambdaFunctor (const T &callable) : LambdaFunctorWrapper (), callable_ (callable) - { } - - LambdaFunctor (T &&callable) : LambdaFunctorWrapper (), callable_ (cr::move (callable)) - { } - - ~LambdaFunctor () override = default; - - public: - void move (uint8 *to) override { - new (to) LambdaFunctor (cr::move (callable_)); - } - - void small (uint8 *to) const override { - new (to) LambdaFunctor (callable_); - } - - R invoke (Args &&... args) override { - return callable_ (cr::forward (args)...); - } - - UniquePtr clone () const override { - return makeUnique > (callable_); - } - }; - - union { - UniquePtr functor_; - uint8 small_[LamdaSmallBufferLength] { }; - }; - - bool ssoObject_ = false; - -private: - void destroy () { - if (ssoObject_) { - reinterpret_cast (small_)->~LambdaFunctorWrapper (); - } - else { - functor_.reset (); - } - } - - void swap (Lambda &rhs) noexcept { - cr::swap (rhs, *this); - } - -public: - explicit Lambda () noexcept : Lambda (nullptr) - { } - - Lambda (decltype (nullptr)) noexcept : functor_ (nullptr), ssoObject_ (false) - { } - - Lambda (const Lambda &rhs) { - if (rhs.ssoObject_) { - reinterpret_cast (rhs.small_)->small (small_); - } - else { - new (small_) UniquePtr (rhs.functor_->clone ()); - } - ssoObject_ = rhs.ssoObject_; - } - - Lambda (Lambda &&rhs) noexcept { - if (rhs.ssoObject_) { - reinterpret_cast (rhs.small_)->move (small_); - new (rhs.small_) UniquePtr (nullptr); - } - else { - new (small_) UniquePtr (cr::move (rhs.functor_)); - } - ssoObject_ = rhs.ssoObject_; - rhs.ssoObject_ = false; - } - - template Lambda (F function) { - if (cr::fix (sizeof (function) > LamdaSmallBufferLength)) { - ssoObject_ = false; - new (small_) UniquePtr (makeUnique > (cr::move (function))); - } - else { - ssoObject_ = true; - new (small_) LambdaFunctor (cr::move (function)); - } - } - - ~Lambda () { - destroy (); - } - -public: - Lambda &operator = (const Lambda &rhs) { - destroy (); - - Lambda tmp (rhs); - swap (tmp); - - return *this; - } - - Lambda &operator = (Lambda &&rhs) noexcept { - destroy (); - - if (rhs.ssoObject_) { - reinterpret_cast (rhs.small_)->move (small_); - new (rhs.small_) UniquePtr (nullptr); - } - else { - new (small_) UniquePtr (cr::move (rhs.functor_)); - } - - ssoObject_ = rhs.ssoObject_; - rhs.ssoObject_ = false; - - return *this; - } - - explicit operator bool () const noexcept { - return ssoObject_ || !!functor_; - } - -public: - R operator () (Args ...args) { - return ssoObject_ ? reinterpret_cast (small_)->invoke (cr::forward (args)...) : functor_->invoke (cr::forward (args)...); - } -}; - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-library.h b/ext/crlib/cr-library.h deleted file mode 100644 index 686415f..0000000 --- a/ext/crlib/cr-library.h +++ /dev/null @@ -1,132 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include -#include - -#if defined (CR_LINUX) || defined (CR_OSX) -# include -# include -# include -# include -# include -#endif - -CR_NAMESPACE_BEGIN - -// handling dynamic library loading -class SharedLibrary final : public DenyCopying { -public: - using Handle = void *; - -private: - Handle handle_ = nullptr; - bool unloadable_ = true; - -public: - explicit SharedLibrary () = default; - - SharedLibrary (StringRef file) { - if (file.empty ()) { - return; - } - load (file); - } - - ~SharedLibrary () { - unload (); - } - -public: - bool load (StringRef file, bool unloadable = true) noexcept { - if (*this) { - unload (); - } - unloadable_ = unloadable; - -#if defined (CR_WINDOWS) - handle_ = LoadLibraryA (file.chars ()); -#else - 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; - - if (!VirtualQuery (address, &mbi, sizeof (mbi))) { - return false; - } - - if (mbi.State != MEM_COMMIT) { - return false; - } - handle_ = reinterpret_cast (mbi.AllocationBase); -#else - Dl_info dli; - plat.bzero (&dli, sizeof (dli)); - - if (dladdr (address, &dli)) { - return load (dli.dli_fname, false); - } -#endif - return handle_ != nullptr; - } - - void unload () noexcept { - if (!handle_ || !unloadable_) { - return; - } - -#if defined (CR_WINDOWS) - FreeLibrary (static_cast (handle_)); -#else - dlclose (handle_); -#endif - handle_ = nullptr; - } - - template R resolve (const char *function) const { - if (!*this) { - return nullptr; - } - return SharedLibrary::getSymbol (handle (), function); - } - - Handle handle () const { - return handle_; - } - -public: - explicit operator bool () const { - return handle_ != nullptr; - } - -public: - template static inline R CR_STDCALL getSymbol (Handle module, const char *function) { - return reinterpret_cast ( -#if defined (CR_WINDOWS) - GetProcAddress (static_cast (module), function) -#else - dlsym (module, function) -#endif - ); - } -}; - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-logger.h b/ext/crlib/cr-logger.h deleted file mode 100644 index bb8a9c9..0000000 --- a/ext/crlib/cr-logger.h +++ /dev/null @@ -1,112 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include - -#include -#include - -CR_NAMESPACE_BEGIN - -class SimpleLogger final : public Singleton { -public: - using PrintFunction = Lambda ; - -private: - String filename_; - PrintFunction printFun_; - -public: - explicit SimpleLogger () = default; - ~SimpleLogger () = default; - -public: - class LogFile final { - private: - File handle_; - - public: - LogFile (StringRef filename) { - handle_.open (filename, "at"); - } - - ~LogFile () { - handle_.close (); - } - - public: - void print (StringRef msg) { - if (!handle_) { - return; - } - handle_.puts (msg.chars ()); - } - }; - -private: - void logToFile (const char *level, const char *msg) { - time_t ticks = time (&ticks); - tm timeinfo {}; - -#if defined (CR_WINDOWS) - localtime_s (&timeinfo, &ticks); -#else - localtime_r (&ticks, &timeinfo); -#endif - - auto timebuf = strings.chars (); - strftime (timebuf, StringBuffer::StaticBufferSize, "%Y-%m-%d %H:%M:%S", &timeinfo); - - LogFile lf (filename_); - lf.print (strings.format ("%s (%s): %s\n", timebuf, level, msg)); - } - -public: - template void fatal (const char *fmt, Args &&...args) { - auto msg = strings.format (fmt, cr::forward (args)...); - - logToFile ("FATAL", msg); - - if (printFun_) { - printFun_ (msg); - } - plat.abort (msg); - } - - template void error (const char *fmt, Args &&...args) { - auto msg = strings.format (fmt, cr::forward (args)...); - - logToFile ("ERROR", msg); - - if (printFun_) { - printFun_ (msg); - } - } - - template void message (const char *fmt, Args &&...args) { - auto msg = strings.format (fmt, cr::forward (args)...); - - logToFile ("INFO", msg); - - if (printFun_) { - printFun_ (msg); - } - } - -public: - void initialize (StringRef filename, PrintFunction printFunction) { - printFun_ = cr::move (printFunction); - filename_ = filename; - } -}; - -// expose global instance -CR_EXPOSE_GLOBAL_SINGLETON (SimpleLogger, logger); - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-math.h b/ext/crlib/cr-math.h deleted file mode 100644 index adb2b0c..0000000 --- a/ext/crlib/cr-math.h +++ /dev/null @@ -1,135 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include - -#if defined (CR_HAS_SSE) -# include -#endif - -#include - -CR_NAMESPACE_BEGIN - -constexpr float kFloatEpsilon = 0.01f; -constexpr float kFloatEqualEpsilon = 0.001f; -constexpr float kFloatCmpEpsilon = 1.192092896e-07f; - -constexpr float kMathPi = 3.141592653589793115997963468544185161590576171875f; -constexpr float kMathPiHalf = kMathPi * 0.5f; - -constexpr float kDegreeToRadians = kMathPi / 180.0f; -constexpr float kRadiansToDegree = 180.0f / kMathPi; - -constexpr bool fzero (const float e) { - return cr::abs (e) < kFloatEpsilon; -} - -constexpr bool fequal (const float a, const float b) { - return cr:: abs (a - b) < kFloatEqualEpsilon; -} - -constexpr float rad2deg (const float r) { - return r * kRadiansToDegree; -} - -constexpr float deg2rad (const float d) { - return d * kDegreeToRadians; -} - -constexpr float modAngles (const float a) { - return 360.0f / 65536.0f * (static_cast (a * (65536.0f / 360.0f)) & 65535); -} - -constexpr float normalizeAngles (const float a) { - return 360.0f / 65536.0f * (static_cast ((a + 180.0f) * (65536.0f / 360.0f)) & 65535) - 180.0f; -} - -constexpr float anglesDifference (const float a, const float b) { - return normalizeAngles (a - b); -} - -inline float sinf (const float value) { - return ::sinf (value); -} - -inline float cosf (const float value) { - return ::cosf (value); -} - -inline float atanf (const float value) { - return ::atanf (value); -} - -inline float atan2f (const float y, const float x) { - return ::atan2f (y, x); -} - -inline float powf (const float x, const float y) { - return ::powf (x, y); -} - -inline float sqrtf (const float value) { - return ::sqrtf (value); -} - -inline float tanf (const float value) { - return ::tanf (value); -} - -inline float ceilf (const float value) { - return ::ceilf (value); -} - -inline void sincosf (const float x, const float y, const float z, float *sines, float *cosines) { -#if defined (CR_HAS_SSE) - auto set = _mm_set_ps (x, y, z, 0.0f); - - auto _mm_sin = [] (__m128 rad) -> __m128 { - static auto pi2 = _mm_set_ps1 (kMathPi * 2); - static auto rp1 = _mm_set_ps1 (4.0f / kMathPi); - static auto rp2 = _mm_set_ps1 (-4.0f / (kMathPi * kMathPi)); - static auto val = _mm_cmpnlt_ps (rad, _mm_set_ps1 (kMathPi)); - static auto csi = _mm_castsi128_ps (_mm_set1_epi32 (0x80000000)); - - val = _mm_and_ps (val, pi2); - rad = _mm_sub_ps (rad, val); - val = _mm_cmpngt_ps (rad, _mm_set_ps1 (-kMathPi)); - val = _mm_and_ps (val, pi2); - rad = _mm_add_ps (rad, val); - val = _mm_mul_ps (_mm_andnot_ps (csi, rad), rp2); - val = _mm_add_ps (val, rp1); - - auto si = _mm_mul_ps (val, rad); - - val = _mm_mul_ps (_mm_andnot_ps (csi, si), si); - val = _mm_sub_ps (val, si); - val = _mm_mul_ps (val, _mm_set_ps1 (0.225f)); - - return _mm_add_ps (val, si); - }; - static auto hpi = _mm_set_ps1 (kMathPiHalf); - - auto s = _mm_sin (set); - auto c = _mm_sin (_mm_add_ps (set, hpi)); - - _mm_store_ps (sines, _mm_shuffle_ps (s, s, _MM_SHUFFLE (0, 1, 2, 3))); - _mm_store_ps (cosines, _mm_shuffle_ps (c, c, _MM_SHUFFLE (0, 1, 2, 3))); -#else - sines[0] = cr::sinf (x); - sines[1] = cr::sinf (y); - sines[2] = cr::sinf (z); - - cosines[0] = cr::cosf (x); - cosines[1] = cr::cosf (y); - cosines[2] = cr::cosf (z); -#endif -} - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-memory.h b/ext/crlib/cr-memory.h deleted file mode 100644 index b6350b5..0000000 --- a/ext/crlib/cr-memory.h +++ /dev/null @@ -1,52 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 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-movable.h b/ext/crlib/cr-movable.h deleted file mode 100644 index e3f0afc..0000000 --- a/ext/crlib/cr-movable.h +++ /dev/null @@ -1,56 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include - -CR_NAMESPACE_BEGIN - -namespace detail { - template struct ClearRef { - using Type = T; - }; - template struct ClearRef { - using Type = T; - }; - template struct ClearRef { - using Type = T; - }; -} - -template typename detail::ClearRef ::Type constexpr &&move (T &&type) noexcept { - return static_cast ::Type &&> (type); -} - -template constexpr T &&forward (typename detail::ClearRef ::Type &type) noexcept { - return static_cast (type); -} - -template constexpr T &&forward (typename detail::ClearRef ::Type &&type) noexcept { - return static_cast (type); -} - -template inline void swap (T &left, T &right) noexcept { - auto temp = cr::move (left); - left = cr::move (right); - right = cr::move (temp); -} - -template inline void swap (T (&left)[S], T (&right)[S]) noexcept { - if (&left == &right) { - return; - } - auto begin = left; - auto end = begin + S; - - for (auto temp = right; begin != end; ++begin, ++temp) { - cr::swap (*begin, *temp); - } -} - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-override.h b/ext/crlib/cr-override.h deleted file mode 100644 index 2f8adb8..0000000 --- a/ext/crlib/cr-override.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include -#include - -void *operator new (size_t size) { - return cr::Memory::get (size); -} - -void *operator new [] (size_t size) { - 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"); -} diff --git a/ext/crlib/cr-platform.h b/ext/crlib/cr-platform.h deleted file mode 100644 index 08b7887..0000000 --- a/ext/crlib/cr-platform.h +++ /dev/null @@ -1,301 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -CR_NAMESPACE_BEGIN - -// detects the build platform -#if defined(__linux__) -# define CR_LINUX -#elif defined(__APPLE__) -# define CR_OSX -#elif defined(_WIN32) -# define CR_WINDOWS -#endif - -#if defined(__ANDROID__) -# define CR_ANDROID -# if defined(LOAD_HARDFP) -# define CR_ANDROID_HARD_FP -# endif -#endif - -// detects the compiler -#if defined(_MSC_VER) -# define CR_CXX_MSVC _MSC_VER -#endif - -#if defined(__clang__) -# define CR_CXX_CLANG __clang__ -#endif - -#if defined(__INTEL_COMPILER) -# define CR_CXX_INTEL __INTEL_COMPILER -#endif - -#if defined(__GNUC__) -# define CR_CXX_GCC __GNUC__ -#endif - -// configure macroses -#define CR_LINKAGE_C extern "C" - -#if defined(CR_WINDOWS) -# define CR_EXPORT CR_LINKAGE_C __declspec (dllexport) -# define CR_STDCALL __stdcall -#elif defined(CR_LINUX) || defined(CR_OSX) -# define CR_EXPORT CR_LINKAGE_C __attribute__((visibility("default"))) -# define CR_STDCALL -#else -# error "Can't configure export macros. Compiler unrecognized." -#endif - -#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__amd64) || (defined(_MSC_VER) && defined(_M_X64)) -# define CR_ARCH_X64 -#elif defined(__i686) || defined(__i686__) || defined(__i386) || defined(__i386__) || defined(i386) || (defined(_MSC_VER) && defined(_M_IX86)) -# define CR_ARCH_X86 -#endif - -#if defined(__arm__) -# define CR_ARCH_ARM -# if defined(__aarch64__) -# define CR_ARCH_ARM64 -# endif -#endif - -#if (defined(CR_ARCH_X86) || defined(CR_ARCH_X64)) && !defined(CR_DEBUG) -# define CR_HAS_SSE -#endif - -#if defined(CR_HAS_SSE) -# if defined (CR_CXX_MSVC) -# define CR_ALIGN16 __declspec (align (16)) -# else -# define CR_ALIGN16 __attribute__((aligned(16))) -# endif -#endif - -// disable warnings regarding intel compiler -#if defined(CR_CXX_INTEL) -# pragma warning (disable : 3280) // declaration hides member "XXX" (declared at line XX) -# pragma warning (disable : 2415) // variable "XXX" of static storage duration was declared but never referenced -# pragma warning (disable : 873) // function "operator new(size_t={unsigned int}, void *)" has no corresponding operator delete (to be called if an exception is thrown during initialization of an allocated object) -# pragma warning (disable : 383) // value copied to temporary, reference to temporary used -# pragma warning (disable : 11074 11075) // remarks about inlining bla-bla-bla -#endif - -// msvc provides us placement new by default -#if defined (CR_CXX_MSVC) -# define __PLACEMENT_NEW_INLINE 1 -#endif - -// disabled gcc warnings -#if defined (CR_CXX_GCC) -# pragma GCC diagnostic ignored "-Wignored-attributes" -#endif - -// avoid linking to GLIBC_2.27 -#if defined (CR_LINUX) && !defined (CR_CXX_INTEL) - __asm__ (".symver powf, powf@GLIBC_2.0"); -#endif - -CR_NAMESPACE_END - -#if defined(CR_WINDOWS) -# define WIN32_LEAN_AND_MEAN -# include -# include - -# if defined (max) -# undef max -# endif - -# if defined (min) -# undef min -# endif - -#else -# include -# include -# include -# include -#endif - -#include -#include -#include -#include -#include - -#if defined (CR_ANDROID) -# include -#endif - -#include - -CR_NAMESPACE_BEGIN - -// helper struct for platform detection -struct Platform : public Singleton { - bool win = false; - bool nix = false; - bool osx = false; - bool android = false; - bool hfp = false; - bool x64 = false; - bool arm = false; - - char appName[64] = {}; - - Platform () { -#if defined(CR_WINDOWS) - win = true; -#endif - -#if defined(CR_ANDROID) - android = true; - -# if defined (CR_ANDROID_HARD_FP) - hfp = true; -# endif -#endif - -#if defined(CR_LINUX) - nix = true; -#endif - -#if defined(CR_OSX) - osx = true; -#endif - -#if defined(CR_ARCH_X64) || defined(CR_ARCH_ARM64) - x64 = true; -#endif - -#if defined(CR_ARCH_ARM) - arm = true; - android = true; -#endif - } - - // set the app name - void setAppName (const char *name) { - snprintf (appName, cr::bufsize (appName), "%s", name); - } - - // helper platform-dependant functions - template bool checkPointer (U *ptr) { -#if defined(CR_WINDOWS) - if (IsBadCodePtr (reinterpret_cast (ptr))) { - return false; - } -#else - (void) (ptr); -#endif - return true; - } - - bool createDirectory (const char *dir) { - int result = 0; -#if defined(CR_WINDOWS) - result = _mkdir (dir); -#else - result = mkdir (dir, 0777); -#endif - return !!result; - } - - bool removeFile (const char *dir) { -#if defined(CR_WINDOWS) - _unlink (dir); -#else - unlink (dir); -#endif - return true; - } - - bool hasModule (const char *mod) { -#if defined(CR_WINDOWS) - return GetModuleHandleA (mod) != nullptr; -#else - (void) (mod); - return true; -#endif - } - - float seconds () { -#if defined(CR_WINDOWS) - LARGE_INTEGER count, freq; - - count.QuadPart = 0; - freq.QuadPart = 0; - - QueryPerformanceFrequency (&freq); - QueryPerformanceCounter (&count); - - return static_cast (count.QuadPart / freq.QuadPart); -#else - timeval tv; - gettimeofday (&tv, nullptr); - - static auto startTime = tv.tv_sec; - - return static_cast (tv.tv_sec - startTime); -#endif - } - - void abort (const char *msg = "OUT OF MEMORY!") noexcept { - fprintf (stderr, "%s\n", msg); - -#if defined (CR_ANDROID) - __android_log_write (ANDROID_LOG_ERROR, appName, msg); -#endif - -#if defined(CR_WINDOWS) - DestroyWindow (GetForegroundWindow ()); - MessageBoxA (GetActiveWindow (), msg, appName, MB_ICONSTOP); -#endif - ::abort (); - } - - // anologue of memset - template void bzero (U *ptr, size_t len) noexcept { -#if defined (CR_WINDOWS) - memset (ptr, 0, len); -#else - auto zeroing = reinterpret_cast (ptr); - - for (size_t i = 0; i < len; ++i) { - zeroing[i] = 0; - } -#endif - } - - const char *env (const char *var) { - static char result[256]; - bzero (result, sizeof (result)); - -#if defined(CR_WINDOWS) && !defined(CR_CXX_GCC) - char *buffer = nullptr; - size_t size = 0; - - if (_dupenv_s (&buffer, &size, var) == 0 && buffer != nullptr) { - strncpy_s (result, buffer, sizeof (result)); - free (buffer); - } -#else - strncpy (result, getenv (var), cr::bufsize (result)); -#endif - return result; - } -}; - -// expose platform singleton -CR_EXPOSE_GLOBAL_SINGLETON (Platform, plat); - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-random.h b/ext/crlib/cr-random.h deleted file mode 100644 index e453641..0000000 --- a/ext/crlib/cr-random.h +++ /dev/null @@ -1,71 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include - -CR_NAMESPACE_BEGIN - -// based on: https://github.com/jeudesprits/PSWyhash/blob/master/Sources/CWyhash/include/wyhash.h -class Random : public Singleton { -private: - uint64 div_ { static_cast (1) << 32ull }; - uint64 state_ { static_cast (time (nullptr)) }; - -public: - explicit Random () = default; - ~Random () = default; - -private: - uint64 wyrand64 () { - constexpr uint64 wyp0 = 0xa0761d6478bd642full, wyp1 = 0xe7037ed1a0b428dbull; - state_ += wyp0; - - return mul (state_ ^ wyp1, state_); - } - - uint32 wyrand32 () { - return static_cast (wyrand64 ()); - } - -private: - uint64_t rotr (uint64 v, uint32 k) { - return (v >> k) | (v << (64 - k)); - } - - uint64 mul (uint64 a, uint64 b) { - uint64 hh = (a >> 32) * (b >> 32); - uint64 hl = (b >> 32) * static_cast (b); - - uint64 lh = static_cast (a) * (b >> 32); - uint64 ll = static_cast (static_cast (a) * static_cast (b)); - - return rotr (hl, 32) ^ rotr (lh, 32) ^ hh ^ ll; - } - -public: - template U get (U, U) = delete; - - template int32 get (int32 low, int32 high) { - return static_cast (wyrand32 () * (static_cast (high) - static_cast (low) + 1.0) / div_ + static_cast (low)); - } - - template float get (float low, float high) { - return static_cast (wyrand32 () * (static_cast (high) - static_cast (low)) / (div_ - 1) + static_cast (low)); - } - -public: - bool chance (int32 limit) { - return get (0, 100) < limit; - } -}; - -// expose global random generator -CR_EXPOSE_GLOBAL_SINGLETON (Random, rg); - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-string.h b/ext/crlib/cr-string.h deleted file mode 100644 index b8455d1..0000000 --- a/ext/crlib/cr-string.h +++ /dev/null @@ -1,1150 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include -#include - -#include -#include -#include -#include -#include - -CR_NAMESPACE_BEGIN - -// helper for null-termination -static const char kNullChar = '\0'; - -// overloaded version of snprintf to take String and StringRef as char arrays -class SNPrintfWrap : public Singleton { -public: - SNPrintfWrap () = default; - ~SNPrintfWrap () = default; - -private: - template U cast (U value) { - return value; - } - - const char *cast (const class String &value); - const char *cast (const class StringRef &value); - -public: - template int32 exec (char *buffer, const size_t maxSize, const char *fmt, Args &&...args) { - if (buffer) { - buffer[0] = kNullChar; - } - return snprintf (buffer, maxSize, fmt, cast (cr::forward (args))...); - } -}; - -// expose global format wrap -CR_EXPOSE_GLOBAL_SINGLETON (SNPrintfWrap, fmtwrap); - - -// simple non-owning string class like std::string_view -class StringRef { -private: - static constexpr size_t len (const char *str) noexcept { - return !*str ? 0 : 1 + len (str + 1); - } - -public: - static constexpr uint32 fnv1a32 (const char *str, uint32 hash = 0x811c9dc5) { - return !*str ? hash : fnv1a32 (str + 1, (hash ^ static_cast (*str)) * 0x01000193); - } - -public: - enum : size_t { - InvalidIndex = static_cast (-1) - }; - -private: - const char *chars_ = ""; - size_t length_ {}; - -public: - constexpr StringRef () noexcept = default; - - constexpr StringRef (const char *chars) : chars_ (chars), length_ (chars ? len (chars) : 0) - { } - - constexpr StringRef (const char *chars, size_t length) : chars_ (chars), length_ (length) - { } - - constexpr StringRef (decltype (nullptr)) : chars_ (""), length_ (0) - { } - - constexpr StringRef (decltype (nullptr), size_t) : chars_ (""), length_ (0) - { } - -public: - StringRef (const String &str); - -public: - constexpr StringRef (const StringRef &) = default; - constexpr StringRef &operator = (const StringRef &) = default; - - constexpr StringRef (StringRef &&) = default; - constexpr StringRef &operator = (StringRef &&) = default; - -public: - constexpr bool operator == (const StringRef &rhs) const { - return length_ == rhs.length_ && memcmp (chars_, rhs.chars_, length_) == 0; - } - - constexpr bool operator != (const StringRef &rhs) const { - return !(*this == rhs); - } - - constexpr char operator [] (size_t index) const { - return chars_[index]; - } - -public: - constexpr bool empty () const { - return length_ == 0; - } - - constexpr size_t length () const { - return length_; - } - - constexpr const char *chars () const { - return chars_; - } - - constexpr bool equals (const StringRef &rhs) const { - return *this == rhs; - } - - constexpr uint32 hash () const { - return fnv1a32 (chars ()); - } - -public: - int32 int_ () const { - return atoi (chars ()); - } - - float float_ () const { - return static_cast (atof (chars ())); - } - - bool startsWith (StringRef prefix) const { - return prefix.length () <= length_ && strncmp (chars (), prefix.chars (), prefix.length ()) == 0; - } - - bool endsWith (StringRef suffix) const { - return suffix.length () <= length_ && strncmp (chars () + length_ - suffix.length (), suffix.chars (), suffix.length ()) == 0; - } - - constexpr bool contains (StringRef rhs) const { - return find (rhs) != InvalidIndex; - } - - constexpr size_t find (char pattern, size_t start = 0) const { - for (size_t i = start; i < length_; ++i) { - if (chars_[i] == pattern) { - return i; - } - } - return InvalidIndex; - } - - constexpr size_t find (StringRef pattern, size_t start = 0) const { - if (pattern.length () > length_ || start > length_) { - return InvalidIndex; - } - - for (size_t i = start; i <= length_ - pattern.length (); ++i) { - size_t index = 0; - - for (; index < pattern.length () && chars_[index]; ++index) { - if (chars_[i + index] != pattern[index]) { - break; - } - } - - if (!pattern[index]) { - return i; - } - } - return InvalidIndex; - } - - constexpr size_t rfind (char pattern) const { - for (size_t i = length_; i != 0; i--) { - if (chars_[i] == pattern) { - return i; - } - } - return InvalidIndex; - } - - constexpr size_t rfind (StringRef pattern) const { - if (pattern.length () > length_) { - return InvalidIndex; - } - bool match = true; - - for (size_t i = length_ - 1; i >= pattern.length (); i--) { - match = true; - - for (size_t j = pattern.length () - 1; j > 0; j--) { - if (chars_[i + i] != pattern[j]) { - match = false; - break; - } - } - - if (match) { - return i; - } - } - return InvalidIndex; - } - - constexpr size_t findFirstOf (StringRef pattern, size_t start = 0) const { - for (size_t i = start; i < length_; ++i) { - for (size_t j = 0; j < pattern.length (); ++j) { - if (chars_[i] == pattern[j]) { - return i; - } - } - } - return InvalidIndex; - } - - constexpr size_t findLastOf (StringRef pattern) const { - for (size_t i = length_ - 1; i > 0; i--) { - for (size_t j = 0; j < pattern.length (); ++j) { - if (chars_[i] == pattern[j]) { - return i; - } - } - } - return InvalidIndex; - } - - constexpr size_t findFirstNotOf (StringRef pattern, size_t start = 0) const { - bool different = true; - - for (size_t i = start; i < length_; ++i) { - different = true; - - for (size_t j = 0; j < pattern.length (); ++j) { - if (chars_[i] == pattern[j]) { - different = false; - break; - } - } - - if (different) { - return i; - } - } - return InvalidIndex; - } - - constexpr size_t findLastNotOf (StringRef pattern) const { - bool different = true; - - for (size_t i = length_ - 1; i > 0; i--) { - different = true; - - for (size_t j = 0; j < pattern.length (); ++j) { - if (chars_[i] == pattern[j]) { - different = false; - break; - } - } - if (different) { - return i; - } - } - return InvalidIndex; - } - - constexpr size_t countChar (char ch) const { - size_t count = 0; - - for (size_t i = 0, e = length (); i != e; ++i) { - if (chars_[i] == ch) { - ++count; - } - } - return count; - } - - constexpr size_t countStr (StringRef pattern) const { - if (pattern.length () > length_) { - return 0; - } - size_t count = 0; - - for (size_t i = 0, e = length_ - pattern.length () + 1; i != e; ++i) { - if (substr (i, pattern.length ()) == pattern) { - ++count; - } - } - return count; - } - - constexpr StringRef substr (size_t start, size_t count = InvalidIndex) const { - start = cr::min (start, length_); - - if (count == InvalidIndex) { - count = length_; - } - return { chars () + start, cr::min (count, length () - start) }; - } - - template constexpr Array split (StringRef delim) const { - Array tokens; - size_t prev = 0, pos = 0; - - while ((pos = find (delim, pos)) != InvalidIndex) { - tokens.push (substr (prev, pos - prev)); - prev = ++pos; - } - tokens.push (substr (prev, pos - prev)); - - return tokens; - } - - template constexpr Array split (size_t maxLength) const { - Array tokens; - - for (size_t i = 0; i < length (); i += maxLength) { - tokens.emplace (substr (i, maxLength)); - } - return tokens; - } - -public: - constexpr const char *begin () const { - return chars_; - } - - constexpr const char *end () const { - return chars_ + length_; - } -}; - -// simple std::string analogue -class String final { -public: - enum : size_t { - InvalidIndex = StringRef::InvalidIndex - }; - -private: - UniquePtr chars_ {}; - size_t length_ {}; - size_t capacity_ {}; - -private: - size_t getGrowFactor (const size_t length) const { - auto capacity = capacity_ ? capacity_ : cr::max (12U, length + 1); - - while (length_ + length > capacity) { - capacity += capacity * 2 / 3; - } - return capacity + (length < 4 ? 8 : length); - } - - size_t calcLength (const char *str, const size_t length) { - return length > 0 ? length : (str ? strlen (str) : 0); - } - - void reset () { - capacity_ = 0; - length_ = 0; - } - -public: - String () = default; - ~String () = default; - - String (const char *str, size_t length = 0) { - assign (str, length); - } - - String (const String &str) { - assign (str.chars ()); - } - - String (StringRef str) { - assign (str.chars (), str.length ()); - } - - String (const char ch) { - assign (ch); - } - - String (String &&rhs) noexcept : chars_ (cr::move (rhs.chars_)), length_ (rhs.length_), capacity_ (rhs.capacity_) { - rhs.reset (); - } - - String (UniquePtr &&rhs, size_t length) noexcept : chars_ (cr::move (rhs)), length_ (length) - {} - -public: - void resize (const size_t amount) noexcept { - if (length_ + amount < capacity_) { - return; - } - const size_t factor = getGrowFactor (amount) + length_; - - if (chars_) { - auto transfer = makeUnique (factor); - memcpy (&transfer[0], &chars_[0], length_); - - chars_ = cr::move (transfer); - } - else { - chars_ = makeUnique (factor); - chars_[0] = kNullChar; - } - capacity_ = factor; - } - - String &assign (const char *str, size_t length = 0) { - length = calcLength (str, length); - - resize (length); - - if (str) { - memcpy (&chars_[0], str, length); - } - else { - chars_[0] = kNullChar; - } - - length_ = length; - chars_[length_] = kNullChar; - - return *this; - } - - String &assign (const String &str, size_t length = 0) { - return assign (str.chars (), length); - } - - String &assign (const char ch) { - return assign (&ch, 1); - } - - String &append (const char *str, size_t length = 0) { - length = calcLength (str, length); - - resize (length); - memcpy (chars_.get () + length_, str, length); - - length_ += length; - chars_[length_] = kNullChar; - - return *this; - } - - String &append (const String &str, size_t length = 0) { - return append (str.chars (), length); - } - - String &append (const char ch) { - return append (&ch, 1); - } - - template String &assignf (const char *fmt, Args &&...args) { - const size_t size = fmtwrap.exec (nullptr, 0, fmt, args...); - - SmallArray buffer (size + 1); - fmtwrap.exec (buffer.data (), size + 1, fmt, cr::forward (args)...); - - return assign (buffer.data ()); - } - - template String &appendf (const char *fmt, Args &&...args) { - if (empty ()) { - return assignf (fmt, cr::forward (args)...); - } - const size_t size = fmtwrap.exec (nullptr, 0, fmt, args...) + length (); - - SmallArray buffer (size + 1); - fmtwrap.exec (buffer.data (), size + 1, fmt, cr::forward (args)...); - - return append (buffer.data ()); - } - -public: - const char &at (size_t index) const { - return chars ()[index]; - } - - char &at (size_t index) { - return const_cast (chars ())[index]; - } - - const char *chars () const { - return chars_ ? chars_.get () : &kNullChar; - } - - size_t length () const { - return length_; - } - - size_t capacity () const { - return capacity_; - } - - bool empty () const { - return !length_; - } - - void clear () { - assign (&kNullChar); - } - - StringRef str () const { - return { chars_.get (), length_ }; - } - -public: - bool insert (size_t index, StringRef str) { - if (str.empty ()) { - return false; - } - - if (index >= length_) { - append (str.chars (), str.length ()); - } - else { - resize (length_ + str.length ()); - - for (size_t i = length_; i > index; --i) { - at (i + str.length () - 1) = at (i - 1); - } - - for (size_t i = 0; i < str.length (); ++i) { - at (i + index) = str[i]; - } - length_ += str.length (); - } - return true; - } - - bool erase (size_t index, size_t count = 1) { - if (index + count > length_) { - return false; - } - length_ -= count; - - for (size_t i = index; i < length_; ++i) { - at (i) = at (i + count); - } - return true; - } - - size_t replace (StringRef needle, StringRef to) { - if (needle.empty () || to.empty ()) { - return 0; - } - size_t replaced = 0, pos = 0; - - while (pos < length ()) { - pos = find (needle, pos); - - if (pos == InvalidIndex) { - break; - } - erase (pos, needle.length ()); - insert (pos, to); - - pos += to.length (); - ++replaced; - } - return replaced; - } - - String &lowercase () { - for (auto &ch : *this) { - ch = static_cast (::tolower (ch)); - } - return *this; - } - - String &uppercase () { - for (auto &ch : *this) { - ch = static_cast (::toupper (ch)); - } - return *this; - } - - String <rim (StringRef characters = "\r\n\t ") { - size_t begin = length_; - - for (size_t i = 0; i < begin; ++i) { - if (characters.find (at (i)) == InvalidIndex) { - begin = i; - break; - } - } - return *this = substr (begin, length_ - begin); - } - - String &rtrim (StringRef characters = "\r\n\t ") { - size_t end = 0; - - for (size_t i = length_; i > 0; --i) { - if (characters.find (at (i - 1)) == InvalidIndex) { - end = i; - break; - } - } - return *this = substr (0, end); - } - - String &trim (StringRef characters = "\r\n\t ") { - return ltrim (characters).rtrim (characters); - } - -public: - uint32 hash () const { - return str ().hash (); - } - - bool contains (StringRef rhs) const { - return str ().contains (rhs); - } - - bool startsWith (StringRef prefix) const { - return str ().startsWith (prefix); - } - - bool endsWith (StringRef suffix) const { - return str ().endsWith (suffix); - } - - size_t find (char pattern, size_t start = 0) const { - return str ().find (pattern, start); - } - - size_t find (StringRef pattern, size_t start = 0) const { - return str ().find (pattern, start); - } - - size_t rfind (char pattern) const { - return str ().rfind (pattern); - } - - size_t rfind (StringRef pattern) const { - return str ().rfind (pattern); - } - - size_t findFirstOf (StringRef pattern, size_t start = 0) const { - return str ().findFirstOf (pattern, start); - } - - size_t findLastOf (StringRef pattern) const { - return str ().findLastOf (pattern); - } - - size_t findFirstNotOf (StringRef pattern, size_t start = 0) const { - return str ().findFirstNotOf (pattern, start); - } - - size_t findLastNotOf (StringRef pattern) const { - return str ().findLastNotOf (pattern); - } - - size_t countChar (char ch) const { - return str ().countChar (ch); - } - - size_t countStr (StringRef pattern) const { - return str ().countStr (pattern); - } - - String substr (size_t start, size_t count = InvalidIndex) const { - return str ().substr (start, count); - } - - Array split (StringRef delim) const { - return str ().split (delim); - } - - Array split (size_t maxLength) const { - return str ().split (maxLength); - } - -public: - int32 int_ () const { - return str ().int_ (); - } - - float float_ () const { - return str ().float_ (); - } - - // for range-based loops -public: - char *begin () { - return const_cast (chars ()); - } - - char *begin () const { - return const_cast (chars ()); - } - - char *end () { - return begin () + length_; - } - - char *end () const { - return begin () + length_; - } - -public: - String &operator = (String &&rhs) noexcept { - if (this != &rhs) { - chars_ = cr::move (rhs.chars_); - length_ = rhs.length_; - capacity_ = rhs.capacity_; - - rhs.reset (); - } - return *this; - } - - String &operator = (const String &rhs) { - return assign (rhs); - } - - String &operator = (const char *rhs) { - return assign (rhs); - } - - String &operator = (char rhs) { - return assign (rhs); - } - - String &operator += (const String &rhs) { - return append (rhs); - } - - String &operator += (const char *rhs) { - return append (rhs); - } - - const char &operator [] (size_t index) const { - return at (index); - } - - char &operator [] (size_t index) { - return at (index); - } - - friend String operator + (const String &lhs, char rhs) { - return String (lhs).append (rhs); - } - - friend String operator + (char lhs, const String &rhs) { - return String (lhs).append (rhs); - } - - friend String operator + (const String &lhs, const char *rhs) { - return String (lhs).append (rhs); - } - - friend String operator + (const char *lhs, const String &rhs) { - return String (lhs).append (rhs); - } - - friend String operator + (const String &lhs, const String &rhs) { - return String (lhs).append (rhs); - } - - friend bool operator == (const String &lhs, const String &rhs) { - return lhs.str ().equals (rhs); - } - - friend bool operator == (const char *lhs, const String &rhs) { - return rhs.str ().equals (lhs); - } - - friend bool operator == (const String &lhs, const char *rhs) { - return lhs.str ().equals (rhs); - } - - friend bool operator != (const String &lhs, const String &rhs) { - return !lhs.str ().equals (rhs); - } - - friend bool operator != (const char *lhs, const String &rhs) { - return !rhs.str ().equals (lhs); - } - - friend bool operator != (const String &lhs, const char *rhs) { - return !lhs.str ().equals (rhs); - } - -public: - static String join (const Array &sequence, StringRef delim, const size_t start = 0) { - if (sequence.empty ()) { - return ""; - } - - if (sequence.length () == 1) { - return sequence.at (0); - } - String result; - - for (size_t index = start; index < sequence.length (); ++index) { - if (index != start) { - result += delim + sequence[index]; - } - else { - result += sequence[index]; - } - } - return result; - } -}; - -// constructor from string to string_ref -inline StringRef::StringRef (const String &str) : chars_ (str.chars ()), length_ (str.length ()) -{ } - -// wrapping String for snprintf -inline const char *SNPrintfWrap::cast (const String &value) { - return value.chars (); -} - -// wrapping StringRef for snprintf -inline const char *SNPrintfWrap::cast (const StringRef &value) { - return value.chars (); -} - -// simple rotation-string pool for holding temporary data passed to different modules and for formatting -class StringBuffer final : public Singleton { -public: - enum : size_t { - StaticBufferSize = static_cast (768), - RotationCount = static_cast (32) - }; - -private: - char data_[RotationCount + 1][StaticBufferSize] {}; - size_t rotate_ = 0; - -public: - StringBuffer () = default; - ~StringBuffer () = default; - -public: - char *chars () noexcept { - if (++rotate_ >= RotationCount) { - rotate_ = 0; - } - auto result = data_[cr::clamp (rotate_, 0, RotationCount)]; - result[0] = kNullChar; - - return result; - } - - template U *format (const U *fmt, Args &&...args) noexcept { - auto buffer = Singleton ::instance ()->chars (); - fmtwrap.exec (buffer, StaticBufferSize, fmt, args...); - - return buffer; - } - - template U *format (const U *fmt) noexcept { - auto buffer = Singleton ::instance ()->chars (); - copy (buffer, fmt, StaticBufferSize); - - return buffer; - } - - // checks if string is not empty - bool isEmpty (const char *input) const noexcept { - if (input == nullptr) { - return true; - } - return *input == kNullChar; - } - - bool matches (const char *str1, const char *str2) noexcept { -#if defined(CR_WINDOWS) - return _stricmp (str1, str2) == 0; -#else - return ::strcasecmp (str1, str2) == 0; -#endif - } - - template U *copy (U *dst, const U *src, size_t len) noexcept { -#if defined(CR_WINDOWS) - strncpy_s (dst, len, src, len - 1); - return dst; -#else - return strncpy (dst, src, len); -#endif - } - - template U *concat (U *dst, const U *src, size_t len) noexcept { -#if defined(CR_WINDOWS) - strncat_s (dst, len, src, len - 1); - return dst; -#else - return strncat (dst, src, len); -#endif - } -}; - -// expose global string pool -CR_EXPOSE_GLOBAL_SINGLETON (StringBuffer, strings); - -// some limited utf8 stuff -class Utf8Tools : public Singleton { -private: - enum : int32 { - Utf8MaxChars = 706 - }; - -private: - // sample implementation from unicode home page: https://web.archive.org/web/19970105220809/http://www.stonehand.com/unicode/standard/fss-utf.html - struct Utf8Table { - int32 cmask, cval, shift; - long lmask, lval; - - Utf8Table (int32 cmask, int32 cval, int32 shift, long lmask, long lval) : - cmask (cmask), cval (cval), shift (shift), lmask (lmask), lval (lval) { - - } - }; - - struct Utf8CaseTable { - int32 from, to; - }; - -private: - Utf8CaseTable upperTable_[Utf8MaxChars] = { - { 0x0061, 0x0041 }, { 0x0062, 0x0042 }, { 0x0063, 0x0043 }, { 0x0064, 0x0044 }, { 0x0065, 0x0045 }, { 0x0066, 0x0046 }, { 0x0067, 0x0047 }, { 0x0068, 0x0048 }, - { 0x0069, 0x0049 }, { 0x006a, 0x004a }, { 0x006b, 0x004b }, { 0x006c, 0x004c }, { 0x006d, 0x004d }, { 0x006e, 0x004e }, { 0x006f, 0x004f }, { 0x0070, 0x0050 }, - { 0x0071, 0x0051 }, { 0x0072, 0x0052 }, { 0x0073, 0x0053 }, { 0x0074, 0x0054 }, { 0x0075, 0x0055 }, { 0x0076, 0x0056 }, { 0x0077, 0x0057 }, { 0x0078, 0x0058 }, - { 0x0079, 0x0059 }, { 0x007a, 0x005a }, { 0x00e0, 0x00c0 }, { 0x00e1, 0x00c1 }, { 0x00e2, 0x00c2 }, { 0x00e3, 0x00c3 }, { 0x00e4, 0x00c4 }, { 0x00e5, 0x00c5 }, - { 0x00e6, 0x00c6 }, { 0x00e7, 0x00c7 }, { 0x00e8, 0x00c8 }, { 0x00e9, 0x00c9 }, { 0x00ea, 0x00ca }, { 0x00eb, 0x00cb }, { 0x00ec, 0x00cc }, { 0x00ed, 0x00cd }, - { 0x00ee, 0x00ce }, { 0x00ef, 0x00cf }, { 0x00f0, 0x00d0 }, { 0x00f1, 0x00d1 }, { 0x00f2, 0x00d2 }, { 0x00f3, 0x00d3 }, { 0x00f4, 0x00d4 }, { 0x00f5, 0x00d5 }, - { 0x00f6, 0x00d6 }, { 0x00f8, 0x00d8 }, { 0x00f9, 0x00d9 }, { 0x00fa, 0x00da }, { 0x00fb, 0x00db }, { 0x00fc, 0x00dc }, { 0x00fd, 0x00dd }, { 0x00fe, 0x00de }, - { 0x00ff, 0x0178 }, { 0x0101, 0x0100 }, { 0x0103, 0x0102 }, { 0x0105, 0x0104 }, { 0x0107, 0x0106 }, { 0x0109, 0x0108 }, { 0x010b, 0x010a }, { 0x010d, 0x010c }, - { 0x010f, 0x010e }, { 0x0111, 0x0110 }, { 0x0113, 0x0112 }, { 0x0115, 0x0114 }, { 0x0117, 0x0116 }, { 0x0119, 0x0118 }, { 0x011b, 0x011a }, { 0x011d, 0x011c }, - { 0x011f, 0x011e }, { 0x0121, 0x0120 }, { 0x0123, 0x0122 }, { 0x0125, 0x0124 }, { 0x0127, 0x0126 }, { 0x0129, 0x0128 }, { 0x012b, 0x012a }, { 0x012d, 0x012c }, - { 0x012f, 0x012e }, { 0x0131, 0x0049 }, { 0x0133, 0x0132 }, { 0x0135, 0x0134 }, { 0x0137, 0x0136 }, { 0x013a, 0x0139 }, { 0x013c, 0x013b }, { 0x013e, 0x013d }, - { 0x0140, 0x013f }, { 0x0142, 0x0141 }, { 0x0144, 0x0143 }, { 0x0146, 0x0145 }, { 0x0148, 0x0147 }, { 0x014b, 0x014a }, { 0x014d, 0x014c }, { 0x014f, 0x014e }, - { 0x0151, 0x0150 }, { 0x0153, 0x0152 }, { 0x0155, 0x0154 }, { 0x0157, 0x0156 }, { 0x0159, 0x0158 }, { 0x015b, 0x015a }, { 0x015d, 0x015c }, { 0x015f, 0x015e }, - { 0x0161, 0x0160 }, { 0x0163, 0x0162 }, { 0x0165, 0x0164 }, { 0x0167, 0x0166 }, { 0x0169, 0x0168 }, { 0x016b, 0x016a }, { 0x016d, 0x016c }, { 0x016f, 0x016e }, - { 0x0171, 0x0170 }, { 0x0173, 0x0172 }, { 0x0175, 0x0174 }, { 0x0177, 0x0176 }, { 0x017a, 0x0179 }, { 0x017c, 0x017b }, { 0x017e, 0x017d }, { 0x0183, 0x0182 }, - { 0x0185, 0x0184 }, { 0x0188, 0x0187 }, { 0x018c, 0x018b }, { 0x0192, 0x0191 }, { 0x0195, 0x01f6 }, { 0x0199, 0x0198 }, { 0x019e, 0x0220 }, { 0x01a1, 0x01a0 }, - { 0x01a3, 0x01a2 }, { 0x01a5, 0x01a4 }, { 0x01a8, 0x01a7 }, { 0x01ad, 0x01ac }, { 0x01b0, 0x01af }, { 0x01b4, 0x01b3 }, { 0x01b6, 0x01b5 }, { 0x01b9, 0x01b8 }, - { 0x01bd, 0x01bc }, { 0x01bf, 0x01f7 }, { 0x01c6, 0x01c4 }, { 0x01c9, 0x01c7 }, { 0x01cc, 0x01ca }, { 0x01ce, 0x01cd }, { 0x01d0, 0x01cf }, { 0x01d2, 0x01d1 }, - { 0x01d4, 0x01d3 }, { 0x01d6, 0x01d5 }, { 0x01d8, 0x01d7 }, { 0x01da, 0x01d9 }, { 0x01dc, 0x01db }, { 0x01dd, 0x018e }, { 0x01df, 0x01de }, { 0x01e1, 0x01e0 }, - { 0x01e3, 0x01e2 }, { 0x01e5, 0x01e4 }, { 0x01e7, 0x01e6 }, { 0x01e9, 0x01e8 }, { 0x01eb, 0x01ea }, { 0x01ed, 0x01ec }, { 0x01ef, 0x01ee }, { 0x01f3, 0x01f1 }, - { 0x01f5, 0x01f4 }, { 0x01f9, 0x01f8 }, { 0x01fb, 0x01fa }, { 0x01fd, 0x01fc }, { 0x01ff, 0x01fe }, { 0x0201, 0x0200 }, { 0x0203, 0x0202 }, { 0x0205, 0x0204 }, - { 0x0207, 0x0206 }, { 0x0209, 0x0208 }, { 0x020b, 0x020a }, { 0x020d, 0x020c }, { 0x020f, 0x020e }, { 0x0211, 0x0210 }, { 0x0213, 0x0212 }, { 0x0215, 0x0214 }, - { 0x0217, 0x0216 }, { 0x0219, 0x0218 }, { 0x021b, 0x021a }, { 0x021d, 0x021c }, { 0x021f, 0x021e }, { 0x0223, 0x0222 }, { 0x0225, 0x0224 }, { 0x0227, 0x0226 }, - { 0x0229, 0x0228 }, { 0x022b, 0x022a }, { 0x022d, 0x022c }, { 0x022f, 0x022e }, { 0x0231, 0x0230 }, { 0x0233, 0x0232 }, { 0x0253, 0x0181 }, { 0x0254, 0x0186 }, - { 0x0256, 0x0189 }, { 0x0257, 0x018a }, { 0x0259, 0x018f }, { 0x025b, 0x0190 }, { 0x0260, 0x0193 }, { 0x0263, 0x0194 }, { 0x0268, 0x0197 }, { 0x0269, 0x0196 }, - { 0x026f, 0x019c }, { 0x0272, 0x019d }, { 0x0275, 0x019f }, { 0x0280, 0x01a6 }, { 0x0283, 0x01a9 }, { 0x0288, 0x01ae }, { 0x028a, 0x01b1 }, { 0x028b, 0x01b2 }, - { 0x0292, 0x01b7 }, { 0x03ac, 0x0386 }, { 0x03ad, 0x0388 }, { 0x03ae, 0x0389 }, { 0x03af, 0x038a }, { 0x03b1, 0x0391 }, { 0x03b2, 0x0392 }, { 0x03b3, 0x0393 }, - { 0x03b4, 0x0394 }, { 0x03b5, 0x0395 }, { 0x03b6, 0x0396 }, { 0x03b7, 0x0397 }, { 0x03b8, 0x0398 }, { 0x03b9, 0x0345 }, { 0x03ba, 0x039a }, { 0x03bb, 0x039b }, - { 0x03bc, 0x00b5 }, { 0x03bd, 0x039d }, { 0x03be, 0x039e }, { 0x03bf, 0x039f }, { 0x03c0, 0x03a0 }, { 0x03c1, 0x03a1 }, { 0x03c3, 0x03a3 }, { 0x03c4, 0x03a4 }, - { 0x03c5, 0x03a5 }, { 0x03c6, 0x03a6 }, { 0x03c7, 0x03a7 }, { 0x03c8, 0x03a8 }, { 0x03c9, 0x03a9 }, { 0x03ca, 0x03aa }, { 0x03cb, 0x03ab }, { 0x03cc, 0x038c }, - { 0x03cd, 0x038e }, { 0x03ce, 0x038f }, { 0x03d9, 0x03d8 }, { 0x03db, 0x03da }, { 0x03dd, 0x03dc }, { 0x03df, 0x03de }, { 0x03e1, 0x03e0 }, { 0x03e3, 0x03e2 }, - { 0x03e5, 0x03e4 }, { 0x03e7, 0x03e6 }, { 0x03e9, 0x03e8 }, { 0x03eb, 0x03ea }, { 0x03ed, 0x03ec }, { 0x03ef, 0x03ee }, { 0x03f2, 0x03f9 }, { 0x03f8, 0x03f7 }, - { 0x03fb, 0x03fa }, { 0x0430, 0x0410 }, { 0x0431, 0x0411 }, { 0x0432, 0x0412 }, { 0x0433, 0x0413 }, { 0x0434, 0x0414 }, { 0x0435, 0x0415 }, { 0x0436, 0x0416 }, - { 0x0437, 0x0417 }, { 0x0438, 0x0418 }, { 0x0439, 0x0419 }, { 0x043a, 0x041a }, { 0x043b, 0x041b }, { 0x043c, 0x041c }, { 0x043d, 0x041d }, { 0x043e, 0x041e }, - { 0x043f, 0x041f }, { 0x0440, 0x0420 }, { 0x0441, 0x0421 }, { 0x0442, 0x0422 }, { 0x0443, 0x0423 }, { 0x0444, 0x0424 }, { 0x0445, 0x0425 }, { 0x0446, 0x0426 }, - { 0x0447, 0x0427 }, { 0x0448, 0x0428 }, { 0x0449, 0x0429 }, { 0x044a, 0x042a }, { 0x044b, 0x042b }, { 0x044c, 0x042c }, { 0x044d, 0x042d }, { 0x044e, 0x042e }, - { 0x044f, 0x042f }, { 0x0450, 0x0400 }, { 0x0451, 0x0401 }, { 0x0452, 0x0402 }, { 0x0453, 0x0403 }, { 0x0454, 0x0404 }, { 0x0455, 0x0405 }, { 0x0456, 0x0406 }, - { 0x0457, 0x0407 }, { 0x0458, 0x0408 }, { 0x0459, 0x0409 }, { 0x045a, 0x040a }, { 0x045b, 0x040b }, { 0x045c, 0x040c }, { 0x045d, 0x040d }, { 0x045e, 0x040e }, - { 0x045f, 0x040f }, { 0x0461, 0x0460 }, { 0x0463, 0x0462 }, { 0x0465, 0x0464 }, { 0x0467, 0x0466 }, { 0x0469, 0x0468 }, { 0x046b, 0x046a }, { 0x046d, 0x046c }, - { 0x046f, 0x046e }, { 0x0471, 0x0470 }, { 0x0473, 0x0472 }, { 0x0475, 0x0474 }, { 0x0477, 0x0476 }, { 0x0479, 0x0478 }, { 0x047b, 0x047a }, { 0x047d, 0x047c }, - { 0x047f, 0x047e }, { 0x0481, 0x0480 }, { 0x048b, 0x048a }, { 0x048d, 0x048c }, { 0x048f, 0x048e }, { 0x0491, 0x0490 }, { 0x0493, 0x0492 }, { 0x0495, 0x0494 }, - { 0x0497, 0x0496 }, { 0x0499, 0x0498 }, { 0x049b, 0x049a }, { 0x049d, 0x049c }, { 0x049f, 0x049e }, { 0x04a1, 0x04a0 }, { 0x04a3, 0x04a2 }, { 0x04a5, 0x04a4 }, - { 0x04a7, 0x04a6 }, { 0x04a9, 0x04a8 }, { 0x04ab, 0x04aa }, { 0x04ad, 0x04ac }, { 0x04af, 0x04ae }, { 0x04b1, 0x04b0 }, { 0x04b3, 0x04b2 }, { 0x04b5, 0x04b4 }, - { 0x04b7, 0x04b6 }, { 0x04b9, 0x04b8 }, { 0x04bb, 0x04ba }, { 0x04bd, 0x04bc }, { 0x04bf, 0x04be }, { 0x04c2, 0x04c1 }, { 0x04c4, 0x04c3 }, { 0x04c6, 0x04c5 }, - { 0x04c8, 0x04c7 }, { 0x04ca, 0x04c9 }, { 0x04cc, 0x04cb }, { 0x04ce, 0x04cd }, { 0x04d1, 0x04d0 }, { 0x04d3, 0x04d2 }, { 0x04d5, 0x04d4 }, { 0x04d7, 0x04d6 }, - { 0x04d9, 0x04d8 }, { 0x04db, 0x04da }, { 0x04dd, 0x04dc }, { 0x04df, 0x04de }, { 0x04e1, 0x04e0 }, { 0x04e3, 0x04e2 }, { 0x04e5, 0x04e4 }, { 0x04e7, 0x04e6 }, - { 0x04e9, 0x04e8 }, { 0x04eb, 0x04ea }, { 0x04ed, 0x04ec }, { 0x04ef, 0x04ee }, { 0x04f1, 0x04f0 }, { 0x04f3, 0x04f2 }, { 0x04f5, 0x04f4 }, { 0x04f9, 0x04f8 }, - { 0x0501, 0x0500 }, { 0x0503, 0x0502 }, { 0x0505, 0x0504 }, { 0x0507, 0x0506 }, { 0x0509, 0x0508 }, { 0x050b, 0x050a }, { 0x050d, 0x050c }, { 0x050f, 0x050e }, - { 0x0561, 0x0531 }, { 0x0562, 0x0532 }, { 0x0563, 0x0533 }, { 0x0564, 0x0534 }, { 0x0565, 0x0535 }, { 0x0566, 0x0536 }, { 0x0567, 0x0537 }, { 0x0568, 0x0538 }, - { 0x0569, 0x0539 }, { 0x056a, 0x053a }, { 0x056b, 0x053b }, { 0x056c, 0x053c }, { 0x056d, 0x053d }, { 0x056e, 0x053e }, { 0x056f, 0x053f }, { 0x0570, 0x0540 }, - { 0x0571, 0x0541 }, { 0x0572, 0x0542 }, { 0x0573, 0x0543 }, { 0x0574, 0x0544 }, { 0x0575, 0x0545 }, { 0x0576, 0x0546 }, { 0x0577, 0x0547 }, { 0x0578, 0x0548 }, - { 0x0579, 0x0549 }, { 0x057a, 0x054a }, { 0x057b, 0x054b }, { 0x057c, 0x054c }, { 0x057d, 0x054d }, { 0x057e, 0x054e }, { 0x057f, 0x054f }, { 0x0580, 0x0550 }, - { 0x0581, 0x0551 }, { 0x0582, 0x0552 }, { 0x0583, 0x0553 }, { 0x0584, 0x0554 }, { 0x0585, 0x0555 }, { 0x0586, 0x0556 }, { 0x1e01, 0x1e00 }, { 0x1e03, 0x1e02 }, - { 0x1e05, 0x1e04 }, { 0x1e07, 0x1e06 }, { 0x1e09, 0x1e08 }, { 0x1e0b, 0x1e0a }, { 0x1e0d, 0x1e0c }, { 0x1e0f, 0x1e0e }, { 0x1e11, 0x1e10 }, { 0x1e13, 0x1e12 }, - { 0x1e15, 0x1e14 }, { 0x1e17, 0x1e16 }, { 0x1e19, 0x1e18 }, { 0x1e1b, 0x1e1a }, { 0x1e1d, 0x1e1c }, { 0x1e1f, 0x1e1e }, { 0x1e21, 0x1e20 }, { 0x1e23, 0x1e22 }, - { 0x1e25, 0x1e24 }, { 0x1e27, 0x1e26 }, { 0x1e29, 0x1e28 }, { 0x1e2b, 0x1e2a }, { 0x1e2d, 0x1e2c }, { 0x1e2f, 0x1e2e }, { 0x1e31, 0x1e30 }, { 0x1e33, 0x1e32 }, - { 0x1e35, 0x1e34 }, { 0x1e37, 0x1e36 }, { 0x1e39, 0x1e38 }, { 0x1e3b, 0x1e3a }, { 0x1e3d, 0x1e3c }, { 0x1e3f, 0x1e3e }, { 0x1e41, 0x1e40 }, { 0x1e43, 0x1e42 }, - { 0x1e45, 0x1e44 }, { 0x1e47, 0x1e46 }, { 0x1e49, 0x1e48 }, { 0x1e4b, 0x1e4a }, { 0x1e4d, 0x1e4c }, { 0x1e4f, 0x1e4e }, { 0x1e51, 0x1e50 }, { 0x1e53, 0x1e52 }, - { 0x1e55, 0x1e54 }, { 0x1e57, 0x1e56 }, { 0x1e59, 0x1e58 }, { 0x1e5b, 0x1e5a }, { 0x1e5d, 0x1e5c }, { 0x1e5f, 0x1e5e }, { 0x1e61, 0x1e60 }, { 0x1e63, 0x1e62 }, - { 0x1e65, 0x1e64 }, { 0x1e67, 0x1e66 }, { 0x1e69, 0x1e68 }, { 0x1e6b, 0x1e6a }, { 0x1e6d, 0x1e6c }, { 0x1e6f, 0x1e6e }, { 0x1e71, 0x1e70 }, { 0x1e73, 0x1e72 }, - { 0x1e75, 0x1e74 }, { 0x1e77, 0x1e76 }, { 0x1e79, 0x1e78 }, { 0x1e7b, 0x1e7a }, { 0x1e7d, 0x1e7c }, { 0x1e7f, 0x1e7e }, { 0x1e81, 0x1e80 }, { 0x1e83, 0x1e82 }, - { 0x1e85, 0x1e84 }, { 0x1e87, 0x1e86 }, { 0x1e89, 0x1e88 }, { 0x1e8b, 0x1e8a }, { 0x1e8d, 0x1e8c }, { 0x1e8f, 0x1e8e }, { 0x1e91, 0x1e90 }, { 0x1e93, 0x1e92 }, - { 0x1e95, 0x1e94 }, { 0x1ea1, 0x1ea0 }, { 0x1ea3, 0x1ea2 }, { 0x1ea5, 0x1ea4 }, { 0x1ea7, 0x1ea6 }, { 0x1ea9, 0x1ea8 }, { 0x1eab, 0x1eaa }, { 0x1ead, 0x1eac }, - { 0x1eaf, 0x1eae }, { 0x1eb1, 0x1eb0 }, { 0x1eb3, 0x1eb2 }, { 0x1eb5, 0x1eb4 }, { 0x1eb7, 0x1eb6 }, { 0x1eb9, 0x1eb8 }, { 0x1ebb, 0x1eba }, { 0x1ebd, 0x1ebc }, - { 0x1ebf, 0x1ebe }, { 0x1ec1, 0x1ec0 }, { 0x1ec3, 0x1ec2 }, { 0x1ec5, 0x1ec4 }, { 0x1ec7, 0x1ec6 }, { 0x1ec9, 0x1ec8 }, { 0x1ecb, 0x1eca }, { 0x1ecd, 0x1ecc }, - { 0x1ecf, 0x1ece }, { 0x1ed1, 0x1ed0 }, { 0x1ed3, 0x1ed2 }, { 0x1ed5, 0x1ed4 }, { 0x1ed7, 0x1ed6 }, { 0x1ed9, 0x1ed8 }, { 0x1edb, 0x1eda }, { 0x1edd, 0x1edc }, - { 0x1edf, 0x1ede }, { 0x1ee1, 0x1ee0 }, { 0x1ee3, 0x1ee2 }, { 0x1ee5, 0x1ee4 }, { 0x1ee7, 0x1ee6 }, { 0x1ee9, 0x1ee8 }, { 0x1eeb, 0x1eea }, { 0x1eed, 0x1eec }, - { 0x1eef, 0x1eee }, { 0x1ef1, 0x1ef0 }, { 0x1ef3, 0x1ef2 }, { 0x1ef5, 0x1ef4 }, { 0x1ef7, 0x1ef6 }, { 0x1ef9, 0x1ef8 }, { 0x1f00, 0x1f08 }, { 0x1f01, 0x1f09 }, - { 0x1f02, 0x1f0a }, { 0x1f03, 0x1f0b }, { 0x1f04, 0x1f0c }, { 0x1f05, 0x1f0d }, { 0x1f06, 0x1f0e }, { 0x1f07, 0x1f0f }, { 0x1f10, 0x1f18 }, { 0x1f11, 0x1f19 }, - { 0x1f12, 0x1f1a }, { 0x1f13, 0x1f1b }, { 0x1f14, 0x1f1c }, { 0x1f15, 0x1f1d }, { 0x1f20, 0x1f28 }, { 0x1f21, 0x1f29 }, { 0x1f22, 0x1f2a }, { 0x1f23, 0x1f2b }, - { 0x1f24, 0x1f2c }, { 0x1f25, 0x1f2d }, { 0x1f26, 0x1f2e }, { 0x1f27, 0x1f2f }, { 0x1f30, 0x1f38 }, { 0x1f31, 0x1f39 }, { 0x1f32, 0x1f3a }, { 0x1f33, 0x1f3b }, - { 0x1f34, 0x1f3c }, { 0x1f35, 0x1f3d }, { 0x1f36, 0x1f3e }, { 0x1f37, 0x1f3f }, { 0x1f40, 0x1f48 }, { 0x1f41, 0x1f49 }, { 0x1f42, 0x1f4a }, { 0x1f43, 0x1f4b }, - { 0x1f44, 0x1f4c }, { 0x1f45, 0x1f4d }, { 0x1f51, 0x1f59 }, { 0x1f53, 0x1f5b }, { 0x1f55, 0x1f5d }, { 0x1f57, 0x1f5f }, { 0x1f60, 0x1f68 }, { 0x1f61, 0x1f69 }, - { 0x1f62, 0x1f6a }, { 0x1f63, 0x1f6b }, { 0x1f64, 0x1f6c }, { 0x1f65, 0x1f6d }, { 0x1f66, 0x1f6e }, { 0x1f67, 0x1f6f }, { 0x1f70, 0x1fba }, { 0x1f71, 0x1fbb }, - { 0x1f72, 0x1fc8 }, { 0x1f73, 0x1fc9 }, { 0x1f74, 0x1fca }, { 0x1f75, 0x1fcb }, { 0x1f76, 0x1fda }, { 0x1f77, 0x1fdb }, { 0x1f78, 0x1ff8 }, { 0x1f79, 0x1ff9 }, - { 0x1f7a, 0x1fea }, { 0x1f7b, 0x1feb }, { 0x1f7c, 0x1ffa }, { 0x1f7d, 0x1ffb }, { 0x1f80, 0x1f88 }, { 0x1f81, 0x1f89 }, { 0x1f82, 0x1f8a }, { 0x1f83, 0x1f8b }, - { 0x1f84, 0x1f8c }, { 0x1f85, 0x1f8d }, { 0x1f86, 0x1f8e }, { 0x1f87, 0x1f8f }, { 0x1f90, 0x1f98 }, { 0x1f91, 0x1f99 }, { 0x1f92, 0x1f9a }, { 0x1f93, 0x1f9b }, - { 0x1f94, 0x1f9c }, { 0x1f95, 0x1f9d }, { 0x1f96, 0x1f9e }, { 0x1f97, 0x1f9f }, { 0x1fa0, 0x1fa8 }, { 0x1fa1, 0x1fa9 }, { 0x1fa2, 0x1faa }, { 0x1fa3, 0x1fab }, - { 0x1fa4, 0x1fac }, { 0x1fa5, 0x1fad }, { 0x1fa6, 0x1fae }, { 0x1fa7, 0x1faf }, { 0x1fb0, 0x1fb8 }, { 0x1fb1, 0x1fb9 }, { 0x1fb3, 0x1fbc }, { 0x1fc3, 0x1fcc }, - { 0x1fd0, 0x1fd8 }, { 0x1fd1, 0x1fd9 }, { 0x1fe0, 0x1fe8 }, { 0x1fe1, 0x1fe9 }, { 0x1fe5, 0x1fec }, { 0x1ff3, 0x1ffc }, { 0x2170, 0x2160 }, { 0x2171, 0x2161 }, - { 0x2172, 0x2162 }, { 0x2173, 0x2163 }, { 0x2174, 0x2164 }, { 0x2175, 0x2165 }, { 0x2176, 0x2166 }, { 0x2177, 0x2167 }, { 0x2178, 0x2168 }, { 0x2179, 0x2169 }, - { 0x217a, 0x216a }, { 0x217b, 0x216b }, { 0x217c, 0x216c }, { 0x217d, 0x216d }, { 0x217e, 0x216e }, { 0x217f, 0x216f }, { 0x24d0, 0x24b6 }, { 0x24d1, 0x24b7 }, - { 0x24d2, 0x24b8 }, { 0x24d3, 0x24b9 }, { 0x24d4, 0x24ba }, { 0x24d5, 0x24bb }, { 0x24d6, 0x24bc }, { 0x24d7, 0x24bd }, { 0x24d8, 0x24be }, { 0x24d9, 0x24bf }, - { 0x24da, 0x24c0 }, { 0x24db, 0x24c1 }, { 0x24dc, 0x24c2 }, { 0x24dd, 0x24c3 }, { 0x24de, 0x24c4 }, { 0x24df, 0x24c5 }, { 0x24e0, 0x24c6 }, { 0x24e1, 0x24c7 }, - { 0x24e2, 0x24c8 }, { 0x24e3, 0x24c9 }, { 0x24e4, 0x24ca }, { 0x24e5, 0x24cb }, { 0x24e6, 0x24cc }, { 0x24e7, 0x24cd }, { 0x24e8, 0x24ce }, { 0x24e9, 0x24cf }, - { 0xff41, 0xff21 }, { 0xff42, 0xff22 }, { 0xff43, 0xff23 }, { 0xff44, 0xff24 }, { 0xff45, 0xff25 }, { 0xff46, 0xff26 }, { 0xff47, 0xff27 }, { 0xff48, 0xff28 }, - { 0xff49, 0xff29 }, { 0xff4a, 0xff2a }, { 0xff4b, 0xff2b }, { 0xff4c, 0xff2c }, { 0xff4d, 0xff2d }, { 0xff4e, 0xff2e }, { 0xff4f, 0xff2f }, { 0xff50, 0xff30 }, - { 0xff51, 0xff31 }, { 0xff52, 0xff32 }, { 0xff53, 0xff33 }, { 0xff54, 0xff34 }, { 0xff55, 0xff35 }, { 0xff56, 0xff36 }, { 0xff57, 0xff37 }, { 0xff58, 0xff38 }, - { 0xff59, 0xff39 }, { 0xff5a, 0xff3a } - }; - -private: - SmallArray utfTable_; - -private: - void buildTable () { - utfTable_.emplace (0x80, 0x00, 0 * 6, 0x7f, 0); // 1 byte sequence - utfTable_.emplace (0xe0, 0xc0, 1 * 6, 0x7ff, 0x80); // 2 byte sequence - utfTable_.emplace (0xf0, 0xe0, 2 * 6, 0xffff, 0x800); // 3 byte sequence - utfTable_.emplace (0xf8, 0xf0, 3 * 6, 0x1fffff, 0x10000); // 4 byte sequence - utfTable_.emplace (0xfc, 0xf8, 4 * 6, 0x3ffffff, 0x200000); // 5 byte sequence - utfTable_.emplace (0xfe, 0xfc, 5 * 6, 0x7fffffff, 0x4000000); // 6 byte sequence - } - - int32 multiByteToWideChar (wchar_t *wide, const char *mbs) { - int32 len = 0; - - auto ch = *mbs; - auto lval = static_cast (ch); - - for (const auto &table : utfTable_) { - len++; - - if ((ch & table.cmask) == table.cval) { - lval &= table.lmask; - - if (lval < table.lval) { - return -1; - } - *wide = static_cast (lval); - return len; - } - mbs++; - auto test = (*mbs ^ 0x80) & 0xff; - - if (test & 0xc0) { - return -1; - } - lval = (lval << 6) | test; - } - return -1; - } - - int32 wideCharToMultiByte (char *mbs, wchar_t wide) { - if (!mbs) { - return 0; - } - long lmask = wide; - int32 len = 0; - - for (const auto &table : utfTable_) { - len++; - - if (lmask <= table.lmask) { - auto ch = table.shift; - *mbs = static_cast (table.cval | (lmask >> ch)); - - while (ch > 0) { - ch -= 6; - mbs++; - - *mbs = 0x80 | ((lmask >> ch) & 0x3F); - } - return len; - } - } - return -1; - } - -public: - Utf8Tools () { - buildTable (); - } - - ~Utf8Tools () = default; - -public: - wchar_t toUpper (wchar_t ch) { - int32 bottom = 0; - int32 top = Utf8MaxChars - 1; - - while (bottom <= top) { - const auto mid = (bottom + top) / 2; - auto cur = static_cast (upperTable_[mid].from); - - if (ch == cur) { - return static_cast (upperTable_[mid].to); - } - if (ch > cur) { - bottom = mid + 1; - } - else { - top = mid - 1; - } - } - return ch; - } - - String strToUpper (StringRef in) { - String result (in); - - auto ptr = const_cast (result.chars ()); - int32 len = 0; - - while (*ptr) { - wchar_t wide = 0; - - multiByteToWideChar (&wide, ptr); - len += wideCharToMultiByte (ptr, toUpper (wide)); - - if (static_cast (len) >= result.length ()) { - break; - } - } - return result.uppercase (); - } -}; - -// expose global utf8 tools -CR_EXPOSE_GLOBAL_SINGLETON (Utf8Tools, utf8tools); - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-twin.h b/ext/crlib/cr-twin.h deleted file mode 100644 index 0543e5f..0000000 --- a/ext/crlib/cr-twin.h +++ /dev/null @@ -1,56 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include -#include - -CR_NAMESPACE_BEGIN - -// simple pair (twin) -template class Twin final { -public: - A first; - B second; - -public: - template Twin (T &&a, U &&b) : first (cr::forward (a)), second (cr::forward (b)) { } - template Twin (const Twin &rhs) : first (rhs.first), second (rhs.second) { } - template Twin (Twin &&rhs) noexcept : first (cr::move (rhs.first)), second (cr::move (rhs.second)) { } - -public: - explicit Twin () = default; - ~Twin () = default; - -public: - template Twin &operator = (const Twin &rhs) { - first = rhs.first; - second = rhs.second; - - return *this; - } - - template Twin &operator = (Twin &&rhs) { - first = cr::move (rhs.first); - second = cr::move (rhs.second); - - return *this; - } - - // specialized operators for binary heap, do not use as it's test only second element -public: - friend bool operator < (const Twin &a, const Twin &b) { - return a.second < b.second; - } - - friend bool operator > (const Twin &a, const Twin &b) { - return b.second < a.second; - } -}; - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-ulz.h b/ext/crlib/cr-ulz.h deleted file mode 100644 index e82a8b9..0000000 --- a/ext/crlib/cr-ulz.h +++ /dev/null @@ -1,312 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include - -CR_NAMESPACE_BEGIN - -// see https://github.com/encode84/ulz/ -class ULZ final : public Singleton { -public: - enum : int32 { - Excess = 16, - UncompressFailure = -1 - }; - -private: - enum : int32 { - WindowBits = 17, - WindowSize = cr::bit (WindowBits), - WindowMask = WindowSize - 1, - - MinMatch = 4, - MaxChain = cr::bit (5), - - HashBits = 19, - HashLength = cr::bit (HashBits), - EmptyHash = -1, - }; - - -private: - SmallArray hashTable_; - SmallArray prevTable_; - -public: - explicit ULZ () { - hashTable_.resize (HashLength); - prevTable_.resize (WindowSize); - } - - ~ULZ () = default; - -public: - int32 compress (uint8 *in, int32 inputLength, uint8 *out) { - for (auto &htb : hashTable_) { - htb = EmptyHash; - } - auto op = out; - - int32 anchor = 0; - int32 cur = 0; - - while (cur < inputLength) { - const int32 maxMatch = inputLength - cur; - - int32 bestLength = 0; - int32 dist = 0; - - if (maxMatch >= MinMatch) { - const auto limit = cr::max (cur - WindowSize, EmptyHash); - - int32 chainLength = MaxChain; - int32 lookup = hashTable_[hash32 (&in[cur])]; - - while (lookup > limit) { - if (in[lookup + bestLength] == in[cur + bestLength] && load (&in[lookup]) == load (&in[cur])) { - int32 length = MinMatch; - - while (length < maxMatch && in[lookup + length] == in[cur + length]) { - ++length; - } - - if (length > bestLength) { - bestLength = length; - dist = cur - lookup; - - if (length == maxMatch) { - break; - } - } - } - - if (--chainLength == 0) { - break; - } - lookup = prevTable_[lookup & WindowMask]; - } - } - - if (bestLength == MinMatch && (cur - anchor) >= (7 + 128)) { - bestLength = 0; - } - - if (bestLength >= MinMatch && bestLength < maxMatch && (cur - anchor) != 6) { - const auto next = cur + 1; - const auto target = bestLength + 1; - const auto limit = cr::max (next - WindowSize, EmptyHash); - - int32 chainLength = MaxChain; - int32 lookup = hashTable_[hash32 (&in[next])]; - - while (lookup > limit) { - if (in[lookup + bestLength] == in[next + bestLength] && load (&in[lookup]) == load (&in[next])) { - int32 length = MinMatch; - - while (length < target && in[lookup + length] == in[next + length]) { - ++length; - } - - if (length == target) { - bestLength = 0; - break; - } - } - - if (--chainLength == 0) { - break; - } - lookup = prevTable_[lookup & WindowMask]; - } - } - - if (bestLength >= MinMatch) { - const auto length = bestLength - MinMatch; - const auto token = ((dist >> 12) & 16) + cr::min (length, 15); - - if (anchor != cur) { - const auto run = cur - anchor; - - if (run >= 7) { - add (op, (7 << 5) + token); - encode (op, run - 7); - } - else { - add (op, (run << 5) + token); - } - copy (op, &in[anchor], run); - op += run; - } - else { - add (op, token); - } - - if (length >= 15) { - encode (op, length - 15); - } - store16 (op, static_cast (dist)); - op += 2; - - while (bestLength-- != 0) { - const auto hash = hash32 (&in[cur]); - - prevTable_[cur & WindowMask] = hashTable_[hash]; - hashTable_[hash] = cur++; - } - anchor = cur; - } - else { - const auto hash = hash32 (&in[cur]); - - prevTable_[cur & WindowMask] = hashTable_[hash]; - hashTable_[hash] = cur++; - } - } - - if (anchor != cur) { - const auto run = cur - anchor; - - if (run >= 7) { - add (op, 7 << 5); - encode (op, run - 7); - } - else { - add (op, run << 5); - } - copy (op, &in[anchor], run); - op += run; - } - return static_cast (op - out); - } - - int32 uncompress (uint8 *in, int32 inputLength, uint8 *out, int32 outLength) { - auto op = out; - auto ip = in; - - const auto opEnd = op + outLength; - const auto ipEnd = ip + inputLength; - - while (ip < ipEnd) { - const auto token = *ip++; - - if (token >= 32) { - auto run = token >> 5; - - if (run == 7) { - run += decode (ip); - } - - if ((opEnd - op) < run || (ipEnd - ip) < run) { - return UncompressFailure; - } - copy (op, ip, run); - - op += run; - ip += run; - - if (ip >= ipEnd) { - break; - } - } - auto length = (token & 15) + MinMatch; - - if (length == (15 + MinMatch)) { - length += decode (ip); - } - - if ((opEnd - op) < length) { - return UncompressFailure; - } - const auto dist = ((token & 16) << 12) + load (ip); - ip += 2; - - auto cp = op - dist; - - if ((op - out) < dist) { - return UncompressFailure; - } - - if (dist >= 8) { - copy (op, cp, length); - op += length; - } - else { - for (int32 i = 0; i < 4; ++i) { - *op++ = *cp++; - } - - while (length-- != 4) { - *op++ = *cp++; - } - } - } - return static_cast (ip == ipEnd) ? static_cast (op - out) : UncompressFailure; - } - -private: - template U load (void *ptr) { - U ret; - memcpy (&ret, ptr, sizeof (U)); - - return ret; - } - - void store16 (void *ptr, uint16 val) { - memcpy (ptr, &val, sizeof (uint16)); - } - - void copy64 (void *dst, void *src) { - memcpy (dst, src, sizeof (uint64)); - } - - uint32 hash32 (void *ptr) { - return (load (ptr) * 0x9e3779b9) >> (32 - HashBits); - } - - void copy (uint8 *dst, uint8 *src, int32 count) { - copy64 (dst, src); - - for (int32 i = 8; i < count; i += 8) { - copy64 (dst + i, src + i); - } - } - - void add (uint8 *&dst, int32 val) { - *dst++ = static_cast (val); - } - - void encode (uint8 *&ptr, uint32 val) { - while (val >= 128) { - val -= 128; - - *ptr++ = 128 + (val & 127); - val >>= 7; - } - *ptr++ = static_cast (val); - } - - uint32 decode (uint8 *&ptr) { - uint32 val = 0; - - for (int32 i = 0; i <= 21; i += 7) { - const uint32 cur = *ptr++; - val += cur << i; - - if (cur < 128) { - break; - } - } - return val; - } -}; - -// expose global ulz object -CR_EXPOSE_GLOBAL_SINGLETON (ULZ, ulz); - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-uniqueptr.h b/ext/crlib/cr-uniqueptr.h deleted file mode 100644 index 87270a1..0000000 --- a/ext/crlib/cr-uniqueptr.h +++ /dev/null @@ -1,206 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include -#include -#include - -CR_NAMESPACE_BEGIN - -// simple unique ptr -template class UniquePtr final : public DenyCopying { -private: - T *ptr_ {}; - -public: - UniquePtr () = default; - - explicit UniquePtr (T *ptr) : ptr_ (ptr) - { } - - UniquePtr (UniquePtr &&rhs) noexcept : ptr_ (rhs.release ()) - { } - - template UniquePtr (UniquePtr &&rhs) noexcept : ptr_ (rhs.release ()) - { } - - ~UniquePtr () { - destroy (); - } - -public: - T *get () const { - return ptr_; - } - - T *release () { - auto ret = ptr_; - ptr_ = nullptr; - - return ret; - } - - void reset (T *ptr = nullptr) { - destroy (); - ptr_ = ptr; - } - -private: - void destroy () { - delete ptr_; - ptr_ = nullptr; - } - -public: - UniquePtr &operator = (UniquePtr &&rhs) noexcept { - if (this != &rhs) { - reset (rhs.release ()); - } - return *this; - } - - template UniquePtr &operator = (UniquePtr &&rhs) noexcept { - if (this != &rhs) { - reset (rhs.release ()); - } - return *this; - } - - UniquePtr &operator = (decltype (nullptr)) { - destroy (); - return *this; - } - - T &operator * () const { - return *ptr_; - } - - T *operator -> () const { - return ptr_; - } - - explicit operator bool () const { - return ptr_ != nullptr; - } -}; - -template class UniquePtr final : public DenyCopying { -private: - T *ptr_ { }; - -public: - UniquePtr () = default; - - explicit UniquePtr (T *ptr) : ptr_ (ptr) - { } - - UniquePtr (UniquePtr &&rhs) noexcept : ptr_ (rhs.release ()) - { } - - template UniquePtr (UniquePtr &&rhs) noexcept : ptr_ (rhs.release ()) - { } - - ~UniquePtr () { - destroy (); - } - -public: - T *get () const { - return ptr_; - } - - T *release () { - auto ret = ptr_; - ptr_ = nullptr; - - return ret; - } - - void reset (T *ptr = nullptr) { - destroy (); - ptr_ = ptr; - } - -private: - void destroy () { - delete[] ptr_; - ptr_ = nullptr; - } - -public: - UniquePtr &operator = (UniquePtr &&rhs) noexcept { - if (this != &rhs) { - reset (rhs.release ()); - } - return *this; - } - - template UniquePtr &operator = (UniquePtr &&rhs) noexcept { - if (this != &rhs) { - reset (rhs.release ()); - } - return *this; - } - - UniquePtr &operator = (decltype (nullptr)) { - destroy (); - return *this; - } - - T &operator [] (size_t index) { - return ptr_[index]; - } - - const T &operator [] (size_t index) const { - return ptr_[index]; - } - - explicit operator bool () const { - return ptr_ != nullptr; - } -}; - -namespace detail { - template struct ClearExtent { - using Type = T; - }; - - template struct ClearExtent { - using Type = T; - }; - - template struct ClearExtent { - using Type = T; - }; - - template struct UniqueIf { - using SingleObject = UniquePtr ; - }; - - template struct UniqueIf { - using UnknownBound = UniquePtr ; - }; - - template struct UniqueIf { - using KnownBound = void; - }; -} - -template typename detail::UniqueIf ::SingleObject makeUnique (Args &&... args) { - return UniquePtr (new T (cr::forward (args)...)); -} - -template typename detail::UniqueIf ::UnknownBound makeUnique (size_t size) { - using Type = typename detail::ClearExtent ::Type; - return UniquePtr (new Type[size] ()); -} - -template typename detail::UniqueIf ::KnownBound makeUnique (Args &&...) = delete; - -CR_NAMESPACE_END diff --git a/ext/crlib/cr-vector.h b/ext/crlib/cr-vector.h deleted file mode 100644 index 864aff0..0000000 --- a/ext/crlib/cr-vector.h +++ /dev/null @@ -1,325 +0,0 @@ -// -// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. -// Copyright © 2004-2021 YaPB Project . -// -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include - -CR_NAMESPACE_BEGIN - -// small simd operations for 3d vector -#if defined (CR_HAS_SSE) - -template class CR_ALIGN16 SimdWrap { -private: - __m128 wrap_dp_sse2 (__m128 v1, __m128 v2) { - auto mul = _mm_mul_ps (v1, v2); - auto res = _mm_add_ps (_mm_shuffle_ps (v2, mul, _MM_SHUFFLE (1, 0, 0, 0)), mul); - - mul = _mm_add_ps (_mm_shuffle_ps (mul, res, _MM_SHUFFLE (0, 3, 0, 0)), res); - - return _mm_shuffle_ps (mul, mul, _MM_SHUFFLE (2, 2, 2, 2)); - } - -public: - union { - __m128 m; - - struct { - T x, y, z; - } vec; - }; - - SimdWrap (const T &x, const T &y, const T &z) { - m = _mm_set_ps (0.0f, z, y, x); - } - - SimdWrap (const T &x, const T &y) { - m = _mm_set_ps (0.0f, 0.0f, y, x); - } - - SimdWrap (__m128 m) : m (m) - { } - -public: - SimdWrap normalize () { - return { _mm_div_ps (m, _mm_sqrt_ps (wrap_dp_sse2 (m, m))) }; - } -}; - -#endif - -// 3dmath vector -template class Vec3D { -public: - T x {}; - T y {}; - T z {}; - -public: - Vec3D (const T &scaler = 0.0f) : x (scaler), y (scaler), z (scaler) - { } - - Vec3D (const T &x, const T &y, const T &z) : x (x), y (y), z (z) - { } - - Vec3D (T *rhs) : x (rhs[0]), y (rhs[1]), z (rhs[2]) - { } - -#if defined (CR_HAS_SSE) - Vec3D (const SimdWrap &rhs) : x (rhs.vec.x), y (rhs.vec.y), z (rhs.vec.z) - { } -#endif - - Vec3D (const Vec3D &) = default; - - Vec3D (decltype (nullptr)) { - clear (); - } - -public: - operator T * () { - return &x; - } - - operator const T * () const { - return &x; - } - - Vec3D operator + (const Vec3D &rhs) const { - return { x + rhs.x, y + rhs.y, z + rhs.z }; - } - - Vec3D operator - (const Vec3D &rhs) const { - return { x - rhs.x, y - rhs.y, z - rhs.z }; - } - - Vec3D operator - () const { - return { -x, -y, -z }; - } - - friend Vec3D operator * (const T &scale, const Vec3D &rhs) { - return { rhs.x * scale, rhs.y * scale, rhs.z * scale }; - } - - Vec3D operator * (const T &scale) const { - return { scale * x, scale * y, scale * z }; - } - - Vec3D operator / (const T &rhs) const { - const auto inv = 1 / (rhs + kFloatEqualEpsilon); - return { inv * x, inv * y, inv * z }; - } - - // cross product - Vec3D operator ^ (const Vec3D &rhs) const { - return { y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x }; - } - - // dot product - T operator | (const Vec3D &rhs) const { - return x * rhs.x + y * rhs.y + z * rhs.z; - } - - const Vec3D &operator += (const Vec3D &rhs) { - x += rhs.x; - y += rhs.y; - z += rhs.z; - - return *this; - } - - const Vec3D &operator -= (const Vec3D &rhs) { - x -= rhs.x; - y -= rhs.y; - z -= rhs.z; - - return *this; - } - - const Vec3D &operator *= (const T &rhs) { - x *= rhs; - y *= rhs; - z *= rhs; - - return *this; - } - - const Vec3D &operator /= (const T &rhs) { - const auto inv = 1 / (rhs + kFloatEqualEpsilon); - - x *= inv; - y *= inv; - z *= inv; - - return *this; - } - - bool operator == (const Vec3D &rhs) const { - return cr::fequal (x, rhs.x) && cr::fequal (y, rhs.y) && cr::fequal (z, rhs.z); - } - - bool operator != (const Vec3D &rhs) const { - return !operator == (rhs); - } - - void operator = (decltype (nullptr)) { - clear (); - } - - const float &operator [] (const int i) const { - return &(x)[i]; - } - - float &operator [] (const int i) { - return &(x)[i]; - } - - Vec3D &operator = (const Vec3D &) = default; - -public: - T length () const { - return cr::sqrtf (lengthSq ()); - } - - T length2d () const { - return cr::sqrtf (cr::square (x) + cr::square (y)); - } - - T lengthSq () const { - return cr::square (x) + cr::square (y) + cr::square (z); - } - - Vec3D get2d () const { - return { x, y, 0.0f }; - } - - Vec3D normalize () const { -#if defined (CR_HAS_SSE) - return SimdWrap { x, y, z }.normalize (); -#else - auto len = length () + cr::kFloatCmpEpsilon; - - if (cr::fzero (len)) { - return { 0.0f, 0.0f, 1.0f }; - } - len = 1.0f / len; - return { x * len, y * len, z * len }; -#endif - } - - Vec3D normalize2d () const { -#if defined (CR_HAS_SSE) - return SimdWrap { x, y }.normalize (); -#else - auto len = length2d () + cr::kFloatCmpEpsilon; - - if (cr::fzero (len)) { - return { 0.0f, 1.0f, 0.0f }; - } - len = 1.0f / len; - return { x * len, y * len, 0.0f }; -#endif - } - - bool empty () const { - return cr::fzero (x) && cr::fzero (y) && cr::fzero (z); - } - - void clear () { - x = y = z = 0.0f; - } - - Vec3D clampAngles () { - x = cr::normalizeAngles (x); - y = cr::normalizeAngles (y); - z = 0.0f; - - return *this; - } - - T pitch () const { - if (cr::fzero (z)) { - return 0.0f; - } - return cr::deg2rad (cr::atan2f (z, length2d ())); - } - - T yaw () const { - if (cr::fzero (x) && cr::fzero (y)) { - return 0.0f; - } - return cr::rad2deg (cr:: atan2f (y, x)); - } - - Vec3D angles () const { - if (cr::fzero (x) && cr::fzero (y)) { - return { z > 0.0f ? 90.0f : 270.0f, 0.0, 0.0f }; - } - return { cr::rad2deg (cr::atan2f (z, length2d ())), cr::rad2deg (cr::atan2f (y, x)), 0.0f }; - } - - void angleVectors (Vec3D *forward, Vec3D *right, Vec3D *upward) const { - enum { pitch, yaw, roll, unused, max }; - - T sines[max] = { 0.0f, 0.0f, 0.0f, 0.0f }; - T cosines[max] = { 0.0f, 0.0f, 0.0f, 0.0f }; - - // compute the sine and cosine compontents - cr::sincosf (cr::deg2rad (x), cr::deg2rad (y), cr::deg2rad (z), sines, cosines); - - if (forward) { - *forward = { - cosines[pitch] * cosines[yaw], - cosines[pitch] * sines[yaw], - -sines[pitch] - }; - } - - if (right) { - *right = { - -sines[roll] * sines[pitch] * cosines[yaw] + cosines[roll] * sines[yaw], - -sines[roll] * sines[pitch] * sines[yaw] - cosines[roll] * cosines[yaw], - -sines[roll] * cosines[pitch] - }; - } - - if (upward) { - *upward = { - cosines[roll] * sines[pitch] * cosines[yaw] + sines[roll] * sines[yaw], - upward->y = cosines[roll] * sines[pitch] * sines[yaw] - sines[roll] * cosines[yaw], - upward->z = cosines[roll] * cosines[pitch] - }; - } - } - - const Vec3D &forward () { - static Vec3D s_fwd {}; - angleVectors (&s_fwd, nullptr, nullptr); - - return s_fwd; - } - - const Vec3D &upward () { - static Vec3D s_up {}; - angleVectors (nullptr, nullptr, &s_up); - - return s_up; - } - - const Vec3D &right () { - static Vec3D s_right {}; - angleVectors (nullptr, &s_right, nullptr); - - return s_right; - } -}; - -// default is float -using Vector = Vec3D ; - -CR_NAMESPACE_END