// Copyright (C) 2007-2025 EQ2EMulator // Licensed under GPL v3 #pragma once #include #include #include #include #include // Debug Levels /* 1 = Normal 3 = Some extended debug info 5 = Light DETAIL info 7 = Heavy DETAIL info 9 = DumpPacket/PrintPacket You should use even numbers too, to define any subset of the above basic template */ #ifndef EQDEBUG #define EQDEBUG 1 #endif #ifndef ThrowError void CatchSignal(int); #if defined(CATCH_CRASH) || defined(_EQDEBUG) #define ThrowError(errstr) { \ std::cout << "Fatal error: " << errstr << " (" << __FILE__ << ", line " << __LINE__ << ")" << std::endl; \ LogWrite(WORLD__ERROR, 0, "Debug", "Thrown Error: %s (%s:%i)", errstr, __FILE__, __LINE__); \ throw errstr; \ } #else #define ThrowError(errstr) { \ std::cout << "Fatal error: " << errstr << " (" << __FILE__ << ", line " << __LINE__ << ")" << std::endl; \ LogWrite(WORLD__ERROR, 0, "Debug", "Thrown Error: %s (%s:%i)", errstr, __FILE__, __LINE__); \ CatchSignal(0); \ } #endif #endif #define DebugBreak() if(0) {} class EQEMuLog { public: EQEMuLog(); ~EQEMuLog(); enum LogIDs { Status = 0, //this must stay the first entry in this list Normal, Error, Debug, Quest, Commands, MaxLogID }; // Callbacks called for each log entry using msgCallbackBuf = void (*)(LogIDs id, const char* buf, std::int8_t size, std::int32_t count); using msgCallbackFmt = void (*)(LogIDs id, const char* fmt, va_list ap); void SetAllCallbacks(msgCallbackFmt proc); void SetAllCallbacks(msgCallbackBuf proc); void SetCallback(LogIDs id, msgCallbackFmt proc); void SetCallback(LogIDs id, msgCallbackBuf proc); bool writebuf(LogIDs id, const char* buf, std::int8_t size, std::int32_t count); bool write(LogIDs id, const char* fmt, ...); bool Dump(LogIDs id, std::uint8_t* data, std::int32_t size, std::int32_t cols = 16, std::int32_t skip = 0); private: bool open(LogIDs id); bool writeNTS(LogIDs id, bool dofile, const char* fmt, ...); // no error checking, assumes is open, no locking, no timestamp, no newline std::mutex MOpen; std::mutex MLog[MaxLogID]; FILE* fp[MaxLogID]; /* LogStatus: bitwise variable 1 = output to file 2 = output to stdout 4 = fopen error, dont retry 8 = use stderr instead (2 must be set) */ std::int8_t pLogStatus[MaxLogID]; msgCallbackFmt logCallbackFmt[MaxLogID]; msgCallbackBuf logCallbackBuf[MaxLogID]; }; #ifdef _EQDEBUG class PerformanceMonitor { public: PerformanceMonitor(std::int64_t* ip) { p = ip; QueryPerformanceCounter(&tmp); } ~PerformanceMonitor() { LARGE_INTEGER tmp2; QueryPerformanceCounter(&tmp2); *p += tmp2.QuadPart - tmp.QuadPart; } LARGE_INTEGER tmp; std::int64_t* p; }; #endif