debug.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*
  2. EQ2Emulator: Everquest II Server Emulator
  3. Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
  4. This file is part of EQ2Emulator.
  5. EQ2Emulator is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. EQ2Emulator is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. /*
  17. JA: File rendered obsolete (2011-08-12)
  18. #include "debug.h"
  19. #include <iostream>
  20. using namespace std;
  21. #include <time.h>
  22. #include <string.h>
  23. #ifdef WIN32
  24. #include <process.h>
  25. #define snprintf _snprintf
  26. #define vsnprintf _vsnprintf
  27. #define strncasecmp _strnicmp
  28. #define strcasecmp _stricmp
  29. #else
  30. #include <sys/types.h>
  31. #include <unistd.h>
  32. #include <stdarg.h>
  33. #endif
  34. #include "../common/MiscFunctions.h"
  35. EQEMuLog* LogFile = new EQEMuLog;
  36. AutoDelete<EQEMuLog> adlf(&LogFile);
  37. static const char* FileNames[EQEMuLog::MaxLogID] = { "logs/eq2emu", "logs/eq2emu", "logs/eq2emu_error", "logs/eq2emu_debug", "logs/eq2emu_quest", "logs/eq2emu_commands" };
  38. static const char* LogNames[EQEMuLog::MaxLogID] = { "Status", "Normal", "Error", "Debug", "Quest", "Command" };
  39. EQEMuLog::EQEMuLog() {
  40. for (int i=0; i<MaxLogID; i++) {
  41. fp[i] = 0;
  42. #if EQDEBUG >= 2
  43. pLogStatus[i] = 1 | 2;
  44. #else
  45. pLogStatus[i] = 0;
  46. #endif
  47. logCallbackFmt[i] = NULL;
  48. logCallbackBuf[i] = NULL;
  49. }
  50. #if EQDEBUG < 2
  51. pLogStatus[Status] = 3;
  52. pLogStatus[Error] = 3;
  53. pLogStatus[Debug] = 3;
  54. pLogStatus[Quest] = 2;
  55. pLogStatus[Commands] = 2;
  56. #endif
  57. }
  58. EQEMuLog::~EQEMuLog() {
  59. for (int i=0; i<MaxLogID; i++) {
  60. if (fp[i])
  61. fclose(fp[i]);
  62. }
  63. }
  64. bool EQEMuLog::open(LogIDs id) {
  65. if (id >= MaxLogID) {
  66. return false;
  67. }
  68. LockMutex lock(&MOpen);
  69. if (pLogStatus[id] & 4) {
  70. return false;
  71. }
  72. if (fp[id]) {
  73. return true;
  74. }
  75. char exename[200] = "";
  76. #if defined(WORLD)
  77. snprintf(exename, sizeof(exename), "_world");
  78. #elif defined(ZONE)
  79. snprintf(exename, sizeof(exename), "_zone");
  80. #endif
  81. char filename[200];
  82. #ifndef NO_PIDLOG
  83. snprintf(filename, sizeof(filename), "%s%s_%04i.log", FileNames[id], exename, getpid());
  84. #else
  85. snprintf(filename, sizeof(filename), "%s%s.log", FileNames[id], exename);
  86. #endif
  87. fp[id] = fopen(filename, "a");
  88. if (!fp[id]) {
  89. cerr << "Failed to open log file: " << filename << endl;
  90. pLogStatus[id] |= 4; // set file state to error
  91. return false;
  92. }
  93. fputs("---------------------------------------------\n",fp[id]);
  94. return true;
  95. }
  96. bool EQEMuLog::write(LogIDs id, const char *fmt, ...) {
  97. char buffer[4096];
  98. if (!this) {
  99. return false;
  100. }
  101. if (id >= MaxLogID) {
  102. return false;
  103. }
  104. bool dofile = false;
  105. if (pLogStatus[id] & 1) {
  106. dofile = open(id);
  107. }
  108. if (!(dofile || pLogStatus[id] & 2))
  109. return false;
  110. LockMutex lock(&MLog[id]);
  111. time_t aclock;
  112. struct tm *newtime;
  113. time( &aclock ); //Get time in seconds
  114. newtime = localtime( &aclock ); //Convert time to struct
  115. if (dofile){
  116. #ifndef NO_PIDLOG
  117. fprintf(fp[id], "[%04d%02d%02d %02d:%02d:%02d] ", newtime->tm_year+1900, newtime->tm_mon+1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec);
  118. #else
  119. fprintf(fp[id], "%04i [%04d%02d%02d %02d:%02d:%02d] ", getpid(), newtime->tm_year+1900, newtime->tm_mon+1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec);
  120. #endif
  121. }
  122. va_list argptr;
  123. va_start(argptr, fmt);
  124. vsnprintf(buffer, sizeof(buffer), fmt, argptr);
  125. va_end(argptr);
  126. if (dofile)
  127. fprintf(fp[id], "%s\n", buffer);
  128. if(logCallbackFmt[id]) {
  129. msgCallbackFmt p = logCallbackFmt[id];
  130. p(id, fmt, argptr );
  131. }
  132. if (pLogStatus[id] & 2) {
  133. if (pLogStatus[id] & 8) {
  134. fprintf(stderr, "[%04d%02d%02d %02d:%02d:%02d] [%s] ", newtime->tm_year+1900, newtime->tm_mon+1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec, LogNames[id]);
  135. fprintf(stderr, "%s\n", buffer);
  136. }
  137. else {
  138. fprintf(stdout, "[%04d%02d%02d %02d:%02d:%02d] [%s] ", newtime->tm_year+1900, newtime->tm_mon+1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec, LogNames[id]);
  139. fprintf(stdout, "%s\n", buffer);
  140. }
  141. }
  142. if (dofile)
  143. fprintf(fp[id], "\n");
  144. if (pLogStatus[id] & 2) {
  145. if (pLogStatus[id] & 8)
  146. fprintf(stderr, "\n");
  147. else
  148. fprintf(stdout, "\n");
  149. }
  150. if(dofile)
  151. fflush(fp[id]);
  152. return true;
  153. }
  154. bool EQEMuLog::writebuf(LogIDs id, const char *buf, int8 size, int32 count) {
  155. if (!this) {
  156. return false;
  157. }
  158. if (id >= MaxLogID) {
  159. return false;
  160. }
  161. bool dofile = false;
  162. if (pLogStatus[id] & 1) {
  163. dofile = open(id);
  164. }
  165. if (!(dofile || pLogStatus[id] & 2))
  166. return false;
  167. LockMutex lock(&MLog[id]);
  168. time_t aclock;
  169. struct tm *newtime;
  170. time( &aclock ); // Get time in seconds
  171. newtime = localtime( &aclock ); // Convert time to struct
  172. if (dofile){
  173. #ifndef NO_PIDLOG
  174. fprintf(fp[id], "[%02d.%02d. - %02d:%02d:%02d] ", newtime->tm_mon+1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec);
  175. #else
  176. fprintf(fp[id], "%04i [%02d.%02d. - %02d:%02d:%02d] ", getpid(), newtime->tm_mon+1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec);
  177. #endif
  178. }
  179. if (dofile) {
  180. fwrite(buf, size, count, fp[id]);
  181. fprintf(fp[id], "\n");
  182. }
  183. if(logCallbackBuf[id]) {
  184. msgCallbackBuf p = logCallbackBuf[id];
  185. p(id, buf, size, count);
  186. }
  187. if (pLogStatus[id] & 2) {
  188. if (pLogStatus[id] & 8) {
  189. fprintf(stderr, "[%s] ", LogNames[id]);
  190. fwrite(buf, size, count, stderr);
  191. fprintf(stderr, "\n");
  192. } else {
  193. fprintf(stdout, "[%s] ", LogNames[id]);
  194. fwrite(buf, size, count, stdout);
  195. fprintf(stdout, "\n");
  196. }
  197. }
  198. if(dofile)
  199. fflush(fp[id]);
  200. return true;
  201. }
  202. bool EQEMuLog::writeNTS(LogIDs id, bool dofile, const char *fmt, ...) {
  203. char buffer[4096];
  204. va_list argptr;
  205. va_start(argptr, fmt);
  206. vsnprintf(buffer, sizeof(buffer), fmt, argptr);
  207. va_end(argptr);
  208. if (dofile)
  209. fprintf(fp[id], "%s\n", buffer);
  210. if (pLogStatus[id] & 2) {
  211. if (pLogStatus[id] & 8)
  212. fprintf(stderr, "%s\n", buffer);
  213. else
  214. fprintf(stdout, "%s\n", buffer);
  215. }
  216. return true;
  217. };
  218. bool EQEMuLog::Dump(LogIDs id, int8* data, int32 size, int32 cols, int32 skip) {
  219. if (!this) {
  220. #if EQDEBUG >= 10
  221. cerr << "Error: Dump() from null pointer"<<endl;
  222. #endif
  223. return false;
  224. }
  225. if (size == 0)
  226. return true;
  227. if (!LogFile)
  228. return false;
  229. if (id >= MaxLogID)
  230. return false;
  231. bool dofile = false;
  232. if (pLogStatus[id] & 1) {
  233. dofile = open(id);
  234. }
  235. if (!(dofile || pLogStatus[id] & 2))
  236. return false;
  237. LockMutex lock(&MLog[id]);
  238. write(id, "Dumping Packet: %i", size);
  239. // Output as HEX
  240. int j = 0; char* ascii = new char[cols+1]; memset(ascii, 0, cols+1);
  241. int32 i;
  242. for(i=skip; i<size; i++) {
  243. if ((i-skip)%cols==0) {
  244. if (i != skip)
  245. writeNTS(id, dofile, " | %s\n", ascii);
  246. writeNTS(id, dofile, "%4i: ", i-skip);
  247. memset(ascii, 0, cols+1);
  248. j = 0;
  249. }
  250. else if ((i-skip)%(cols/2) == 0) {
  251. writeNTS(id, dofile, "- ");
  252. }
  253. writeNTS(id, dofile, "%02X ", (unsigned char)data[i]);
  254. if (data[i] >= 32 && data[i] < 127)
  255. ascii[j++] = data[i];
  256. else
  257. ascii[j++] = '.';
  258. }
  259. int32 k = ((i-skip)-1)%cols;
  260. if (k < 8)
  261. writeNTS(id, dofile, " ");
  262. for (int32 h = k+1; h < cols; h++) {
  263. writeNTS(id, dofile, " ");
  264. }
  265. writeNTS(id, dofile, " | %s\n", ascii);
  266. if (dofile)
  267. fflush(fp[id]);
  268. safe_delete_array(ascii);
  269. return true;
  270. }
  271. void EQEMuLog::SetCallback(LogIDs id, msgCallbackFmt proc) {
  272. if (!this)
  273. return;
  274. if (id >= MaxLogID) {
  275. return;
  276. }
  277. logCallbackFmt[id] = proc;
  278. }
  279. void EQEMuLog::SetCallback(LogIDs id, msgCallbackBuf proc) {
  280. if (!this)
  281. return;
  282. if (id >= MaxLogID) {
  283. return;
  284. }
  285. logCallbackBuf[id] = proc;
  286. }
  287. void EQEMuLog::SetAllCallbacks(msgCallbackFmt proc) {
  288. if (!this)
  289. return;
  290. int r;
  291. for(r = Status; r < MaxLogID; r++) {
  292. SetCallback((LogIDs)r, proc);
  293. }
  294. }
  295. void EQEMuLog::SetAllCallbacks(msgCallbackBuf proc) {
  296. if (!this)
  297. return;
  298. int r;
  299. for(r = Status; r < MaxLogID; r++) {
  300. SetCallback((LogIDs)r, proc);
  301. }
  302. }
  303. */