mirror of
git://git.psyced.org/git/psyced
synced 2024-08-15 03:25:10 +00:00
176 lines
5.1 KiB
C
176 lines
5.1 KiB
C
|
// $Id: decode.c,v 1.28 2008/01/21 10:25:12 lynx Exp $ // vim:syntax=lpc
|
||
|
//
|
||
|
// generic CTCP implementation, also includes color code filter.
|
||
|
// msa (Markku Savela, if i remember the spelling right) came up
|
||
|
// with the crazy idea of using binary code 1 as the escape code
|
||
|
// for CTCP, so we put that code into the variable msa.
|
||
|
//
|
||
|
#include <net.h>
|
||
|
|
||
|
volatile string msa, msare, cc, bc, uc;
|
||
|
|
||
|
// belongs into create() really..
|
||
|
decodeInit() {
|
||
|
msa = " "; msa[0] = 0x01;
|
||
|
msare = msa+".*"+msa;
|
||
|
cc = " "; cc[0] = 0x03; // same as msa
|
||
|
bc = " ", bc[0] = 0x02; // same as msa
|
||
|
uc = " ", uc[0] = 0x1F; // same as msa
|
||
|
}
|
||
|
|
||
|
// to be inherited
|
||
|
ctcp(type, text, target, req, srcnick, source) {
|
||
|
mapping vars;
|
||
|
|
||
|
P2(("%O %s %O -> %O: %O %O\n", ME,
|
||
|
req ? "REQ" : "REP",
|
||
|
srcnick, target, type, text))
|
||
|
|
||
|
vars = ([ "_nick" : srcnick,
|
||
|
"_value" : text || "",
|
||
|
"_type" : type ]);
|
||
|
|
||
|
sendmsg(target, (req? "_request": "_status") +"_legacy_CTCP",
|
||
|
"[_nick] "+ (req? "requests": "sends")+
|
||
|
" IRC legacy command '[_type]'.",
|
||
|
vars, source );
|
||
|
}
|
||
|
|
||
|
// to be inherited
|
||
|
version(text, target, req, srcnick, source) {
|
||
|
if (req && !text) {
|
||
|
P2(("%O VREQ(1=%O) %O -> %O: %O\n", ME, req,
|
||
|
srcnick, target, text))
|
||
|
|
||
|
sendmsg(target, "_request_version",
|
||
|
"[_nick] requests your version.",
|
||
|
([ "_nick" : srcnick ]), source );
|
||
|
#ifndef NO_IRC_AUTO_REQUEST_VERSION
|
||
|
} else if (target == query_server_unl()) {
|
||
|
if (text) vSet("agent", text);
|
||
|
#endif
|
||
|
} else {
|
||
|
PT(("%O VREP(0=%O) %O -> %O: %O\n", ME, req,
|
||
|
srcnick, target, text))
|
||
|
|
||
|
// generally unused as we don't send ctcp version to our clients
|
||
|
sendmsg(target, "_status_version_agent",
|
||
|
"Version: [_nick] is using \"[_version_agent]\" ([_version]).", ([
|
||
|
"_nick" : srcnick,
|
||
|
"_version" : SERVER_VERSION,
|
||
|
"_version_server": SERVER_DESCRIPTION,
|
||
|
"_version_agent" : text
|
||
|
]), source );
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// text, recipient string from irc, req: PRIVMSG/_request:1, NOTICE/_status:0
|
||
|
decode(text, rcpt, req) {
|
||
|
// filtering first.. 'cause some crazy people may be putting
|
||
|
// color codes inside of ctcp requests etc.
|
||
|
|
||
|
// filtering for mirc color codes
|
||
|
// these will never make it into a psyc standard ;)
|
||
|
// so they need to be removed
|
||
|
unless (strstr(text, cc) == -1) {
|
||
|
text = regreplace(text, cc + "[0-9][0-9],[0-9][0-9]", "", 1);
|
||
|
text = regreplace(text, cc + "[0-9][0-9],[0-9]", "", 1);
|
||
|
text = regreplace(text, cc + "[0-9],[0-9][0-9]", "", 1);
|
||
|
text = regreplace(text, cc + "[0-9],[0-9]", "", 1);
|
||
|
text = regreplace(text, cc + ",[0-9][0-9]", "", 1);
|
||
|
text = regreplace(text, cc + ",[0-9]", "", 1);
|
||
|
text = regreplace(text, cc + "[0-9][0-9]", "", 1);
|
||
|
text = regreplace(text, cc + "[0-9]", "", 1);
|
||
|
text = regreplace(text, cc, "", 1);
|
||
|
}
|
||
|
|
||
|
// filtering for irc bold code
|
||
|
unless (strstr(text, bc) == -1)
|
||
|
text = regreplace(text, bc, "", 1);
|
||
|
|
||
|
// filtering for irc underline code
|
||
|
unless (strstr(text, uc) == -1)
|
||
|
text = regreplace(text, uc, "", 1);
|
||
|
|
||
|
// it is more correct to check the whole text string for msa,
|
||
|
// but in practice no irc entity ever produces such a string
|
||
|
// with CTCP interspersed into the plain text, so were much
|
||
|
// more efficient to just look at the first character
|
||
|
if (text[0] == 0x01) {
|
||
|
string ctcpcode, ctcptext;
|
||
|
array(string) extract;
|
||
|
|
||
|
extract = regexplode(text, msare);
|
||
|
unless (sizeof(extract) >= 2) return; // unbalanced msa
|
||
|
ctcpcode = extract[1][1..<2];
|
||
|
sscanf(ctcpcode, "%s %s", ctcpcode, ctcptext);
|
||
|
ctcpcode = upper_case(ctcpcode);
|
||
|
P2(("CTCP %O w/ value %O found.\n", ctcpcode, ctcptext))
|
||
|
|
||
|
switch (ctcpcode) {
|
||
|
case "ACTION":
|
||
|
action(ctcptext, rcpt);
|
||
|
break;
|
||
|
case "VERSION":
|
||
|
unless (rcpt) break;
|
||
|
version(ctcptext, rcpt, req);
|
||
|
break;
|
||
|
case "PING":
|
||
|
if (rcpt)
|
||
|
if (req)
|
||
|
ping(rcpt, ctcptext);
|
||
|
// else ignore it for now as we cant tag it
|
||
|
break;
|
||
|
case "XCHAT":
|
||
|
// xchat sends an additional non-standard reply
|
||
|
// to the ctcp version request. we need to ignore
|
||
|
// this, instead of routing it to the server root.
|
||
|
break;
|
||
|
// this is an EXPERIMENTAL extension from fippo, but
|
||
|
// since this code can only be triggered by the
|
||
|
// appropriate irssi script, we can just leave it here
|
||
|
case "TYPING":
|
||
|
PT(("ctcp typing %O\n", ctcptext))
|
||
|
unless(rcpt) break;
|
||
|
switch(ctcptext) {
|
||
|
case "INACTIVE":
|
||
|
case "PAUSE":
|
||
|
case "COMPOSE":
|
||
|
case "ACTIVE":
|
||
|
case "GONE":
|
||
|
tell(rcpt, "", 0, 0, "_notice_typing_" + lower_case(ctcptext));
|
||
|
break;
|
||
|
default:
|
||
|
ctcp(ctcpcode, ctcptext, rcpt, req);
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
unless (rcpt) break;
|
||
|
ctcp(ctcpcode, ctcptext, rcpt, req);
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
return text;
|
||
|
}
|
||
|
|
||
|
// ein klein wenig ratlosigkeit
|
||
|
#if 1
|
||
|
irctext(template, vars, data, source) {
|
||
|
int i;
|
||
|
string output = psyctext(template, vars, data, source);
|
||
|
for (i=strstr(output, "%"); i>=0; i=strstr(output, "%", i)) {
|
||
|
output[i] = 0x01; // support for msa's CTCP char
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
#else
|
||
|
ircp(output) {
|
||
|
int i;
|
||
|
for (i=strstr(output, "%"); i>=0; i=strstr(output, "%", i)) {
|
||
|
output[i] = 0x01; // support for msa's CTCP char
|
||
|
}
|
||
|
return emit(output);
|
||
|
}
|
||
|
#endif
|