⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chat.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		SilcPurpleChatWb wb;		wb = silc_calloc(1, sizeof(*wb));		wb->sg = sg;		wb->channel = channel;		act = purple_menu_action_new(_("Draw On Whiteboard"),		                           PURPLE_CALLBACK(silcpurple_chat_wb),		                           (void *)wb, NULL);		m = g_list_append(m, act);	}	return m;}/******************************* Joining Etc. ********************************/void silcpurple_chat_join_done(SilcClient client,			     SilcClientConnection conn,			     SilcClientEntry *clients,			     SilcUInt32 clients_count,			     void *context){	PurpleConnection *gc = client->application;	SilcPurple sg = gc->proto_data;	SilcChannelEntry channel = context;	PurpleConversation *convo;	SilcUInt32 retry = SILC_PTR_TO_32(channel->context);	SilcHashTableList htl;	SilcChannelUser chu;	GList *users = NULL, *flags = NULL;	char tmp[256];	if (!clients && retry < 1) {		/* Resolving users failed, try again. */		channel->context = SILC_32_TO_PTR(retry + 1);		silc_client_get_clients_by_channel(client, conn, channel,						   silcpurple_chat_join_done, channel);		return;	}	/* Add channel to Purple */	channel->context = SILC_32_TO_PTR(++sg->channel_ids);	serv_got_joined_chat(gc, sg->channel_ids, channel->channel_name);	convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,							channel->channel_name, sg->account);	if (!convo)		return;	/* Add all users to channel */	silc_hash_table_list(channel->user_list, &htl);	while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {		PurpleConvChatBuddyFlags f = PURPLE_CBFLAGS_NONE;		if (!chu->client->nickname)			continue;		chu->context = SILC_32_TO_PTR(sg->channel_ids);		if (chu->mode & SILC_CHANNEL_UMODE_CHANFO)			f |= PURPLE_CBFLAGS_FOUNDER;		if (chu->mode & SILC_CHANNEL_UMODE_CHANOP)			f |= PURPLE_CBFLAGS_OP;		users = g_list_append(users, g_strdup(chu->client->nickname));		flags = g_list_append(flags, GINT_TO_POINTER(f));		if (chu->mode & SILC_CHANNEL_UMODE_CHANFO) {			if (chu->client == conn->local_entry)				g_snprintf(tmp, sizeof(tmp),					   _("You are channel founder on <I>%s</I>"),					   channel->channel_name);			else				g_snprintf(tmp, sizeof(tmp),					   _("Channel founder on <I>%s</I> is <I>%s</I>"),					   channel->channel_name, chu->client->nickname);			purple_conversation_write(convo, NULL, tmp,						PURPLE_MESSAGE_SYSTEM, time(NULL));		}	}	silc_hash_table_list_reset(&htl);	purple_conv_chat_add_users(PURPLE_CONV_CHAT(convo), users, NULL, flags, FALSE);	g_list_free(users);	g_list_free(flags);	/* Set topic */	if (channel->topic)		purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), NULL, channel->topic);	/* Set nick */	purple_conv_chat_set_nick(PURPLE_CONV_CHAT(convo), conn->local_entry->nickname);}char *silcpurple_get_chat_name(GHashTable *data){	return g_strdup(g_hash_table_lookup(data, "channel"));}	void silcpurple_chat_join(PurpleConnection *gc, GHashTable *data){	SilcPurple sg = gc->proto_data;	SilcClient client = sg->client;	SilcClientConnection conn = sg->conn;	const char *channel, *passphrase, *parentch;	if (!conn)		return;	channel = g_hash_table_lookup(data, "channel");	passphrase = g_hash_table_lookup(data, "passphrase");	/* Check if we are joining a private group.  Handle it	   purely locally as it's not a real channel */	if (strstr(channel, "[Private Group]")) {		SilcChannelEntry channel_entry;		SilcChannelPrivateKey key;		PurpleChat *c;		SilcPurplePrvgrp grp;		c = purple_blist_find_chat(sg->account, channel);		parentch = purple_blist_node_get_string((PurpleBlistNode *)c, "parentch");		if (!parentch)			return;		channel_entry = silc_client_get_channel(sg->client, sg->conn,							(char *)parentch);		if (!channel_entry ||		    !silc_client_on_channel(channel_entry, sg->conn->local_entry)) {			char tmp[512];			g_snprintf(tmp, sizeof(tmp),				   _("You have to join the %s channel before you are "				     "able to join the private group"), parentch);			purple_notify_error(gc, _("Join Private Group"),					  _("Cannot join private group"), tmp);			return;		}		/* Add channel private key */		if (!silc_client_add_channel_private_key(client, conn,							 channel_entry, channel,							 NULL, NULL,							 (unsigned char *)passphrase,							 strlen(passphrase), &key))			return;		/* Join the group */		grp = silc_calloc(1, sizeof(*grp));		if (!grp)			return;		grp->id = ++sg->channel_ids + SILCPURPLE_PRVGRP;		grp->chid = SILC_PTR_TO_32(channel_entry->context);		grp->parentch = parentch;		grp->channel = channel;		grp->key = key;		sg->grps = g_list_append(sg->grps, grp);		serv_got_joined_chat(gc, grp->id, channel);		return;	}	/* XXX We should have other properties here as well:	   1. whether to try to authenticate to the channel	     1a. with default key,	     1b. with specific key.	   2. whether to try to authenticate to become founder.	     2a. with default key,	     2b. with specific key.	   Since now such variety is not possible in the join dialog	   we always use -founder and -auth options, which try to	   do both 1 and 2 with default keys. */	/* Call JOIN */	if ((passphrase != NULL) && (*passphrase != '\0'))		silc_client_command_call(client, conn, NULL, "JOIN",					 channel, passphrase, "-auth", "-founder", NULL);	else		silc_client_command_call(client, conn, NULL, "JOIN",					 channel, "-auth", "-founder", NULL);}void silcpurple_chat_invite(PurpleConnection *gc, int id, const char *msg,			  const char *name){	SilcPurple sg = gc->proto_data;	SilcClient client = sg->client;	SilcClientConnection conn = sg->conn;	SilcHashTableList htl;	SilcChannelUser chu;	gboolean found = FALSE;	if (!conn)		return;	/* See if we are inviting on a private group.  Invite	   to the actual channel */	if (id > SILCPURPLE_PRVGRP) {		GList *l;		SilcPurplePrvgrp prv;		for (l = sg->grps; l; l = l->next)			if (((SilcPurplePrvgrp)l->data)->id == id)				break;		if (!l)			return;		prv = l->data;		id = prv->chid;	}	/* Find channel by id */	silc_hash_table_list(conn->local_entry->channels, &htl);	while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {		if (SILC_PTR_TO_32(chu->channel->context) == id ) {			found = TRUE;			break;		}	}	silc_hash_table_list_reset(&htl);	if (!found)		return;	/* Call INVITE */	silc_client_command_call(client, conn, NULL, "INVITE",				 chu->channel->channel_name,				 name, NULL);}void silcpurple_chat_leave(PurpleConnection *gc, int id){	SilcPurple sg = gc->proto_data;	SilcClient client = sg->client;	SilcClientConnection conn = sg->conn;	SilcHashTableList htl;	SilcChannelUser chu;	gboolean found = FALSE;	GList *l;	SilcPurplePrvgrp prv;	if (!conn)		return;	/* See if we are leaving a private group */	if (id > SILCPURPLE_PRVGRP) {		SilcChannelEntry channel;		for (l = sg->grps; l; l = l->next)			if (((SilcPurplePrvgrp)l->data)->id == id)				break;		if (!l)			return;		prv = l->data;		channel = silc_client_get_channel(sg->client, sg->conn,						  (char *)prv->parentch);		if (!channel)			return;		silc_client_del_channel_private_key(client, conn,						    channel, prv->key);		silc_free(prv);		sg->grps = g_list_remove(sg->grps, prv);		serv_got_chat_left(gc, id);		return;	}	/* Find channel by id */	silc_hash_table_list(conn->local_entry->channels, &htl);	while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {		if (SILC_PTR_TO_32(chu->channel->context) == id ) {			found = TRUE;			break;		}	}	silc_hash_table_list_reset(&htl);	if (!found)		return;	/* Call LEAVE */	silc_client_command_call(client, conn, NULL, "LEAVE",				 chu->channel->channel_name, NULL);	serv_got_chat_left(gc, id);	/* Leave from private groups on this channel as well */	for (l = sg->grps; l; l = l->next)		if (((SilcPurplePrvgrp)l->data)->chid == id) {			prv = l->data;			silc_client_del_channel_private_key(client, conn,							    chu->channel,							    prv->key);			serv_got_chat_left(gc, prv->id);			silc_free(prv);			sg->grps = g_list_remove(sg->grps, prv);			if (!sg->grps)				break;		}}int silcpurple_chat_send(PurpleConnection *gc, int id, const char *msg, PurpleMessageFlags msgflags){	SilcPurple sg = gc->proto_data;	SilcClient client = sg->client;	SilcClientConnection conn = sg->conn;	SilcHashTableList htl;	SilcChannelUser chu;	SilcChannelEntry channel = NULL;	SilcChannelPrivateKey key = NULL;	SilcUInt32 flags;	int ret;	char *msg2, *tmp;	gboolean found = FALSE;	gboolean sign = purple_account_get_bool(sg->account, "sign-verify", FALSE);	if (!msg || !conn)		return 0;	flags = SILC_MESSAGE_FLAG_UTF8;	tmp = msg2 = purple_unescape_html(msg);	if (!g_ascii_strncasecmp(msg2, "/me ", 4))	{		msg2 += 4;		if (!*msg2) {			g_free(tmp);			return 0;		}		flags |= SILC_MESSAGE_FLAG_ACTION;	} else if (strlen(msg) > 1 && msg[0] == '/') {		if (!silc_client_command_call(client, conn, msg + 1))			purple_notify_error(gc, _("Call Command"), _("Cannot call command"),							  _("Unknown command"));		g_free(tmp);		return 0;	}	if (sign)		flags |= SILC_MESSAGE_FLAG_SIGNED;	/* Get the channel private key if we are sending on	   private group */	if (id > SILCPURPLE_PRVGRP) {		GList *l;		SilcPurplePrvgrp prv;		for (l = sg->grps; l; l = l->next)			if (((SilcPurplePrvgrp)l->data)->id == id)				break;		if (!l) {			g_free(tmp);			return 0;		}		prv = l->data;		channel = silc_client_get_channel(sg->client, sg->conn,						  (char *)prv->parentch);		if (!channel) {			g_free(tmp);			return 0;		}		key = prv->key;	}	if (!channel) {		/* Find channel by id */		silc_hash_table_list(conn->local_entry->channels, &htl);		while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {			if (SILC_PTR_TO_32(chu->channel->context) == id ) {				found = TRUE;				break;			}		}		silc_hash_table_list_reset(&htl);		if (!found) {			g_free(tmp);			return 0;		}		channel = chu->channel;	}	/* Send channel message */	ret = silc_client_send_channel_message(client, conn, channel, key,					       flags, (unsigned char *)msg2,					       strlen(msg2), TRUE);	if (ret) {		serv_got_chat_in(gc, id, purple_connection_get_display_name(gc), 0, msg,				 time(NULL));	}	g_free(tmp);	return ret;}void silcpurple_chat_set_topic(PurpleConnection *gc, int id, const char *topic){	SilcPurple sg = gc->proto_data;	SilcClient client = sg->client;	SilcClientConnection conn = sg->conn;	SilcHashTableList htl;	SilcChannelUser chu;	gboolean found = FALSE;	if (!conn)		return;	/* See if setting topic on private group.  Set it	   on the actual channel */	if (id > SILCPURPLE_PRVGRP) {		GList *l;		SilcPurplePrvgrp prv;		for (l = sg->grps; l; l = l->next)			if (((SilcPurplePrvgrp)l->data)->id == id)				break;		if (!l)			return;		prv = l->data;		id = prv->chid;	}	/* Find channel by id */	silc_hash_table_list(conn->local_entry->channels, &htl);	while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {		if (SILC_PTR_TO_32(chu->channel->context) == id ) {			found = TRUE;			break;		}	}	silc_hash_table_list_reset(&htl);	if (!found)		return;	/* Call TOPIC */	silc_client_command_call(client, conn, NULL, "TOPIC",				 chu->channel->channel_name, topic, NULL);}PurpleRoomlist *silcpurple_roomlist_get_list(PurpleConnection *gc){	SilcPurple sg = gc->proto_data;	SilcClient client = sg->client;	SilcClientConnection conn = sg->conn;	GList *fields = NULL;	PurpleRoomlistField *f;	if (!conn)		return NULL;	if (sg->roomlist)		purple_roomlist_unref(sg->roomlist);	sg->roomlist_canceled = FALSE;	sg->roomlist = purple_roomlist_new(purple_connection_get_account(gc));	f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", "channel", TRUE);	fields = g_list_append(fields, f);	f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_INT,				    _("Users"), "users", FALSE);	fields = g_list_append(fields, f);	f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING,				    _("Topic"), "topic", FALSE);	fields = g_list_append(fields, f);	purple_roomlist_set_fields(sg->roomlist, fields);	/* Call LIST */	silc_client_command_call(client, conn, "LIST");	purple_roomlist_set_in_progress(sg->roomlist, TRUE);	return sg->roomlist;}void silcpurple_roomlist_cancel(PurpleRoomlist *list){	PurpleConnection *gc = purple_account_get_connection(list->account);	SilcPurple sg;	if (!gc)		return;	sg = gc->proto_data;	purple_roomlist_set_in_progress(list, FALSE);	if (sg->roomlist == list) {		purple_roomlist_unref(sg->roomlist);		sg->roomlist = NULL;		sg->roomlist_canceled = TRUE;	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -