TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
LinkExtractor Class Reference

#include <ChatLink.h>

Public Member Functions

 LinkExtractor (const char *msg)
 
 ~LinkExtractor ()
 
bool IsValidMessage ()
 

Private Types

typedef std::list< ChatLink * > Links
 

Private Attributes

Links _links
 
std::istringstream _iss
 

Member Typedef Documentation

typedef std::list<ChatLink*> LinkExtractor::Links
private

Constructor & Destructor Documentation

LinkExtractor::LinkExtractor ( const char *  msg)
explicit
582 : _iss(msg) { }
std::istringstream _iss
Definition: ChatLink.h:175
LinkExtractor::~LinkExtractor ( )
585 {
586  for (Links::iterator itr = _links.begin(); itr != _links.end(); ++itr)
587  delete *itr;
588  _links.clear();
589 }
Links _links
Definition: ChatLink.h:174

Member Function Documentation

bool LinkExtractor::IsValidMessage ( )
592 {
593  const char validSequence[6] = "cHhhr";
594  const char* validSequenceIterator = validSequence;
595 
596  char buffer[256];
597 
598  std::istringstream::pos_type startPos = 0;
599  uint32 color = 0;
600 
601  ChatLink* link = NULL;
602  while (!_iss.eof())
603  {
604  if (validSequence == validSequenceIterator)
605  {
606  link = NULL;
607  _iss.ignore(255, PIPE_CHAR);
608  startPos = _iss.tellg() - std::istringstream::pos_type(1);
609  }
610  else if (_iss.get() != PIPE_CHAR)
611  {
612  TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence aborted unexpectedly", _iss.str().c_str());
613  return false;
614  }
615 
616  // pipe has always to be followed by at least one char
617  if (_iss.peek() == '\0')
618  {
619  TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): pipe followed by '\\0'", _iss.str().c_str());
620  return false;
621  }
622 
623  // no further pipe commands
624  if (_iss.eof())
625  break;
626 
627  char commandChar;
628  _iss >> commandChar;
629 
630  // | in normal messages is escaped by ||
631  if (commandChar != PIPE_CHAR)
632  {
633  if (commandChar == *validSequenceIterator)
634  {
635  if (validSequenceIterator == validSequence+4)
636  validSequenceIterator = validSequence;
637  else
638  ++validSequenceIterator;
639  }
640  else
641  {
642  TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): invalid sequence, expected '%c' but got '%c'", _iss.str().c_str(), *validSequenceIterator, commandChar);
643  return false;
644  }
645  }
646  else if (validSequence != validSequenceIterator)
647  {
648  // no escaped pipes in sequences
649  TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): got escaped pipe in sequence", _iss.str().c_str());
650  return false;
651  }
652 
653  switch (commandChar)
654  {
655  case 'c':
656  if (!ReadHex(_iss, color, 8))
657  {
658  TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): invalid hexadecimal number while reading color", _iss.str().c_str());
659  return false;
660  }
661  break;
662  case 'H':
663  // read chars up to colon = link type
664  _iss.getline(buffer, 256, DELIMITER);
665  if (_iss.eof())
666  {
667  TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly", _iss.str().c_str());
668  return false;
669  }
670 
671  if (strcmp(buffer, "item") == 0)
672  link = new ItemChatLink();
673  else if (strcmp(buffer, "quest") == 0)
674  link = new QuestChatLink();
675  else if (strcmp(buffer, "trade") == 0)
676  link = new TradeChatLink();
677  else if (strcmp(buffer, "talent") == 0)
678  link = new TalentChatLink();
679  else if (strcmp(buffer, "spell") == 0)
680  link = new SpellChatLink();
681  else if (strcmp(buffer, "enchant") == 0)
682  link = new EnchantmentChatLink();
683  else if (strcmp(buffer, "achievement") == 0)
684  link = new AchievementChatLink();
685  else if (strcmp(buffer, "glyph") == 0)
686  link = new GlyphChatLink();
687  else
688  {
689  TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): user sent unsupported link type '%s'", _iss.str().c_str(), buffer);
690  return false;
691  }
692  _links.push_back(link);
693  link->SetColor(color);
694  if (!link->Initialize(_iss))
695  return false;
696  break;
697  case 'h':
698  // if h is next element in sequence, this one must contain the linked text :)
699  if (*validSequenceIterator == 'h')
700  {
701  // links start with '['
702  if (_iss.get() != '[')
703  {
704  TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): link caption doesn't start with '['", _iss.str().c_str());
705  return false;
706  }
707  _iss.getline(buffer, 256, ']');
708  if (_iss.eof())
709  {
710  TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly", _iss.str().c_str());
711  return false;
712  }
713 
714  if (!link)
715  return false;
716 
717  if (!link->ValidateName(buffer, _iss.str().c_str()))
718  return false;
719  }
720  break;
721  case 'r':
722  if (link)
723  link->SetBounds(startPos, _iss.tellg());
724  case '|':
725  // no further payload
726  break;
727  default:
728  TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): got invalid command |%c", _iss.str().c_str(), commandChar);
729  return false;
730  }
731  }
732 
733  // check if every opened sequence was also closed properly
734  if (validSequence != validSequenceIterator)
735  {
736  TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): EOF in active sequence", _iss.str().c_str());
737  return false;
738  }
739 
740  return true;
741 }
arena_t NULL
Definition: jemalloc_internal.h:624
std::istringstream _iss
Definition: ChatLink.h:175
Links _links
Definition: ChatLink.h:174
#define TC_LOG_TRACE(filterType__,...)
Definition: Log.h:195
uint32_t uint32
Definition: Define.h:150

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

std::istringstream LinkExtractor::_iss
private
Links LinkExtractor::_links
private

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