1#include "mtx/responses/common.hpp"
2
3#include <nlohmann/json.hpp>
4
5#include "mtx/events.hpp"
6#include "mtx/events/aliases.hpp"
7#include "mtx/events/avatar.hpp"
8#include "mtx/events/canonical_alias.hpp"
9#include "mtx/events/create.hpp"
10#include "mtx/events/guest_access.hpp"
11#include "mtx/events/history_visibility.hpp"
12#include "mtx/events/join_rules.hpp"
13#include "mtx/events/member.hpp"
14#include "mtx/events/name.hpp"
15#include "mtx/events/pinned_events.hpp"
16#include "mtx/events/power_levels.hpp"
17#include "mtx/events/reaction.hpp"
18#include "mtx/events/redaction.hpp"
19#include "mtx/events/tag.hpp"
20#include "mtx/events/topic.hpp"
21#include "mtx/events/voip.hpp"
22#include "mtx/log.hpp"
23
24using json = nlohmann::json;
25using namespace mtx::events::account_data;
26using namespace mtx::events::state;
27using namespace mtx::events::msg;
28
29namespace mtx {
30namespace responses {
31void
32from_json(const nlohmann::json &obj, RoomId &response)
33{
34 response.room_id = obj.at(key: "room_id").get<std::string>();
35}
36
37void
38from_json(const nlohmann::json &obj, EventId &response)
39{
40 response.event_id = obj.at(key: "event_id").get<mtx::identifiers::Event>();
41}
42
43void
44from_json(const nlohmann::json &obj, FilterId &response)
45{
46 response.filter_id = obj.at(key: "filter_id").get<std::string>();
47}
48
49void
50from_json(const nlohmann::json &obj, Version &response)
51{
52 response.version = obj.at(key: "version").get<std::string>();
53}
54
55void
56from_json(const nlohmann::json &obj, Success &success)
57{
58 success.success = obj.at(key: "success").get<bool>();
59}
60
61void
62from_json(const nlohmann::json &obj, Available &response)
63{
64 response.available = obj.at(key: "available").get<bool>();
65}
66
67void
68from_json(const nlohmann::json &obj, RequestToken &r)
69{
70 r.sid = obj.at(key: "sid").get<std::string>();
71
72 if (obj.contains(key: "submit_url"))
73 r.submit_url = obj.at(key: "submit_url").get<std::string>();
74}
75
76void
77from_json(const nlohmann::json &obj, Aliases &response)
78{
79 response.aliases = obj.at(key: "aliases").get<std::vector<std::string>>();
80}
81
82namespace utils {
83
84void
85log_error(std::exception &err, const json &event)
86{
87 mtx::utils::log::log()->warn(fmt: "Error parsing events: {}, {}", args: err.what(), args: event.dump(indent: 2));
88}
89
90void
91log_error(const std::string &err, const json &event)
92{
93 mtx::utils::log::log()->warn(fmt: "Error parsing events: {}, {}", args: err, args: event.dump(indent: 2));
94}
95
96void
97parse_room_account_data_events(
98 const json &events,
99 std::vector<mtx::events::collections::RoomAccountDataEvents> &container)
100{
101 container.clear();
102 container.reserve(n: events.size());
103
104 for (const auto &e : events) {
105 const auto type = mtx::events::getEventType(obj: e);
106
107 // if (!e.contains("content") || e["content"].empty()) {
108 // container.emplace_back(events::AccountDataEvent<events::msg::Redacted>(e));
109 // break;
110 //}
111
112 try {
113 switch (type) {
114 case events::EventType::Direct: {
115 container.emplace_back(args: events::AccountDataEvent<Direct>(e));
116 break;
117 }
118 case events::EventType::Tag: {
119 container.emplace_back(args: events::AccountDataEvent<Tags>(e));
120 break;
121 }
122 case events::EventType::FullyRead: {
123 container.emplace_back(
124 args: events::AccountDataEvent<events::account_data::FullyRead>(e));
125 break;
126 }
127 case events::EventType::PushRules: {
128 container.emplace_back(args: events::AccountDataEvent<pushrules::GlobalRuleset>(e));
129 break;
130 }
131 case events::EventType::NhekoHiddenEvents: {
132 container.emplace_back(args: events::AccountDataEvent<nheko_extensions::HiddenEvents>(e));
133 break;
134 }
135 case events::EventType::ImagePackRooms: {
136 container.emplace_back(
137 args: events::AccountDataEvent<events::msc2545::ImagePackRooms>(e));
138 break;
139 }
140 case events::EventType::ImagePackInAccountData: {
141 container.emplace_back(args: events::AccountDataEvent<events::msc2545::ImagePack>(e));
142 break;
143 }
144 case events::EventType::Unsupported: {
145 container.emplace_back(args: events::EphemeralEvent<events::Unknown>(e));
146 break;
147 }
148 case events::EventType::KeyVerificationCancel:
149 case events::EventType::KeyVerificationRequest:
150 case events::EventType::KeyVerificationStart:
151 case events::EventType::KeyVerificationReady:
152 case events::EventType::KeyVerificationDone:
153 case events::EventType::KeyVerificationAccept:
154 case events::EventType::KeyVerificationKey:
155 case events::EventType::KeyVerificationMac:
156 case events::EventType::SecretRequest:
157 case events::EventType::SecretSend:
158 case events::EventType::Presence:
159 case events::EventType::Reaction:
160 case events::EventType::RoomAliases:
161 case events::EventType::RoomAvatar:
162 case events::EventType::RoomCanonicalAlias:
163 case events::EventType::RoomCreate:
164 case events::EventType::RoomEncrypted:
165 case events::EventType::Dummy:
166 case events::EventType::RoomEncryption:
167 case events::EventType::RoomGuestAccess:
168 case events::EventType::RoomHistoryVisibility:
169 case events::EventType::RoomJoinRules:
170 case events::EventType::RoomKey:
171 case events::EventType::ForwardedRoomKey:
172 case events::EventType::RoomKeyRequest:
173 case events::EventType::RoomMember:
174 case events::EventType::RoomMessage:
175 case events::EventType::RoomName:
176 case events::EventType::RoomPinnedEvents:
177 case events::EventType::RoomPowerLevels:
178 case events::EventType::RoomRedaction:
179 case events::EventType::RoomTombstone:
180 case events::EventType::RoomTopic:
181 case events::EventType::Widget:
182 case events::EventType::VectorWidget:
183 case events::EventType::PolicyRuleUser:
184 case events::EventType::PolicyRuleRoom:
185 case events::EventType::PolicyRuleServer:
186 case events::EventType::SpaceChild:
187 case events::EventType::SpaceParent:
188 case events::EventType::Sticker:
189 case events::EventType::CallInvite:
190 case events::EventType::CallCandidates:
191 case events::EventType::CallAnswer:
192 case events::EventType::CallHangUp:
193 case events::EventType::CallSelectAnswer:
194 case events::EventType::CallReject:
195 case events::EventType::CallNegotiate:
196 case events::EventType::Typing:
197 case events::EventType::Receipt:
198 case events::EventType::ImagePackInRoom:
199 continue;
200 }
201 } catch (std::exception &err) {
202 log_error(err, event: e);
203 }
204 }
205}
206
207void
208compose_timeline_events(json &events,
209 const std::vector<mtx::events::collections::TimelineEvents> &container)
210{
211 const auto &c = container.at(n: 0);
212 events = std::visit(visitor: [](auto e) { return json(e); }, variants: c);
213}
214
215void
216parse_timeline_events(const json &events,
217 std::vector<mtx::events::collections::TimelineEvents> &container)
218{
219 container.clear();
220 container.reserve(n: events.size());
221
222 for (const auto &e : events) {
223 const auto type = mtx::events::getEventType(obj: e);
224
225 try {
226 if (e.contains(key: "unsigned") && e["unsigned"].contains(key: "redacted_by")) {
227 if (e.contains(key: "state_key"))
228 container.emplace_back(args: events::StateEvent<events::msg::Redacted>(e));
229 else
230 container.emplace_back(args: events::RoomEvent<events::msg::Redacted>(e));
231 continue;
232 }
233 switch (type) {
234 case events::EventType::Reaction: {
235 container.emplace_back(args: events::RoomEvent<events::msg::Reaction>(e));
236 break;
237 }
238 case events::EventType::RoomAliases: {
239 container.emplace_back(args: events::StateEvent<events::state::Aliases>(e));
240 break;
241 }
242 case events::EventType::RoomAvatar: {
243 container.emplace_back(args: events::StateEvent<Avatar>(e));
244 break;
245 }
246 case events::EventType::RoomCanonicalAlias: {
247 container.emplace_back(args: events::StateEvent<CanonicalAlias>(e));
248 break;
249 }
250 case events::EventType::RoomCreate: {
251 container.emplace_back(args: events::StateEvent<Create>(e));
252 break;
253 }
254 case events::EventType::RoomEncrypted: {
255 container.emplace_back(args: events::EncryptedEvent<mtx::events::msg::Encrypted>(e));
256 break;
257 }
258 case events::EventType::RoomEncryption: {
259 container.emplace_back(args: events::StateEvent<Encryption>(e));
260 break;
261 }
262 case events::EventType::RoomGuestAccess: {
263 container.emplace_back(args: events::StateEvent<GuestAccess>(e));
264
265 break;
266 }
267 case events::EventType::RoomHistoryVisibility: {
268 container.emplace_back(args: events::StateEvent<HistoryVisibility>(e));
269
270 break;
271 }
272 case events::EventType::RoomJoinRules: {
273 container.emplace_back(args: events::StateEvent<JoinRules>(e));
274
275 break;
276 }
277 case events::EventType::RoomMember: {
278 container.emplace_back(args: events::StateEvent<Member>(e));
279
280 break;
281 }
282 case events::EventType::RoomName: {
283 container.emplace_back(args: events::StateEvent<Name>(e));
284
285 break;
286 }
287 case events::EventType::RoomPowerLevels: {
288 container.emplace_back(args: events::StateEvent<PowerLevels>(e));
289
290 break;
291 }
292 case events::EventType::RoomRedaction: {
293 container.emplace_back(args: events::RedactionEvent<mtx::events::msg::Redaction>(e));
294
295 break;
296 }
297 case events::EventType::RoomTombstone: {
298 container.emplace_back(args: events::StateEvent<Tombstone>(e));
299
300 break;
301 }
302 case events::EventType::RoomTopic: {
303 container.emplace_back(args: events::StateEvent<Topic>(e));
304
305 break;
306 }
307 case events::EventType::Widget: {
308 container.emplace_back(args: events::StateEvent<Widget>(e));
309
310 break;
311 }
312 case events::EventType::VectorWidget: {
313 container.emplace_back(args: events::StateEvent<Widget>(e));
314
315 break;
316 }
317 case events::EventType::PolicyRuleUser: {
318 container.emplace_back(args: events::StateEvent<policy_rule::UserRule>(e));
319
320 break;
321 }
322 case events::EventType::PolicyRuleRoom: {
323 container.emplace_back(args: events::StateEvent<policy_rule::RoomRule>(e));
324
325 break;
326 }
327 case events::EventType::PolicyRuleServer: {
328 container.emplace_back(args: events::StateEvent<policy_rule::ServerRule>(e));
329
330 break;
331 }
332 case events::EventType::SpaceChild: {
333 container.emplace_back(args: events::StateEvent<space::Child>(e));
334
335 break;
336 }
337 case events::EventType::SpaceParent: {
338 container.emplace_back(args: events::StateEvent<space::Parent>(e));
339
340 break;
341 }
342 case events::EventType::ImagePackInRoom: {
343 container.emplace_back(args: events::StateEvent<events::msc2545::ImagePack>(e));
344
345 break;
346 }
347 case events::EventType::KeyVerificationStart: {
348 container.emplace_back(args: events::RoomEvent<events::msg::KeyVerificationStart>(e));
349
350 break;
351 }
352 case events::EventType::KeyVerificationAccept: {
353 container.emplace_back(args: events::RoomEvent<events::msg::KeyVerificationAccept>(e));
354
355 break;
356 }
357 case events::EventType::KeyVerificationDone: {
358 container.emplace_back(args: events::RoomEvent<events::msg::KeyVerificationDone>(e));
359
360 break;
361 }
362 case events::EventType::KeyVerificationReady: {
363 container.emplace_back(args: events::RoomEvent<events::msg::KeyVerificationReady>(e));
364
365 break;
366 }
367 case events::EventType::KeyVerificationKey: {
368 container.emplace_back(args: events::RoomEvent<events::msg::KeyVerificationKey>(e));
369
370 break;
371 }
372 case events::EventType::KeyVerificationMac: {
373 container.emplace_back(args: events::RoomEvent<events::msg::KeyVerificationMac>(e));
374
375 break;
376 }
377 case events::EventType::KeyVerificationCancel: {
378 container.emplace_back(args: events::RoomEvent<events::msg::KeyVerificationCancel>(e));
379
380 break;
381 }
382 case events::EventType::RoomMessage: {
383 using MsgType = mtx::events::MessageType;
384 const auto msg_type = mtx::events::getMessageType(obj: e.at(key: "content"));
385
386 switch (msg_type) {
387 case MsgType::Audio: {
388 container.emplace_back(args: events::RoomEvent<events::msg::Audio>(e));
389
390 break;
391 }
392 case MsgType::Confetti: {
393 container.emplace_back(args: events::RoomEvent<events::msg::Confetti>(e));
394
395 break;
396 }
397 case MsgType::Emote: {
398 container.emplace_back(args: events::RoomEvent<events::msg::Emote>(e));
399
400 break;
401 }
402 case MsgType::File: {
403 container.emplace_back(args: events::RoomEvent<events::msg::File>(e));
404
405 break;
406 }
407 case MsgType::Image: {
408 container.emplace_back(args: events::RoomEvent<events::msg::Image>(e));
409
410 break;
411 }
412 case MsgType::Location: {
413 /* events::RoomEvent<events::msg::Location> location = e; */
414 /* container.emplace_back(location); */
415 break;
416 }
417 case MsgType::Notice: {
418 container.emplace_back(args: events::RoomEvent<events::msg::Notice>(e));
419
420 break;
421 }
422 case MsgType::Text: {
423 container.emplace_back(args: events::RoomEvent<events::msg::Text>(e));
424
425 break;
426 }
427 case MsgType::Video: {
428 container.emplace_back(args: events::RoomEvent<events::msg::Video>(e));
429
430 break;
431 }
432 case MsgType::KeyVerificationRequest: {
433 container.emplace_back(
434 args: events::RoomEvent<events::msg::KeyVerificationRequest>(e));
435
436 break;
437 }
438 case MsgType::Unknown: {
439 container.emplace_back(args: events::RoomEvent<events::Unknown>(e));
440 break;
441 }
442 }
443 break;
444 }
445 case events::EventType::Sticker: {
446 container.emplace_back(args: events::Sticker(e));
447
448 break;
449 }
450 case events::EventType::CallInvite: {
451 container.emplace_back(args: events::RoomEvent<events::voip::CallInvite>(e));
452
453 break;
454 }
455 case events::EventType::CallCandidates: {
456 container.emplace_back(args: events::RoomEvent<events::voip::CallCandidates>(e));
457
458 break;
459 }
460 case events::EventType::CallAnswer: {
461 container.emplace_back(args: events::RoomEvent<events::voip::CallAnswer>(e));
462
463 break;
464 }
465 case events::EventType::CallHangUp: {
466 container.emplace_back(args: events::RoomEvent<events::voip::CallHangUp>(e));
467
468 break;
469 }
470 case events::EventType::CallSelectAnswer: {
471 container.emplace_back(args: events::RoomEvent<events::voip::CallSelectAnswer>(e));
472
473 break;
474 }
475 case events::EventType::CallReject: {
476 container.emplace_back(args: events::RoomEvent<events::voip::CallReject>(e));
477
478 break;
479 }
480 case events::EventType::CallNegotiate: {
481 container.emplace_back(args: events::RoomEvent<events::voip::CallNegotiate>(e));
482
483 break;
484 }
485 case events::EventType::RoomPinnedEvents: {
486 container.emplace_back(args: events::StateEvent<events::state::PinnedEvents>(e));
487
488 break;
489 }
490 case events::EventType::Unsupported: {
491 container.emplace_back(args: events::RoomEvent<events::Unknown>(e));
492
493 break;
494 }
495 case events::EventType::KeyVerificationRequest:
496 case events::EventType::RoomKey: // Not part of timeline or state
497 case events::EventType::ForwardedRoomKey: // Not part of timeline or state
498 case events::EventType::RoomKeyRequest: // Not part of the timeline
499 case events::EventType::Direct: // Not part of the timeline or state
500 case events::EventType::Tag: // Not part of the timeline or state
501 case events::EventType::Presence: // Not part of the timeline or state
502 case events::EventType::PushRules: // Not part of the timeline or state
503 case events::EventType::SecretRequest: // Not part of the timeline or state
504 case events::EventType::SecretSend: // Not part of the timeline or state
505 case events::EventType::Typing:
506 case events::EventType::Receipt:
507 case events::EventType::FullyRead:
508 case events::EventType::NhekoHiddenEvents:
509 case events::EventType::ImagePackRooms:
510 case events::EventType::ImagePackInAccountData:
511 case events::EventType::Dummy:
512 continue;
513 }
514 } catch (std::exception &err) {
515 log_error(err, event: e);
516 }
517 }
518}
519
520void
521parse_device_events(const json &events,
522 std::vector<mtx::events::collections::DeviceEvents> &container)
523{
524 container.clear();
525 container.reserve(n: events.size());
526 for (const auto &e : events) {
527 const auto type = mtx::events::getEventType(obj: e);
528
529 try {
530 switch (type) {
531 case events::EventType::RoomEncrypted: {
532 const auto algo = e.at(key: "content").at(key: "algorithm").get<std::string>();
533 // Algorithm determines whether it's an olm or megolm event
534 if (algo == "m.olm.v1.curve25519-aes-sha2") {
535 container.emplace_back(args: events::DeviceEvent<OlmEncrypted>(e));
536 } else if (algo == "m.megolm.v1.aes-sha2") {
537 container.emplace_back(args: events::DeviceEvent<Encrypted>(e));
538 } else {
539 log_error(err: "Invalid m.room.encrypted algorithm", event: e);
540 continue;
541 }
542 break;
543 }
544 case events::EventType::Dummy: {
545 container.emplace_back(args: events::DeviceEvent<Dummy>(e));
546
547 break;
548 }
549 case events::EventType::RoomKey: {
550 container.emplace_back(args: events::DeviceEvent<RoomKey>(e));
551
552 break;
553 }
554 case events::EventType::ForwardedRoomKey: {
555 container.emplace_back(args: events::DeviceEvent<ForwardedRoomKey>(e));
556
557 break;
558 }
559 case events::EventType::RoomKeyRequest: {
560 container.emplace_back(args: events::DeviceEvent<KeyRequest>(e));
561
562 break;
563 }
564 case events::EventType::KeyVerificationCancel: {
565 container.emplace_back(args: events::DeviceEvent<KeyVerificationCancel>(e));
566
567 break;
568 }
569 case events::EventType::KeyVerificationRequest:
570 container.emplace_back(args: events::DeviceEvent<KeyVerificationRequest>(e));
571
572 break;
573 case events::EventType::KeyVerificationStart:
574 container.emplace_back(args: events::DeviceEvent<KeyVerificationStart>(e));
575
576 break;
577 case events::EventType::KeyVerificationAccept:
578 container.emplace_back(args: events::DeviceEvent<KeyVerificationAccept>(e));
579
580 break;
581 case events::EventType::KeyVerificationKey:
582 container.emplace_back(args: events::DeviceEvent<KeyVerificationKey>(e));
583
584 break;
585 case events::EventType::KeyVerificationMac:
586 container.emplace_back(args: events::DeviceEvent<KeyVerificationMac>(e));
587
588 break;
589 case events::EventType::KeyVerificationReady:
590 container.emplace_back(args: events::DeviceEvent<KeyVerificationReady>(e));
591
592 break;
593 case events::EventType::KeyVerificationDone:
594 container.emplace_back(args: events::DeviceEvent<KeyVerificationDone>(e));
595
596 break;
597 case events::EventType::SecretSend:
598 container.emplace_back(args: events::DeviceEvent<SecretSend>(e));
599
600 break;
601 case events::EventType::SecretRequest:
602 container.emplace_back(args: events::DeviceEvent<SecretRequest>(e));
603
604 break;
605 case events::EventType::Unsupported:
606 container.emplace_back(args: events::DeviceEvent<events::Unknown>(e));
607
608 break;
609 default:
610 continue;
611 }
612 } catch (std::exception &err) {
613 log_error(err, event: e);
614 }
615 }
616}
617
618void
619parse_state_events(const json &events,
620 std::vector<mtx::events::collections::StateEvents> &container)
621{
622 container.clear();
623 container.reserve(n: events.size());
624
625 for (const auto &e : events) {
626 const auto type = mtx::events::getEventType(obj: e);
627
628 try {
629 if (e.contains(key: "unsigned") && e["unsigned"].contains(key: "redacted_by")) {
630 container.emplace_back(args: events::StateEvent<events::msg::Redacted>(e));
631 continue;
632 }
633
634 switch (type) {
635 case events::EventType::RoomAliases: {
636 container.emplace_back(args: events::StateEvent<events::state::Aliases>(e));
637
638 break;
639 }
640 case events::EventType::RoomAvatar: {
641 container.emplace_back(args: events::StateEvent<Avatar>(e));
642 break;
643 }
644 case events::EventType::RoomCanonicalAlias: {
645 container.emplace_back(args: events::StateEvent<CanonicalAlias>(e));
646
647 break;
648 }
649 case events::EventType::RoomCreate: {
650 container.emplace_back(args: events::StateEvent<Create>(e));
651
652 break;
653 }
654 case events::EventType::RoomEncryption: {
655 container.emplace_back(args: events::StateEvent<Encryption>(e));
656
657 break;
658 }
659 case events::EventType::RoomGuestAccess: {
660 container.emplace_back(args: events::StateEvent<GuestAccess>(e));
661
662 break;
663 }
664 case events::EventType::RoomHistoryVisibility: {
665 container.emplace_back(args: events::StateEvent<HistoryVisibility>(e));
666
667 break;
668 }
669 case events::EventType::RoomJoinRules: {
670 container.emplace_back(args: events::StateEvent<JoinRules>(e));
671
672 break;
673 }
674 case events::EventType::RoomMember: {
675 container.emplace_back(args: events::StateEvent<Member>(e));
676
677 break;
678 }
679 case events::EventType::RoomName: {
680 container.emplace_back(args: events::StateEvent<Name>(e));
681
682 break;
683 }
684 case events::EventType::RoomPowerLevels: {
685 container.emplace_back(args: events::StateEvent<PowerLevels>(e));
686
687 break;
688 }
689 case events::EventType::RoomTombstone: {
690 container.emplace_back(args: events::StateEvent<Tombstone>(e));
691
692 break;
693 }
694 case events::EventType::RoomTopic: {
695 container.emplace_back(args: events::StateEvent<Topic>(e));
696
697 break;
698 }
699 case events::EventType::Widget: {
700 container.emplace_back(args: events::StateEvent<Widget>(e));
701
702 break;
703 }
704 case events::EventType::VectorWidget: {
705 container.emplace_back(args: events::StateEvent<Widget>(e));
706
707 break;
708 }
709 case events::EventType::PolicyRuleUser: {
710 container.emplace_back(args: events::StateEvent<policy_rule::UserRule>(e));
711
712 break;
713 }
714 case events::EventType::PolicyRuleRoom: {
715 container.emplace_back(args: events::StateEvent<policy_rule::RoomRule>(e));
716
717 break;
718 }
719 case events::EventType::PolicyRuleServer: {
720 container.emplace_back(args: events::StateEvent<policy_rule::ServerRule>(e));
721
722 break;
723 }
724 case events::EventType::SpaceChild: {
725 container.emplace_back(args: events::StateEvent<space::Child>(e));
726
727 break;
728 }
729 case events::EventType::SpaceParent: {
730 container.emplace_back(args: events::StateEvent<space::Parent>(e));
731
732 break;
733 }
734 case events::EventType::ImagePackInRoom: {
735 container.emplace_back(args: events::StateEvent<events::msc2545::ImagePack>(e));
736
737 break;
738 }
739 case events::EventType::RoomPinnedEvents: {
740 container.emplace_back(args: events::StateEvent<events::state::PinnedEvents>(e));
741
742 break;
743 }
744 case events::EventType::Unsupported: {
745 container.emplace_back(args: events::StateEvent<events::Unknown>(e));
746
747 break;
748 }
749 case events::EventType::Sticker:
750 case events::EventType::Reaction:
751 case events::EventType::RoomEncrypted: /* Does this need to be here? */
752 case events::EventType::RoomKey: // Not part of timeline or state
753 case events::EventType::ForwardedRoomKey: // Not part of timeline or state
754 case events::EventType::RoomKeyRequest: // Not part of the timeline or state
755 case events::EventType::RoomMessage:
756 case events::EventType::RoomRedaction:
757 case events::EventType::Direct: // Not part of the timeline or state
758 case events::EventType::Tag: // Not part of the timeline or state
759 case events::EventType::Presence: // Not part of the timeline or state
760 case events::EventType::PushRules: // Not part of the timeline or state
761 case events::EventType::KeyVerificationCancel:
762 case events::EventType::KeyVerificationRequest:
763 case events::EventType::KeyVerificationStart:
764 case events::EventType::KeyVerificationReady:
765 case events::EventType::KeyVerificationDone:
766 case events::EventType::KeyVerificationAccept:
767 case events::EventType::KeyVerificationKey:
768 case events::EventType::KeyVerificationMac:
769 case events::EventType::SecretRequest:
770 case events::EventType::SecretSend:
771 case events::EventType::CallInvite:
772 case events::EventType::CallCandidates:
773 case events::EventType::CallAnswer:
774 case events::EventType::CallHangUp:
775 case events::EventType::CallSelectAnswer:
776 case events::EventType::CallReject:
777 case events::EventType::CallNegotiate:
778 case events::EventType::Typing:
779 case events::EventType::Receipt:
780 case events::EventType::FullyRead:
781 case events::EventType::NhekoHiddenEvents:
782 case events::EventType::ImagePackRooms:
783 case events::EventType::ImagePackInAccountData:
784 case events::EventType::Dummy:
785 continue;
786 }
787 } catch (std::exception &err) {
788 log_error(err, event: e);
789 }
790 }
791}
792
793void
794parse_stripped_events(const json &events,
795 std::vector<mtx::events::collections::StrippedEvents> &container)
796{
797 container.clear();
798 container.reserve(n: events.size());
799
800 for (const auto &e : events) {
801 const auto type = mtx::events::getEventType(obj: e);
802
803 try {
804 switch (type) {
805 case events::EventType::RoomAliases: {
806 container.emplace_back(args: events::StrippedEvent<mtx::events::state::Aliases>(e));
807
808 break;
809 }
810 case events::EventType::RoomAvatar: {
811 container.emplace_back(args: events::StrippedEvent<Avatar>(e));
812
813 break;
814 }
815 case events::EventType::RoomCanonicalAlias: {
816 container.emplace_back(args: events::StrippedEvent<CanonicalAlias>(e));
817
818 break;
819 }
820 case events::EventType::RoomCreate: {
821 container.emplace_back(args: events::StrippedEvent<Create>(e));
822
823 break;
824 }
825 case events::EventType::RoomGuestAccess: {
826 container.emplace_back(args: events::StrippedEvent<GuestAccess>(e));
827
828 break;
829 }
830 case events::EventType::RoomHistoryVisibility: {
831 container.emplace_back(args: events::StrippedEvent<HistoryVisibility>(e));
832
833 break;
834 }
835 case events::EventType::RoomJoinRules: {
836 container.emplace_back(args: events::StrippedEvent<JoinRules>(e));
837
838 break;
839 }
840 case events::EventType::RoomMember: {
841 container.emplace_back(args: events::StrippedEvent<Member>(e));
842
843 break;
844 }
845 case events::EventType::RoomName: {
846 container.emplace_back(args: events::StrippedEvent<Name>(e));
847
848 break;
849 }
850 case events::EventType::RoomPowerLevels: {
851 container.emplace_back(args: events::StrippedEvent<PowerLevels>(e));
852
853 break;
854 }
855 case events::EventType::RoomTombstone: {
856 container.emplace_back(args: events::StrippedEvent<Tombstone>(e));
857
858 break;
859 }
860 case events::EventType::RoomTopic: {
861 container.emplace_back(args: events::StrippedEvent<Topic>(e));
862
863 break;
864 }
865 case events::EventType::Widget: {
866 container.emplace_back(args: events::StrippedEvent<Widget>(e));
867
868 break;
869 }
870 case events::EventType::VectorWidget: {
871 container.emplace_back(args: events::StrippedEvent<Widget>(e));
872
873 break;
874 }
875 case events::EventType::PolicyRuleUser: {
876 container.emplace_back(args: events::StrippedEvent<policy_rule::UserRule>(e));
877
878 break;
879 }
880 case events::EventType::PolicyRuleRoom: {
881 container.emplace_back(args: events::StrippedEvent<policy_rule::RoomRule>(e));
882
883 break;
884 }
885 case events::EventType::PolicyRuleServer: {
886 container.emplace_back(args: events::StrippedEvent<policy_rule::ServerRule>(e));
887
888 break;
889 }
890 case events::EventType::SpaceChild: {
891 container.emplace_back(args: events::StrippedEvent<space::Child>(e));
892
893 break;
894 }
895 case events::EventType::SpaceParent: {
896 container.emplace_back(args: events::StrippedEvent<space::Parent>(e));
897
898 break;
899 }
900 case events::EventType::RoomPinnedEvents: {
901 container.emplace_back(args: events::StrippedEvent<events::state::PinnedEvents>(e));
902
903 break;
904 }
905 case events::EventType::Unsupported: {
906 container.emplace_back(args: events::StrippedEvent<events::Unknown>(e));
907
908 break;
909 }
910 case events::EventType::Sticker:
911 case events::EventType::Reaction:
912 case events::EventType::RoomEncrypted:
913 case events::EventType::RoomEncryption:
914 case events::EventType::RoomMessage:
915 case events::EventType::RoomRedaction:
916 case events::EventType::RoomKey: // Not part of timeline or state
917 case events::EventType::ForwardedRoomKey: // Not part of timeline or state
918 case events::EventType::RoomKeyRequest: // Not part of the timeline or state
919 case events::EventType::Direct: // Not part of the timeline or state
920 case events::EventType::Tag: // Not part of the timeline or state
921 case events::EventType::Presence: // Not part of the timeline or state
922 case events::EventType::PushRules: // Not part of the timeline or state
923 case events::EventType::KeyVerificationCancel:
924 case events::EventType::KeyVerificationRequest:
925 case events::EventType::KeyVerificationStart:
926 case events::EventType::KeyVerificationReady:
927 case events::EventType::KeyVerificationDone:
928 case events::EventType::KeyVerificationAccept:
929 case events::EventType::KeyVerificationKey:
930 case events::EventType::KeyVerificationMac:
931 case events::EventType::SecretRequest:
932 case events::EventType::SecretSend:
933 case events::EventType::CallInvite:
934 case events::EventType::CallCandidates:
935 case events::EventType::CallAnswer:
936 case events::EventType::CallHangUp:
937 case events::EventType::CallSelectAnswer:
938 case events::EventType::CallReject:
939 case events::EventType::CallNegotiate:
940 case events::EventType::Typing:
941 case events::EventType::Receipt:
942 case events::EventType::FullyRead:
943 case events::EventType::NhekoHiddenEvents:
944 case events::EventType::ImagePackInAccountData:
945 case events::EventType::ImagePackInRoom:
946 case events::EventType::ImagePackRooms:
947 case events::EventType::Dummy:
948 continue;
949 }
950 } catch (std::exception &err) {
951 log_error(err, event: e);
952 }
953 }
954}
955
956void
957parse_ephemeral_events(const json &events,
958 std::vector<mtx::events::collections::EphemeralEvents> &container)
959{
960 container.clear();
961 container.reserve(n: events.size());
962 for (const auto &e : events) {
963 const auto type = mtx::events::getEventType(obj: e);
964
965 try {
966 switch (type) {
967 case events::EventType::Typing: {
968 container.emplace_back(args: events::EphemeralEvent<events::ephemeral::Typing>(e));
969 break;
970 }
971 case events::EventType::Receipt: {
972 container.emplace_back(args: events::EphemeralEvent<events::ephemeral::Receipt>(e));
973
974 break;
975 }
976 case events::EventType::Unsupported: {
977 container.emplace_back(args: events::EphemeralEvent<events::Unknown>(e));
978
979 break;
980 }
981 default:
982 continue;
983 }
984 } catch (std::exception &err) {
985 utils::log_error(err, event: e);
986 }
987 }
988}
989}
990
991void
992from_json(const nlohmann::json &arr, StateEvents &response)
993{
994 utils::parse_state_events(events: arr, container&: response.events);
995}
996}
997}
998