Chat.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. #include "Chat.h"
  2. #include <File.h>
  3. #include <Logging.h>
  4. #include "Game.h"
  5. #include "Player.h"
  6. const Framework::Text Chat::CHANNEL_INFO = "system:INFO";
  7. const Framework::Text Chat::CHANNEL_WARNING = "system:WARNING";
  8. const Framework::Text Chat::CHANNEL_ERROR = "system:ERROR";
  9. Chat::Chat()
  10. : ReferenceCounter(),
  11. commandExecutor(new ChatCommandExecutor())
  12. {
  13. Framework::File messageData;
  14. messageData.setFile(
  15. Game::INSTANCE->getWorldDirectory() + "/chat/history.chat");
  16. if (messageData.exists() && messageData.open(Framework::File::Style::read))
  17. {
  18. Framework::Logging::info()
  19. << "loading chat history from " << messageData.zPfad()->getText()
  20. << "\nDelete that file to reset the chat history or use the "
  21. "'/resetChat [channel] [timestamp]' command."; // TODO: implement
  22. // /resetChat
  23. // command
  24. while (!messageData.isEnd())
  25. {
  26. ChatMessage* message = new ChatMessage(&messageData);
  27. history.add(message);
  28. }
  29. messageData.close();
  30. }
  31. }
  32. Chat::~Chat()
  33. {
  34. commandExecutor->release();
  35. }
  36. void Chat::addMessage(ChatMessage* message)
  37. {
  38. cs.lock();
  39. history.add(message);
  40. NetworkMessage* nMsg = new NetworkMessage();
  41. nMsg->sendChatMessage(message);
  42. nMsg->setUseBackground();
  43. for (auto it = observer.begin(); it;)
  44. {
  45. if (!it->isValid())
  46. {
  47. it.remove();
  48. continue;
  49. }
  50. if (it->isSubscribedTo(message->getChannel())
  51. && (!message->getTargetPlayerName().getLength()
  52. || it->getPlayerName().isEqual(message->getTargetPlayerName())))
  53. {
  54. Entity* zEtity = Game::INSTANCE->zEntity(it->getEntityId());
  55. if (zEtity)
  56. {
  57. Game::INSTANCE->sendMessage(
  58. dynamic_cast<NetworkMessage*>(nMsg->getThis()), zEtity);
  59. }
  60. }
  61. it++;
  62. }
  63. nMsg->release();
  64. cs.unlock();
  65. }
  66. void Chat::addObserver(int entityId)
  67. {
  68. cs.lock();
  69. ChatObserver* obs = new ChatObserver(entityId);
  70. this->observer.add(obs);
  71. Framework::Text name = obs->getPlayerName();
  72. for (ChatMessage* msg : history)
  73. {
  74. if (obs->isSubscribedTo(msg->getChannel())
  75. && (!msg->getTargetPlayerName().getLength()
  76. || name.isEqual(msg->getTargetPlayerName())))
  77. {
  78. NetworkMessage* nMsg = new NetworkMessage();
  79. nMsg->sendChatMessage(msg);
  80. nMsg->setUseBackground();
  81. Game::INSTANCE->sendMessage(
  82. nMsg, Game::INSTANCE->zEntity(entityId));
  83. }
  84. }
  85. Entity* zPlayer = Game::INSTANCE->zEntity(entityId);
  86. if (zPlayer)
  87. {
  88. NetworkMessage* options = new NetworkMessage();
  89. options->sendChatOptions(obs);
  90. Game::INSTANCE->sendMessage(options, zPlayer);
  91. }
  92. cs.unlock();
  93. }
  94. void Chat::removeObserver(int entityId)
  95. {
  96. cs.lock();
  97. for (auto it = this->observer.begin(); it; it++)
  98. {
  99. if (it->getEntityId() == entityId)
  100. {
  101. it->save();
  102. it.remove();
  103. break;
  104. }
  105. }
  106. cs.unlock();
  107. }
  108. void Chat::chatApi(Framework::StreamReader* zRequest,
  109. Entity* zSource,
  110. NetworkMessage* zResponse)
  111. {
  112. char id;
  113. zRequest->read(&id, 1);
  114. switch (id)
  115. {
  116. case 0: // send message
  117. {
  118. short len;
  119. zRequest->read((char*)&len, 2);
  120. char* buffer = new char[len + 1];
  121. zRequest->read(buffer, len);
  122. buffer[len] = 0;
  123. if (buffer[0] == '/')
  124. {
  125. if (!commandExecutor->execute(buffer, zSource))
  126. {
  127. sendMessageTo("Unknown kommand. Use /help to get "
  128. "information about all known commands.",
  129. zSource,
  130. CHANNEL_ERROR);
  131. }
  132. }
  133. else
  134. {
  135. Player* p = dynamic_cast<Player*>(zSource);
  136. if (p)
  137. {
  138. broadcastMessage(
  139. buffer, getPlayerChannelName(p->getName()));
  140. }
  141. else
  142. {
  143. // TODO: implement entity channels
  144. }
  145. }
  146. delete[] buffer;
  147. break;
  148. }
  149. case 1: // add channel
  150. {
  151. char len;
  152. zRequest->read(&len, 1);
  153. char* buffer = new char[len + 1];
  154. zRequest->read(buffer, len);
  155. buffer[(int)len] = 0;
  156. for (ChatObserver* observer : this->observer)
  157. {
  158. if (observer->getEntityId() == zSource->getId())
  159. {
  160. observer->addChannel(buffer);
  161. break;
  162. }
  163. }
  164. delete[] buffer;
  165. break;
  166. }
  167. case 2: // remove channel
  168. {
  169. char len;
  170. zRequest->read(&len, 1);
  171. char* buffer = new char[len + 1];
  172. zRequest->read(buffer, len);
  173. buffer[(int)len] = 0;
  174. for (ChatObserver* observer : this->observer)
  175. {
  176. if (observer->getEntityId() == zSource->getId())
  177. {
  178. observer->removeChannel(buffer);
  179. }
  180. }
  181. delete[] buffer;
  182. break;
  183. }
  184. case 3: // add ignored player
  185. {
  186. char len;
  187. zRequest->read(&len, 1);
  188. char* buffer = new char[len + 1];
  189. zRequest->read(buffer, len);
  190. buffer[(int)len] = 0;
  191. for (ChatObserver* observer : this->observer)
  192. {
  193. if (observer->getEntityId() == zSource->getId())
  194. {
  195. observer->addIgnoredPlayer(buffer);
  196. }
  197. }
  198. delete[] buffer;
  199. break;
  200. }
  201. case 4: // remove ignored player
  202. {
  203. char len;
  204. zRequest->read(&len, 1);
  205. char* buffer = new char[len + 1];
  206. zRequest->read(buffer, len);
  207. buffer[(int)len] = 0;
  208. for (ChatObserver* observer : this->observer)
  209. {
  210. if (observer->getEntityId() == zSource->getId())
  211. {
  212. observer->removeIgnoredPlayer(buffer);
  213. }
  214. }
  215. delete[] buffer;
  216. break;
  217. }
  218. }
  219. }
  220. void Chat::broadcastMessage(Framework::Text message, Framework::Text channel)
  221. {
  222. addMessage(new ChatMessage(message, channel, ""));
  223. Framework::Logging::info() << "Chat [" << channel << "] " << message;
  224. }
  225. void Chat::sendMessageTo(
  226. Framework::Text message, Entity* zTarget, Framework::Text channel)
  227. {
  228. if (!zTarget)
  229. {
  230. Framework::Logging::info() << message;
  231. return;
  232. }
  233. Player* p = dynamic_cast<Player*>(zTarget);
  234. if (p)
  235. {
  236. addMessage(new ChatMessage(message, channel, p->getName()));
  237. }
  238. }
  239. void Chat::save()
  240. {
  241. cs.lock();
  242. for (ChatObserver* obs : observer)
  243. {
  244. obs->save();
  245. }
  246. Framework::File messageData;
  247. messageData.setFile(
  248. Game::INSTANCE->getWorldDirectory() + "/chat/history.chat");
  249. if (!messageData.exists()) messageData.create();
  250. messageData.open(Framework::File::Style::write);
  251. for (ChatMessage* msg : history)
  252. {
  253. msg->writeTo(&messageData);
  254. }
  255. messageData.close();
  256. cs.unlock();
  257. }
  258. ChatCommandExecutor* Chat::zCommandExecutor() const
  259. {
  260. return commandExecutor;
  261. }
  262. Framework::Text Chat::getPlayerChannelName(Framework::Text playerName)
  263. {
  264. return Framework::Text("player:") + playerName;
  265. }