diff options
author | tomsmeding <tom.smeding@gmail.com> | 2017-04-15 18:09:48 +0200 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2017-04-15 18:58:34 +0200 |
commit | 8e1a1c1f01aef52ba8b2af47503461320a0abc20 (patch) | |
tree | 58a10a92ae3ad8b26db8efb72ded1169d50537e9 /broadcast.c | |
parent | 393b27c556008d1ae4eaa7438fa8a376202b1c88 (diff) |
server: Send _push online messages on online change
Diffstat (limited to 'broadcast.c')
-rw-r--r-- | broadcast.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/broadcast.c b/broadcast.c new file mode 100644 index 0000000..0517dc3 --- /dev/null +++ b/broadcast.c @@ -0,0 +1,89 @@ +#include <string.h> +#include "broadcast.h" +#include "db.h" +#include "net.h" +#include "user_data.h" + + +// Returns whether value was new and therefore inserted into the list. +// If already present, does nothing and returns false. +// Assumes enough space for the possible new item. +static bool sorted_insert(i64 *buf,i64 len,i64 value){ + if(len==0){ + buf[0]=value; + return true; + } + i64 L=0,H=len-1; + if(buf[L]==value||buf[H]==value)return false; + if(value<buf[L]){ + memmove(buf+1,buf,len*sizeof(i64)); + buf[0]=value; + return true; + } + if(value>buf[H]){ + buf[len]=value; + return true; + } + while(L<H){ + i64 M=L+(H-L)/2; + if(buf[M]==value)return false; + if(buf[M]<value){ + L=M+1; + if(buf[L]>value)break; + } else if(buf[M]>value){ + H=M-1; + if(buf[H]<value){ + L=M; + break; + } + } + } + if(buf[L]==value)return false; + // We insert left of L + memmove(buf+L+1,buf+L,len-L); + buf[L]=value; + return true; +} + +void broadcast_online_change(i64 userid){ + i64 seencap=16,seenlen=0; + i64 *seen=malloc(seencap,i64); + + struct db_room_list rooms=db_list_rooms(userid); + for(i64 i=0;i<rooms.count;i++){ + struct db_user_list members=db_list_members(rooms.list[i].id); + for(i64 j=0;j<members.count;j++){ + if(members.list[j].id==userid)continue; + i64 nfds; + (void)userdata_online(members.list[j].id,&nfds); + if(nfds==0)continue; + if(seenlen==seencap){ + seencap*=2; + seen=realloc(seen,seencap,i64); + } + bool inserted=sorted_insert(seen,seenlen,members.list[j].id); + seenlen+=inserted; + } + db_nullify_user_list(members); + } + db_nullify_room_list(rooms); + + char *name=db_get_username(userid); + i64 numonline; + (void)userdata_online(userid,&numonline); + + char *buf; + i64 len=asprintf(&buf,"_push online %" PRIi64 " %s\n",numonline,name); + free(name); + + for(i64 i=0;i<seenlen;i++){ + i64 nfds; + const int *fds=userdata_online(seen[i],&nfds); + for(i64 j=0;j<nfds;j++){ + net_send_raw_text(fds[j],buf,len); + } + } + + free(buf); + free(seen); +} |