/[LeafOK_CVS]/lbbs/src/user_list.c
ViewVC logotype

Diff of /lbbs/src/user_list.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.6 by sysadm, Wed Oct 22 04:48:53 2025 UTC Revision 1.10 by sysadm, Wed Oct 22 10:38:23 2025 UTC
# Line 71  const USER_ACTION_MAP user_action_map[] Line 71  const USER_ACTION_MAP user_action_map[]
71                  {"BBS_NET", "站点穿梭"},                  {"BBS_NET", "站点穿梭"},
72                  {"CHICKEN", "电子小鸡"},                  {"CHICKEN", "电子小鸡"},
73                  {"EDIT_ARTICLE", "修改文章"},                  {"EDIT_ARTICLE", "修改文章"},
74                    {"LOGIN", "进入大厅"},
75                  {"MENU", "菜单选择"},                  {"MENU", "菜单选择"},
76                  {"POST_ARTICLE", "撰写文章"},                  {"POST_ARTICLE", "撰写文章"},
77                  {"REPLY_ARTICLE", "回复文章"},                  {"REPLY_ARTICLE", "回复文章"},
78                  {"USER_LIST", "查花名册"},                  {"USER_LIST", "查花名册"},
79                  {"USER_ONLINE", "环顾四周"},                  {"USER_ONLINE", "环顾四周"},
80                  {"VIEW_ARTICLE", "阅读文章"},                  {"VIEW_ARTICLE", "阅读文章"},
81                  {"VIEW_FILE", "查看文档"}};                  {"VIEW_FILE", "查看文档"},
82                    {"WWW", "Web浏览"}};
83    
84  const int user_action_map_size = 11;  const int user_action_map_size = sizeof(user_action_map) / sizeof(USER_ACTION_MAP);
85    
86  static int user_list_try_rd_lock(int semid, int wait_sec);  static int user_list_try_rd_lock(int semid, int wait_sec);
87  static int user_list_try_rw_lock(int semid, int wait_sec);  static int user_list_try_rw_lock(int semid, int wait_sec);
# Line 91  static int user_list_rw_lock(int semid); Line 93  static int user_list_rw_lock(int semid);
93  static int user_list_load(MYSQL *db, USER_LIST *p_list);  static int user_list_load(MYSQL *db, USER_LIST *p_list);
94  static int user_online_list_load(MYSQL *db, USER_ONLINE_LIST *p_list);  static int user_online_list_load(MYSQL *db, USER_ONLINE_LIST *p_list);
95    
96    static int user_info_index_uid_comp(const void *ptr1, const void *ptr2)
97    {
98            const USER_INFO_INDEX_UID *p1 = ptr1;
99            const USER_INFO_INDEX_UID *p2 = ptr2;
100    
101            if (p1->uid < p2->uid)
102            {
103                    return -1;
104            }
105            else if (p1->uid > p2->uid)
106            {
107                    return 1;
108            }
109            else if (p1->id < p2->id)
110            {
111                    return -1;
112            }
113            else if (p1->id > p2->id)
114            {
115                    return 1;
116            }
117            return 0;
118    }
119    
120  int user_list_load(MYSQL *db, USER_LIST *p_list)  int user_list_load(MYSQL *db, USER_LIST *p_list)
121  {  {
122          MYSQL_RES *rs = NULL;          MYSQL_RES *rs = NULL;
# Line 98  int user_list_load(MYSQL *db, USER_LIST Line 124  int user_list_load(MYSQL *db, USER_LIST
124          char sql[SQL_BUFFER_LEN];          char sql[SQL_BUFFER_LEN];
125          int ret = 0;          int ret = 0;
126          int i;          int i;
127            int32_t last_uid = -1;
128    
129          if (db == NULL || p_list == NULL)          if (db == NULL || p_list == NULL)
130          {          {
# Line 105  int user_list_load(MYSQL *db, USER_LIST Line 132  int user_list_load(MYSQL *db, USER_LIST
132                  return -1;                  return -1;
133          }          }
134    
135            if (p_list->user_count > 0)
136            {
137                    last_uid = p_list->users[p_list->user_count - 1].uid;
138            }
139    
140          snprintf(sql, sizeof(sql),          snprintf(sql, sizeof(sql),
141                           "SELECT user_list.UID AS UID, username, nickname, gender, gender_pub, life, exp, "                           "SELECT user_list.UID AS UID, username, nickname, gender, gender_pub, life, exp, "
142                           "UNIX_TIMESTAMP(signup_dt), UNIX_TIMESTAMP(last_login_dt), UNIX_TIMESTAMP(birthday) "                           "UNIX_TIMESTAMP(signup_dt), UNIX_TIMESTAMP(last_login_dt), UNIX_TIMESTAMP(birthday) "
143                           "FROM user_list INNER JOIN user_pubinfo ON user_list.UID = user_pubinfo.UID "                           "FROM user_list INNER JOIN user_pubinfo ON user_list.UID = user_pubinfo.UID "
144                           "INNER JOIN user_reginfo ON user_list.UID = user_reginfo.UID "                           "INNER JOIN user_reginfo ON user_list.UID = user_reginfo.UID "
145                           "WHERE enable ORDER BY UID");                           "WHERE enable ORDER BY username");
146    
147          if (mysql_query(db, sql) != 0)          if (mysql_query(db, sql) != 0)
148          {          {
# Line 129  int user_list_load(MYSQL *db, USER_LIST Line 161  int user_list_load(MYSQL *db, USER_LIST
161          i = 0;          i = 0;
162          while ((row = mysql_fetch_row(rs)))          while ((row = mysql_fetch_row(rs)))
163          {          {
164                    // record
165                    p_list->users[i].id = i;
166                  p_list->users[i].uid = atoi(row[0]);                  p_list->users[i].uid = atoi(row[0]);
167                  strncpy(p_list->users[i].username, row[1], sizeof(p_list->users[i].username) - 1);                  strncpy(p_list->users[i].username, row[1], sizeof(p_list->users[i].username) - 1);
168                  p_list->users[i].username[sizeof(p_list->users[i].username) - 1] = '\0';                  p_list->users[i].username[sizeof(p_list->users[i].username) - 1] = '\0';
# Line 142  int user_list_load(MYSQL *db, USER_LIST Line 176  int user_list_load(MYSQL *db, USER_LIST
176                  p_list->users[i].last_login_dt = (row[8] == NULL ? 0 : atol(row[8]));                  p_list->users[i].last_login_dt = (row[8] == NULL ? 0 : atol(row[8]));
177                  p_list->users[i].birthday = (row[9] == NULL ? 0 : atol(row[9]));                  p_list->users[i].birthday = (row[9] == NULL ? 0 : atol(row[9]));
178    
179                    // index
180                    p_list->index_uid[i].uid = p_list->users[i].uid;
181                    p_list->index_uid[i].id = i;
182    
183                  i++;                  i++;
184                  if (i >= BBS_max_user_count)                  if (i >= BBS_max_user_count)
185                  {                  {
# Line 152  int user_list_load(MYSQL *db, USER_LIST Line 190  int user_list_load(MYSQL *db, USER_LIST
190          mysql_free_result(rs);          mysql_free_result(rs);
191          rs = NULL;          rs = NULL;
192    
193            // Sort index
194            if (i != p_list->user_count || p_list->users[i - 1].uid != last_uid) // Count of users changed
195            {
196                    qsort(p_list->index_uid, (size_t)i, sizeof(USER_INFO_INDEX_UID), user_info_index_uid_comp);
197    #ifdef _DEBUG
198                    log_error("Rebuild index of %d users, last_uid=%d\n", i, p_list->users[i - 1].uid);
199    #endif
200            }
201    
202          p_list->user_count = i;          p_list->user_count = i;
203    
204  #ifdef _DEBUG  #ifdef _DEBUG
# Line 181  int user_online_list_load(MYSQL *db, USE Line 228  int user_online_list_load(MYSQL *db, USE
228          snprintf(sql, sizeof(sql),          snprintf(sql, sizeof(sql),
229                           "SELECT SID, UID, ip, current_action, UNIX_TIMESTAMP(login_tm), "                           "SELECT SID, UID, ip, current_action, UNIX_TIMESTAMP(login_tm), "
230                           "UNIX_TIMESTAMP(last_tm) FROM user_online "                           "UNIX_TIMESTAMP(last_tm) FROM user_online "
231                           "WHERE last_tm >= SUBDATE(NOW(), INTERVAL %d SECOND) "                           "WHERE last_tm >= SUBDATE(NOW(), INTERVAL %d SECOND) AND UID <> 0 "
232                           "ORDER BY last_tm DESC",                           "ORDER BY last_tm DESC",
233                           BBS_user_off_line);                           BBS_user_off_line);
234    
# Line 202  int user_online_list_load(MYSQL *db, USE Line 249  int user_online_list_load(MYSQL *db, USE
249          i = 0;          i = 0;
250          while ((row = mysql_fetch_row(rs)))          while ((row = mysql_fetch_row(rs)))
251          {          {
252                    p_list->users[i].id = i;
253                  strncpy(p_list->users[i].session_id, row[0], sizeof(p_list->users[i].session_id) - 1);                  strncpy(p_list->users[i].session_id, row[0], sizeof(p_list->users[i].session_id) - 1);
   
254                  p_list->users[i].session_id[sizeof(p_list->users[i].session_id) - 1] = '\0';                  p_list->users[i].session_id[sizeof(p_list->users[i].session_id) - 1] = '\0';
255                  if (query_user_info(atoi(row[1]), &(p_list->users[i].user_info)) <= 0)  
256                    if ((ret = query_user_info_by_uid(atoi(row[1]), &(p_list->users[i].user_info))) < 0)
257                  {                  {
258                          log_error("query_user_info(%d) error\n", atoi(row[1]));                          log_error("query_user_info(%d) error\n", atoi(row[1]));
259                          continue;                          continue;
260                  }                  }
261                    else if (ret == 0) // skip Guest
262                    {
263                            continue;
264                    }
265    
266                  strncpy(p_list->users[i].ip, row[2], sizeof(p_list->users[i].ip) - 1);                  strncpy(p_list->users[i].ip, row[2], sizeof(p_list->users[i].ip) - 1);
267                  p_list->users[i].ip[sizeof(p_list->users[i].ip) - 1] = '\0';                  p_list->users[i].ip[sizeof(p_list->users[i].ip) - 1] = '\0';
# Line 219  int user_online_list_load(MYSQL *db, USE Line 271  int user_online_list_load(MYSQL *db, USE
271                  p_list->users[i].current_action_title = NULL;                  p_list->users[i].current_action_title = NULL;
272                  if (p_list->users[i].current_action[0] == '\0')                  if (p_list->users[i].current_action[0] == '\0')
273                  {                  {
274                          p_list->users[i].current_action_title = "Web浏览";                          p_list->users[i].current_action_title = "";
275                  }                  }
276                  else if (trie_dict_get(p_trie_action_dict, p_list->users[i].current_action, (int64_t *)(&(p_list->users[i].current_action_title))) < 0)                  else if (trie_dict_get(p_trie_action_dict, p_list->users[i].current_action, (int64_t *)(&(p_list->users[i].current_action_title))) < 0)
277                  {                  {
# Line 231  int user_online_list_load(MYSQL *db, USE Line 283  int user_online_list_load(MYSQL *db, USE
283                  p_list->users[i].login_tm = (row[4] == NULL ? 0 : atol(row[4]));                  p_list->users[i].login_tm = (row[4] == NULL ? 0 : atol(row[4]));
284                  p_list->users[i].last_tm = (row[5] == NULL ? 0 : atol(row[5]));                  p_list->users[i].last_tm = (row[5] == NULL ? 0 : atol(row[5]));
285    
286                    // index
287                    p_list->index_uid[i].uid = p_list->users[i].user_info.uid;
288                    p_list->index_uid[i].id = i;
289    
290                  i++;                  i++;
291                  if (i >= BBS_max_user_online_count)                  if (i >= BBS_max_user_online_count)
292                  {                  {
# Line 241  int user_online_list_load(MYSQL *db, USE Line 297  int user_online_list_load(MYSQL *db, USE
297          mysql_free_result(rs);          mysql_free_result(rs);
298          rs = NULL;          rs = NULL;
299    
300            // Sort index
301            if (i > 0)
302            {
303                    qsort(p_list->index_uid, (size_t)i, sizeof(USER_INFO_INDEX_UID), user_info_index_uid_comp);
304    #ifdef _DEBUG
305                    log_error("Rebuild index of %d online users\n", i);
306    #endif
307            }
308    
309          p_list->user_count = i;          p_list->user_count = i;
310    
311  #ifdef _DEBUG  #ifdef _DEBUG
312          log_error("Loaded %d users\n", p_list->user_count);          log_error("Loaded %d online users\n", p_list->user_count);
313  #endif  #endif
314    
315  cleanup:  cleanup:
# Line 447  int user_list_pool_reload(int online_use Line 512  int user_list_pool_reload(int online_use
512                          log_error("user_online_list_load() error\n");                          log_error("user_online_list_load() error\n");
513                          return -2;                          return -2;
514                  }                  }
515    
516                    // No online user, no need to swap lists
517                    if (p_user_list_pool->p_online_current->user_count == 0 && p_user_list_pool->p_online_new->user_count == 0)
518                    {
519                            return 0;
520                    }
521          }          }
522          else          else
523          {          {
# Line 747  cleanup: Line 818  cleanup:
818          return ret;          return ret;
819  }  }
820    
821  int query_user_info(int32_t uid, USER_INFO *p_user)  int query_user_info(int32_t id, USER_INFO *p_user)
822    {
823            int ret = 0;
824    
825            if (p_user == NULL)
826            {
827                    log_error("NULL pointer error\n");
828                    return -1;
829            }
830    
831            // acquire lock of user list
832            if (user_list_rd_lock(p_user_list_pool->semid) < 0)
833            {
834                    log_error("user_list_rd_lock() error\n");
835                    return -2;
836            }
837    
838            if (id >= 0 && id < p_user_list_pool->p_current->user_count) // Found
839            {
840                    *p_user = p_user_list_pool->p_current->users[id];
841                    ret = 1;
842            }
843    
844            // release lock of user list
845            if (user_list_rd_unlock(p_user_list_pool->semid) < 0)
846            {
847                    log_error("user_list_rd_unlock() error\n");
848                    ret = -1;
849            }
850    
851            return ret;
852    }
853    
854    int query_user_info_by_uid(int32_t uid, USER_INFO *p_user)
855  {  {
856          int left;          int left;
857          int right;          int right;
858          int mid;          int mid;
859            int32_t id;
860          int ret = 0;          int ret = 0;
861    
862          if (p_user == NULL)          if (p_user == NULL)
# Line 773  int query_user_info(int32_t uid, USER_IN Line 878  int query_user_info(int32_t uid, USER_IN
878          while (left < right)          while (left < right)
879          {          {
880                  mid = (left + right) / 2;                  mid = (left + right) / 2;
881                  if (uid < p_user_list_pool->p_current->users[mid].uid)                  if (uid < p_user_list_pool->p_current->index_uid[mid].uid)
882                  {                  {
883                          right = mid;                          right = mid;
884                  }                  }
885                  else if (uid > p_user_list_pool->p_current->users[mid].uid)                  else if (uid > p_user_list_pool->p_current->index_uid[mid].uid)
886                  {                  {
887                          left = mid + 1;                          left = mid + 1;
888                  }                  }
889                  else // if (uid == p_user_list_pool->p_current->users[mid].uid)                  else // if (uid == p_user_list_pool->p_current->index_uid[mid].uid)
890                  {                  {
891                          left = mid;                          left = mid;
892                          break;                          break;
893                  }                  }
894          }          }
895    
896          if (uid == p_user_list_pool->p_current->users[left].uid) // Found          if (uid == p_user_list_pool->p_current->index_uid[left].uid) // Found
897            {
898                    id = p_user_list_pool->p_current->index_uid[left].id;
899                    if ((ret = query_user_info(id, p_user)) <= 0)
900                    {
901                            log_error("query_user_info(id=%d) error: %d\n", id, ret);
902                    }
903                    else
904                    {
905                            ret = 1;
906                    }
907            }
908    
909            // release lock of user list
910            if (user_list_rd_unlock(p_user_list_pool->semid) < 0)
911            {
912                    log_error("user_list_rd_unlock() error\n");
913                    ret = -1;
914            }
915    
916            return ret;
917    }
918    
919    int query_user_online_info(int32_t id, USER_ONLINE_INFO *p_user)
920    {
921            int ret = 0;
922    
923            if (p_user == NULL)
924            {
925                    log_error("NULL pointer error\n");
926                    return -1;
927            }
928    
929            // acquire lock of user list
930            if (user_list_rd_lock(p_user_list_pool->semid) < 0)
931            {
932                    log_error("user_list_rd_lock() error\n");
933                    return -2;
934            }
935    
936            if (id >= 0 && id < p_user_list_pool->p_online_current->user_count) // Found
937          {          {
938                  *p_user = p_user_list_pool->p_current->users[left];                  *p_user = p_user_list_pool->p_online_current->users[id];
939                  ret = 1;                  ret = 1;
940          }          }
941    


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1