ChatCommand.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
  3. * All rights reserved. Distributed under the terms of the MIT license.
  4. */
  5. #include "ChatCommand.h"
  6. #include <Catalog.h>
  7. #include <StringList.h>
  8. #include "Conversation.h"
  9. #include "MainWindow.h"
  10. #include "TheApp.h"
  11. #undef B_TRANSLATION_CONTEXT
  12. #define B_TRANSLATION_CONTEXT "ChatCommand"
  13. ChatCommand::ChatCommand(const char* name, BMessage msg, bool toProtocol,
  14. List<int32> argTypes)
  15. :
  16. fName(name),
  17. fMessage(msg),
  18. fToProto(toProtocol),
  19. fArgTypes(argTypes)
  20. {
  21. }
  22. ChatCommand::ChatCommand(BMessage* data)
  23. : BArchivable(data)
  24. {
  25. data->FindString("_name", &fName);
  26. data->FindString("_desc", &fDescription);
  27. data->FindBool("_proto", &fToProto);
  28. data->FindMessage("_msg", &fMessage);
  29. int32 argType, i = 0;
  30. while (data->FindInt32("_argtype", i, &argType) == B_OK) {
  31. fArgTypes.AddItem(argType);
  32. i++;
  33. }
  34. }
  35. status_t
  36. ChatCommand::Archive(BMessage* data, bool deep)
  37. {
  38. status_t ret = BArchivable::Archive(data, deep);
  39. data->AddString("_name", fName);
  40. data->AddString("_desc", fDescription);
  41. data->AddBool("_proto", fToProto);
  42. data->AddMessage("_msg", new BMessage(fMessage));
  43. for (int i = 0; i < fArgTypes.CountItems(); i++)
  44. data->AddInt32("_argtype", fArgTypes.ItemAt(i));
  45. return ret;
  46. }
  47. ChatCommand*
  48. ChatCommand::Instantiate(BMessage* data)
  49. {
  50. if (!validate_instantiation(data, "ChatCommand"))
  51. return NULL;
  52. return new ChatCommand(data);
  53. }
  54. void
  55. ChatCommand::SetDesc(const char* description)
  56. {
  57. fDescription = description;
  58. }
  59. bool
  60. ChatCommand::Parse(BString args, BString* errorMsg, Conversation* chat)
  61. {
  62. BMessage* msg = new BMessage(fMessage);
  63. msg->AddString("chat_id", chat->GetId());
  64. msg->AddInt64("instance", chat->GetProtocolLooper()->GetInstance());
  65. if (fArgTypes.CountItems() == 0) {
  66. msg->AddString("misc_str", args);
  67. return _Send(msg, chat);
  68. }
  69. if (_ProcessArgs(args, msg, errorMsg, chat) == true)
  70. return _Send(msg, chat);
  71. return false;
  72. }
  73. bool
  74. ChatCommand::_ProcessArgs(BString args, BMessage* msg, BString* errorMsg,
  75. Conversation* chat)
  76. {
  77. int32 argCount = fArgTypes.CountItems();
  78. BStringList argList;
  79. args.Split(" ", false, argList);
  80. for (int i = 0; i < argCount; i++) {
  81. BString arg = argList.StringAt(i);
  82. const char* strName = "misc_str";
  83. switch (fArgTypes.ItemAt(i))
  84. {
  85. case CMD_ROOM_PARTICIPANT:
  86. {
  87. User* user = _FindUser(arg, chat->Users());
  88. if (user == NULL) {
  89. errorMsg->SetTo(B_TRANSLATE("%user% isn't a member of this "
  90. "room."));
  91. errorMsg->ReplaceAll("%user%", arg);
  92. return false;
  93. }
  94. msg->AddString("user_id", user->GetId());
  95. break;
  96. }
  97. case CMD_KNOWN_USER:
  98. {
  99. User* user = _FindUser(arg, chat->GetProtocolLooper()->Users());
  100. if (user == NULL) {
  101. errorMsg->SetTo(B_TRANSLATE("You aren't contacts with and "
  102. "have no chats in common with %user%. Shame."));
  103. errorMsg->ReplaceAll("%user%", arg);
  104. return false;
  105. }
  106. msg->AddString("user_id", user->GetId());
  107. break;
  108. }
  109. case CMD_ANY_USER:
  110. msg->AddString("user_id", arg);
  111. break;
  112. case CMD_BODY_STRING:
  113. strName = "body";
  114. default:
  115. // If string's the last argument, it can be longer than one word
  116. if (i == (argCount - 1) && argList.CountStrings() > argCount)
  117. for (int j = i + 1; j < argList.CountStrings(); j++)
  118. arg << " " << argList.StringAt(j);
  119. msg->AddString(strName, arg);
  120. }
  121. }
  122. return true;
  123. }
  124. User*
  125. ChatCommand::_FindUser(BString idOrName, UserMap users)
  126. {
  127. if (idOrName.IsEmpty() == true)
  128. return NULL;
  129. bool idFound = false;
  130. User* user = users.ValueFor(idOrName, &idFound);
  131. if (idFound == false)
  132. for (int i = 0; i < users.CountItems(); i++) {
  133. User* check = users.ValueAt(i);
  134. if (check != NULL && check->GetName() == idOrName)
  135. return check;
  136. }
  137. return user;
  138. }
  139. bool
  140. ChatCommand::_Send(BMessage* msg, Conversation* chat)
  141. {
  142. if (fToProto == true)
  143. chat->GetProtocolLooper()->PostMessage(msg);
  144. else
  145. ((TheApp*)be_app)->GetMainWindow()->PostMessage(msg);
  146. return true;
  147. }