diff --git a/src/stationapi/Node.hpp b/src/stationapi/Node.hpp index 6ce98a3..be5235c 100644 --- a/src/stationapi/Node.hpp +++ b/src/stationapi/Node.hpp @@ -8,6 +8,7 @@ #include #include #include +#include template class Node : public UdpManagerHandler { diff --git a/src/stationchat/CMakeLists.txt b/src/stationchat/CMakeLists.txt index b2e335e..b2c53d0 100644 --- a/src/stationchat/CMakeLists.txt +++ b/src/stationchat/CMakeLists.txt @@ -34,6 +34,7 @@ add_executable(stationchat protocol/SetApiVersion.hpp protocol/SetAvatarAttributes.hpp protocol/UpdatePersistentMessage.hpp + protocol/UpdatePersistentMessages.hpp ChatAvatar.cpp ChatAvatar.hpp diff --git a/src/stationchat/GatewayClient.cpp b/src/stationchat/GatewayClient.cpp index 8a6d521..7ee4723 100644 --- a/src/stationchat/GatewayClient.cpp +++ b/src/stationchat/GatewayClient.cpp @@ -42,6 +42,7 @@ #include "protocol/SetApiVersion.hpp" #include "protocol/SetAvatarAttributes.hpp" #include "protocol/UpdatePersistentMessage.hpp" +#include "protocol/UpdatePersistentMessages.hpp" #include "easylogging++.h" @@ -138,6 +139,9 @@ void GatewayClient::OnIncoming(std::istringstream& istream) { case ChatRequestType::UPDATEPERSISTENTMESSAGE: HandleIncomingMessage(istream); break; + case ChatRequestType::UPDATEPERSISTENTMESSAGES: + HandleIncomingMessage(istream); + break; case ChatRequestType::IGNORESTATUS: HandleIncomingMessage(istream); break; diff --git a/src/stationchat/PersistentMessageService.cpp b/src/stationchat/PersistentMessageService.cpp index 3f22d3d..fe2f34a 100644 --- a/src/stationchat/PersistentMessageService.cpp +++ b/src/stationchat/PersistentMessageService.cpp @@ -208,3 +208,32 @@ void PersistentMessageService::UpdateMessageStatus( sqlite3_finalize(stmt); } + +void PersistentMessageService::BulkUpdateMessageStatus( + uint32_t avatarId, const std::u16string& category, PersistentState newStatus) +{ + sqlite3_stmt* stmt; + + char sql[] = "UPDATE persistent_message SET status = @status WHERE avatar_id = @avatar_id AND " + "category = @category"; + + auto result = sqlite3_prepare_v2(db_, sql, -1, &stmt, 0); + if (result != SQLITE_OK) { + throw SQLite3Exception{result, sqlite3_errmsg(db_)}; + } + + int statusIdx = sqlite3_bind_parameter_index(stmt, "@status"); + int avatarIdIdx = sqlite3_bind_parameter_index(stmt, "@avatar_id"); + int categoryIdx = sqlite3_bind_parameter_index(stmt, "@category"); + + sqlite3_bind_int(stmt, statusIdx, static_cast(newStatus)); + sqlite3_bind_int(stmt, avatarIdIdx, avatarId); + std::string cat = FromWideString(category); + sqlite3_bind_text(stmt, categoryIdx, cat.c_str(), -1, nullptr); + + result = sqlite3_step(stmt); + if (result != SQLITE_DONE) { + throw SQLite3Exception{result, sqlite3_errmsg(db_)}; + } + sqlite3_finalize(stmt); +} diff --git a/src/stationchat/PersistentMessageService.hpp b/src/stationchat/PersistentMessageService.hpp index a61a812..6a8b1bc 100644 --- a/src/stationchat/PersistentMessageService.hpp +++ b/src/stationchat/PersistentMessageService.hpp @@ -25,6 +25,9 @@ public: void UpdateMessageStatus( uint32_t avatarId, uint32_t messageId, PersistentState status); + void BulkUpdateMessageStatus( + uint32_t avatarId, const std::u16string& category, PersistentState newStatus); + private: sqlite3* db_; }; diff --git a/src/stationchat/protocol/Protocol.cpp b/src/stationchat/protocol/Protocol.cpp index 8fa6188..bedb370 100644 --- a/src/stationchat/protocol/Protocol.cpp +++ b/src/stationchat/protocol/Protocol.cpp @@ -43,6 +43,7 @@ #include "protocol/SetApiVersion.hpp" #include "protocol/SetAvatarAttributes.hpp" #include "protocol/UpdatePersistentMessage.hpp" +#include "protocol/UpdatePersistentMessages.hpp" #include "easylogging++.h" @@ -729,3 +730,11 @@ UpdatePersistentMessage::UpdatePersistentMessage(GatewayClient* client, const Re messageService_->UpdateMessageStatus( request.srcAvatarId, request.messageId, request.status); } + +UpdatePersistentMessages::UpdatePersistentMessages(GatewayClient *client, const RequestType &request, ResponseType &response) + : messageService_{client->GetNode()->GetMessageService()} +{ + LOG(INFO) << "UPDATEPERSISTENTMESSAGES request received"; + messageService_->BulkUpdateMessageStatus( + request.srcAvatarId, request.category, request.newStatus); +} diff --git a/src/stationchat/protocol/UpdatePersistentMessages.hpp b/src/stationchat/protocol/UpdatePersistentMessages.hpp new file mode 100755 index 0000000..f271086 --- /dev/null +++ b/src/stationchat/protocol/UpdatePersistentMessages.hpp @@ -0,0 +1,67 @@ +/** + * UpdatePersistentMessages.hpp + * Specific handling for bulk-message update requests + * e.g. for use with /emptyMail command + * + * SWG Source Addition - 2021 + * Authors: Aconite + */ + +#pragma once + +#include "ChatEnums.hpp" +#include "PersistentMessage.hpp" + +class PersistentMessageService; +class GatewayClient; + +/** Begin UpdatePersistentMessages Request */ + +struct ReqUpdatePersistentMessages { + const ChatRequestType type = ChatRequestType::UPDATEPERSISTENTMESSAGES; + uint32_t track; + uint32_t srcAvatarId; + PersistentState currentStatus; + PersistentState newStatus; + std::u16string category; +}; + +template +void read(StreamT& ar, ReqUpdatePersistentMessages& data) { + read(ar, data.track); + read(ar, data.srcAvatarId); + read(ar, data.currentStatus); + read(ar, data.newStatus); + read(ar, data.category); +} + +/** Begin UpdatePersistentMessages Response */ + +struct ResUpdatePersistentMessages { + ResUpdatePersistentMessages(uint32_t track_) + : track{track_} + , result{ChatResultCode::SUCCESS} {} + + const ChatResponseType type = ChatResponseType::UPDATEPERSISTENTMESSAGES; + uint32_t track; + ChatResultCode result; +}; + +template +void write(StreamT& ar, const ResUpdatePersistentMessages& data) { + write(ar, data.type); + write(ar, data.track); + write(ar, data.result); +} + +class UpdatePersistentMessages { +public: + using RequestType = ReqUpdatePersistentMessages; + using ResponseType = ResUpdatePersistentMessages; + + UpdatePersistentMessages(GatewayClient* client, const RequestType& request, ResponseType& response); + +private: + PersistentMessageService* messageService_; +}; +