llfloatergroupbulkban.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. /**
  2. * @file llfloatergroupbulkban.cpp
  3. * @brief Floater to ban Residents from a group.
  4. *
  5. * $LicenseInfo:firstyear=2006&license=viewergpl$
  6. *
  7. * Copyright (c) 2006-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "boost/foreach.hpp"
  34. #include "llfloatergroupbulkban.h"
  35. #include "llavatarnamecache.h"
  36. #include "llbutton.h"
  37. #include "llnamelistctrl.h"
  38. #include "llnotifications.h"
  39. #include "llscrolllistctrl.h"
  40. #include "lltextbox.h"
  41. #include "lltrans.h"
  42. #include "lluictrlfactory.h"
  43. #include "llagent.h"
  44. #include "llavataractions.h"
  45. #include "llavatartracker.h"
  46. #include "llfloateravatarpicker.h"
  47. #include "llpanelgroupbulk.h"
  48. #include "llgroupmgr.h"
  49. #include "llpanelgroupbulk.h"
  50. #include "llviewerobjectlist.h"
  51. // Globals
  52. LLFloaterGroupBulkBan::instances_map_t LLFloaterGroupBulkBan::sInstances;
  53. class LLFloaterGroupBulkBanData
  54. {
  55. public:
  56. LLFloaterGroupBulkBanData(LLFloater* self, const LLUUID& group_id)
  57. : mSelf(self),
  58. mGroupId(group_id),
  59. mPanel(NULL)
  60. {
  61. }
  62. ~LLFloaterGroupBulkBanData()
  63. {
  64. }
  65. LLFloater* mSelf;
  66. LLUUID mGroupId;
  67. LLPanelGroupBulkBan* mPanel;
  68. };
  69. //////////////////////////////////////////////////////////////////////
  70. // LLPanelGroupBulkBan
  71. //////////////////////////////////////////////////////////////////////
  72. class LLPanelGroupBulkBan final : public LLPanelGroupBulk
  73. {
  74. public:
  75. LLPanelGroupBulkBan(const LLUUID& group_id, LLFloater* parent);
  76. ~LLPanelGroupBulkBan() {}
  77. bool postBuild() override;
  78. static void callbackClickSubmit(void* userdata);
  79. void submit() override;
  80. private:
  81. std::string buildAvListArgument(std::vector<LLAvatarName> av_names,
  82. const std::string& format);
  83. };
  84. LLPanelGroupBulkBan::LLPanelGroupBulkBan(const LLUUID& group_id,
  85. LLFloater* parent)
  86. : LLPanelGroupBulk(group_id, parent)
  87. {
  88. }
  89. bool LLPanelGroupBulkBan::postBuild()
  90. {
  91. if (!mImplementation) return false;
  92. mImplementation->mLoadingText = getString("loading");
  93. mImplementation->mGroupName = getChild<LLTextBox>("group_name_text",
  94. true, false);
  95. LLNameListCtrl* list = getChild<LLNameListCtrl>("banned_agent_list",
  96. true, false);
  97. mImplementation->mBulkAgentList = list;
  98. if (list)
  99. {
  100. list->setCommitOnSelectionChange(true);
  101. list->setCommitCallback(LLPanelGroupBulkImpl::callbackSelect);
  102. list->setCallbackUserData(mImplementation);
  103. }
  104. LLButton* button = getChild<LLButton>("add_button", true, false);
  105. if (button)
  106. {
  107. // default to opening avatarpicker automatically
  108. // (*impl::callbackClickAdd)((void*)this);
  109. button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickAdd,
  110. this);
  111. }
  112. button = getChild<LLButton>("remove_button", true, false);
  113. mImplementation->mRemoveButton = button;
  114. if (button)
  115. {
  116. button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickRemove,
  117. mImplementation);
  118. button->setEnabled(false);
  119. }
  120. button = getChild<LLButton>("ban_button", true, false);
  121. mImplementation->mOKButton = button;
  122. if (button)
  123. {
  124. button->setClickedCallback(LLPanelGroupBulkBan::callbackClickSubmit,
  125. this);
  126. button->setEnabled(false);
  127. }
  128. button = getChild<LLButton>("cancel_button", true, false);
  129. if (button)
  130. {
  131. button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel,
  132. mImplementation);
  133. }
  134. mImplementation->mTooManySelected = getString("ban_selection_too_large");
  135. update();
  136. return true;
  137. }
  138. void LLPanelGroupBulkBan::callbackClickSubmit(void* userdata)
  139. {
  140. LLPanelGroupBulkBan* selfp = (LLPanelGroupBulkBan*)userdata;
  141. if (selfp)
  142. {
  143. selfp->submit();
  144. }
  145. }
  146. void LLPanelGroupBulkBan::submit()
  147. {
  148. if (!mImplementation || !mImplementation->mBulkAgentList) return;
  149. if (!gAgent.hasPowerInGroup(mImplementation->mGroupID,
  150. GP_GROUP_BAN_ACCESS))
  151. {
  152. // Fail ! Agent no longer has ban rights (permissions could have
  153. // changed after button was pressed).
  154. LLSD msg;
  155. msg["MESSAGE"] = getString("ban_not_permitted");
  156. gNotifications.add("GenericAlert", msg);
  157. if (mImplementation->mParentFloater) // Paranoia
  158. {
  159. mImplementation->mParentFloater->close();
  160. }
  161. return;
  162. }
  163. LLGroupMgrGroupData* gdatap =
  164. gGroupMgr.getGroupData(mImplementation->mGroupID);
  165. if (gdatap && gdatap->mBanList.size() >= GB_MAX_BANNED_AGENTS)
  166. {
  167. // Fail ! Size limit exceeded. List could have updated after button
  168. // was pressed.
  169. LLSD msg;
  170. msg["MESSAGE"] = getString("ban_limit_fail");
  171. gNotifications.add("GenericAlert", msg);
  172. if (mImplementation->mParentFloater) // Paranoia
  173. {
  174. mImplementation->mParentFloater->close();
  175. }
  176. return;
  177. }
  178. uuid_vec_t banned_agent_list;
  179. std::vector<LLScrollListItem*> agents = mImplementation->mBulkAgentList->getAllData();
  180. for (std::vector<LLScrollListItem*>::iterator iter = agents.begin(),
  181. end = agents.end();
  182. iter != end; ++iter)
  183. {
  184. LLScrollListItem* agent = *iter;
  185. if (agent) // Paranoia
  186. {
  187. banned_agent_list.emplace_back(agent->getUUID());
  188. }
  189. }
  190. // Max bans (= max invites) per request to match server cap.
  191. if ((S32)banned_agent_list.size() > LLPanelGroupBulkImpl::MAX_GROUP_INVITES)
  192. {
  193. // Fail!
  194. LLSD msg;
  195. msg["MESSAGE"] = mImplementation->mTooManySelected;
  196. gNotifications.add("GenericAlert", msg);
  197. if (mImplementation->mParentFloater) // Paranoia
  198. {
  199. mImplementation->mParentFloater->close();
  200. }
  201. return;
  202. }
  203. // Remove already banned users and yourself from request.
  204. bool banning_self = false;
  205. uuid_vec_t::iterator reject = std::find(banned_agent_list.begin(),
  206. banned_agent_list.end(), gAgentID);
  207. if (reject != banned_agent_list.end())
  208. {
  209. banned_agent_list.erase(reject);
  210. banning_self = true;
  211. }
  212. // Will hold already banned avatars and avatars not banned because of the
  213. // bans number limit
  214. std::vector<LLAvatarName> already_banned_avnames;
  215. std::vector<LLAvatarName> out_of_limit_avnames;
  216. if (gdatap)
  217. {
  218. BOOST_FOREACH(const LLGroupMgrGroupData::ban_list_t::value_type& group_ban_pair,
  219. gdatap->mBanList)
  220. {
  221. const LLUUID& group_ban_agent_id = group_ban_pair.first;
  222. reject = std::find(banned_agent_list.begin(),
  223. banned_agent_list.end(), group_ban_agent_id);
  224. if (reject != banned_agent_list.end())
  225. {
  226. LLAvatarName av_name;
  227. LLAvatarNameCache::get(group_ban_agent_id, &av_name);
  228. already_banned_avnames.emplace_back(av_name);
  229. banned_agent_list.erase(reject);
  230. if (banned_agent_list.size() == 0)
  231. {
  232. break;
  233. }
  234. }
  235. // This check should always be the last one before we send the
  236. // request, otherwise we have a possibility of cutting more then we
  237. // need to.
  238. if (banned_agent_list.size() >
  239. GB_MAX_BANNED_AGENTS - gdatap->mBanList.size())
  240. {
  241. reject = banned_agent_list.begin() + GB_MAX_BANNED_AGENTS -
  242. gdatap->mBanList.size();
  243. uuid_vec_t::iterator list_end = banned_agent_list.end();
  244. for (uuid_vec_t::iterator it = reject; it != list_end; ++it)
  245. {
  246. LLAvatarName av_name;
  247. LLAvatarNameCache::get(*it, &av_name);
  248. out_of_limit_avnames.emplace_back(av_name);
  249. }
  250. banned_agent_list.erase(reject, banned_agent_list.end());
  251. }
  252. }
  253. }
  254. // Send the request and eject the members
  255. if (banned_agent_list.size())
  256. {
  257. gGroupMgr.sendGroupBanRequest(LLGroupMgr::REQUEST_POST,
  258. mImplementation->mGroupID,
  259. LLGroupMgr::BAN_CREATE |
  260. LLGroupMgr::BAN_UPDATE,
  261. banned_agent_list);
  262. gGroupMgr.sendGroupMemberEjects(mImplementation->mGroupID,
  263. banned_agent_list);
  264. }
  265. // Build and issue the notification if needed
  266. bool already_banned = already_banned_avnames.size() > 0;
  267. bool out_limit = out_of_limit_avnames.size() > 0;
  268. if (already_banned || banning_self || out_limit)
  269. {
  270. std::string reasons;
  271. if (already_banned)
  272. {
  273. reasons += "\n " + buildAvListArgument(already_banned_avnames,
  274. "already_banned");
  275. }
  276. if (banning_self)
  277. {
  278. reasons += "\n " + getString("cant_ban_yourself");
  279. }
  280. if (out_limit)
  281. {
  282. reasons += "\n " + buildAvListArgument(out_of_limit_avnames,
  283. "ban_limit_reached");
  284. }
  285. LLStringUtil::format_map_t msg_args;
  286. msg_args["[REASONS]"] = reasons;
  287. LLSD msg;
  288. if (already_banned)
  289. {
  290. msg["MESSAGE"] = getString("partial_ban", msg_args);
  291. }
  292. else
  293. {
  294. msg["MESSAGE"] = getString("ban_failed", msg_args);
  295. }
  296. gNotifications.add("GenericAlert", msg);
  297. }
  298. // then close
  299. if (mImplementation->mParentFloater) // Paranoia
  300. {
  301. mImplementation->mParentFloater->close();
  302. }
  303. }
  304. std::string LLPanelGroupBulkBan::buildAvListArgument(std::vector<LLAvatarName> av_names,
  305. const std::string& format)
  306. {
  307. std::string names_string;
  308. LLAvatarActions::buildAvatarsList(av_names, names_string, true);
  309. LLStringUtil::format_map_t args;
  310. args["[RESIDENTS]"] = names_string;
  311. return getString(format, args);
  312. }
  313. ///////////////////////////////////////////////////////////////////////////////
  314. // LLFloaterGroupBulkBan
  315. ///////////////////////////////////////////////////////////////////////////////
  316. // static
  317. void* LLFloaterGroupBulkBan::createPanel(void* userdata)
  318. {
  319. LLFloaterGroupBulkBanData* data = (LLFloaterGroupBulkBanData*)userdata;
  320. if (data)
  321. {
  322. data->mPanel = new LLPanelGroupBulkBan(data->mGroupId, data->mSelf);
  323. return data->mPanel;
  324. }
  325. else
  326. {
  327. return NULL;
  328. }
  329. }
  330. LLFloaterGroupBulkBan::LLFloaterGroupBulkBan(const LLUUID& group_id)
  331. : LLFloater(group_id.asString()),
  332. mGroupID(group_id),
  333. mBulkBanPanelp(NULL)
  334. {
  335. // Create the group bulk ban panel together with this floater
  336. LLFloaterGroupBulkBanData* data = new LLFloaterGroupBulkBanData(this,
  337. group_id);
  338. LLCallbackMap::map_t factory_map;
  339. factory_map["bulk_ban_panel"] = LLCallbackMap(createPanel, data);
  340. LLUICtrlFactory::getInstance()->buildFloater(this,
  341. "floater_group_ban.xml",
  342. &factory_map);
  343. mBulkBanPanelp = data->mPanel;
  344. delete data;
  345. }
  346. //virtual
  347. LLFloaterGroupBulkBan::~LLFloaterGroupBulkBan()
  348. {
  349. if (mGroupID.notNull())
  350. {
  351. sInstances.erase(mGroupID);
  352. }
  353. if (mBulkBanPanelp)
  354. {
  355. delete mBulkBanPanelp;
  356. mBulkBanPanelp = NULL;
  357. }
  358. }
  359. //static
  360. void LLFloaterGroupBulkBan::showForGroup(const LLUUID& group_id,
  361. uuid_vec_t* agent_ids,
  362. LLView* parent)
  363. {
  364. // Make sure group_id isn't null
  365. if (group_id.isNull())
  366. {
  367. llwarns << "Null group_id passed ! Aborting." << llendl;
  368. return;
  369. }
  370. // If we do not have a floater for this group, create one.
  371. LLFloaterGroupBulkBan* fgb = get_ptr_in_map(sInstances, group_id);
  372. if (!fgb)
  373. {
  374. fgb = new LLFloaterGroupBulkBan(group_id);
  375. if (!fgb || !fgb->mBulkBanPanelp)
  376. {
  377. llwarns << "Could not create the floater ! Aborting." << llendl;
  378. return;
  379. }
  380. if (parent && gFloaterViewp && gFloaterViewp->getParentFloater(parent))
  381. {
  382. gFloaterViewp->getParentFloater(parent)->addDependentFloater(fgb);
  383. }
  384. sInstances[group_id] = fgb;
  385. fgb->mBulkBanPanelp->clear();
  386. }
  387. if (!fgb->mBulkBanPanelp) // Paranoia
  388. {
  389. llwarns << "NULL panel in floater ! Aborting." << llendl;
  390. return;
  391. }
  392. if (agent_ids)
  393. {
  394. fgb->mBulkBanPanelp->addUsers(*agent_ids);
  395. }
  396. fgb->open();
  397. fgb->mBulkBanPanelp->update();
  398. }