OregonCore  revision be9e804-git
Your Favourite TBC server
Console Class Reference

#include <Console.h>

Classes

class  CliRunnable
 

Public Member Functions

 Console ()
 
 ~Console ()
 

Protected Member Functions

void Initialize ()
 
void SetLoading (bool show, const char *caption="Initializing")
 
void SetLoadingLabel (const char *label, bool br=true)
 
void FatalError (const char *msg)
 
void MainLoop ()
 
void RunCommandLoop ()
 
void RunLogViewLoop ()
 
void DrawLogo ()
 
bool IsEnabled () const
 
void Beep ()
 
void Restore ()
 

Private Types

typedef std::list< std::string > History
 
typedef HANDLE PipeType
 

Private Member Functions

void SetTitle (const char *title)
 
void Refresh ()
 
int GetChar ()
 
void DrawLoading ()
 
void UpdateLog ()
 
WindowMakeWindow (int h, int w, int y, int x)
 
void ResizeWindow (Window *win, int h, int w, int y, int x)
 
void DestroyWindow (Window *win)
 

Private Attributes

std::set< Window * > m_windows
 
bool m_IamEnabled
 
History m_cmdHistory
 
PipeType m_loggerFd
 
Windowm_logoWindow
 
Windowm_loadWindow
 
Windowm_logViewer
 
Windowm_cmdOutput
 

Friends

class World
 
class Master
 
class Log
 
class UnixDebugger
 
void LoadSQLUpdates ()
 

Detailed Description

Definition at line 13 of file Console.h.

Member Typedef Documentation

typedef std::list<std::string> Console::History
private

Definition at line 83 of file Console.h.

typedef HANDLE Console::PipeType
private

Definition at line 85 of file Console.h.

Constructor & Destructor Documentation

Console::Console ( )

Definition at line 57 of file Console.cpp.

References HandleConsoleInterrupt(), and SetTitle().

58 {
59  SetTitle("OregonCore");
60  #if PLATFORM == PLATFORM_WINDOWS
61  SetConsoleCtrlHandler(&HandleConsoleInterrupt, TRUE);
62  #endif
63 }
BOOL WINAPI HandleConsoleInterrupt(DWORD)
Definition: Console.cpp:49
PipeType m_loggerFd
Definition: Console.h:91
void SetTitle(const char *title)
Definition: Console.h:59
Window * m_logoWindow
Definition: Console.h:93
bool m_IamEnabled
Definition: Console.h:81
Window * m_loadWindow
Definition: Console.h:94
Console::~Console ( )

Definition at line 65 of file Console.cpp.

References DestroyWindow(), m_IamEnabled, m_loggerFd, and m_windows.

66 {
67  if (!m_IamEnabled)
68  return;
69 
70  for (std::set<Window*>::const_iterator it = m_windows.begin(); it != m_windows.end(); )
71  {
72  DestroyWindow(*it);
73  it = m_windows.begin();
74  }
75 
76  endwin();
77 
78  if (m_loggerFd)
79  #if PLATFORM == PLATFORM_WINDOWS
80  CloseHandle(m_loggerFd);
81  #else
82  close(m_loggerFd);
83  #endif
84 }
void DestroyWindow(Window *win)
Definition: Console.cpp:201
PipeType m_loggerFd
Definition: Console.h:91
bool m_IamEnabled
Definition: Console.h:81
std::set< Window * > m_windows
Definition: Console.h:80

Member Function Documentation

void Console::Beep ( )
inlineprotected

Definition at line 44 of file Console.h.

45  {
46  beep();
47  }
void Console::DestroyWindow ( Window win)
private

Definition at line 201 of file Console.cpp.

References m_windows.

Referenced by FatalError(), MainLoop(), RunCommandLoop(), RunLogViewLoop(), SetLoading(), SetTitle(), and ~Console().

202 {
203  if (!win)
204  return;
205 
206  werase(win); // make it blank
207  wrefresh(win); // apply
208  m_windows.erase(win);
209  delwin(win);
210 }
std::set< Window * > m_windows
Definition: Console.h:80
void Console::DrawLoading ( )
private

Referenced by SetTitle().

void Console::DrawLogo ( )
protected

Definition at line 760 of file Console.cpp.

References m_IamEnabled, m_logoWindow, sLog, and TermColor.

Referenced by FatalError(), and MainLoop().

761 {
762  static const char FavString[] = "Your Favourite TBC Server";
763 
764  if (m_IamEnabled)
765  {
766  werase(m_logoWindow);
767  scrollok(m_logoWindow, TRUE);
768  wattrset(m_logoWindow, A_BOLD | TermColor(COLOR_GREEN));
769  mvwprintw(m_logoWindow, 0, 0, "%s", sOregonLogo);
770  wattroff(m_logoWindow, TermColor(COLOR_GREEN));
771  wattron(m_logoWindow, TermColor(COLOR_CYAN));
772 
773  mvwprintw(m_logoWindow, 1, sOregonLogoCols / 2 - (sizeof(FavString) - 1) / 2, "%s", FavString);
774  mvwprintw(m_logoWindow, sOregonLogoRows - 1, 0, "%s", "https://www.oregon-core.net");
775 
776  wattroff(m_logoWindow, TermColor(COLOR_CYAN));
777  wrefresh(m_logoWindow);
778  }
779  else
780  {
781  sLog.outString();
782  for (uint32 i = 0; i < sOregonLogoRows; i++)
783  sLog.outString("%.*s", sOregonLogoCols, &sOregonLogo[i * sOregonLogoCols]);
784  sLog.outString("https://www.oregon-core.net\n");
785  }
786 }
#define sLog
Log class singleton.
Definition: Log.h:187
#define TermColor(x)
Definition: Console.cpp:20
Window * m_logoWindow
Definition: Console.h:93
ACE_UINT32 uint32
Definition: Define.h:71
bool m_IamEnabled
Definition: Console.h:81
void Console::FatalError ( const char *  msg)
protected

Definition at line 734 of file Console.cpp.

References ASSERT, DestroyWindow(), DrawLogo(), GetChar(), m_IamEnabled, MakeWindow(), and TermColor.

735 {
737 
738  erase();
739 
740  Window* errWin = MakeWindow(LINES - (2 + sOregonLogoRows), sOregonLogoCols, 2 + sOregonLogoRows, COLS / 2 - sOregonLogoCols / 2);
741  wattrset(errWin, A_BOLD | TermColor(COLOR_RED));
742  wprintw(errWin, "FATAL ERROR:"
743  "\n\n"
744  "%s"
745  "\n\n"
746  "Press enter to exit", msg);
747  wrefresh(stdscr);
748  DrawLogo();
749  wrefresh(errWin);
750 
751  timeout(-1);
752  for (int c = GetChar(); (c != KEY_ENTER && c != '\n' && c != '\r'); c = GetChar())
753  ;
754 
755  DestroyWindow(errWin);
756 
757  endwin();
758 }
WINDOW Window
Definition: Console.h:9
void DestroyWindow(Window *win)
Definition: Console.cpp:201
Window * MakeWindow(int h, int w, int y, int x)
Definition: Console.cpp:193
int GetChar()
Definition: Console.cpp:218
#define TermColor(x)
Definition: Console.cpp:20
#define ASSERT
Definition: Errors.h:29
bool m_IamEnabled
Definition: Console.h:81
void DrawLogo()
Definition: Console.cpp:760
int Console::GetChar ( )
private

Definition at line 218 of file Console.cpp.

References SCROLLDN_MASK, and SCROLLUP_MASK.

Referenced by FatalError(), MainLoop(), RunCommandLoop(), RunLogViewLoop(), and SetTitle().

219 {
220  int ch = getch();
221  if (ch == KEY_MOUSE)
222  {
223  MEVENT event;
224  if (getmouse(&event) == OK)
225  {
226  if (event.bstate & SCROLLUP_MASK)
227  ch = KEY_SR; // scroll up
228  else if (event.bstate & SCROLLDN_MASK)
229  ch = KEY_SF; // scroll down
230  }
231  }
232  return ch;
233 }
#define SCROLLDN_MASK
Definition: Console.cpp:17
#define SCROLLUP_MASK
Definition: Console.cpp:16
void Console::Initialize ( void  )
protected

Definition at line 86 of file Console.cpp.

References dup2, fileno, m_cmdOutput, m_IamEnabled, m_loadWindow, m_loggerFd, m_logoWindow, m_logViewer, MakeWindow(), Refresh(), and sConfig.

87 {
88  m_IamEnabled = true;
89 
90  initscr(); // init curses
91  cbreak(); // turn off line buffering
92  noecho(); // turn off echoing of chars by terminal
93  keypad(stdscr, TRUE); // enable use of F1-F12 keys, arrows, etc.
94  curs_set(0); // try to make the cursor invisible
95  idlok(stdscr, TRUE); // allow terminal controls line ins/del
96  idcok(stdscr, TRUE); // allow terminal controls char ins/del
97  scrollok(stdscr, TRUE); // allow scrolling
98  leaveok(stdscr, TRUE); // dont move cursor (performance)
99  nonl(); // disable new line feed translating
100  start_color(); // initialize colors
101 
102  use_default_colors();
103  if (has_colors())
104  for (int i = 1; i <= COLORS; i++)
105  init_pair(i + 1, i, -1);
106 
107  mousemask(ALL_MOUSE_EVENTS & ~REPORT_MOUSE_POSITION, NULL); // allow mouse interaction
108  mouseinterval(0);
109 
110  int width = sConfig.GetIntDefault("Console.Width", 0);
111  int height = sConfig.GetIntDefault("Console.Height", 0);
112 
113  if (width > 0 && height > 0)
114  resizeterm(height, width);
115 
116  if (!m_logoWindow)
117  {
118  // win height width y x
119  m_logoWindow = MakeWindow(sOregonLogoRows, sOregonLogoCols, 1, COLS / 2 - sOregonLogoCols / 2);
120  m_loadWindow = MakeWindow(3, sOregonLogoCols, 2 + sOregonLogoRows, COLS / 2 - sOregonLogoCols / 2);
121 
122  int rows = 0xFFFF / COLS;
123  m_logViewer = newpad(rows, COLS);
124  idlok(m_logViewer, TRUE);
125  idcok(m_logViewer, TRUE);
126  scrollok(m_logViewer, TRUE);
127  wmove(m_logViewer, rows - 1, COLS - 1);
128  wprintw(m_logViewer, " ");
129 
130  m_cmdOutput = dupwin(m_logViewer);
131  }
132 
133  Refresh();
134 
135  // we abuse stderr to bring us data from logger
136  #if PLATFORM == PLATFORM_WINDOWS
137  HANDLE writer, reader;
138  char pipeName[MAX_PATH];
139  sprintf(pipeName, "\\\\.\\Pipe\\LocalOCAnon.%u", GetCurrentProcessId());
140  SetLastError(0);
141  reader = CreateNamedPipeA(pipeName, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE, 1, 4096, 0xFFFF, 1000, NULL);
142  writer = CreateFileA(pipeName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, NULL);
143 
144  if (GetLastError())
145  {
146  if (!reader || reader == INVALID_HANDLE_VALUE)
147  CloseHandle(reader);
148  if (!writer || writer == INVALID_HANDLE_VALUE)
149  CloseHandle(writer);
150  fclose(stderr);
151  return;
152  }
153 
154  SetStdHandle(STD_ERROR_HANDLE, writer);
155  //stderr->_file = _open_osfhandle((long) writer, _O_TEXT);
156  dup2(_open_osfhandle((long) writer, 0), fileno(stderr));
157  m_loggerFd = reader;
158  #else
159  int fds[2];
160  if (!pipe(fds))
161  {
162  // 0 - reader, 1 - writer
163  if (-1 == dup2(fds[1], STDERR_FILENO))
164  fclose(stderr);
165  else
166  {
167  fcntl(fds[0], F_SETFL, fcntl(fds[0], F_GETFL) | O_NONBLOCK | O_CLOEXEC);
168  fcntl(fds[1], F_SETFL, fcntl(fds[1], F_GETFL) | O_NONBLOCK | O_CLOEXEC);
169  m_loggerFd = fds[0];
170 
171  setvbuf(stderr, NULL, _IOLBF, 0);
172  }
173  }
174  else
175  fclose(stderr);
176  #endif
177 }
#define dup2
Definition: Common.h:136
#define sConfig
Definition: Config.h:52
PipeType m_loggerFd
Definition: Console.h:91
Window * m_logViewer
Definition: Console.h:95
Window * m_cmdOutput
Definition: Console.h:96
Window * MakeWindow(int h, int w, int y, int x)
Definition: Console.cpp:193
void Refresh()
Definition: Console.cpp:179
#define fileno
Definition: Common.h:135
Window * m_logoWindow
Definition: Console.h:93
bool m_IamEnabled
Definition: Console.h:81
Window * m_loadWindow
Definition: Console.h:94
bool Console::IsEnabled ( ) const
inlineprotected

Definition at line 39 of file Console.h.

References m_IamEnabled.

40  {
41  return m_IamEnabled;
42  }
bool m_IamEnabled
Definition: Console.h:81
void Console::MainLoop ( )
protected

Definition at line 243 of file Console.cpp.

References DestroyWindow(), DrawLogo(), GetChar(), World::IsStopped(), m_loadWindow, m_logoWindow, MakeWindow(), Refresh(), ResizeWindow(), RunCommandLoop(), RunLogViewLoop(), sLog, sWorld, TermColor, ticketmgr, UpdateLog(), and value.

244 {
246 
247  int MenuActiveItem = 0;
248  time_t startTime = time(0); // we use our own timer due to thread-safety
249 
250  // height width y x
251  Window* menuWindow = MakeWindow(MenuItems + 2, 19, 1 + sOregonLogoRows + 1, COLS / 2 - 10 - 2);
252  Window* infoWindow = MakeWindow(4, sOregonLogoCols, 5 + sOregonLogoRows + MenuItems, COLS / 2 - sOregonLogoCols / 2);
253 
254  flushinp();
255 
256  wattron(menuWindow, A_BOLD | TermColor(COLOR_CYAN));
257  wborder(menuWindow, '|', '|', '-', '-', '+', '+', '+', '+');
258  wattroff(menuWindow, A_BOLD | TermColor(COLOR_CYAN));
259 
260  DrawLogo();
261 
262  while (!World::IsStopped())
263  {
264  // draw menu
265  for (int i = 0; i < MenuItems; i++)
266  {
267  if (MenuActiveItem == i)
268  {
269  wattron(menuWindow, A_BOLD | TermColor(COLOR_GREEN));
270  mvwprintw(menuWindow, i + 1, 1, "* %s *", Menu[i]);
271  wattroff(menuWindow, A_BOLD | TermColor(COLOR_GREEN));
272  }
273  else if (Menu[i][0] == '-')
274  mvwprintw(menuWindow, i + 1, 1, "--%s--", Menu[i]);
275  else
276  mvwprintw(menuWindow, i + 1, 1, " %s ", Menu[i]);
277  }
278 
279  // draw info
280  enum InfoValue
281  {
282  INFO_EMPTY,
283 
284  INFO_PLAYERS_ONLINE,
285  INFO_PLAYERS_QUEUED,
286  INFO_PLAYERS_MAX,
287 
288  INFO_REVISION,
289  INFO_LOGMASK,
290  INFO_UPTIME,
291  INFO_TICKETS
292  };
293 
294  struct
295  {
296  int y;
297  int x;
298  const char* type;
299  InfoValue value;
300  } InfoTable[]
301  =
302  {
303  { 0, 0, "Players:", INFO_PLAYERS_ONLINE },
304  { 1, 0, " ", INFO_PLAYERS_QUEUED },
305  { 2, 0, " ", INFO_PLAYERS_MAX, },
306  { 3, 0, " ", INFO_EMPTY, },
307 
308  { 0, 34, "Revision:", INFO_REVISION, },
309  { 1, 34, "LogMask:", INFO_LOGMASK, },
310  { 2, 34, "Uptime: ", INFO_UPTIME, },
311  { 3, 34, "Tickets: ", INFO_TICKETS, }
312  };
313 
314  for (uint32 i = 0; i < sizeof(InfoTable) / sizeof(*InfoTable); i++)
315  {
316  wmove(infoWindow, InfoTable[i].y, InfoTable[i].x);
317  wattron(infoWindow, A_BOLD | TermColor(COLOR_GREEN));
318  wprintw(infoWindow, "%s", InfoTable[i].type);
319  wattroff(infoWindow, A_BOLD | TermColor(COLOR_GREEN));
320  switch (InfoTable[i].value)
321  {
322  case INFO_PLAYERS_ONLINE:
323  wprintw(infoWindow, " %u (online)", sWorld.GetActiveSessionCount());
324  break;
325  case INFO_PLAYERS_QUEUED:
326  wprintw(infoWindow, " %u (queued)", sWorld.GetQueuedSessionCount());
327  break;
328  case INFO_PLAYERS_MAX:
329  wprintw(infoWindow, " %u (max)", sWorld.GetMaxActiveSessionCount() + sWorld.GetMaxQueuedSessionCount());
330  break;
331  case INFO_REVISION:
332  wprintw(infoWindow, " %s", _REVISION);
333  break;
334  case INFO_LOGMASK:
335  wprintw(infoWindow, " %lu", sLog.GetLogMask());
336  break;
337  case INFO_UPTIME:
338  {
339  time_t diff = time(0) - startTime;
340  uint32 mins = diff / 60;
341  uint32 hours = mins / 60;
342  uint32 days = hours / 24;
343  wprintw(infoWindow, " %ud %uh %um", days, hours % 24, mins % 60);
344  }
345  break;
346  case INFO_TICKETS:
347  wprintw(infoWindow, " %lu", ticketmgr.GM_TicketList.size());
348  default:
349  break;
350  }
351  }
352 
353  wrefresh(m_logoWindow);
354  wrefresh(menuWindow);
355  wrefresh(infoWindow);
356 
357  UpdateLog();
358 
359  // align timeout to the next minute
360  timeout((60 - ((time(0) - startTime) % 60)) * 1000);
361  int ch = GetChar();
362 
363  switch (ch)
364  {
365  case KEY_UP:
366  MenuActiveItem = (MenuActiveItem == 0) ? MenuItems - 1 : (MenuActiveItem - 1);
367  if (Menu[MenuActiveItem][0] == '-')
368  MenuActiveItem--;
369  break;
370  case KEY_DOWN:
371  MenuActiveItem = (MenuActiveItem >= MenuItems - 1) ? 0 : (MenuActiveItem + 1);
372  if (Menu[MenuActiveItem][0] == '-')
373  MenuActiveItem++;
374  break;
375  case KEY_ENTER:
376  case '\n':
377  case '\r':
378 
379  switch (MenuActiveItem)
380  {
381  case 0: /* Run a Command */
382  RunCommandLoop();
383  break;
384  case 1: /* Real-time logs */
385  RunLogViewLoop();
386  break;
387  case 3: /* shutdown */
388  endwin();
389  raise(SIGINT);
390  break;
391  }
392 
393  /* Fallthrough */
394  case KEY_RESIZE:
395 
396  erase();
397 
398  // win height width y x
399  ResizeWindow(m_logoWindow, sOregonLogoRows, sOregonLogoCols, 1, COLS / 2 - sOregonLogoCols / 2);
400  ResizeWindow(menuWindow, MenuItems + 2, 19, 1 + sOregonLogoRows + 1, std::max<int>(0, COLS / 2 - 10 - 2));
401  ResizeWindow(infoWindow, 4, sOregonLogoCols, 5 + sOregonLogoRows + MenuItems, COLS / 2 - sOregonLogoCols / 2);
402 
403  wattron(menuWindow, A_BOLD | TermColor(COLOR_CYAN));
404  wborder(menuWindow, '|', '|', '-', '-', '+', '+', '+', '+');
405  wattroff(menuWindow, A_BOLD | TermColor(COLOR_CYAN));
406 
407  Refresh();
408  DrawLogo();
409  break;
410  default:
411  break;;
412  }
413  }
414 
415  DestroyWindow(menuWindow);
416  DestroyWindow(infoWindow);
417 }
WINDOW Window
Definition: Console.h:9
void DestroyWindow(Window *win)
Definition: Console.cpp:201
#define sLog
Log class singleton.
Definition: Log.h:187
static bool IsStopped()
Definition: World.h:638
void RunLogViewLoop()
Definition: Console.cpp:625
Window * MakeWindow(int h, int w, int y, int x)
Definition: Console.cpp:193
etc mysql my cnf *Then change max_allowed_packet to a bigger value
int GetChar()
Definition: Console.cpp:218
#define TermColor(x)
Definition: Console.cpp:20
void Refresh()
Definition: Console.cpp:179
void ResizeWindow(Window *win, int h, int w, int y, int x)
Definition: Console.cpp:212
void UpdateLog()
Definition: Console.cpp:788
Window * m_logoWindow
Definition: Console.h:93
#define sWorld
Definition: World.h:860
void RunCommandLoop()
Definition: Console.cpp:455
ACE_UINT32 uint32
Definition: Define.h:71
Window * m_loadWindow
Definition: Console.h:94
#define ticketmgr
Definition: TicketMgr.h:94
void DrawLogo()
Definition: Console.cpp:760
Window * Console::MakeWindow ( int  h,
int  w,
int  y,
int  x 
)
private

Definition at line 193 of file Console.cpp.

References m_windows.

Referenced by FatalError(), Initialize(), MainLoop(), RunCommandLoop(), RunLogViewLoop(), and SetTitle().

194 {
195  Window* win = newwin(h, w, y, x);
196  leaveok(win, TRUE);
197  m_windows.insert(win);
198  return win;
199 }
WINDOW Window
Definition: Console.h:9
std::set< Window * > m_windows
Definition: Console.h:80
void Console::Refresh ( )
private

Definition at line 179 of file Console.cpp.

References m_windows.

Referenced by Initialize(), MainLoop(), and SetTitle().

180 {
181  wrefresh(stdscr);
182 
183  for (std::set<Window*>::const_iterator it = m_windows.begin(); it != m_windows.end(); it++)
184  wrefresh(*it);
185 }
std::set< Window * > m_windows
Definition: Console.h:80
void Console::ResizeWindow ( Window win,
int  h,
int  w,
int  y,
int  x 
)
private

Definition at line 212 of file Console.cpp.

Referenced by MainLoop(), RunCommandLoop(), RunLogViewLoop(), and SetTitle().

213 {
214  mvwin(win, y, x);
215  wresize(win, h, w);
216 }
void Console::Restore ( )
protected

Definition at line 187 of file Console.cpp.

References m_IamEnabled.

188 {
189  endwin();
190  m_IamEnabled = false;
191 }
bool m_IamEnabled
Definition: Console.h:81
void Console::RunCommandLoop ( )
protected

Definition at line 455 of file Console.cpp.

References CMD_FINISHED, CMD_SUCCESS, CBArg::colored, DestroyWindow(), GetChar(), World::IsStopped(), m_cmdHistory, m_cmdOutput, MakeWindow(), ResizeWindow(), ACE_Based::Thread::Sleep(), CBArg::status, sWorld, TermColor, and CBArg::win.

Referenced by MainLoop().

456 {
457  History::iterator historyCur = m_cmdHistory.begin();
458  if (m_cmdHistory.size())
459  std::advance(historyCur, m_cmdHistory.size() - 1);
460 
461  int no = 1;
462 
463  int lineWidth = COLS - (sizeof("Oregon>") - 1);
464  Window* cmdLine = MakeWindow(1, lineWidth, LINES - 1, (sizeof("Oregon>") - 1));
465 
466  erase();
467  curs_set(1);
468 
469  attron(A_BOLD | TermColor(COLOR_GREEN));
470  mvprintw(LINES - 1, 0, "Oregon> ");
471  attroff(A_BOLD | TermColor(COLOR_GREEN));
472  wattrset(cmdLine, A_PROTECT | TermColor(COLOR_WHITE));
473 
474  int y, mx, my;
475  int pageSize = LINES - 1;
476  getmaxyx(m_cmdOutput, my, mx);
477  y = my - 1 - pageSize;
478 
479  leaveok(cmdLine, FALSE);
480  wmove(cmdLine, 0, 0);
481 
482  pnoutrefresh(m_cmdOutput, y, 0, 0, 0, LINES - 2, COLS);
483  wrefresh(stdscr);
484  wrefresh(cmdLine);
485 
486  bool update = true;
487 
488  std::string buffer = "";
489 
490  while (!World::IsStopped())
491  {
492  if (update)
493  {
494  pnoutrefresh(m_cmdOutput, y, 0, 0, 0, LINES - 2, COLS);
495 
496  attron(A_BOLD | TermColor(COLOR_GREEN));
497  mvprintw(LINES - 1, 0, "Oregon> ");
498  attroff(A_BOLD | TermColor(COLOR_GREEN));
499 
500  wrefresh(stdscr);
501 
502  update = false;
503  }
504 
505  werase(cmdLine);
506  wrefresh(cmdLine);
507  mvwprintw(cmdLine, 0, 0, "%s", buffer.c_str() + std::max<int>(0, (buffer.size() - (lineWidth - 1))));
508  wmove(cmdLine, 0, std::min<size_t>(lineWidth - 1, buffer.size()));
509  wrefresh(cmdLine);
510 
511  int ch = GetChar();
512  if (ch >= 0x20 && ch < 0x7F)
513  {
514  if (buffer.empty() && ch != '.')
515  buffer.append(1, '.');
516  buffer.append(1, ch);
517  }
518  else if (ch == KEY_UP)
519  {
520  historyCur--;
521  if (historyCur != m_cmdHistory.end())
522  buffer = *historyCur;
523  else
524  buffer.clear();
525  }
526  else if (ch == KEY_DOWN)
527  {
528  historyCur++;
529  if (historyCur != m_cmdHistory.end())
530  buffer = *historyCur;
531  else
532  buffer.clear();
533  }
534  else if (ch == KEY_BACKSPACE || ch == 0x7F || ch == 0x08)
535  {
536  if (buffer.size())
537  buffer.resize(buffer.size() - 1);
538  }
539  else if (ch == KEY_PPAGE) // page up
540  {
541  update = true;
542  y = std::max<int>(0, y - pageSize);
543  }
544  else if (ch == KEY_NPAGE) // page down
545  {
546  update = true;
547  y = std::min<int>(my - 1 - pageSize, y + pageSize);
548  }
549  else if (ch == KEY_SR) // scroll up
550  {
551  update = true;
552  y = std::max<int>(0, y - 1);
553  }
554  else if (ch == KEY_SF) // scroll down
555  {
556  update = true;
557  y = std::min<int>(my - 1 - pageSize, y + 1);
558  }
559  else if ((ch == KEY_ENTER || ch == '\n' || ch == '\r'))
560  {
561  if (buffer.empty() || buffer == ".exit" || buffer == ".quit")
562  break;
563 
564  curs_set(0);
565 
566  CBArg result;
567  result.win = m_cmdOutput;
568  result.status = 0;
569  result.colored = (no ^= 1);
570 
571  sWorld.QueueCliCommand(new CliCommandHolder(&result, buffer.c_str(), &PrintCommandResultCallback, &CommandFinishedCallback));
572 
573  /* command is issued we now block until command is executed, to prevent crash in PrintCommandResultCallback:
574  when server shuts down and we destroy output window before last World::Update() which calls PrintCmdResCB;
575  also this ensures thread-safety between curses calls */
576  do
578  while (!(result.status & CMD_FINISHED) && !World::IsStopped());
579 
580  #if OREGON_DEBUG
581  if (!(result.status & CMD_SUCCESS))
582  {
583  wattron(m_cmdOutput, A_BOLD | TermColor(COLOR_RED));
584  wprintw(m_cmdOutput, "Command failed :(\n");
585  wattroff(m_cmdOutput, A_BOLD | TermColor(COLOR_RED));
586  }
587  #endif
588 
589  update = true;
590 
591  m_cmdHistory.push_back(buffer);
592  historyCur = m_cmdHistory.begin();
593  std::advance(historyCur, m_cmdHistory.size() - 1);
594 
595  buffer.clear();
596  curs_set(1);
597  }
598  else if (ch == KEY_RESIZE)
599  {
600  lineWidth = COLS - (sizeof("Oregon>") - 1);
601 
602  wresize(m_cmdOutput, 0xFFFF / COLS, COLS);
603 
604  ResizeWindow(cmdLine, 1, lineWidth, LINES - 1, (sizeof("Oregon>") - 1));
605  wmove(m_cmdOutput, LINES - 2, COLS - 1);
606 
607  werase(stdscr);
608 
609  pageSize = LINES - 4;
610  getmaxyx(m_cmdOutput, my, mx);
611  wmove(m_cmdOutput, my - 1, mx - 1);
612  waddch(m_cmdOutput, ' ');
613 
614  y = my - pageSize;
615 
616  update = true;
617  }
618 
619  }
620 
621  curs_set(0);
622  DestroyWindow(cmdLine);
623 }
bool colored
Definition: Console.cpp:429
WINDOW Window
Definition: Console.h:9
History m_cmdHistory
Definition: Console.h:90
void DestroyWindow(Window *win)
Definition: Console.cpp:201
static bool IsStopped()
Definition: World.h:638
Window * m_cmdOutput
Definition: Console.h:96
volatile long status
Definition: Console.cpp:428
static void Sleep(unsigned long msecs)
Definition: Threading.cpp:237
Window * MakeWindow(int h, int w, int y, int x)
Definition: Console.cpp:193
Window * win
Definition: Console.cpp:427
int GetChar()
Definition: Console.cpp:218
#define TermColor(x)
Definition: Console.cpp:20
void ResizeWindow(Window *win, int h, int w, int y, int x)
Definition: Console.cpp:212
#define sWorld
Definition: World.h:860
void Console::RunLogViewLoop ( )
protected

Definition at line 625 of file Console.cpp.

References DestroyWindow(), GetChar(), World::IsStopped(), m_logViewer, MakeWindow(), ResizeWindow(), TermColor, and UpdateLog().

Referenced by MainLoop().

626 {
627  const char info[] = "Use arrows, PgUp/PgDn to scroll. Enter to return. (%lu%%)";
628  size_t len = sizeof(info) - 1;
629 
630  int y, mx, my;
631  int pageSize = LINES - 4;
632  getmaxyx(m_logViewer, my, mx);
633  my--;
634 
635  y = my - pageSize;
636 
637  Window* infoWindow = MakeWindow(2, len, LINES - 2, COLS / 2 - len / 2);
638  wattron(infoWindow, A_BOLD | TermColor(COLOR_GREEN));
639 
640  erase();
641  refresh();
642 
643  wrefresh(infoWindow);
644  timeout(1000);
645 
646  while (!World::IsStopped())
647  {
648  if (y == my - pageSize)
649  {
650  UpdateLog();
651  prefresh(m_logViewer, y, 0, 0, 0, pageSize + 1, COLS);
652  }
653  else
654  prefresh(m_logViewer, y, 0, 0, 0, pageSize, COLS);
655 
656  werase(infoWindow);
657  mvwprintw(infoWindow, 0, 0, info, (100 * y) / (my - pageSize));
658  wrefresh(infoWindow);
659 
660  int ch = GetChar();
661 
662  if (ch == KEY_ENTER || ch == '\r' || ch == '\n')
663  break;
664  else if (ch == KEY_PPAGE) // page up
665  y = std::max<int>(0, y - pageSize);
666  else if (ch == KEY_NPAGE) // page down
667  y = std::min<int>(my - pageSize, y + pageSize);
668  else if (ch == KEY_UP || ch == KEY_SR)
669  y = std::max<int>(0, y - 1);
670  else if (ch == KEY_DOWN || ch == KEY_SF)
671  y = std::min<int>(my - pageSize, y + 1);
672  else if (ch == KEY_RESIZE)
673  {
674  ResizeWindow(infoWindow, 2, len, LINES - 2, COLS / 2 - len / 2);
675 
676  wresize(m_logViewer, 0xFFFF / COLS, COLS);
677 
678  pageSize = LINES - 4;
679  getmaxyx(m_logViewer, my, mx);
680  wmove(m_logViewer, my - 1, mx - 1);
681  waddch(m_logViewer, ' ');
682 
683  y = my - pageSize;
684  }
685  }
686 
687  DestroyWindow(infoWindow);
688 }
WINDOW Window
Definition: Console.h:9
void DestroyWindow(Window *win)
Definition: Console.cpp:201
static bool IsStopped()
Definition: World.h:638
Window * m_logViewer
Definition: Console.h:95
Window * MakeWindow(int h, int w, int y, int x)
Definition: Console.cpp:193
int GetChar()
Definition: Console.cpp:218
#define TermColor(x)
Definition: Console.cpp:20
void ResizeWindow(Window *win, int h, int w, int y, int x)
Definition: Console.cpp:212
void UpdateLog()
Definition: Console.cpp:788
void Console::SetLoading ( bool  show,
const char *  caption = "Initializing" 
)
protected

Definition at line 690 of file Console.cpp.

References DestroyWindow(), m_IamEnabled, and m_loadWindow.

691 {
692  if (!m_loadWindow || !m_IamEnabled)
693  return;
694 
695  if (on)
696  {
697  const char stop[] = "Press <CTRL-C> to stop";
698 
699  wattron(m_loadWindow, A_BOLD);
700 
701  wprintw(m_loadWindow, "%s ", caption);
702  mvwprintw(m_loadWindow, 0, sOregonLogoCols - (sizeof(stop) - 1), "%s", stop);
703 
704  wattroff(m_loadWindow, A_BOLD);
705  wrefresh(m_loadWindow);
706  }
707  else
708  {
710  m_loadWindow = NULL;
711  }
712 }
void DestroyWindow(Window *win)
Definition: Console.cpp:201
bool m_IamEnabled
Definition: Console.h:81
Window * m_loadWindow
Definition: Console.h:94
void Console::SetLoadingLabel ( const char *  label,
bool  br = true 
)
protected

Definition at line 714 of file Console.cpp.

References m_IamEnabled, m_loadWindow, and sLog.

715 {
716  if (m_IamEnabled)
717  {
718  if (!m_loadWindow)
719  return;
720 
721  wmove(m_loadWindow, 2, 0);
722  wclrtoeol(m_loadWindow);
723  mvwprintw(m_loadWindow, 2, 0, "%s", label);
724  wrefresh(m_loadWindow);
725  }
726  else
727  {
728  if (br)
729  sLog.outString();
730  sLog.outString("%s", label);
731  }
732 }
#define sLog
Log class singleton.
Definition: Log.h:187
bool m_IamEnabled
Definition: Console.h:81
Window * m_loadWindow
Definition: Console.h:94
void Console::SetTitle ( const char *  title)
inlineprivate

Definition at line 59 of file Console.h.

References DestroyWindow(), DrawLoading(), GetChar(), MakeWindow(), Refresh(), ResizeWindow(), and UpdateLog().

Referenced by Console().

60  {
61  #if PLATFORM == PLATFORM_WINDOWS
62  SetConsoleTitle("OregonCore");
63  #elif PLATFORM == PLATFORM_UNIX
64  printf("\033]0;%s\007", title);
65  fflush(stdout);
66  #endif
67  }
void Console::UpdateLog ( )
private

Definition at line 788 of file Console.cpp.

References m_loggerFd, m_logViewer, and TermColor.

Referenced by MainLoop(), RunLogViewLoop(), and SetTitle().

789 {
790  /* Before you start optimizing or "repairing" this functions bear in mind:
791  * we read from pipe (we try to read atomic chunks)
792  * read() calls are used in non-blocking I/O
793  * ReadFile() calls are used with PeekNamedPipe() to achieve non-blocking I/O
794  * read()/ReadFile() don't guarantee to read exactly *size* bytes
795  * we call this function to *free* bytes so logger can send another data
796 
797  So to properly handle colors we use our own special escapes:
798  * to apply a color we send 0xFF byte following with the color value
799  * to unapply color we send 0xFE byte
800  * 0xFF and 0xFE are chosen because they are invalid for utf8
801  * one call to this function may read 0xFF byte but not the actual color
802  so we use *static* control to check if the previous byte was 0xFF
803 
804  I admit this function is terrible for performance, although:
805  * it's run from separate thread (cliThread)
806  * user probably won't notice a delay
807  */
808 
809  static long control = 0;
810  unsigned char buffer[PIPE_BUF];
811 
812  #if PLATFORM == PLATFORM_WINDOWS
813  unsigned long len, i, total;
814  while (PeekNamedPipe(m_loggerFd, NULL, 0, NULL, &total, NULL) &&
815  total &&
816  ReadFile(m_loggerFd, buffer, std::min<unsigned long>(total, sizeof(buffer)), &len, NULL))
817  #else
818  ssize_t len, i;
819  while ((len = read(m_loggerFd, (char*)buffer, sizeof(buffer))) > 0)
820  #endif
821  {
822  for (i = 0; i < len; i++)
823  {
824  switch (buffer[i])
825  {
826  case 0xFF:
827  control = 1;
828  continue;
829  case 0xFE:
830  wattrset(m_logViewer, A_NORMAL);
831  continue;
832  default:
833  if (control)
834  {
835  control = 0;
836  if (buffer[i] > 7)
837  wattrset(m_logViewer, A_BOLD | TermColor(buffer[i] - 8));
838  else
839  wattrset(m_logViewer, TermColor(buffer[i]));
840  continue;
841  }
842 
843  waddch(m_logViewer, buffer[i]);
844  }
845  }
846  }
847 }
PipeType m_loggerFd
Definition: Console.h:91
Window * m_logViewer
Definition: Console.h:95
#define TermColor(x)
Definition: Console.cpp:20

Friends And Related Function Documentation

void LoadSQLUpdates ( )
friend
friend class Log
friend

Definition at line 22 of file Console.h.

friend class Master
friend

Definition at line 21 of file Console.h.

friend class UnixDebugger
friend

Definition at line 23 of file Console.h.

friend class World
friend

Definition at line 20 of file Console.h.

Member Data Documentation

History Console::m_cmdHistory
private

Definition at line 90 of file Console.h.

Referenced by RunCommandLoop().

Window* Console::m_cmdOutput
private

Definition at line 96 of file Console.h.

Referenced by Initialize(), and RunCommandLoop().

bool Console::m_IamEnabled
private
Window* Console::m_loadWindow
private

Definition at line 94 of file Console.h.

Referenced by Initialize(), MainLoop(), SetLoading(), and SetLoadingLabel().

PipeType Console::m_loggerFd
private

Definition at line 91 of file Console.h.

Referenced by Initialize(), UpdateLog(), and ~Console().

Window* Console::m_logoWindow
private

Definition at line 93 of file Console.h.

Referenced by DrawLogo(), Initialize(), and MainLoop().

Window* Console::m_logViewer
private

Definition at line 95 of file Console.h.

Referenced by Initialize(), RunLogViewLoop(), and UpdateLog().

std::set<Window*> Console::m_windows
private

Definition at line 80 of file Console.h.

Referenced by DestroyWindow(), MakeWindow(), Refresh(), and ~Console().


The documentation for this class was generated from the following files: