Changeset 6257
- Timestamp:
- 06/11/08 08:20:10 (4 months ago)
- Location:
- branches/licq_group
- Files:
-
- 7 modified
-
include/licq_events.h (modified) (2 diffs)
-
include/licq_icqd.h (modified) (1 diff)
-
include/licq_packets.h (modified) (1 diff)
-
include/licq_user.h (modified) (9 diffs)
-
src/icqd-srv.cpp (modified) (7 diffs)
-
src/icqpacket.cpp (modified) (15 diffs)
-
src/user.cpp (modified) (31 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/licq_group/include/licq_events.h
r6217 r6257 406 406 * 407 407 * For contact updates, ppid and id are valid. For group updates, argument 408 * holds the group id .408 * holds the group id except for reordered which applies to entire list. 409 409 */ 410 410 enum SubSignals_UPDATExLIST … … 415 415 LIST_GROUP_ADDED = 4, /**< A group was added to the list */ 416 416 LIST_GROUP_REMOVED = 5, /**< A group was removed from the list */ 417 LIST_GROUP_CHANGED = 6 /**< Data for a group has changed */ 417 LIST_GROUP_CHANGED = 6, /**< Data for a group has changed */ 418 LIST_GROUP_REORDERED = 7, /**< Group sorting has changed */ 418 419 }; 419 420 -
branches/licq_group/include/licq_icqd.h
r6227 r6257 470 470 void icqRenameUser(const char *_szId); 471 471 void icqExportUsers(UserStringList &, unsigned short); 472 void icqExportGroups( GroupList &);472 void icqExportGroups(const GroupNameMap& groups); 473 473 void icqUpdateServerGroups(); 474 474 void icqUpdatePhoneBookTimestamp(); -
branches/licq_group/include/licq_packets.h
r6227 r6257 404 404 { 405 405 public: 406 CPU_ExportGroupsToServerList( GroupList &);406 CPU_ExportGroupsToServerList(const GroupNameMap& groups); 407 407 }; 408 408 -
branches/licq_group/include/licq_user.h
r6248 r6257 7 7 #include <list> 8 8 #include <map> 9 #include <set> 9 10 #include <string> 10 11 #include <vector> … … 114 115 continue; \ 115 116 } 117 118 #define FOR_EACH_GROUP_START(x) \ 119 { \ 120 LicqGroup* pGroup; \ 121 GroupMap* _gl_ = gUserManager.LockGroupList(LOCK_R); \ 122 for (GroupMap::iterator _i_ = _gl_->begin(); \ 123 _i_ != _gl_->end(); ++_i_) \ 124 { \ 125 pGroup = _i_->second; \ 126 pGroup->Lock(x); \ 127 { 128 129 #define FOR_EACH_GROUP_START_SORTED(x) \ 130 { \ 131 LicqGroup* pGroup; \ 132 std::list<LicqGroup*> _sortedGroups_; \ 133 FOR_EACH_GROUP_START(LOCK_R) \ 134 _sortedGroups_.push_back(pGroup); \ 135 } \ 136 pGroup->Unlock(); \ 137 } \ 138 } \ 139 _sortedGroups_.sort(compare_groups); \ 140 for (std::list<LicqGroup*>::iterator _i_ = _sortedGroups_.begin(); \ 141 _i_ != _sortedGroups_.end(); ++_i_) \ 142 { \ 143 pGroup = *_i_; \ 144 pGroup->Lock(x); \ 145 { 146 147 #define FOR_EACH_GROUP_CONTINUE \ 148 { \ 149 pGroup->Unlock(); \ 150 continue; \ 151 } 152 153 #define FOR_EACH_GROUP_BREAK \ 154 { \ 155 pGroup->Unlock(); \ 156 break; \ 157 } 158 159 #define FOR_EACH_GROUP_END \ 160 } \ 161 pGroup->Unlock(); \ 162 } \ 163 gUserManager.UnlockGroupList(); \ 164 } 165 116 166 117 167 … … 179 229 } 180 230 231 class ICQuser; 232 class ICQOwner; 233 class LicqGroup; 234 181 235 typedef std::list<ICQUser *> UserList; 182 236 typedef std::list<class ICQOwner *> OwnerList; 183 typedef std::vector<char *> GroupList; 184 typedef std::vector<unsigned short> GroupIDList; 237 typedef std::set<unsigned short> UserGroupList; 238 typedef std::map<unsigned short, LicqGroup*> GroupMap; 239 typedef std::map<unsigned short, std::string> GroupNameMap; 185 240 typedef std::list<unsigned long> UinList; 186 241 typedef std::list<char *> UserStringList; … … 734 789 const char *HistoryFile() { return m_fHistory.FileName(); } 735 790 736 // Group functions 737 unsigned long GetGroups(GroupType g) { return(m_nGroups[g]); } 738 void SetGroups(GroupType g, unsigned long s) { m_nGroups[g] = s; SaveLicqInfo(); } 739 bool GetInGroup(GroupType, unsigned short); 740 void SetInGroup(GroupType, unsigned short, bool); 741 void AddToGroup(GroupType, unsigned short); 742 void RemoveFromGroup(GroupType, unsigned short); 791 /** 792 * Get user groups this user is member of 793 * 794 * @return List of groups 795 */ 796 const UserGroupList& GetGroups() const { return myGroups; } 797 798 /** 799 * Get system groups this user is member of 800 * 801 * @return Bitmask of server groups 802 */ 803 unsigned long GetSystemGroups() const { return mySystemGroups; } 804 805 /** 806 * Set user groups this user is member of 807 * 808 * @param groups List of groups 809 */ 810 void SetGroups(const UserGroupList& groups) { myGroups = groups; } 811 812 /** 813 * Set system groups this user is member of 814 * 815 * @param groups Bitmask of server groups 816 */ 817 void SetSystemGroups(unsigned long groups) { mySystemGroups = groups; } 818 819 /** 820 * Check if user is member of a group 821 * 822 * @param gtype Group type (GROUPS_SYSTEM or GROUPS_USER) 823 * @param groupId Id of group to check 824 * @return True if group exists and user is member 825 */ 826 bool GetInGroup(GroupType gtype, unsigned short groupId) const; 827 828 /** 829 * Convenience function to set membership of user for a group 830 * 831 * @param gtype Group type (GROUPS_SYSTEM or GROUPS_USER) 832 * @param groupId Id of group 833 * @param member True to add user to group, false to remove user from group 834 */ 835 void SetInGroup(GroupType gtype, unsigned short groupId, bool member); 836 837 /** 838 * Add user to a group 839 * 840 * @param gtype Group type (GROUPS_SYSTEM or GROUPS_USER) 841 * @param groupId Id of group to add 842 */ 843 void AddToGroup(GroupType gtype, unsigned short groupId); 844 845 /** 846 * Remove user from a group 847 * 848 * @param gtype Group type (GROUPS_SYSTEM or GROUPS_USER) 849 * @pram groupId Id of group to leave 850 * @return True if group was valid and user was a member 851 */ 852 bool RemoveFromGroup(GroupType gtype, unsigned short groupId); 853 743 854 // Short cuts to above functions 744 855 bool InvisibleList() { return GetInGroup(GROUPS_SYSTEM, GROUP_INVISIBLE_LIST); } … … 862 973 unsigned short m_nTyping; 863 974 unsigned long m_nUin, 864 m_nStatus, 865 m_nGroups[2]; 975 m_nStatus; 976 UserGroupList myGroups; /**< List of user groups */ 977 unsigned long mySystemGroups; /**< Bitmask for system groups */ 866 978 unsigned short m_nSequence; 867 979 unsigned long m_nPhoneFollowMeStatus, m_nICQphoneStatus, m_nSharedFilesStatus; … … 980 1092 static pthread_mutex_t mutex_nNumUserEvents; 981 1093 982 friend class CUserGroup;983 1094 friend class CUserManager; 984 1095 friend class CICQDaemon; … … 1074 1185 }; 1075 1186 1187 /** 1188 * Class holding data for a user group in the contact list. 1189 * System groups only exists as a bitmask in ICQUser. 1190 * 1191 * Note: LicqGroup objects should only be created, deleted or modified from the 1192 * user manager. If set functions are called directly, plugins will not receive 1193 * any signal notifying them of the change. 1194 */ 1195 class LicqGroup 1196 { 1197 public: 1198 /** 1199 * Constructor, creates a new user group 1200 * 1201 * @param id Group id, must be unique 1202 * @param name Group name 1203 */ 1204 LicqGroup(unsigned short id, const std::string& name); 1205 1206 /** 1207 * Destructor 1208 */ 1209 virtual ~LicqGroup(); 1210 1211 /** 1212 * Get id for group. This is an id used locally by Licq and is persistant for 1213 * each group. 1214 * 1215 * @return Group id 1216 */ 1217 unsigned short id() const { return myId; } 1218 1219 /** 1220 * Get name of group as should be displayed in the user interface 1221 * 1222 * @return Group name 1223 */ 1224 const std::string& name() const { return myName; } 1225 1226 /** 1227 * Get sorting index for the group. This is used by user interface plugins to 1228 * determine sorting order for the groups. Lower numbers should be displayed 1229 * higher in the list. 1230 * 1231 * @return Sorting index for this group 1232 */ 1233 unsigned short sortIndex() const { return mySortIndex; } 1234 1235 /** 1236 * Group id for this group in the ICQ server side list 1237 * 1238 * @return ICQ server group id or 0 if not set or not known 1239 */ 1240 unsigned short icqGroupId() const { return myIcqGroupId; } 1241 1242 /** 1243 * Set group name 1244 * 1245 * @param name New group name 1246 */ 1247 void setName(const std::string& name) { myName = name; } 1248 1249 /** 1250 * Set sorting index for group 1251 * 1252 * @param sortIndex Group sorting index 1253 */ 1254 void setSortIndex(unsigned short sortIndex) { mySortIndex = sortIndex; } 1255 1256 /** 1257 * Set group id in ICQ server side list 1258 * 1259 * @param icqGroupId ICQ server group id 1260 */ 1261 void setIcqGroupId(unsigned short icqGroupId) { myIcqGroupId = icqGroupId; } 1262 1263 /** 1264 * Lock group for access 1265 * 1266 * @param lockType Type of lock (LOCK_R or LOCK_W) 1267 */ 1268 void Lock(unsigned short lockType); 1269 1270 /** 1271 * Release current lock for group 1272 */ 1273 void Unlock(); 1274 1275 private: 1276 unsigned short myId; 1277 std::string myName; 1278 unsigned short mySortIndex; 1279 unsigned short myIcqGroupId; 1280 1281 pthread_rdwr_t myMutex; 1282 unsigned short myLockType; 1283 }; 1284 1285 /** 1286 * Helper function for sorting group list 1287 * 1288 * @param first Left hand group to compare 1289 * @param second Right hand group to compare 1290 * @return True if first has a lower sorting index than second 1291 */ 1292 bool compare_groups(const LicqGroup* first, const LicqGroup* second); 1293 1076 1294 class CUserManager 1077 1295 { … … 1105 1323 UserList *LockUserList(unsigned short); 1106 1324 void UnlockUserList(); 1107 GroupList *LockGroupList(unsigned short); 1325 1326 /** 1327 * Lock group list for access 1328 * Call UnlockGroupList when lock is no longer needed 1329 * 1330 * @param lockType Type of lock (LOCK_R or LOCK_W) 1331 * @return Map of all user groups indexed by group ids 1332 */ 1333 GroupMap* LockGroupList(unsigned short lockType); 1334 1335 /** 1336 * Release group list lock 1337 */ 1108 1338 void UnlockGroupList(); 1109 GroupIDList *LockGroupIDList(unsigned short); 1110 void UnlockGroupIDList(); 1339 1111 1340 OwnerList *LockOwnerList(unsigned short); 1112 1341 void UnlockOwnerList(); 1113 1342 1114 bool AddGroup(char *, unsigned short = 0); 1115 void RemoveGroup(unsigned short); 1116 void RenameGroup(unsigned short, const char *, bool = true); 1343 /** 1344 * Find and lock a group 1345 * After use, the lock must be released by calling DropGroup() 1346 * 1347 * @param groupId Id of group to fetch 1348 * @param lockType Type of lock to get 1349 * @return The group if found no NULL if groupId was invalid 1350 */ 1351 LicqGroup* FetchGroup(unsigned short groupId, unsigned short lockType); 1352 1353 /** 1354 * Release the lock for a group preivously returned by FetchGroup() 1355 * 1356 * @param group The group to unlock 1357 */ 1358 void DropGroup(LicqGroup* group); 1359 1360 /** 1361 * Add a user group 1362 * 1363 * @param name Group name, must be unique 1364 * @param icqGroupId ICQ server group id 1365 * @return Id of new group or zero if group could not be created 1366 */ 1367 unsigned short AddGroup(const std::string& name, unsigned short icqGroupId = 0); 1368 1369 /** 1370 * Remove a user group 1371 * 1372 * @param groupId Id of group to remove 1373 */ 1374 void RemoveGroup(unsigned short groupId); 1375 1376 /** 1377 * Rename a user group 1378 * 1379 * @param groupId Id of group to rename 1380 * @param name New group name, must be unique 1381 * @param sendUpdate True if server group should be updated 1382 * @return True if group was successfully renamed 1383 */ 1384 bool RenameGroup(unsigned short groupId, const std::string& name, bool sendUpdate = true); 1385 1386 /** 1387 * Get number of user groups 1388 * 1389 * @return Number of user groups 1390 */ 1117 1391 unsigned short NumGroups(); 1392 1393 /** 1394 * Save user group list to configuration file 1395 * Note: This function assumes that user group list is already locked. 1396 */ 1118 1397 void SaveGroups(); 1119 void SwapGroups(unsigned short g1, unsigned short g2); 1120 1121 void AddGroupID(unsigned short); 1122 void RemoveGroupID(unsigned short); 1123 void ModifyGroupID(char *, unsigned short); 1124 void SaveGroupIDs(); 1125 unsigned short GetIDFromGroup(const char *); 1126 unsigned short GetGroupFromID(unsigned short); 1398 1399 /** 1400 * Move sorting position for a group 1401 * Sorting position for other groups may also be changed to make sure all 1402 * groups have unique sorting indexes. 1403 * 1404 * @param groupId Id of group to move 1405 * @param newIndex New sorting index where 0 is the top position 1406 */ 1407 void ModifyGroupSorting(unsigned short groupId, unsigned short newIndex); 1408 1409 /** 1410 * Change ICQ server group id for a user group 1411 * 1412 * @param name Name of group to change 1413 * @param icqGroupId ICQ server group id to set 1414 */ 1415 void ModifyGroupID(const std::string& name, unsigned short icqGroupId); 1416 1417 /** 1418 * Change ICQ server group id for a user group 1419 * 1420 * @param groupId Id of group to change 1421 * @param icqGroupId ICQ server group id to set 1422 */ 1423 void ModifyGroupID(unsigned short groupId, unsigned short icqGroupId); 1424 1425 /** 1426 * Get ICQ group id from group name 1427 * 1428 * @param name Group name 1429 * @return Id for ICQ server group or 0 if not found 1430 */ 1431 unsigned short GetIDFromGroup(const std::string& name); 1432 1433 /** 1434 * Get ICQ group id from group 1435 * 1436 * @param groupId Group 1437 * @return Id for iCQ server group or 0 if groupId was invalid 1438 */ 1439 unsigned short GetIDFromGroup(unsigned short groupId); 1440 1441 /** 1442 * Get group id from ICQ server group id 1443 * 1444 * @param icqGroupId ICQ server group id 1445 * @return Id for group or 0 if not found 1446 */ 1447 unsigned short GetGroupFromID(unsigned short icqGroupId); 1448 1449 /** 1450 * Find id for group with a given name 1451 * 1452 * @param name Name of the group 1453 * @return Id for the group or 0 if there is no group with that name 1454 */ 1455 unsigned short GetGroupFromName(const std::string& name); 1127 1456 1128 1457 unsigned short GenerateSID(); … … 1147 1476 1148 1477 protected: 1149 pthread_rdwr_t mutex_grouplist, mutex_userlist, mutex_ groupidlist, mutex_ownerlist;1150 1151 Group List m_vszGroups;1478 pthread_rdwr_t mutex_grouplist, mutex_userlist, mutex_ownerlist; 1479 1480 GroupMap myGroups; 1152 1481 UserList m_vpcUsers; 1153 1482 OwnerList m_vpcOwners; 1154 GroupIDList m_vnGroupsID;1155 1483 CUserHashTable m_hUsers; 1156 1484 ICQOwner *m_xOwner; 1157 1485 unsigned long m_nOwnerUin; 1158 1486 unsigned short m_nDefaultGroup, m_nNewUserGroup, 1159 m_nUserListLockType, m _nGroupListLockType,1160 m_n GroupIDListLockType, m_nOwnerListLockType;1487 m_nUserListLockType, myGroupListLockType, 1488 m_nOwnerListLockType; 1161 1489 bool m_bAllowSave; 1162 1490 char* m_szDefaultEncoding; -
branches/licq_group/src/icqd-srv.cpp
r6246 r6257 118 118 { 119 119 // Export groups 120 GroupList groups; 121 GroupList *g = gUserManager.LockGroupList(LOCK_R); 122 GroupIDList *gID = gUserManager.LockGroupIDList(LOCK_R); 123 124 for (unsigned int i = 0; i < gID->size(); i++) 125 { 126 if ((*gID)[i] == 0) 127 { 128 groups.push_back((*g)[i]); 129 } 130 } 131 132 gUserManager.UnlockGroupList(); 133 gUserManager.UnlockGroupIDList(); 134 135 if (groups.size()) 120 GroupNameMap groups; 121 FOR_EACH_GROUP_START(LOCK_R) 122 { 123 if (pGroup->icqGroupId() == 0) 124 groups[pGroup->id()] = pGroup->name(); 125 } 126 FOR_EACH_GROUP_END 127 128 if (groups.size() > 0) 136 129 icqExportGroups(groups); 137 130 … … 224 217 if (!UseServerContactList()) return; 225 218 CSrvPacketTcp *pReply; 226 219 227 220 pReply = new CPU_UpdateToServerList("", ICQ_ROSTxGROUP, 0); 228 221 addToModifyUsers(pReply->SubSequence(), ""); 229 222 gLog.Info(tr("%sUpdating top level group.\n"), L_SRVxSTR); 230 223 SendExpectEvent_Server(0, pReply, NULL); 231 232 GroupList *g = gUserManager.LockGroupList(LOCK_R); 233 GroupIDList *gID = gUserManager.LockGroupIDList(LOCK_R); 234 235 for (unsigned int i = 0; i < gID->size(); i++) 236 { 237 if ((*gID)[i]) 238 { 239 pReply = new CPU_UpdateToServerList((*g)[i], ICQ_ROSTxGROUP, 240 (*gID)[i]); 241 gLog.Info(tr("%sUpdating group %s.\n"), L_SRVxSTR, (*g)[i]); 224 225 FOR_EACH_GROUP_START(LOCK_R) 226 { 227 unsigned int gid = pGroup->icqGroupId(); 228 if (gid != 0) 229 { 230 const char* gname = pGroup->name().c_str(); 231 pReply = new CPU_UpdateToServerList(gname, ICQ_ROSTxGROUP, gid); 232 gLog.Info(tr("%sUpdating group %s.\n"), L_SRVxSTR, gname); 242 233 addToModifyUsers(pReply->SubSequence(), ""); 243 234 SendExpectEvent_Server(0, pReply, NULL); 244 235 } 245 236 } 246 247 gUserManager.UnlockGroupList(); 248 gUserManager.UnlockGroupIDList(); 237 FOR_EACH_GROUP_END 249 238 } 250 239 … … 310 299 311 300 //-----icqExportGroups---------------------------------------------------------- 312 void CICQDaemon::icqExportGroups( GroupList &groups)301 void CICQDaemon::icqExportGroups(const GroupNameMap& groups) 313 302 { 314 303 if (!UseServerContactList()) return; … … 4271 4260 } 4272 4261 } 4273 4262 4274 4263 u->SetIgnoreList(nType == ICQ_ROSTxIGNORE); 4275 4264 4276 4265 if (!isOnList) 4277 4266 { … … 4280 4269 } 4281 4270 4271 // Save GSID, SID and group memberships 4272 u->SaveLicqInfo(); 4273 4282 4274 PushPluginSignal(new CICQSignal(SIGNAL_UPDATExUSER, USER_GENERAL, 4283 4275 u->IdString(), u->PPID())); … … 4302 4294 { 4303 4295 if (!UseServerContactList()) break; 4304 4296 4305 4297 if (szId[0] != '\0' && nTag != 0) 4306 4298 { 4307 4299 // Rename the group if we have it already or else add it 4308 4300 unsigned short nGroup = gUserManager.GetGroupFromID(nTag); 4309 if (nGroup == gUserManager.NumGroups())4301 if (nGroup == 0) 4310 4302 { 4311 4303 if (!gUserManager.AddGroup(szUnicodeName, nTag)) … … 4520 4512 4521 4513 4522 GroupList *g = gUserManager.LockGroupList(LOCK_R);4514 LicqGroup* group = gUserManager.FetchGroup(n, LOCK_R); 4523 4515 std::string groupName; 4524 if (e->ExtraInfo() == 0 )4516 if (e->ExtraInfo() == 0 || group == NULL) 4525 4517 groupName = ""; // top level 4526 4518 else 4527 groupName = (*g)[n-1]; 4528 gUserManager.UnlockGroupList(); 4519 groupName = group->name(); 4520 if (group != NULL) 4521 gUserManager.DropGroup(group); 4529 4522 4530 4523 // Start editing server list -
branches/licq_group/src/icqpacket.cpp
r6230 r6257 41 41 #include "support.h" 42 42 43 using namespace std; 43 44 44 45 unsigned short ReversePort(unsigned short p) … … 2813 2814 { 2814 2815 // Use the first group that the user is in as the server stored group 2815 GroupIDList *pID = gUserManager.LockGroupIDList(LOCK_R); 2816 for (unsigned short j = 1; j < pID->size() + 1; j++) 2816 const UserGroupList& userGroups = u->GetGroups(); 2817 2818 for (UserGroupList::const_iterator j = userGroups.begin(); j != userGroups.end(); ++j) 2817 2819 { 2818 if (u->GetInGroup(GROUPS_USER, j)) 2819 { 2820 m_nGSID = (*pID)[j-1]; 2821 if (m_nGSID) 2822 break; 2823 } 2820 m_nGSID = gUserManager.GetIDFromGroup(*j); 2821 if (m_nGSID != 0) 2822 break; 2824 2823 } 2825 2824 … … 2828 2827 { 2829 2828 unsigned short nNewGroup = gUserManager.NewUserGroup(); 2830 if (nNewGroup && nNewGroup <= pID->size()) 2831 m_nGSID = (*pID)[nNewGroup-1]; 2832 2833 if (m_nGSID == 0 && pID->size()) 2834 m_nGSID = (*pID)[0]; // first group if none was specified 2829 m_nGSID = gUserManager.GetIDFromGroup(nNewGroup); 2830 2831 if (m_nGSID == 0) 2832 { 2833 // First group if none was specified 2834 GroupMap* groups = gUserManager.LockGroupList(LOCK_R); 2835 if (groups->size() > 0) 2836 { 2837 LicqGroup* g = groups->begin()->second; 2838 g->Lock(LOCK_R); 2839 m_nGSID = g->icqGroupId(); 2840 g->Unlock(); 2841 } 2842 gUserManager.UnlockGroupList(); 2843 } 2835 2844 2836 2845 if (m_nGSID == 0) 2837 2846 m_nGSID = 1; // General (unless user renamed group or wasnt created yet) 2838 2847 } 2839 gUserManager.UnlockGroupIDList();2840 2848
