#ifndef SHARED_SHARED_HH_ #define SHARED_SHARED_HH_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "shared/math/math.hh" #include "shared/net/proto.hh" namespace shared { using time_point_t = decltype(std::chrono::steady_clock::now()); using time_duration_t = decltype(std::chrono::steady_clock::now() - std::chrono::steady_clock::now()); float get_duration_seconds(const time_duration_t& duration) noexcept; std::string make_string_lower(std::string str) noexcept; std::string read_file(const std::string& path); [[nodiscard]] std::string compress_string(const std::string& str); [[nodiscard]] std::optional maybe_decompress_string(const std::string& str) noexcept; std::ofstream open_file(const std::string& dir, const std::ios_base::openmode mode = std::ios::trunc); constexpr unsigned long MAX_SAY_LENGTH = 32ul; constexpr unsigned long MAX_USER_PASS_LENGTH = 64; using tick_t = std::uint32_t; // Thread safe printing - this MESS will be cleaned up when we have std::print. namespace print { class print_base { protected: static inline std::mutex lock; public: enum class colour { black = 30, red = 31, green = 32, yellow = 33, blue = 34, magenta = 35, cyan = 36, white = 37, none = 39, grey = 90, bright_red = 91, bright_green = 92, bright_yellow = 93, bright_blue = 94, bright_magenta = 95, bright_cyan = 96, bright_white = 97 }; static std::string make_colour(const colour clr) noexcept { return {"\033[" + std::to_string(static_cast(clr)) + "m"}; } protected: static void print_message(std::ostream& os, const std::string_view colour, const bool cerr = false) noexcept { const std::lock_guard guard(lock); static const std::string none = make_colour(colour::none); (cerr ? std::cerr : std::cout) << colour << os.rdbuf() << none; } }; class print_time { // operator<< returns time as stringstream public: friend std::ostream& operator<<(std::ostream& os, const print_time&) noexcept { const auto epoch = std::time(nullptr); struct tm* local = localtime(&epoch); using pb = print_base; static const std::string white = pb::make_colour(pb::colour::white); static const std::string none = pb::make_colour(pb::colour::none); os << white << std::put_time(local, "[%F %T] ") << none; return os; } }; class print_colour : public print_base { private: enum print_base::colour colour; bool cerr; public: print_colour(const decltype(colour) colour, const decltype(cerr) cerr) noexcept : colour(colour), cerr(cerr) {} template print_colour& operator<<(const T& obj) noexcept { std::stringstream ss{}; ss << obj; print_base::print_message(ss, make_colour(this->colour), this->cerr); return *this; } }; inline auto time = print_time{}; inline print_colour message{print_base::colour::white, false}; inline print_colour notify{print_base::colour::cyan, false}; inline print_colour warn{print_base::colour::bright_yellow, true}; inline print_colour fault{print_base::colour::bright_red, true}; inline print_colour debug{print_base::colour::magenta, true}; } // namespace print inline std::atomic should_exit = false; }; // namespace shared #endif