diff --git a/CHANGESTODO b/CHANGESTODO index bcf1d43..d294745 100644 --- a/CHANGESTODO +++ b/CHANGESTODO @@ -8,11 +8,19 @@ ________________________________________________________________________ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ? support tls multiplexing on all suitable ports +? bugs in psyced install procedure + - pointless to keep gentoo files in this git, if they can't be updated separately + ++ teach net/smtp to trust localhost etc. ++ teach net/smtp to ask recipient object if spam rules are to be applied ________________________________________________________________________ == currently being inspected =========================================== ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ +- jabber logout isn't announced or offline avail isn't processed + ... apparently other side did not logout properly, as it doesn't happen always + - neither USE_THE_NICK or USE_AUTOALIAS work flawlessly. in the case of the latter, _nick either displays without uniform for remote people, or it occasionally shows a room's nick instead of the user's nick. @@ -22,6 +30,11 @@ ________________________________________________________________________ templates and removing _nick vars. during this tradition we keep the USE_THE_NICK code running. several "invite issues" should be solved once nicks are gone. + +- psyced.org tells me: Ungültige Route nach psyc://psyced.org + im psyc://psyced.org/~lynx Context festgestellt. + +? who's gonna clean up the mess of having too many websites ? ________________________________________________________________________ == psyced 1.0 ========================================================== ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ @@ -1367,6 +1380,11 @@ ________________________________________________________________________ ! When the /topic command makes funny errors, then your room has a custom cmd() and doesn't pass vars over. It should use ON_COMMAND instead! +________________________________________________________________________ +* PSYC FUTURES see also http://about.psyc.eu/Category:Vapor +¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ++ http://about.psyc.eu/Hashtags ++ http://about.psyc.eu/Follower ________________________________________________________________________ * TOYS IN THE ATTIC ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ @@ -1478,7 +1496,7 @@ ________________________________________________________________________ is not accepted by the UNI and thus does not make it into _list_places - _do_leave does not forward the echo from remote places back to the client -- NEW_UNLINK: place and v("place") aren't in sync (new changes for psyc clients) +- place and v("place") aren't in sync (new changes for psyc clients) + if newbie: directly show register dialog (lynx should add _status_unregistered or so) @@ -1769,6 +1787,10 @@ see also: http://about.psyc.eu/SPAM evtl nicht alle im richtigen channel, um den enter zu sehen..) == IRC ISSUES 1.0 ====================================================== +- according to rfc and ircd source IRC parser should accept when the last + argument is just a word instead of a phrase prefixed by : + this is unusual, but legal: "PRIVMSG #blah hello" + + some irc clients do not implement their own pinging, and some NATs really kill your irc session if it is too quiet too long. we need optional server side pings @@ -3870,4 +3892,6 @@ psyctext entity nicknames (experimental). allows to remove nicks from protocol. spyc/* psyc/* + should a _date type run on unixtime minus PSYC_EPOCH? - +install.sh ++ don't leave _host_IP uncommented ++ mkdir data/* log/* diff --git a/bin/psyconf b/bin/psyconf index 3625e4b..7b4d5ab 100755 --- a/bin/psyconf +++ b/bin/psyconf @@ -361,7 +361,7 @@ X my $hc = 0; ## ldmud bug number one: you have to provide hostname AFTER hostaddr - if ($c{_basic_host_IP}) { + if ($c{_basic_host_IP} =~ /^[0-9\.]+$/) { $psyced .= " --hostaddr $c{_basic_host_IP}"; $hc = 1; # problem? } diff --git a/config/versioncontrol.tcsh b/config/versioncontrol.tcsh index e16e5ea..4304350 100644 --- a/config/versioncontrol.tcsh +++ b/config/versioncontrol.tcsh @@ -36,3 +36,10 @@ alias ctoc '(cd $CVSHOME;cvs diff -bur HEAD CHANGESTODO|& difvu -' alias ctodo '(cd $PSYCEDHOME;cvs update CHANGESTODO;$EDITOR CHANGESTODO;cvs ci -m + CHANGESTODO)' alias todo '(cd $PSYCEDHOME;$EDITOR CHANGESTODO)' +# edit all files that contain a certain keyword +# uses the +/searchstring syntax supported by vi and other smart editors +alias gred '$EDITOR "+/\!*" `grep -swIrl \!* .`' +# grep -r is a bit stupid: it follows symlinks, then shows us files twice +# so using the git full text index may be smarter and faster +alias ggred '$EDITOR "+/\!*" `git grep -w -l \!*`' + diff --git a/install.sh b/install.sh index fdc9378..04861b1 100755 --- a/install.sh +++ b/install.sh @@ -1,18 +1,20 @@ #!/bin/sh +# # new age sh (SUSv2 etc) are supposed to handle our syntax # but if that's not true, try a bash or ksh here. # -# psyced installation script -# $Id: install.sh,v 1.165 2008/10/16 13:07:13 lynx Exp $ -# -# original version by oswald!osw@ld.pages.de on IRCnet, 22aug00 -# heavy improvements by heldensaga and psyc://psyced.org/~lynX -# switched from function foo to foo() syntax as suggested by cebewee -# # we could also use a strategy for finding the best bash or ksh # on this system and re-execing ourselves because an old bourne # shell will not be able to deal with this script completely +####### psyced installation script ####### +# +# original version 2000-08-22 by Kai 'Oswald' Seidler (oswaldism.de) +# heavy improvements by heldensaga and psyc://psyced.org/~lynX +# switched from function foo to foo() syntax as suggested by cebewee +# +####### + # Use 'ldmud' here if you want to use an ldmud rather than a psyclpc' #driver="ldmud" #zip="gz" @@ -39,24 +41,32 @@ lo="" if test -d "/etc/portage" then - cat < /dev/null @@ -164,10 +174,12 @@ echo "${hi}PSYCED INSTALLATION WIZARD${lo}" if ! test -e data.tar then - echo "This installation script is designed to work with an image of the" - echo "current development tree in a file called data.tar. Obtain a" - echo "psyced release tar from http://www.psyced.org, which contains" - echo "both this script and its data.tar" + cat < /dev/null then - : + ; else if test "x$userid" = "xroot" then @@ -1107,7 +1120,16 @@ else $exit fi +# we need to be completely sure these directories exist, +# so we just go ahead with brute force :) +# +mkdir -m $BASE_PERM -p $LOG_DIR 2> /dev/null +mkdir -m $BASE_PERM -p $LOG_DIR/place 2> /dev/null +mkdir -m $BASE_PERM -p $DATA_DIR 2> /dev/null +mkdir -m $BASE_PERM -p $DATA_DIR/person 2> /dev/null +mkdir -m $BASE_PERM -p $DATA_DIR/place 2> /dev/null mkdir -p $ARCH_DIR 2>/dev/null + if test -d $ARCH_DIR then if test ! -w $ARCH_DIR @@ -1193,11 +1215,10 @@ EOF # # TODO: don't say this if either $driver or erq failed to compile! # echo "${hi}COMPILATION DONE${lo}" echo "" - fi - # i have a feeling i should be using ARCH_DIR here - if test -d bin-$arch - then + # i have a feeling i should be using ARCH_DIR here + if test -d bin-$arch + then cd bin-$arch for i in * do @@ -1209,9 +1230,10 @@ EOF done cd .. - else + else echo "${hi}WARNING:${lo} Couldn't install architecture dependent binaries because I can't find them!" echo "" + fi fi else echo "Hmm.. couldn't create $ARCH_DIR! Aborting." diff --git a/place/ircgate.c b/place/ircgate.c index bc64167..c06e1ec 100644 --- a/place/ircgate.c +++ b/place/ircgate.c @@ -6,7 +6,8 @@ // // to make this work you need to add the following to local.h: // -// #define RELAY "ircgate" +// #define RELAY "ircgate" // name of ircnet (?) +// #define RELAY_OBJECT "place/ircgate" // this class // // do not use in existing psyced communities in the current set up // as currently all incoming traffic is presumed to be meant for the @@ -39,13 +40,13 @@ #define IRCGATE_LOCAL "pw" #define NAME "IRCgate" -#define ON_CONNECT login(); +#define ON_CONNECT onConnect(); #define CONNECT_IRC "localhost", 7000 #define EMULATE_SERVER // don't be a bot #include -login() { +onConnect() { PT(("ircgate serving into "+query_ip_number()+"\n")) // login procedure may vary with different flavors of ircd, // that's why we keep it entirely here diff --git a/world/default/en/jabber.textdb b/world/default/en/jabber.textdb index e8b32c9..5d8dd52 100644 --- a/world/default/en/jabber.textdb +++ b/world/default/en/jabber.textdb @@ -1,6 +1,12 @@ ## vim:syntax=mail ## Check utf-8: Praise Atatürk! +_notice_add_alias_temporary +|## shouldn't be sent to jabber clients + +_failure_unavailable_alias +|## shouldn't be sent to jabber clients + _MISC_character_command |## since several clients started catching / commands.. |+ diff --git a/world/local b/world/local new file mode 120000 index 0000000..c820590 --- /dev/null +++ b/world/local @@ -0,0 +1 @@ +../local \ No newline at end of file diff --git a/world/log b/world/log new file mode 120000 index 0000000..033579f --- /dev/null +++ b/world/log @@ -0,0 +1 @@ +../log \ No newline at end of file diff --git a/world/net/include/net.h b/world/net/include/net.h index 0903830..f57a14b 100644 --- a/world/net/include/net.h +++ b/world/net/include/net.h @@ -216,8 +216,6 @@ # define WANT_S2S_SASL # define ENTER_MEMBERS # define PERSISTENT_MASTERS -# define NEW_LINK -# define NEW_UNLINK # define NEW_RENDER # define MUCSUC #endif @@ -232,7 +230,7 @@ // fippo's brilliant single-user channel emulation for jabber MUCs // unfortunately it provides no advantages over the old method, yet. // would be cool to cache a member list at least! TODO -# define PERSISTENT_SLAVES +// efine PERSISTENT_SLAVES // postponed // efine IRC_FRIENDCHANNEL // hopelessly needs more work # ifdef HTTP_PATH # define HTFORWARD // let person entity buffer output for http usage diff --git a/world/net/include/place.gen b/world/net/include/place.gen index 373ed3d..d03b00d 100644 --- a/world/net/include/place.gen +++ b/world/net/include/place.gen @@ -146,7 +146,7 @@ inherit NET_PATH "place/mailcast"; # ifdef PUBLIC inherit NET_PATH "place/public"; # else - // special case in the archetype options logic, see also the .pl + // special case in the archetype options logic, see also psyconf # ifndef PLACE_HISTORY # ifdef PLACE_HISTORY_EXPORT # define PLACE_HISTORY diff --git a/world/net/irc/common.c b/world/net/irc/common.c index 7b5aa8c..061b705 100644 --- a/world/net/irc/common.c +++ b/world/net/irc/common.c @@ -44,6 +44,11 @@ parse(a) { if (a == "") return; // don't let " \n" execute "/s" unless (sscanf(a, ":%s %s", from, t)) t = a; sscanf(t, "%s :%s", t, text); + // when 'text' is not present, the last argument could be a single + // word text according to rfc. this has never seemed to hurt, but + // we are not exactly compliant in that sense. we could copy the + // last arg over into text, but that requires to change the api + // into explode()-based. WONTFIX unless (sscanf(t, "%s %s", cmd, args)) cmd = t; if (cmd) ircMsg(from, lower_case(cmd), args, text, a); return 1; diff --git a/world/net/irc/server.c b/world/net/irc/server.c index 238ef2f..a1efe60 100644 --- a/world/net/irc/server.c +++ b/world/net/irc/server.c @@ -19,7 +19,9 @@ volatile string pass; // for now it's a bit complicated to re-issue all joins and i'm not // even sure if it would be enough for the irc clients.. so better -// just quit the old object and start anew. +// just quit the old object and start anew. a bit silly when user +// objects have just been incarnated and never actually logged in - +// for each ircer we thus incarnate twice. FIXME keepUserObject(user) { return 0; } qScheme() { return "irc"; } diff --git a/world/net/jabber/user.c b/world/net/jabber/user.c index 8961af0..3f91137 100644 --- a/world/net/jabber/user.c +++ b/world/net/jabber/user.c @@ -571,17 +571,14 @@ iq(XMLNode node) { P3(("%O IQ node %O\n", ME, node)) firstchild = getfirstchild(node); - unless(firstchild) { - switch(node["@type"]) { + unless(firstchild) switch(node["@type"]) { case "get": - break; case "set": - break; case "result": - break; case "error": break; - } + default: + P1(("%O got invalid iq %O\n", ME, node)) return; } helper = firstchild; @@ -732,7 +729,14 @@ iq(XMLNode node) { break; case "set": helper = helper["/item"]; - if (helper && helper["@subscription"] == "remove") { + if (!mappingp(helper)) { + P1(("no item in iq set %O from %O in %O\n", + node, previous_object(), ME)) + // FIXME: what is the correct behaviour + // in this case? + return; + } + if (helper["@subscription"] == "remove") { string buddy = jid2ppl(helper["@jid"]); #ifndef _flag_disable_module_friendship P2(("remove %O from roster\n", helper["@jid"])) @@ -1009,6 +1013,7 @@ iq(XMLNode node) { break; #endif default: + P1(("%O got IQ with unknown namespace: %O\n", ME, node)) switch(node["@type"]) { case "get": if (node["@to"]) { diff --git a/world/net/person.c b/world/net/person.c index 475c091..9647889 100644 --- a/world/net/person.c +++ b/world/net/person.c @@ -476,10 +476,15 @@ qLocation(string service) { return v("locations")[service]; } -// returns 0 if that was just an update -// 1 on success +// returns 0 if that was just an update. 1 on success. +// this was originally used by sip/udp only, then slowly +// integrated into existing code sLocation(string service, mixed data) { ASSERT("sLocation", v("locations"), v("locations")) + // should this function also call register_location ? + // yes because a delivery error should remove clients + // from the location table, too.. not just proper + // unlink requests FIXME if (v("locations")[service] == data) return 0; unless (data) { string retval = v("locations")[service]; @@ -489,7 +494,6 @@ sLocation(string service, mixed data) { return v("locations")[service] = data; } -#ifdef NEW_LINK static linkSet(service, location, source) { P1(("linkSet(%O, %O, %O) called in %O: linking.\n", service, location, source, ME)); @@ -524,9 +528,8 @@ static linkSet(service, location, source) { // for simple clients on link when a place is set } } -#endif -#ifdef NEW_UNLINK -static linkDel(service, source) { +static linkDel(service, source, variant) { + string mc = "_notice_unlink"; string candidate = v("locations")[service]; unless (candidate) { P3(("linkDel(%O, %O) called in %O: no such candidate!\n", @@ -536,18 +539,31 @@ static linkDel(service, source) { P1(("linkDel(%O, %O) called in %O: unlinking %O.\n", service, source, ME, candidate)); unless (source) source = candidate; + // sLocation? register_location(candidate, 0); + // maybe actual deletion would need to be delayed after + // letting locations know. they might still be sending + // stuff to us, right? m_delete(v("locations"), service || 0); - if (service) sendmsg(source, "_notice_unlink_service", 0, + if (variant) mc += variant; + if (service) sendmsg(source, mc, 0, ([ "_service" : service, "_location_service" : candidate, "_identification" : v("_source") ])); - else sendmsg(source, "_notice_unlink", 0, + else sendmsg(source, mc, 0, ([ "_location" : candidate, "_identification" : v("_source") ])); return candidate; } -#endif +static linkCleanUp(variant) { + mixed type, loc; + + foreach (type, loc : v("locations")) { + P2(("linkCleanUp(%O) to %O's ex-%O-client %O\n", + variant, ME, type, loc)) + linkDel(type, 0, variant); + } +} // extend sName() from name.c sName2(a) { @@ -615,7 +631,9 @@ sName2(a) { availability = v("availability"); #endif // _flag_disable_module_presence - unless (v("locations")) vSet("locations", ([ ])); + if (v("locations")) linkCleanUp("_crash"); + else vSet("locations", ([ ])); + // protection against file read errors if (IS_NEWBIE) { if (boss(a)) { @@ -630,7 +648,7 @@ sName2(a) { destruct(ME); return 0; } -#ifndef RELAY +#ifdef _flag_enable_administrator_by_nick else if (strstr(lower_case(a), "admin") != -1) { this_player()->w("_failure_object_create_admin", "This nickname is available to administrators only."); @@ -647,20 +665,6 @@ sName2(a) { // maybe use v("identification") here? vSet("_source", psyc_name(ME)); - - // TODO: needs to be foreached for all types of locations? - if (e = v("locations")[0]) { -#ifdef NEW_UNLINK - linkDel(0); -#else - P2(("sending _status_unlinked to ex-client %O\n", e)) - // no clue if the UNL is still out there.. - // lets send a ping so it can reconnect - // but first we have to delete it from our structures! - m_delete(v("locations"), 0); - sendmsg(e, "_status_unlinked", 0, ([])); -#endif - } return MYNICK; // means new name accepted } @@ -874,41 +878,6 @@ msg(mixed source, mc, data, mapping vars, showingLog) { if (showingLog) return display; // logView() in action // btw, when reviewing log, all users are displayed equal size -#if 0 - // hack that permits us to use same mapping across - // all user objects in a room. really should be using - // copies of the mapping for each user - or forbid to - // write into the mapping. this statement in particular - // also protects us from "intruder" _display settings, - // so it's useful anyway. - // - m_delete(vars, "_display"); -#endif -#if 0 //ndef NEW_UNLINK - if (abbrev("_request_link_", mc)) { - vars["_service"] = mc[14..]; - mc = "_set_password"; - } else if (abbrev("_request_unlink_", mc)) { - vars["_service"] = mc[16..]; - mc = "_request_unlink"; - } else if (abbrev("_request_location_", mc)) { - vars["_service"] = mc[18..]; - mc = "_request_location"; - // diese kette an abbrevs ist schrecklich ineffizient und zudem - // nicht für jede nachricht nötig.. unlink und diese failure können - // doch nur von eigenen locations kommen, also tiefergelegt werden - // in einen if (itsme) block hinein..!? im switch ist es nicht so - // tragisch, wenn methoden für bestimmte fälle gar nicht eintreten - // können, aber abbrevs die jedes mal durchgelaufen werden müssen, - // die geben mir zu denken ob das überhaupt eine gute idee war - // zusatzinformation hinten an die methode dranzuhängen. vielleicht - // ist das ja der eigentliche fehler und man sollte _method und - // _service lieber gutheissen und pflegen.. whatchathink? TODO -// } else if (abbrev("_failure_unsuccessful_delivery_", mc)) { -// vars["_method"] = mc[31..]; -// mc = "_failure_unsuccessful_delivery"; - } -#endif #ifdef RELAY remotesource = 0; #endif @@ -1045,21 +1014,8 @@ case "_set_password": // oh. we let it suggest a *different* location? // interesting. why don't we also do this for clients? // and who is using this code anyway? -#ifdef NEW_UNLINK linkDel(vars["_service"]); -#endif -#ifdef NEW_LINK linkSet(vars["_service"], vars["_location"], source); -#else - if (vars["_location"]) { - v("locations")[vars["_service"]] = vars["_location"]; - } else v("locations")[vars["_service"]] = source; - sendmsg(source, "_notice_link_"+ vars["_service"], - "You have been linked to [_service].", ([ - "_service" : vars["_service"], - ])); - register_location(source, ME); -#endif return 0; } #if 0 @@ -1098,11 +1054,7 @@ case "_set_password": } // we are a legitimate new client. // lets inform the old one -#ifdef NEW_UNLINK linkDel(0, t); -#else - sendmsg(t, "_notice_unlink"); -#endif // now we leave the old client circuit // to die off.. let's hope that's safe } @@ -1143,11 +1095,7 @@ case "_set_password": object o; save(); if (interactive(ME)) { -#ifdef NEW_UNLINK linkDel(); -#else - ME->w("_notice_unlink"); -#endif remove_interactive(ME); } o = named_clone(PSYC_PATH "user", MYNICK); @@ -1159,10 +1107,6 @@ case "_set_password": o->msg(source, mc, data, vars); return destruct(ME); } -#endif -#ifndef NEW_LINK - v("locations")[0] = source; - register_location(source, ME); #endif // used by _request_authentication if (u = parse_uniform(source)) vSet("ip", u[UHost]); @@ -1213,22 +1157,7 @@ case "_set_password": #endif // yeah right.. //unless (interactive()) vSet("host", source); -#ifdef NEW_LINK linkSet(0, vars["_location"], source); -#else - sendmsg(source, "_notice_link", 0, ([ - "_tag_reply": vars["_tag"], - "_nick" : MYNICK ])); - // PSYCion users dont have queries. - // until there are more clients this will - // be enough TODO - vDel("query"); - // clients either use _request_input - // and thus support current place and query, - // or otherwise _message to places and people - // and never use _request_input, therefore - // not get into trouble with query & place....? -#endif // moved logon after _notice_linked // which is more appropriate for most clients // lets see if theres any problem with that @@ -1300,16 +1229,11 @@ case "_set_password": :)); // dont display, dont log, it is handled async #endif return 0; +// _request_do_exit currently logs out clients anyway +// don't use this: case "_request_exit": if (itsme && source == v("locations")[0]) { -#ifdef NEW_UNLINK linkDel(0, source); -#else - sendmsg(source, "_notice_unlink_exit", - 0, ([])); - register_location(source); - m_delete(v("locations"), 0); -#endif quit(); return 0; } else { @@ -1324,15 +1248,7 @@ case "_request_unlink": member(v("locations"), vars["_service"])) { if (source == v("locations")[vars["_service"]] || checkPassword(vars["_password"])) { -#ifdef NEW_UNLINK linkDel(vars["_service"]); -#else - m_delete(v("locations"), vars["_service"]); - sendmsg(source, "_notice_unlink_"+ - vars["_service"], - "You have been unlinked from [_service].", - ([ "_service" : vars["_service"] ])); -#endif return 0; } else { // report? @@ -1341,14 +1257,7 @@ case "_request_unlink": } } else if (member(v("locations"), 0) && source == v("locations")[0]) { -#ifdef NEW_UNLINK linkDel(0); -#else - m_delete(v("locations"), 0); - register_location(source, 0); - sendmsg(source, "_notice_unlink", - 0, ([])); -#endif if (mc == "_request_unlink_disconnect" && !ONLINE) { // manually calling disconnected() .. hmmm disconnected(); @@ -1729,8 +1638,12 @@ case "_notice_invitation": case "_message_private_question": case "_message_private": // same filtering code as couple lines above - if (( IS_NEWBIE || !itsme && FILTERED(source)) && - (!profile || profile[PPL_NOTIFY] <= PPL_NOTIFY_PENDING)) { + if (( +#ifndef _flag_enable_unauthenticated_message_private + IS_NEWBIE || +#endif + (!itsme && FILTERED(source)) && + (!profile || profile[PPL_NOTIFY] <= PPL_NOTIFY_PENDING))) { PT(("_failure_filter_strangers to %O from %O\n", source, ME)) sendmsg(source, "_failure_filter_strangers", 0, ([ "_nick" : MYNICK ]) ); @@ -2606,6 +2519,10 @@ reboot(reason, restart, pass) { //unless (clonep(ME)) return; if (blueprint(ME) == ME) return; P2(("%O shutting down\n", ME)) + + // temporary, please remove after 2009-04 + if (!v("locations")) vSet("locations", ([])); + #if !defined(SLAVE) && !defined(_flag_disable_info_session) if (ONLINE) { // same in net/psyc/circuit.c @@ -2640,9 +2557,12 @@ quit(immediate, variant) { int rc; P3(("person:QUIT(%O,%O) in %O\n", immediate,variant, ME)) -#ifdef NEW_UNLINK - linkDel(0); -#endif + // keeping services running while logging out should be possible.. but + //linkDel(0); + if (sizeof(v("locations"))) { + // the if should only trigger at first pass + linkCleanUp(); + } if (immediate == 1 || (immediate && find_call_out(#'quit) != -1)) { rc = save(); if (sizeof(places)) { @@ -2658,8 +2578,13 @@ quit(immediate, variant) { P1(("intercepted recursive QUIT %O\n", ME || MYNICK )) return 0; } + P4(("** QUITTING %O: av %O, sc %O\n", ME, availability, v("scheme"))) #ifndef _flag_disable_module_presence switch(v("scheme")) { + case 0: + // scheme is 0 when a user entity has never been logged + // in, like friends in a roster that get incarnated + break; // jabber/user:quit() is called on @type 'unavailable' // so it relies on quit() to announce offline status //case "jabber": @@ -2679,19 +2604,28 @@ quit(immediate, variant) { // value would be nice. and we should have a delayed unavailability // automation feature here to avoid frequent relogin announcements. case "psyc": - if (variant != "_disconnect") break; + if (variant != "_disconnect") { + P3(("++SKIP psyc client %O %O. announce yourself!\n", + variant, ME)) + break; + } // fall thru in case of _disconnect // which indicates, we died an irregular death default: -# ifdef CACHE_PRESENCE - //announce(AVAILABILITY_OFFLINE, 0, ask4upd8s == 0); +# ifdef ALPHA + if (availability > AVAILABILITY_OFFLINE) { +# if 0 //def CACHE_PRESENCE + announce(AVAILABILITY_OFFLINE, 0, ask4upd8s == 0); +# else + announce(AVAILABILITY_OFFLINE); +# endif + } # else - //announce(AVAILABILITY_OFFLINE); -# endif if (availability) { announce(AVAILABILITY_OFFLINE); availability = 0; } +# endif } #endif // _flag_disable_module_presence // TODO: here we need to leave all our friends cslaves @@ -2792,8 +2726,21 @@ announce(level, manual, verbose, text) { text = text ? (MYNICK +" "+ text +".") : ""; // fun: "Reclaim your chat. Use PSYC. PSYC delivers."; } - // can this "optimization" cause async presence effects..? - if (!changed && availability == level) return 0; + if (!changed && availability == level) { + // this check ensures that we do not send "fake" announces + // for user entities which are being deallocated but + // were never actually logged in (absent friends of users) + // ... maybe this stops now that i added 'case 0:' + // + // we also get here when user objects are force quitted + // by keepUserObject() even if they were created just now + // ... see irc/server.. it's a FIXME + // + // unfortunately it seems to also affect other scenarios + P3(("++SKIP %O announce %O(%O,%O) %O changed: %d, av: %O\n", + ME, level, manual, verbose, text, changed, availability)) + return 0; + } if (level) vSet("availability", availability = level); else level = availability; // sending EXPIRED not permitted here P2(("%O announce %O(%O,%O) %O changed: %d, mood: %O\n", ME, diff --git a/world/net/place/archetype.gen b/world/net/place/archetype.gen index ee3b50e..2194cf2 100644 --- a/world/net/place/archetype.gen +++ b/world/net/place/archetype.gen @@ -935,6 +935,14 @@ private leaveMsg(ni, isError, source, mc, data, vars) { // optimize away the echo isn't really pragmatic.. TODO. // we may also simplify the context specification then, huh? // +#ifdef EXPERIMENTAL + // first send tagged echo to the person leaving + unless(isError) sendmsg(source, mc, data, vars+ ([ "_source_relay" : source ])); + // remove her from the context + remove_member(source, vars["_INTERNAL_origin"]); + // let everybody else know about the loss + unless(isError || v("_filter_presence")) castmsg(source, mc, data, vars); +#else unless(isError) { if (v("_filter_presence")) { // arent you a little heavy on the relays here? i dont get it @@ -943,6 +951,7 @@ private leaveMsg(ni, isError, source, mc, data, vars) { else castmsg(source, mc, data, vars); } remove_member(source, vars["_INTERNAL_origin"]); +#endif // it's probably safer to call this hook _after_ removing // the candidate to avoid risking loops leave(source, mc, data, vars); // hook here.. hardly ever used @@ -1521,21 +1530,13 @@ reboot(reason, restart) { // not so sure about this mc ;) "_warning_unavailable_temporary_shutdown", #else -#ifndef ECHOES "_notice_place_leave_temporary_shutdown", -#else /* ECHOES */ - "_echo_place_leave_temporary_shutdown", -#endif /* ECHOES */ #endif // used to output _source here, but when a UNI relays // the message to a UNL, the UNI is shown instead of ME "Server for [_nick_place] is being restarted: [_reason]", ([ "_reason": reason ]) ); -#ifndef ECHOES else castmsg(ME, "_notice_place_leave_shutdown", // _permanent ? -#else /* ECHOES */ - else castmsg(ME, "_echo_place_leave_shutdown", // _permanent ? -#endif /* ECHOES */ "Server for [_nick_place] is shutting down: [_reason]", ([ "_reason": reason ]) ); #ifndef PERSISTENT_MASTERS @@ -1552,11 +1553,7 @@ reboot(reason, restart) { quit() { save(); #ifndef PERSISTENT_MASTERS -#ifndef ECHOES castmsg(ME, "_notice_place_leave_temporary", -#else /* ECHOES */ - castmsg(ME, "_echo_place_leave_temporary", -#endif /* ECHOES */ "[_nick_place] is temporarily being shut down for reload.", ([ "_nick_place" : MYNICK ]) ); #endif diff --git a/world/net/psyc/user.c b/world/net/psyc/user.c index 6ff48dc..e0b3005 100644 --- a/world/net/psyc/user.c +++ b/world/net/psyc/user.c @@ -10,7 +10,7 @@ qHasCurrentPlace() { return 0; } logon() { #ifdef NO_EXTERNAL_LOGINS - return destruct(ME); + return destruct(ME); #endif // psyc users dont have their own socket, so the driver // does not call disconnected() for them - this enables the diff --git a/world/net/user.c b/world/net/user.c index e95d7fb..f18fce2 100644 --- a/world/net/user.c +++ b/world/net/user.c @@ -598,6 +598,7 @@ msg(source, mc, data, mapping vars, showingLog) { P3(("%O time %O data %O from %O\n", ME, t, data, vars)) } PSYC_TRY(mc) { +#ifndef ALPHA case "_jabber_iq_error": // DONT reply P2(("%O got %O", ME, mc)) break; @@ -610,6 +611,7 @@ case "_jabber_iq_set": sendmsg(source, "_error_unsupported_method", 0, ([ "_tag_reply" : vars["_tag"] ])); break; +#endif case "_jabber": P1(("%O got %O", ME, mc)) break; @@ -896,19 +898,27 @@ case "_status_presence": case "_notice_person_absent_netburp": if (vars["_context"] != place) return 1; break; -#if 1 case "_failure_unsuccessful_delivery": case "_failure_network_connect_invalid_port": // is this the right place to do this? i have seen a recursion where // person.c was never asked for opinion, so i'm putting this into user.c +#ifdef ALPHA + string loc; + foreach (t, loc : v("locations")) + if (vars["_source_relay"] == loc) { + P1(("%O in %O talking to its %O location at %O.", + mc, ME, t, loc)) + sLocation(t, 0); + } +#else // TODO: walk thru entire locations mapping! if (vars["_source_relay"] == v("locations")[0]) { - P0(("%O got %O, deleting 0 from %O\n", ME, - mc, v("locations"))) - m_delete(v("locations"), 0); + P0(("%O got %O, deleting 0 from %O\n", ME, + mc, v("locations"))) + m_delete(v("locations"), 0); } - // fall thru - not strictly necessary but adds a feature #endif + // fall thru - not strictly necessary but adds a feature case "_failure_redirect_permanent": // we currently have no implementation for permanent changes case "_failure_redirect_temporary": @@ -1271,7 +1281,8 @@ w(string mc, string data, mapping vars, mixed source, int showingLog) { if (!loc) { // oh.. happens on beta? P1(("%O late deletion of a %O zero location - should never happen\n", ME, type)) - m_delete(v("locations"), type); + //m_delete(v("locations"), type); + sLocation(type, 0); continue; } #endif diff --git a/world/net/usercmd.i b/world/net/usercmd.i index 6249eec..fd5e22a 100644 --- a/world/net/usercmd.i +++ b/world/net/usercmd.i @@ -1771,6 +1771,9 @@ case "_unlink": unlink(vars["_service"]); return 1; case "_exit": + // so this is some kind of ugly hack not to be used.. huh? + announce(AVAILABILITY_OFFLINE); + // fall thru case "_quit": // bye(vars["_reason"]); quit();