1 #include "useractions.h"
2
3 #include <wx/intl.h>
4 #include <wx/colour.h>
5 #include "settings.h"
6 #include "helper/slconfig.h"
7 #include <cmath>
8 #include "utils/customdialogs.h"
9
10 #include "mainwindow.h"
11 #include "mainchattab.h"
12 #include "hosting/mainjoinbattletab.h"
13 #include "hosting/battleroomtab.h"
14 #include "battlelist/battlelisttab.h"
15 #include "chatpanel.h"
16 #include <options/mainoptionstab.h>
17 #include <options/groupoptionspanel.h>
18 #include <lslutils/globalsmanager.h>
19
20 const wxColour defaultHLcolor ( 255, 0, 0 );
21
useractions()22 UserActions& useractions()
23 {
24 static LSL::Util::LineInfo<UserActions> m( AT );
25 static LSL::Util::GlobalObjectHolder<UserActions, LSL::Util::LineInfo<UserActions> > m_useractions( m );
26 return m_useractions;
27 }
28
UserActions()29 UserActions::UserActions()
30 {
31 Init();
32 }
33
~UserActions()34 UserActions::~UserActions()
35 {
36
37 }
38
DoActionOnUser(const UserActions::ActionType action,const wxString & name)39 bool UserActions::DoActionOnUser( const UserActions::ActionType action, const wxString& name )
40 {
41 // preventing action on oneself wasn't the best idea, login gets disabled
42 //if ( m_knownUsers.Index( name ) == -1 || ui().IsThisMe(name) || action == ActNone )
43
44 if ( m_knownUsers.Index( name ) == -1 || action == ActNone )
45 return false;
46 else
47 return ( m_actionsGroups.find( action ) != m_actionsGroups.end() && m_actionsPeople[action].Index( name ) != -1 );
48
49 return false;
50 }
51
Init()52 void UserActions::Init()
53 {
54 m_actionNames.clear();
55 m_actionNames.push_back(_("none"));
56 m_actionNames.push_back(_("highlight"));
57 m_actionNames.push_back(_("notify login/out"));
58 m_actionNames.push_back(_("ignore chat"));
59 m_actionNames.push_back(_("ignore pm"));
60 m_actionNames.push_back(_("autokick"));
61 m_actionNames.push_back( _("notify hosted battle"));
62 m_actionNames.push_back(_("notify status change"));
63
64 m_configActionNames.clear();
65 m_configActionNames.push_back(_T("none"));
66 m_configActionNames.push_back(_T("highlight"));
67 m_configActionNames.push_back(_T("notify_login"));
68 m_configActionNames.push_back(_T("ignore_chat"));
69 m_configActionNames.push_back(_T("ignore_pm"));
70 m_configActionNames.push_back(_T("autokick"));
71 m_configActionNames.push_back(_T("notify_hosted"));
72 m_configActionNames.push_back(_T("notify_status"));
73
74 m_actionTooltips.clear();
75 m_actionTooltips.push_back(_("no action at all"));
76 m_actionTooltips.push_back(_("highlight user in nick list and battles he participates in"));
77 m_actionTooltips.push_back(_("popup a message box when user logs in/out from the server"));
78 m_actionTooltips.push_back(_("you won't see message by these users in normal channels"));
79 m_actionTooltips.push_back(_("ignore private messages of these users, no pm window will open if any of these try to contact you privately"));
80 m_actionTooltips.push_back(_("automatically kick users from battles hosted by yourself"));
81 m_actionTooltips.push_back(_("popup a message box when user hosts a new battle"));
82 m_actionTooltips.push_back(_("popup a message box when user changes away status"));
83
84 // setup if empty
85 if (!cfg().Exists(_T( "/Groups"))) {
86 AddGroup( _("Default") );
87 AddGroup( _("Ignore PM") );
88 ChangeAction( _("Ignore PM"), UserActions::ActIgnorePM );
89 AddGroup( _("Ignore chat") );
90 ChangeAction( _("Ignore chat"), UserActions::ActIgnoreChat );
91 AddGroup( _("Battle Autokick") );
92 ChangeAction( _("Battle Autokick"), UserActions::ActAutokick );
93 AddGroup( _("Friends") );
94 ChangeAction( _("Friends"), UserActions::ActNotifBattle );
95 ChangeAction( _("Friends"), UserActions::ActHighlight );
96 ChangeAction( _("Friends"), UserActions::ActNotifLogin );
97 // TODO select better color
98 SetGroupColor( _("Friends"), wxColour( 0, 0, 255 ) );
99 }
100
101
102 // read
103 m_groupNames = GetGroups();
104 m_groupMap.clear();
105 m_groupActions.clear();
106 m_actionsGroups.clear();
107 m_actionsPeople.clear();
108 m_knownUsers.Clear();
109 for ( unsigned int i = 0; i < m_groupNames.GetCount(); ++i)
110 {
111 wxString name = m_groupNames[i];
112 m_groupMap[name] = GetPeopleList( name );
113 for ( unsigned int k = 0; k < m_groupMap[name].GetCount(); ++k)
114 {
115 wxString user = m_groupMap[name][k];
116 m_knownUsers.Add( user );
117 m_peopleGroup[ user ] = name;
118 }
119 m_groupActions[name] = GetGroupActions( name );
120 }
121 for ( int i = 0; i < m_actionNames.size(); ++i)
122 {
123 UserActions::ActionType cur = (UserActions::ActionType) (int) std::pow( 2.0, i);
124 wxArrayString tmp;
125 for ( unsigned int j = 0; j < m_groupNames.GetCount(); ++j)
126 {
127 wxString name = m_groupNames[j];
128 if ( ( m_groupActions[name] & cur ) != 0 )
129 {
130 tmp.Add( name );
131 for ( unsigned int k = 0; k < m_groupMap[name].GetCount(); ++k)
132 {
133 m_actionsPeople[cur].Add( (m_groupMap[name])[k] );
134 }
135 }
136 }
137 tmp.Sort();
138 m_actionsGroups[cur] = tmp;
139 }
140 m_actionsGroups[ActNone] = m_groupNames;
141 m_groupNames.Sort();
142 m_knownUsers.Sort();
143 }
144
UpdateUI()145 void UserActions::UpdateUI()
146 {
147 try
148 {
149 ui().mw().GetBattleListTab().UpdateHighlights();
150 } catch(...){}
151
152 try
153 {
154 ui().mw().GetChatTab().UpdateNicklistHighlights();
155 } catch(...){}
156
157 try
158 {
159 ui().mw().GetJoinTab().GetBattleRoomTab().UpdateHighlights();
160 } catch(...){}
161 }
162
GetGroupNames() const163 wxArrayString UserActions::GetGroupNames() const
164 {
165 return m_groupNames;
166 }
167
AddUserToGroup(const wxString & group,const wxString & name)168 void UserActions::AddUserToGroup( const wxString& group, const wxString& name )
169 {
170 if ( IsKnown( name , false ) || ui().IsThisMe( name ) )
171 return;
172 m_groupMap[group].Add(name);
173 SetPeopleList( m_groupMap[group], group );
174 Init();
175 UpdateUI();
176 }
177
DeleteGroup(const wxString & group)178 void UserActions::DeleteGroup(const wxString& group )
179 {
180 if ( cfg().Exists( _T( "/Groups/" ) + group ) ) {
181 cfg().DeleteGroup( _T( "/Groups/" ) + group );
182 }
183 Init();
184 UpdateUI();
185 }
186
GetPeopleList(const wxString & group) const187 wxArrayString UserActions::GetPeopleList( const wxString& group ) const
188 {
189 wxArrayString list;
190 slConfig::PathGuard pathGuard ( &cfg(), _T( "/Groups/" ) + group + _T( "/Members/" ) );
191 unsigned int friendsCount = cfg().GetNumberOfEntries( false );
192 for ( unsigned int i = 0; i < friendsCount ; i++ )
193 {
194 wxString ToAdd;
195 if ( cfg().Read( _T( "/Groups/" ) + group + _T( "/Members/" ) + TowxString( i ), &ToAdd ) ) list.Add( ToAdd );
196 }
197 return list;
198 }
199
200
AddGroup(const wxString & group)201 void UserActions::AddGroup(const wxString& group )
202 {
203 if ( !cfg().Exists( _T( "/Groups/" ) + group ) ) {
204 cfg().Write( _T( "/Groups/" ) , group );
205 //set defaults
206 SetGroupActions( group, UserActions::ActNone );
207 SetGroupHLColor( defaultHLcolor, group );
208 }
209 Init();
210 UpdateUI();
211 }
212
213
ChangeAction(const wxString & group,const ActionType action,bool add)214 void UserActions::ChangeAction( const wxString& group, const ActionType action, bool add )
215 {
216 ActionType old = m_groupActions[group];
217 old = (ActionType) ( add ? (old | action) : (old & ~action ) );
218 SetGroupActions( group, old );
219 Init();
220 UpdateUI();
221 }
222
SetGroupActions(const wxString & group,ActionType action) const223 void UserActions::SetGroupActions( const wxString& group, ActionType action ) const
224 {
225 wxString key = _T( "/Groups/" ) + group + _T( "/Opts/ActionsList" );
226 cfg().DeleteGroup( key );
227 key += _T( "/" );
228 unsigned int tmp = action & ( ( UserActions::ActLast << 1 ) - 1 );
229 for(auto config: m_configActionNames) {
230 if ( tmp&1 ) cfg().Write( key + config, true );
231 tmp >>= 1;
232 }
233 }
234
GetGroupActions(const wxString & group) const235 UserActions::ActionType UserActions::GetGroupActions( const wxString& group ) const
236 {
237 wxString key = _T( "/Groups/" ) + group + _T( "/Opts/Actions" );
238 if ( cfg().HasEntry( key ) )// Backward compatibility.
239 {
240 wxLogMessage( _T( "loading deprecated group actions and updating config" ) );
241 UserActions::ActionType action = ( UserActions::ActionType )cfg().Read( key, ( long )UserActions::ActNone ) ;
242 cfg().DeleteEntry( key );
243
244 SetGroupActions( group, action );
245
246 return action;
247 }
248 key = _T( "/Groups/" ) + group + _T( "/Opts/ActionsList" );
249 if ( !cfg().Exists( key ) ) return UserActions::ActNone;
250 key += _T( "/" );
251 int mask = 1;
252 int result = 0;
253 for(auto config: m_configActionNames) {
254 if ( cfg().Read( key + config, 0l ) ) {
255 result |= mask;
256 }
257 mask <<= 1;
258 }
259 if ( result == 0 ) return UserActions::ActNone;
260 return ( UserActions::ActionType )result;
261 }
262
GetGroupAction(const wxString & group) const263 UserActions::ActionType UserActions::GetGroupAction( const wxString& group ) const
264 {
265 const GroupActionMap::const_iterator res = m_groupActions.find(group);
266 return res->second;
267 }
268
GetGroupOfUser(const wxString & user) const269 wxString UserActions::GetGroupOfUser( const wxString& user ) const
270 {
271 const PeopleGroupMap::const_iterator res = m_peopleGroup.find(user);
272 return res->second;
273 }
274
SetGroupColor(const wxString & group,const wxColour & color)275 void UserActions::SetGroupColor( const wxString& group, const wxColour& color )
276 {
277 SetGroupHLColor( color, group );
278 Init();
279 UpdateUI();
280 }
281
GetGroupHLColor(const wxString & group) const282 wxColour UserActions::GetGroupHLColor( const wxString& group ) const
283 {
284 return wxColour( cfg().Read( _T( "/Groups/" ) + group + _T( "/Opts/HLColor" ) , _T( "#64648C" ) ) );
285 }
286
SetGroupHLColor(const wxColour & color,const wxString & group)287 void UserActions::SetGroupHLColor( const wxColour& color, const wxString& group )
288 {
289 cfg().Write( _T( "/Groups/" ) + group + _T( "/Opts/HLColor" ), color.GetAsString( wxC2S_HTML_SYNTAX ) );
290 }
291
GetGroups()292 wxArrayString UserActions::GetGroups( )
293 {
294 return cfg().GetGroupList( _T( "/Groups/" ) );
295 }
296
297
GetGroupColor(const wxString & group) const298 wxColour UserActions::GetGroupColor( const wxString& group ) const
299 {
300 return GetGroupHLColor( group );
301 }
302
IsKnown(const wxString & name,bool outputWarning) const303 bool UserActions::IsKnown( const wxString& name, bool outputWarning ) const
304 {
305 bool ret = m_knownUsers.Index( name ) != -1;
306 if ( outputWarning ){
307 customMessageBoxNoModal( SL_MAIN_ICON, _("To prevent logical inconsistencies, adding a user to more than one group is not allowed"),
308 _("Cannot add user to group") );
309 }
310
311 return ret;
312 }
313
RemoveUser(const wxString & name)314 void UserActions::RemoveUser(const wxString& name )
315 {
316 wxString group = m_peopleGroup[name];
317 m_groupMap[group].Remove(name);
318 SetPeopleList( m_groupMap[group], group );
319 Init();
320 UpdateUI();
321 }
322
SetPeopleList(const wxArrayString & friends,const wxString & group)323 void UserActions::SetPeopleList( const wxArrayString& friends, const wxString& group )
324 {
325 unsigned int friendsCount = friends.GetCount();
326 cfg().DeleteGroup( _T( "/Groups/" ) + group + _T( "/Members/" ) );
327 for ( unsigned int i = 0; i < friendsCount ; i++ )
328 {
329 cfg().Write( _T( "/Groups/" ) + group + _T( "/Members/" ) + TowxString( i ), friends[i] );
330 }
331 }
332