jabber/user honors FRIEND_AVAILABILITY and more

This commit is contained in:
psyc://psyced.org/~lynX 2009-03-02 23:02:54 +01:00
parent 8b8cd94ec0
commit d248048454
10 changed files with 93 additions and 74 deletions

View File

@ -750,6 +750,13 @@ remoteMUC:
________________________________________________________________________ ________________________________________________________________________
== JABBER CLIENT ISSUES (...experimental is justified...) ============== == JABBER CLIENT ISSUES (...experimental is justified...) ==============
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
- accurate availability values from friends aren't stored and delivered
- re-subscribe isn't properly handled (so we do friend(0) earlier instead)
- when unsubscribing a user, no proper ack is sent to client
(but relogin helps ;))
- v("place") isn't automatically set when actively joining a chat - v("place") isn't automatically set when actively joining a chat
- the /me command ist not properly treated - the /me command ist not properly treated
@ -770,16 +777,6 @@ ________________________________________________________________________
- elmex: fippo: psyced.org failt soweit ichs seh bei mir alle tests bis auf den IQ auth test. - elmex: fippo: psyced.org failt soweit ichs seh bei mir alle tests bis auf den IQ auth test.
... Net::XMPP2 installieren und damit den muve testen? ... Net::XMPP2 installieren und damit den muve testen?
- <iq id="2" type="error">
<query xmlns="jabber:iq:register">
<error code="406" type="cancel">
<conflict xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</query>
</iq>
elmex: der error muss aussen in den iq error
<iq><query/><error/></iq>
- elmex: ausserdem geht das unregister wohl net richtig, denn - elmex: ausserdem geht das unregister wohl net richtig, denn
beim registrieren bekomme ich halt den conflict da. beim registrieren bekomme ich halt den conflict da.
@ -825,8 +822,6 @@ ________________________________________________________________________
fiPP: wir mögen resourcen überhaupt nicht fiPP: wir mögen resourcen überhaupt nicht
fiPP: das wird alles gefiltert und vom server beantwortet fiPP: das wird alles gefiltert und vom server beantwortet
- elmex: fippo: von subscription prozedur brauch ich garnicht anfangen oder?
- elmex: disco geht auch nicht - elmex: disco geht auch nicht
fiPP: dass wir auf iq teilweise mit message antworten ist nen uralter bug fiPP: dass wir auf iq teilweise mit message antworten ist nen uralter bug
end<< 2nd_testxmpp@beta.ve.example.com/x end<< 2nd_testxmpp@beta.ve.example.com/x
@ -898,9 +893,6 @@ ________________________________________________________________________
- aimgate sendeoptimierung auf #if 0 - aimgate sendeoptimierung auf #if 0
? ouch.. wir haben immernoch psyctext fehler:
net/jabber/user#example <presence to='example@example.org/Home' from='oops@example.org/irc'><x from='oops@example.org/irc' stamp='[_INTERNAL_time_jabber]' xmlns='jabber:x:delay'/></presence>
- niekie entered #welcome both by telnet and xmpp. when the telnet - niekie entered #welcome both by telnet and xmpp. when the telnet
logged out, his xmpp client thought he had left the muc also. logged out, his xmpp client thought he had left the muc also.
ok, so the psyced did correctly handle both your identities.. only that your client interpreted the other you leaving as you leaving.. kind of logical ok, so the psyced did correctly handle both your identities.. only that your client interpreted the other you leaving as you leaving.. kind of logical
@ -911,6 +903,8 @@ ________________________________________________________________________
erscheint er also immernoch online) erscheint er also immernoch online)
+ In welcome spricht mb: is there a way to turn off the welcome messages everytime someone gets connected to psyc, it is a bit irritating when you use clients like ichat who do not filter those messages into a seperate channel + In welcome spricht mb: is there a way to turn off the welcome messages everytime someone gets connected to psyc, it is a bit irritating when you use clients like ichat who do not filter those messages into a seperate channel
? ouch.. wir haben immernoch psyctext fehler:
net/jabber/user#example <presence to='example@example.org/Home' from='oops@example.org/irc'><x from='oops@example.org/irc' stamp='[_INTERNAL_time_jabber]' xmlns='jabber:x:delay'/></presence>
- <presence to="example@example.org/mozdev" from="test@example.org"> - <presence to="example@example.org/mozdev" from="test@example.org">
<x xmlns="jabber:x:delay" from="test@example.org" <x xmlns="jabber:x:delay" from="test@example.org"
stamp="[_INTERNAL_time_jabber]"/> stamp="[_INTERNAL_time_jabber]"/>
@ -987,9 +981,6 @@ ________________________________________________________________________
buddymachen, dann geht der im laufe der transaktion verloren und man buddymachen, dann geht der im laufe der transaktion verloren und man
muss ihn später nochmal setzen! muss ihn später nochmal setzen!
- "00:05 ... Ich bin gerade nicht hier."
net/jabber/user maps away messages to mottoaction instead of presencetext
________________________________________________________________________ ________________________________________________________________________
== JABBER FILE TRANSFERS =============================================== == JABBER FILE TRANSFERS ===============================================
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
@ -3923,5 +3914,7 @@ net/user
jabber/user jabber/user
- fixed major bug in output of presence state (showFriends) - fixed major bug in output of presence state (showFriends)
- fixed outgoing presence support (announce) - fixed outgoing presence support (announce)
jabber/server
- fixed various iq errors as elmex noted: <iq><query/><error/></iq>
pkggen pkggen
+ ported from cvs to git + ported from cvs to git

View File

@ -500,5 +500,11 @@ _status_person_absent_offline
_status_friendship_established _status_friendship_established
|<presence to='[_INTERNAL_target_jabber]' from='[_INTERNAL_source_jabber_bare]' type='subscribed'/> |<presence to='[_INTERNAL_target_jabber]' from='[_INTERNAL_source_jabber_bare]' type='subscribed'/>
_warning_duplicate_friendship
|## useless information
_warning_pending_friendship
|## useless information
_warning_usage_set_language _warning_usage_set_language
|## |## doesn't look good on jabber

View File

@ -236,8 +236,9 @@ jabberisten die freundschaft zum user#fippo entfernte:
ME, t, source, _routes)) ME, t, source, _routes))
} }
} else { } else {
// happens when doing /unfr. must be a bug in user.c // happens when doing /unfr. it's when the implied unfriend
P0(("%O encountered unnecessary remove of %O from %O\n", // comes back from the other side.
P2(("%O encountered unnecessary remove of %O from %O\n",
ME, source, _routes)) ME, source, _routes))
} }
} }

View File

@ -38,8 +38,6 @@ virtual inherit JABBER_PATH "common";
#define XMPP "xmpp:" #define XMPP "xmpp:"
#define IQ_OFF "</query></iq>"
#define NS_XMPP "urn:ietf:params:xml:ns:" #define NS_XMPP "urn:ietf:params:xml:ns:"
#define IMPLODE_XML(list, tag) pointerp(list) ? tag + implode(list, "</" + tag[1..] + tag) + "</" + tag[1..] : tag[..<2] + "/>" #define IMPLODE_XML(list, tag) pointerp(list) ? tag + implode(list, "</" + tag[1..] + tag) + "</" + tag[1..] : tag[..<2] + "/>"

View File

@ -193,14 +193,14 @@ jabberMsg(XMLNode node) {
// super dirty.. this should all be in textdb // super dirty.. this should all be in textdb
packet = sprintf("<iq type='result' id='%s'>" packet = sprintf("<iq type='result' id='%s'>"
"<query xmlns='jabber:iq:register'/>" "<query xmlns='jabber:iq:register'/>"
"<error code='501>Registration by XMPP not permitted.</error>" IQ_OFF, "<error code='501>Registration by XMPP not permitted.</error></iq>",
id); id);
#else #else
packet = sprintf("<iq type='result' id='%s'>" packet = sprintf("<iq type='result' id='%s'>"
"<query xmlns='jabber:iq:register'>" "<query xmlns='jabber:iq:register'>"
"<instructions>You dont even need to register, " "<instructions>You dont even need to register, "
"this is psyced. Manual at http://help.pages.de</instructions>" "this is psyced. Manual at http://help.pages.de</instructions>"
"<name/><email/><username/><password/>" IQ_OFF, "<name/><email/><username/><password/></query></iq>",
id); id);
#endif #endif
emit(packet); emit(packet);
@ -219,20 +219,18 @@ jabberMsg(XMLNode node) {
} }
unless (user -> isNewbie()) { unless (user -> isNewbie()) {
// already registered to someone else // already registered to someone else
packet += "<error code='406' type='cancel'>" packet += "</query><error code='406' type='cancel'>"
"<conflict xmlns='" NS_XMPP "xmpp-stanzas'/>" "<conflict xmlns='" NS_XMPP "xmpp-stanzas'/>"
"</error>" "</error></iq>";
IQ_OFF;
emit(packet); emit(packet);
QUIT QUIT
} else unless ((t = helper["/username"]) && } else unless ((t = helper["/username"]) &&
t[Cdata] && t[Cdata] &&
(t = helper["/password"]) && (t = helper["/password"]) &&
t[Cdata]) { t[Cdata]) {
packet += "<error code='406' type='modify'>" packet += "</query><error code='406' type='modify'>"
"<not-acceptable xmlns='" NS_XMPP "xmpp-stanzas'/>" "<not-acceptable xmlns='" NS_XMPP "xmpp-stanzas'/>"
"</error>" "</error></iq>";
IQ_OFF;
emit(packet); emit(packet);
QUIT QUIT
} else { } else {

View File

@ -19,8 +19,8 @@ volatile int isplacemsg;
volatile int hasroster = 0; // client has requested roster volatile int hasroster = 0; // client has requested roster
volatile mapping jabber2avail, volatile mapping affiliations = ([ ]); // hack to support affiliations
affiliations = ([ ]); // hack to support affiliations volatile mapping jabber2avail;
#include JABBER_PATH "disco.c" #include JABBER_PATH "disco.c"
// #include NET_PATH "members.i" // isn't this include redundant? // #include NET_PATH "members.i" // isn't this include redundant?
@ -238,21 +238,23 @@ msg(source, mc, data, mapping vars, showingLog) {
showFriends() { showFriends() {
// send presence for online friends // send presence for online friends
string template = T("_notice_presence_here_plain",
"<presence to='[_INTERNAL_target_jabber]' "
"from='[_INTERNAL_source_jabber]'/>");
string packet = ""; string packet = "";
mixed person;
int av;
foreach(mixed friend : m_indices(friends)) { foreach(person: m_indices(friends)) if (person) {
if (friend) av = friends[person, FRIEND_AVAILABILITY];
packet += psyctext(template, ([ packet += psyctext(T("_status_presence"+ avail2mc[av],
"_INTERNAL_target_jabber" : myjid, "<presence to='[_INTERNAL_target_jabber]' "
"_INTERNAL_source_jabber" : mkjid(friend), "from='[_INTERNAL_source_jabber]'/>"), ([
"_INTERNAL_mood_jabber" : "neutral" "_INTERNAL_target_jabber" : myjid,
])); "_INTERNAL_source_jabber" : mkjid(person),
"_description_presence" : "", // TODO: get these from state
"_INTERNAL_mood_jabber" : "neutral"
]));
} }
if (strlen(packet)) emit(packet); if (strlen(packet)) emit(packet);
P2(("%O jabberish showFriends: %O outputs as %O\n", ME, friends, packet)) PT(("%O jabberish showFriends: %O outputs as %O\n", ME, friends, packet))
} }
logon() { logon() {
@ -312,7 +314,7 @@ presence(XMLNode node) {
} }
#ifndef _flag_disable_presence_directed_XMPP #ifndef _flag_disable_presence_directed_XMPP
if (node["@to"]) { if (node["@to"]) {
target = jid2unl(node["@to"]); target = jid2ppl(node["@to"]);
if (isplacemsg) { if (isplacemsg) {
mixed *u = parse_uniform(XMPP + node["@to"]); mixed *u = parse_uniform(XMPP + node["@to"]);
P2(("some kind of place stuff\n")) P2(("some kind of place stuff\n"))
@ -358,10 +360,9 @@ presence(XMLNode node) {
} }
# ifndef _flag_disable_module_friendship # ifndef _flag_disable_module_friendship
} else if (node["@type"] == "subscribe") { } else if (node["@type"] == "subscribe") {
// was: friend(({ jid2unl(node["@to"]) }), 0); friend(0, 0, jid2ppl(node["@to"]));
friend(0, jid2unl(node["@to"]));
} else if (node["@type"] == "unsubscribe") { } else if (node["@type"] == "unsubscribe") {
friend(1, jid2unl(node["@to"])); friend(1, 0, jid2ppl(node["@to"]));
# endif // _flag_disable_module_friendship # endif // _flag_disable_module_friendship
} else if (abbrev(XMPP, target)) { } else if (abbrev(XMPP, target)) {
// if the person is not on our buddylist, // if the person is not on our buddylist,
@ -436,7 +437,7 @@ message(XMLNode node) {
P0(("%O jabber message() without 'to'-attribute\n")) P0(("%O jabber message() without 'to'-attribute\n"))
return; return;
} }
target = jid2unl(node["@to"]); target = jid2ppl(node["@to"]);
unless (u = parse_uniform(XMPP + node["@to"])) { D("impossible!\n"); } unless (u = parse_uniform(XMPP + node["@to"])) { D("impossible!\n"); }
isplacemsg = ISPLACEMSG(node["@to"]); isplacemsg = ISPLACEMSG(node["@to"]);
@ -538,7 +539,7 @@ message(XMLNode node) {
} }
// _message_private // _message_private
nick = jid2unl(node["@to"]); nick = jid2ppl(node["@to"]);
// P2(("nick: %s\n", nick)) // P2(("nick: %s\n", nick))
// TODO: vars["_time_INTERNAL"] => jabber:x:delay, JEP-0091 // TODO: vars["_time_INTERNAL"] => jabber:x:delay, JEP-0091
#if 0 #if 0
@ -565,7 +566,7 @@ iq(XMLNode node) {
mixed *vars; mixed *vars;
vars = ([ "_nick": MYNICK ]); vars = ([ "_nick": MYNICK ]);
target = jid2unl(node["@to"]); target = jid2ppl(node["@to"]);
isplacemsg = stringp(target) && strlen(target) && ISPLACEMSG(target); isplacemsg = stringp(target) && strlen(target) && ISPLACEMSG(target);
P3(("%O IQ node %O\n", ME, node)) P3(("%O IQ node %O\n", ME, node))
@ -721,7 +722,7 @@ iq(XMLNode node) {
ME, "_list_acquaintance_notification" + variant + "_roster", friend)) ME, "_list_acquaintance_notification" + variant + "_roster", friend))
} }
} }
emit(packet + IQ_OFF); emit(packet +"</query></iq>");
// here we should redisplay requests skipped above // here we should redisplay requests skipped above
// oder kann man die einfach reinmixen - nein // oder kann man die einfach reinmixen - nein
// foreach skipped // foreach skipped
@ -732,10 +733,10 @@ iq(XMLNode node) {
case "set": case "set":
helper = helper["/item"]; helper = helper["/item"];
if (helper && helper["@subscription"] == "remove") { if (helper && helper["@subscription"] == "remove") {
string buddy = jid2unl(helper["@jid"]); string buddy = jid2ppl(helper["@jid"]);
#ifndef _flag_disable_module_friendship #ifndef _flag_disable_module_friendship
P2(("remove %O from roster\n", helper["@jid"])) P2(("remove %O from roster\n", helper["@jid"]))
friend(1, buddy); friend(1, 0, buddy);
#endif #endif
m_delete(xbuddylist, buddy); m_delete(xbuddylist, buddy);
emit(sprintf("<iq type='result' id='%s'/>", tag)); emit(sprintf("<iq type='result' id='%s'/>", tag));
@ -747,7 +748,11 @@ iq(XMLNode node) {
string name; string name;
jid = helper["@jid"]; jid = helper["@jid"];
buddy = jid2unl(jid); unless (stringp(jid)) {
P0(("invalid jid for %O in %O\n", name, ME))
break;
}
buddy = jid2ppl(jid);
unless (xbuddylist[buddy]) unless (xbuddylist[buddy])
subscription = "none"; subscription = "none";
else else
@ -776,14 +781,6 @@ iq(XMLNode node) {
// //
// roster push // roster push
// maybe we can just implode the former "groups" here // maybe we can just implode the former "groups" here
unless (stringp(jid)) {
P0(("invalid jid for %O in %O\n", name, ME))
break;
}
unless (stringp(subscription)) {
P0(("invalid subscription for %O in %O\n", jid, ME))
break;
}
unless (stringp(name)) { unless (stringp(name)) {
// nicht schlimm.. hat der user das alias-feld // nicht schlimm.. hat der user das alias-feld
// einfach leergelassen // einfach leergelassen
@ -798,7 +795,14 @@ iq(XMLNode node) {
IMPLODE_XML(xbuddylist[buddy], "<group>"))); IMPLODE_XML(xbuddylist[buddy], "<group>")));
if (stringp(tag)) if (stringp(tag))
emit(sprintf("<iq type='result' id='%s'/>", tag)); emit(sprintf("<iq type='result' id='%s'/>", tag));
#ifndef _flag_disable_module_friendship
// client will send presence subscribe in opposite direction
// so we shouldn't need this. alas, there seems to be a bug
// with re-subscribe
friend(0, 0, buddy);
#else
save(); save();
#endif
} }
break; break;
case "result": case "result":
@ -1075,12 +1079,13 @@ iq(XMLNode node) {
} }
} }
// this isn't really used consistently... // this converts a user@host into a local nick or uniform
string jid2unl(string jid) { // in a potentially not too consistent way
string jid2ppl(string jid) {
string node, host, resource; string node, host, resource;
string t; string t;
P3(("jid2unl saw %O\n", jid)) P3(("jid2ppl saw %O\n", jid))
unless(jid) return 0; unless(jid) return 0;
// //
// TODO: what if jid == SERVER_HOST? // TODO: what if jid == SERVER_HOST?

View File

@ -73,7 +73,16 @@ volatile mapping lastaway;
volatile mixed availability; volatile mixed availability;
#endif // _flag_disable_module_presence #endif // _flag_disable_module_presence
// complex data structure of peers. see peer.h
volatile mapping ppl; volatile mapping ppl;
// friends contains the currently available peers.
// technically, friends is a multi-dimensional mapping:
// uniforms or objects pointing to nick and availability.
// it should be 0-dimensional instead, only containing objects:
// local entities vs. context slaves for remote entities.
// in both cases providing the typical state information:
// availability, mood, presence text, icons and photos...
volatile mapping friends; volatile mapping friends;
#ifdef RELAY #ifdef RELAY
@ -2094,7 +2103,9 @@ case "_request_friendship_implied":
// but the other side may be confused or have lost its // but the other side may be confused or have lost its
// state, so we let it know once more // state, so we let it know once more
default: default:
// if (mc != "_notice_friendship_established") { // this stops loops of _status_friendship_established
// but maybe we should just never act on that mc
if (mc != t2) {
sendmsg(source, t2, data, sendmsg(source, t2, data,
([ "_nick": MYNICK ]) ); ([ "_nick": MYNICK ]) );
// friendship with oneself.. // friendship with oneself..
@ -2117,7 +2128,7 @@ case "_request_friendship_implied":
// why did we want to filter this? // why did we want to filter this?
// weil das zeug nervt. // weil das zeug nervt.
//display = 0; //display = 0;
// } }
myLogAppend(source, mc, data, vars); myLogAppend(source, mc, data, vars);
// display sollte hier gleich 0 sein wenn man // display sollte hier gleich 0 sein wenn man
// schon mit der person befreundet ist... // schon mit der person befreundet ist...

View File

@ -251,13 +251,13 @@ int psyc_sendmsg(mixed target, string mc, mixed data, mapping vars,
} }
host = lower_case(u[UHost]); host = lower_case(u[UHost]);
if (query_udp_port() == port && is_localhost(host)) { if (query_udp_port() == port && is_localhost(host)) {
// this happens when a psyc client sends to a local
// target that hasn't been incarnated yet...
o = find_psyc_object(u); o = find_psyc_object(u);
// cache the resulting object for the url // cache the resulting object for the url
if (o) { if (o) {
// currently find_psyc_object returns 0 for the P2(("psyc_sendmsg registering %O for %O found by parsing uniform\n",
// local root, thus register_target messes up next. ouch. target, o))
P1(("psyc_sendmsg registering target %O for %O found through %O\n",
target, o, u))
register_target(target, o); register_target(target, o);
} }
#ifndef __PIKE__ // TPD #ifndef __PIKE__ // TPD

View File

@ -1640,7 +1640,10 @@ disconnected(remainder) {
// actually - we could show all messages since last activity // actually - we could show all messages since last activity
// from user. TODO // from user. TODO
#ifdef AVAILABILITY_OFFLINE #ifdef AVAILABILITY_OFFLINE
if (availability == AVAILABILITY_OFFLINE) return; if (availability == AVAILABILITY_OFFLINE) {
P1(("i think i am already offline, so i won't quit (%O)\n", ME))
return;
}
#endif #endif
if (find_call_out(#'quit) != -1) return; if (find_call_out(#'quit) != -1) return;
// if (place) sendmsg(place, "_notice_place_leave_disconnect", // if (place) sendmsg(place, "_notice_place_leave_disconnect",

View File

@ -2232,9 +2232,10 @@ protected invite(nick, vars) {
// two ways to call this: // two ways to call this:
// the gui style is friend(deleteflag, entity, optlNick)) // the gui style is friend(deleteflag, entity, optlNick))
// the cmdline style is friend(deleteflag, 0, nickname) // the cmdline style is friend(deleteflag, 0, nickname)
protected friend(rm, entity, ni, trustee) { friend(rm, entity, ni, trustee) {
mixed t; mixed t;
P0(("friend(%O, %O, %O, %O) in %O\n", rm, entity, ni, trustee, ME))
if (IS_NEWBIE) { if (IS_NEWBIE) {
#ifdef VOLATILE #ifdef VOLATILE
w("_error_unavailable_function_here", w("_error_unavailable_function_here",
@ -2287,6 +2288,7 @@ protected friend(rm, entity, ni, trustee) {
"All contact data for [_nick_target] deleted.", "All contact data for [_nick_target] deleted.",
([ "_nick_target": ni ]) ); ([ "_nick_target": ni ]) );
m_delete(ppl, t); m_delete(ppl, t);
m_delete(friends, entity);
return 1; return 1;
} }
w("_error_unknown_acquaintance", w("_error_unknown_acquaintance",
@ -2318,6 +2320,8 @@ protected friend(rm, entity, ni, trustee) {
// TODO: gender support // TODO: gender support
([ "_nick": MYNICK, "_possessive": "the" ]) ); ([ "_nick": MYNICK, "_possessive": "the" ]) );
m_delete(friends, entity); m_delete(friends, entity);
PT(("entity %O (%O) removed from friends %O\n",
entity, t, friends))
//} //}
return 1; return 1;
} }