📄 zephyr.c
字号:
new_f->env = "@i"; new_f->has_closer = TRUE; new_f->closer_mask = 15; frames = new_f; message += 3; } else if (!g_ascii_strncasecmp(message + 1, "b>", 2)) { new_f = g_new(zframe, 1); new_f->enclosing = frames; new_f->text = g_string_new(""); new_f->href = NULL; new_f->is_href = FALSE; new_f->closing = "</b>"; new_f->env = "@b"; new_f->has_closer = TRUE; new_f->closer_mask = 15; frames = new_f; message += 3; } else if (!g_ascii_strncasecmp(message + 1, "br>", 3)) { g_string_append_c(frames->text, '\n'); message += 4; } else if (!g_ascii_strncasecmp(message + 1, "a href=\"", 8)) { message += 9; new_f = g_new(zframe, 1); new_f->enclosing = frames; new_f->text = g_string_new(""); new_f->href = NULL; new_f->is_href = FALSE; new_f->closing = "</a>"; new_f->env = ""; new_f->has_closer = FALSE; new_f->closer_mask = frames->closer_mask; frames = new_f; new_f = g_new(zframe, 1); new_f->enclosing = frames; new_f->text = g_string_new(""); new_f->href = NULL; new_f->is_href = TRUE; new_f->closing = "\">"; new_f->has_closer = FALSE; new_f->closer_mask = frames->closer_mask; frames = new_f; } else if (!g_ascii_strncasecmp(message + 1, "font", 4)) { new_f = g_new(zframe, 1); new_f->enclosing = frames; new_f->text = g_string_new(""); new_f->href = NULL; new_f->is_href = FALSE; new_f->closing = "</font>"; new_f->has_closer = TRUE; new_f->closer_mask = 15; message += 5; while (*message == ' ') message++; if (!g_ascii_strncasecmp(message, "color=\"", 7)) { message += 7; new_f->env = "@"; frames = new_f; new_f = g_new(zframe, 1); new_f->enclosing = frames; new_f->env = "@color"; new_f->text = g_string_new(""); new_f->href = NULL; new_f->is_href = FALSE; new_f->closing = "\">"; new_f->has_closer = TRUE; new_f->closer_mask = 15; } else if (!g_ascii_strncasecmp(message, "face=\"", 6)) { message += 6; new_f->env = "@"; frames = new_f; new_f = g_new(zframe, 1); new_f->enclosing = frames; new_f->env = "@font"; new_f->text = g_string_new(""); new_f->href = NULL; new_f->is_href = FALSE; new_f->closing = "\">"; new_f->has_closer = TRUE; new_f->closer_mask = 15; } else if (!g_ascii_strncasecmp(message, "size=\"", 6)) { message += 6; if ((*message == '1') || (*message == '2')) { new_f->env = "@small"; } else if ((*message == '3') || (*message == '4')) { new_f->env = "@medium"; } else if ((*message == '5') || (*message == '6') || (*message == '7')) { new_f->env = "@large"; } else { new_f->env = ""; new_f->has_closer = FALSE; new_f->closer_mask = frames->closer_mask; } message += 3; } else { /* Drop all unrecognized/misparsed font tags */ new_f->env = ""; new_f->has_closer = FALSE; new_f->closer_mask = frames->closer_mask; while (g_ascii_strncasecmp(message, "\">", 2) != 0) { message++; } if (*message != '\0') message += 2; } frames = new_f; } else { /* Catch all for all unrecognized/misparsed <foo> tage */ g_string_append_c(frames->text, *message++); } } else if (*message == '@') { g_string_append(frames->text, "@@"); message++; } else if (*message == '}') { if (frames->closer_mask & ~1) { frames->closer_mask &= ~1; g_string_append_c(frames->text, *message++); } else { g_string_append(frames->text, "@[}]"); message++; } } else if (*message == ']') { if (frames->closer_mask & ~2) { frames->closer_mask &= ~2; g_string_append_c(frames->text, *message++); } else { g_string_append(frames->text, "@{]}"); message++; } } else if (*message == ')') { if (frames->closer_mask & ~4) { frames->closer_mask &= ~4; g_string_append_c(frames->text, *message++); } else { g_string_append(frames->text, "@{)}"); message++; } } else if (!g_ascii_strncasecmp(message, ">", 4)) { if (frames->closer_mask & ~8) { frames->closer_mask &= ~8; g_string_append_c(frames->text, *message++); } else { g_string_append(frames->text, "@{>}"); message += 4; } } else { g_string_append_c(frames->text, *message++); } } ret = frames->text->str; g_string_free(frames->text, FALSE); g_free(frames); purple_debug_info("zephyr","zephyr outputted %s\n",ret); return ret;}/* this parses zephyr formatting and converts it to html. For example, if * you pass in "@{@color(blue)@i(hello)}" you should get out * "<font color=blue><i>hello</i></font>". */static char *zephyr_to_html(const char *message){ zframe *frames, *curr; char *ret; frames = g_new(zframe, 1); frames->text = g_string_new(""); frames->enclosing = NULL; frames->closing = ""; frames->has_closer = FALSE; frames->closer = NULL; while (*message) { if (*message == '@' && message[1] == '@') { g_string_append(frames->text, "@"); message += 2; } else if (*message == '@') { int end; for (end = 1; message[end] && (isalnum(message[end]) || message[end] == '_'); end++); if (message[end] && (message[end] == '{' || message[end] == '[' || message[end] == '(' || !g_ascii_strncasecmp(message + end, "<", 4))) { zframe *new_f; char *buf; buf = g_new0(char, end); g_snprintf(buf, end, "%s", message + 1); message += end; new_f = g_new(zframe, 1); new_f->enclosing = frames; new_f->has_closer = TRUE; new_f->closer = (*message == '{' ? "}" : *message == '[' ? "]" : *message == '(' ? ")" : ">"); message += (*message == '&' ? 4 : 1); if (!g_ascii_strcasecmp(buf, "italic") || !g_ascii_strcasecmp(buf, "i")) { new_f->text = g_string_new("<i>"); new_f->closing = "</i>"; } else if (!g_ascii_strcasecmp(buf, "small")) { new_f->text = g_string_new("<font size=\"1\">"); new_f->closing = "</font>"; } else if (!g_ascii_strcasecmp(buf, "medium")) { new_f->text = g_string_new("<font size=\"3\">"); new_f->closing = "</font>"; } else if (!g_ascii_strcasecmp(buf, "large")) { new_f->text = g_string_new("<font size=\"7\">"); new_f->closing = "</font>"; } else if (!g_ascii_strcasecmp(buf, "bold") || !g_ascii_strcasecmp(buf, "b")) { new_f->text = g_string_new("<b>"); new_f->closing = "</b>"; } else if (!g_ascii_strcasecmp(buf, "font")) { zframe *extra_f; extra_f = g_new(zframe, 1); extra_f->enclosing = frames; new_f->enclosing = extra_f; extra_f->text = g_string_new(""); extra_f->has_closer = FALSE; extra_f->closer = frames->closer; extra_f->closing = "</font>"; new_f->text = g_string_new("<font face=\""); new_f->closing = "\">"; } else if (!g_ascii_strcasecmp(buf, "color")) { zframe *extra_f; extra_f = g_new(zframe, 1); extra_f->enclosing = frames; new_f->enclosing = extra_f; extra_f->text = g_string_new(""); extra_f->has_closer = FALSE; extra_f->closer = frames->closer; extra_f->closing = "</font>"; new_f->text = g_string_new("<font color=\""); new_f->closing = "\">"; } else { new_f->text = g_string_new(""); new_f->closing = ""; } frames = new_f; } else { /* Not a formatting tag, add the character as normal. */ g_string_append_c(frames->text, *message++); } } else if (frames->closer && !g_ascii_strncasecmp(message, frames->closer, strlen(frames->closer))) { zframe *popped; gboolean last_had_closer; message += strlen(frames->closer); if (frames && frames->enclosing) { do { popped = frames; frames = frames->enclosing; g_string_append(frames->text, popped->text->str); g_string_append(frames->text, popped->closing); g_string_free(popped->text, TRUE); last_had_closer = popped->has_closer; g_free(popped); } while (frames && frames->enclosing && !last_had_closer); } else { g_string_append_c(frames->text, *message); } } else if (*message == '\n') { g_string_append(frames->text, "<br>"); message++; } else { g_string_append_c(frames->text, *message++); } } /* go through all the stuff that they didn't close */ while (frames->enclosing) { curr = frames; g_string_append(frames->enclosing->text, frames->text->str); g_string_append(frames->enclosing->text, frames->closing); g_string_free(frames->text, TRUE); frames = frames->enclosing; g_free(curr); } ret = frames->text->str; g_string_free(frames->text, FALSE); g_free(frames); return ret;}static gboolean pending_zloc(zephyr_account *zephyr,char *who){ GList *curr; for (curr = zephyr->pending_zloc_names; curr != NULL; curr = curr->next) { char* normalized_who = local_zephyr_normalize(zephyr,who); if (!g_ascii_strcasecmp(normalized_who, (char *)curr->data)) { g_free((char *)curr->data); zephyr->pending_zloc_names = g_list_remove(zephyr->pending_zloc_names, curr->data); return TRUE; } } return FALSE;}/* Called when the server notifies us a message couldn't get sent */static void message_failed(PurpleConnection *gc, ZNotice_t notice, struct sockaddr_in from){ if (g_ascii_strcasecmp(notice.z_class, "message")) { gchar* chat_failed = g_strdup_printf(_("Unable to send to chat %s,%s,%s"),notice.z_class,notice.z_class_inst,notice.z_recipient); purple_notify_error(gc,"",chat_failed,NULL); g_free(chat_failed); } else { purple_notify_error(gc, notice.z_recipient, _("User is offline"), NULL); }}static void handle_message(PurpleConnection *gc,ZNotice_t notice){ zephyr_account* zephyr = gc->proto_data; if (!g_ascii_strcasecmp(notice.z_class, LOGIN_CLASS)) { /* well, we'll be updating in 20 seconds anyway, might as well ignore this. */ } else if (!g_ascii_strcasecmp(notice.z_class, LOCATE_CLASS)) { if (!g_ascii_strcasecmp(notice.z_opcode, LOCATE_LOCATE)) { int nlocs; char *user; PurpleBuddy *b; /* XXX add real error reporting */ if (ZParseLocations(¬ice, NULL, &nlocs, &user) != ZERR_NONE) return; if ((b = purple_find_buddy(gc->account, user)) == NULL) { char* stripped_user = zephyr_strip_local_realm(zephyr,user); b = purple_find_buddy(gc->account,stripped_user); g_free(stripped_user); } if ((b && pending_zloc(zephyr,b->name)) || pending_zloc(zephyr,user)) { ZLocations_t locs; int one = 1; PurpleNotifyUserInfo *user_info = purple_notify_user_info_new(); char *tmp; purple_notify_user_info_add_pair(user_info, _("User"), (b ? b->name : user)); if (b && b->alias) purple_notify_user_info_add_pair(user_info, _("Alias"), b->alias); if (!nlocs) { purple_notify_user_info_add_pair(user_info, NULL, _("Hidden or not logged-in")); } for (; nlocs > 0; nlocs--) { /* XXX add real error reporting */ ZGetLocations(&locs, &one); tmp = g_strdup_printf(_("<br>At %s since %s"), locs.host, locs.time); purple_notify_user_info_add_pair(user_info, _("Location"), tmp); g_free(tmp); } purple_notify_userinfo(gc, (b ? b->name : user), user_info, NULL, NULL); purple_notify_user_info_destroy(user_info); } else { if (nlocs>0) purple_prpl_got_user_status(gc->account, b ? b->name : user, "available", NULL); else purple_prpl_got_user_status(gc->account, b ? b->name : user, "offline", NULL); } g_free(user); } } else { char *buf, *buf2, *buf3; char *send_inst; PurpleConversation *gconv1; PurpleConvChat *gcc; char *ptr = (char *) notice.z_message + (strlen(notice.z_message) + 1); int len; char *sendertmp = g_strdup_printf("%s", zephyr->username); int signature_length = strlen(notice.z_message); int message_has_no_body = 0; PurpleMessageFlags flags = 0; gchar *tmpescape; /* Need to deal with 0 length messages to handle typing notification (OPCODE) ping messages */ /* One field zephyrs would have caused purple to crash */ if ( (notice.z_message_len == 0) || (signature_length >= notice.z_message_len - 1)) { message_has_no_body = 1; len = 0; purple_debug_info("zephyr","message_size %d %d %d\n",len,notice.z_message_len,signature_length); buf3 = g_strdup(""); } else { len = notice.z_message_len - ( signature_length +1); purple_debug_info("zephyr","message_size %d %d %d\n",len,notice.z_message_len,signature_length); buf = g_malloc(len + 1); g_snprintf(buf, len + 1, "%s", ptr); g_strchomp(buf); tmpescape = g_markup_escape_text(buf, -1); g_free(buf); buf2 = zephyr_to_html(tmpescape); buf3 = zephyr_recv_convert(gc,buf2, strlen(buf2)); g_free(buf2); g_free(tmpescape); } if (!g_ascii_strcasecmp(notice.z_class, "MESSAGE") && !g_ascii_strcasecmp(notice.z_class_inst, "PERSONAL") && !g_ascii_strcasecmp(notice.z_recipient,zephyr->username)) { gchar* stripped_sender; if (!g_ascii_strcasecmp(notice.z_message, "Automated reply:")) flags |= PURPLE_MESSAGE_AUTO_RESP; stripped_sender = zephyr_strip_local_realm(zephyr,notice.z_sender); if (!g_ascii_strcasecmp(notice.z_opcode,"PING")) serv_got_typing(gc,stripped_sender,ZEPHYR_TYPING_RECV_TIMEOUT, PURPLE_TYPING); else { /* Based on the values of account->permit_deny, account->permit, account>deny , and the buddylist */ GSList* l; gboolean in_deny; switch (gc->account->perm_deny) { case PURPLE_PRIVACY_ALLOW_ALL: in_deny = 0; break; case PURPLE_PRIVACY_DENY_ALL: in_deny = 1; break; case PURPLE_PRIVACY_ALLOW_USERS: /* See if stripped_sender is in gc->account->permit and allow appropriately */ in_deny = 1; for(l=gc->account->permit;l!=NULL;l=l->next) { if (!purple_utf8_strcasecmp(stripped_sender, purple_normalize(gc->account, (char *)l->data))) { in_deny=0; break; } } break; case PURPLE_PRIVACY_DENY_USERS: /* See if stripped_sender is in gc->account->deny and deny if so */ in_deny = 0; for(l=gc->account->deny;l!=NULL;l=l->next) { if (!purple_utf8_strcasecmp(stripped_sender, purple_normalize(gc->account, (char *)l->data))) { in_deny=1; break; } } break; case PURPLE_PRIVACY_ALLOW_BUDDYLIST: in_deny = 1; if (purple_find_buddy(gc->account,stripped_sender)!=NULL) { in_deny = 0; } break; default: in_deny=0; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -