123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- #include "Chat.h"
- #include <Datei.h>
- #include "Game.h"
- #include "Player.h"
- const Framework::Text Chat::CHANNEL_INFO = "system:INFO";
- const Framework::Text Chat::CHANNEL_WARNING = "system:WARNING";
- const Framework::Text Chat::CHANNEL_ERROR = "system:ERROR";
- Chat::Chat()
- : ReferenceCounter(),
- commandExecutor(new ChatCommandExecutor())
- {
- Framework::Datei messageData;
- messageData.setDatei(
- Game::INSTANCE->getWorldDirectory() + "/chat/history.chat");
- if (messageData.existiert()
- && messageData.open(Framework::Datei::Style::lesen))
- {
- std::cout << "loading chat history from "
- << messageData.zPfad()->getText() << std::endl
- << "Delete that file to reset the chat history or use the "
- "'/resetChat [channel] [timestamp]' command."
- << std::endl; // TODO: implement /resetChat command
- while (!messageData.istEnde())
- {
- ChatMessage* message = new ChatMessage(&messageData);
- history.add(message);
- }
- messageData.close();
- }
- }
- Chat::~Chat()
- {
- commandExecutor->release();
- }
- void Chat::addMessage(ChatMessage* message)
- {
- cs.lock();
- history.add(message);
- NetworkMessage* nMsg = new NetworkMessage();
- nMsg->sendChatMessage(message);
- nMsg->setUseBackground();
- for (auto it = observer.begin(); it;)
- {
- if (!it->isValid())
- {
- it.remove();
- continue;
- }
- if (it->isSubscribedTo(message->getChannel())
- && (!message->getTargetPlayerName().getLength()
- || it->getPlayerName().istGleich(
- message->getTargetPlayerName())))
- {
- Entity* zEtity = Game::INSTANCE->zEntity(it->getEntityId());
- if (zEtity)
- {
- Game::INSTANCE->sendMessage(
- dynamic_cast<NetworkMessage*>(nMsg->getThis()), zEtity);
- }
- }
- it++;
- }
- nMsg->release();
- cs.unlock();
- }
- void Chat::addObserver(int entityId)
- {
- cs.lock();
- ChatObserver* obs = new ChatObserver(entityId);
- this->observer.add(obs);
- Framework::Text name = obs->getPlayerName();
- for (ChatMessage* msg : history)
- {
- if (obs->isSubscribedTo(msg->getChannel())
- && (!msg->getTargetPlayerName().getLength()
- || name.istGleich(msg->getTargetPlayerName())))
- {
- NetworkMessage* nMsg = new NetworkMessage();
- nMsg->sendChatMessage(msg);
- nMsg->setUseBackground();
- Game::INSTANCE->sendMessage(
- nMsg, Game::INSTANCE->zEntity(entityId));
- }
- }
- Entity* zPlayer = Game::INSTANCE->zEntity(entityId);
- if (zPlayer)
- {
- NetworkMessage* options = new NetworkMessage();
- options->sendChatOptions(obs);
- Game::INSTANCE->sendMessage(options, zPlayer);
- }
- cs.unlock();
- }
- void Chat::removeObserver(int entityId)
- {
- cs.lock();
- for (auto it = this->observer.begin(); it; it++)
- {
- if (it->getEntityId() == entityId)
- {
- it->save();
- it.remove();
- break;
- }
- }
- cs.unlock();
- }
- void Chat::chatApi(Framework::StreamReader* zRequest,
- Entity* zSource,
- NetworkMessage* zResponse)
- {
- char id;
- zRequest->lese(&id, 1);
- switch (id)
- {
- case 0: // send message
- {
- short len;
- zRequest->lese((char*)&len, 2);
- char* buffer = new char[len + 1];
- zRequest->lese(buffer, len);
- buffer[len] = 0;
- if (buffer[0] == '/')
- {
- if (!commandExecutor->execute(buffer, zSource))
- {
- sendMessageTo("Unknown kommand. Use /help to get "
- "information about all known commands.",
- zSource,
- CHANNEL_ERROR);
- }
- }
- else
- {
- Player* p = dynamic_cast<Player*>(zSource);
- if (p)
- {
- broadcastMessage(
- buffer, getPlayerChannelName(p->getName()));
- }
- else
- {
- // TODO: implement entity channels
- }
- }
- delete[] buffer;
- break;
- }
- case 1: // add channel
- {
- char len;
- zRequest->lese(&len, 1);
- char* buffer = new char[len + 1];
- zRequest->lese(buffer, len);
- buffer[(int)len] = 0;
- for (ChatObserver* observer : this->observer)
- {
- if (observer->getEntityId() == zSource->getId())
- {
- observer->addChannel(buffer);
- break;
- }
- }
- delete[] buffer;
- break;
- }
- case 2: // remove channel
- {
- char len;
- zRequest->lese(&len, 1);
- char* buffer = new char[len + 1];
- zRequest->lese(buffer, len);
- buffer[(int)len] = 0;
- for (ChatObserver* observer : this->observer)
- {
- if (observer->getEntityId() == zSource->getId())
- {
- observer->removeChannel(buffer);
- }
- }
- delete[] buffer;
- break;
- }
- case 3: // add ignored player
- {
- char len;
- zRequest->lese(&len, 1);
- char* buffer = new char[len + 1];
- zRequest->lese(buffer, len);
- buffer[(int)len] = 0;
- for (ChatObserver* observer : this->observer)
- {
- if (observer->getEntityId() == zSource->getId())
- {
- observer->addIgnoredPlayer(buffer);
- }
- }
- delete[] buffer;
- break;
- }
- case 4: // remove ignored player
- {
- char len;
- zRequest->lese(&len, 1);
- char* buffer = new char[len + 1];
- zRequest->lese(buffer, len);
- buffer[(int)len] = 0;
- for (ChatObserver* observer : this->observer)
- {
- if (observer->getEntityId() == zSource->getId())
- {
- observer->removeIgnoredPlayer(buffer);
- }
- }
- delete[] buffer;
- break;
- }
- }
- }
- void Chat::broadcastMessage(Framework::Text message, Framework::Text channel)
- {
- addMessage(new ChatMessage(message, channel, ""));
- std::cout << "Chat [" << channel << "] " << message << "\n";
- }
- void Chat::sendMessageTo(
- Framework::Text message, Entity* zTarget, Framework::Text channel)
- {
- if (!zTarget)
- {
- std::cout << message << "\n";
- return;
- }
- Player* p = dynamic_cast<Player*>(zTarget);
- if (p)
- {
- addMessage(new ChatMessage(message, channel, p->getName()));
- }
- }
- void Chat::save()
- {
- cs.lock();
- for (ChatObserver* obs : observer)
- {
- obs->save();
- }
- Framework::Datei messageData;
- messageData.setDatei(
- Game::INSTANCE->getWorldDirectory() + "/chat/history.chat");
- if (!messageData.existiert()) messageData.erstellen();
- messageData.open(Framework::Datei::Style::schreiben);
- for (ChatMessage* msg : history)
- {
- msg->writeTo(&messageData);
- }
- messageData.close();
- cs.unlock();
- }
- ChatCommandExecutor* Chat::zCommandExecutor() const
- {
- return commandExecutor;
- }
- Framework::Text Chat::getPlayerChannelName(Framework::Text playerName)
- {
- return Framework::Text("player:") + playerName;
- }
|