Chat.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. #include "Chat.h"
  2. #include <Datei.h>
  3. #include "Game.h"
  4. #include "Player.h"
  5. const Framework::Text Chat::CHANNEL_INFO = "system:INFO";
  6. const Framework::Text Chat::CHANNEL_WARNING = "system:WARNING";
  7. const Framework::Text Chat::CHANNEL_ERROR = "system:ERROR";
  8. Chat::Chat()
  9. : ReferenceCounter(),
  10. commandExecutor(new ChatCommandExecutor())
  11. {
  12. Framework::Datei messageData;
  13. messageData.setDatei(
  14. Game::INSTANCE->getWorldDirectory() + "/chat/history.chat");
  15. if (messageData.existiert()
  16. && messageData.open(Framework::Datei::Style::lesen))
  17. {
  18. std::cout << "loading chat history from "
  19. << messageData.zPfad()->getText() << std::endl
  20. << "Delete that file to reset the chat history or use the "
  21. "'/resetChat [channel] [timestamp]' command."
  22. << std::endl; // TODO: implement /resetChat command
  23. while (!messageData.istEnde())
  24. {
  25. ChatMessage* message = new ChatMessage(&messageData);
  26. history.add(message);
  27. }
  28. messageData.close();
  29. }
  30. }
  31. Chat::~Chat()
  32. {
  33. commandExecutor->release();
  34. }
  35. void Chat::addMessage(ChatMessage* message)
  36. {
  37. cs.lock();
  38. history.add(message);
  39. NetworkMessage* nMsg = new NetworkMessage();
  40. nMsg->sendChatMessage(message);
  41. nMsg->setUseBackground();
  42. for (auto it = observer.begin(); it;)
  43. {
  44. if (!it->isValid())
  45. {
  46. it.remove();
  47. continue;
  48. }
  49. if (it->isSubscribedTo(message->getChannel())
  50. && (!message->getTargetPlayerName().getLength()
  51. || it->getPlayerName().istGleich(
  52. 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.istGleich(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->lese(&id, 1);
  114. switch (id)
  115. {
  116. case 0: // send message
  117. {
  118. short len;
  119. zRequest->lese((char*)&len, 2);
  120. char* buffer = new char[len + 1];
  121. zRequest->lese(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->lese(&len, 1);
  153. char* buffer = new char[len + 1];
  154. zRequest->lese(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->lese(&len, 1);
  171. char* buffer = new char[len + 1];
  172. zRequest->lese(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->lese(&len, 1);
  188. char* buffer = new char[len + 1];
  189. zRequest->lese(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->lese(&len, 1);
  205. char* buffer = new char[len + 1];
  206. zRequest->lese(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. std::cout << "Chat [" << channel << "] " << message << "\n";
  224. }
  225. void Chat::sendMessageTo(
  226. Framework::Text message, Entity* zTarget, Framework::Text channel)
  227. {
  228. if (!zTarget)
  229. {
  230. std::cout << message << "\n";
  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::Datei messageData;
  247. messageData.setDatei(
  248. Game::INSTANCE->getWorldDirectory() + "/chat/history.chat");
  249. if (!messageData.existiert()) messageData.erstellen();
  250. messageData.open(Framework::Datei::Style::schreiben);
  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. }