Chat.cpp 7.7 KB

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