From 4d15033c34ffc116481efa4d9c97f4433ae6e61b Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 16 Feb 2010 01:06:06 +0100 Subject: [PATCH 1/3] typofix --- world/net/user.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/world/net/user.c b/world/net/user.c index 125137b..fec9a8b 100644 --- a/world/net/user.c +++ b/world/net/user.c @@ -923,11 +923,12 @@ case "_failure_network_connect_invalid_port": // person.c was never asked for opinion, so i'm putting this into user.c #if 0 //def ALPHA string loc; - foreach (t, loc : v("locations")s) + foreach (t, loc : v("locations")) { if (member(loc, vars["_source_relay"])) { P1(("%O in %O talking to its %O location at %O.", mc, ME, t, loc)) sLocation(t, 0); + } } #else foreach (string type, mapping locs : v("locations")) { From 424bc2bf7042ccd532a24fa9b2a43220dfadacd0 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 20 Feb 2010 23:22:52 +0100 Subject: [PATCH 2/3] user channel improvements - allow arbitrary user channels to be subscribed, e.g. #follow or #friends, /sub ~user defaults to #follow - friends & /invite'd strangers are allowed to join --- world/drivers/ldmud/master/accept.c | 8 ++-- world/net/library.i | 3 +- world/net/library/legal.c | 6 +-- world/net/person.c | 22 +++++++++++ world/net/place/archetype.gen | 5 +++ world/net/place/threads.c | 17 +++++--- world/net/place/userthreads.c | 60 ++++++++++++++++++++++++++--- world/net/user.c | 2 +- 8 files changed, 103 insertions(+), 20 deletions(-) diff --git a/world/drivers/ldmud/master/accept.c b/world/drivers/ldmud/master/accept.c index 445bfec..4bf8585 100644 --- a/world/drivers/ldmud/master/accept.c +++ b/world/drivers/ldmud/master/accept.c @@ -391,10 +391,10 @@ object compile_object(string file) { unless (name = SIMUL_EFUN_FILE->legal_name(name, 1)) return (object)0; - string username; - if (sscanf(file, "place/~%s#updates", username)) { - object p; - unless ((p = SIMUL_EFUN_FILE->summon_person(username, NET_PATH "user")) && p->vQuery("password")) { + string username, channel; + if (sscanf(file, "place/~%s#%s", username, channel)) { + object p = SIMUL_EFUN_FILE->summon_person(username, NET_PATH "user"); + unless (p && !p->isNewbie()) { P3(("PLACE %O NOT CLONED: %O isn't a registered user\n", name, username)); return (object)0; } diff --git a/world/net/library.i b/world/net/library.i index 65f86f9..382ac4a 100644 --- a/world/net/library.i +++ b/world/net/library.i @@ -547,11 +547,12 @@ int boss(mixed guy) { mixed find_place(mixed a) { P3((">> find_place(%O)\n", a)) - string path, err; + string path, err, nick; object o; if (objectp(a)) return a; if (path = lower_uniform(a)) return path; + if (sscanf(a, "~%s", nick) && legal_name(nick)) a += "#follow"; unless (a = legal_name(a, 1)) return 0; path = PLACE_PATH + lower_case(a); // assumes amylaar o = find_object(path); diff --git a/world/net/library/legal.c b/world/net/library/legal.c index e54a6c2..d26c17a 100644 --- a/world/net/library/legal.c +++ b/world/net/library/legal.c @@ -27,9 +27,9 @@ varargs string legal_name(string name, int place) { return 0; } - string nick; - if (place && sscanf(name, "~%s#updates", nick)) - n = nick; + string nick, channel; + if (place && sscanf(name, "~%s#%s", nick, channel)) + return (legal_name(nick) && legal_name(channel)) ? name : 0; string chars = "\ abcdefghijklmnopqrstuvwxyz\ diff --git a/world/net/person.c b/world/net/person.c index d7ec2d6..b1bd5e4 100644 --- a/world/net/person.c +++ b/world/net/person.c @@ -655,6 +655,8 @@ sName2(a) { if (v("locations")) linkCleanUp("_crash"); else vSet("locations", ([ ])); + unless (v("channels")) vSet("channels", ([])); + // protection against file read errors if (IS_NEWBIE) { if (boss(a)) { @@ -2917,6 +2919,26 @@ static qFriends() { return present[1..]; } +qFriend(object snicker) { + P3((">> qFriend(%O)\n", snicker)) + return member(friends, snicker); +} + +qFollower(object snicker) { + P3((">> qFollower(%O)\n", snicker)) + foreach (string c : v("channels")) { + object p = find_place(c); + P3((">>> c: %O, p: %O\n", c, p)) + if (p && p->qMember(snicker)) return 1; + } + return 0; +} + +sChannel(string channel) { + P3((">> sChannel(%O)\n", channel)) + v("channels")[channel] = 1; +} + sPerson(person, ix, value) { P2(("%O: sPerson(%O, %O, %O) bfor: %O\n", MYNICK, person, ix, value, ppl)) // TODO: we need some register_context / deregister_context here diff --git a/world/net/place/archetype.gen b/world/net/place/archetype.gen index 9976a01..2fe0998 100644 --- a/world/net/place/archetype.gen +++ b/world/net/place/archetype.gen @@ -2614,3 +2614,8 @@ qAide(snicker, aidesonly) { qOwner(snicker) { return member(v("owners"), lower_case(snicker)); } #endif + +qMember(snicker) { + P3((">> qMember(%O) in _u: %O\n", snicker, _u)) + return member(_u, snicker); +} diff --git a/world/net/place/threads.c b/world/net/place/threads.c index 9a494ee..584894b 100644 --- a/world/net/place/threads.c +++ b/world/net/place/threads.c @@ -113,7 +113,7 @@ cmd(a, args, b, source, vars) { case "blog": case "submit": case "addentry": - unless (qAide(SNICKER)) return; + unless (canPost(SNICKER)) return; unless (sizeof(args) >= 1) { sendmsg(source, "_warning_usage_submit", "Usage: /submit ", ([ ])); @@ -123,7 +123,7 @@ cmd(a, args, b, source, vars) { // TODO: append fuer multiline-sachen #if 0 case "iterator": - unless (qAide(SNICKER)) return; + unless (canPost(SNICKER)) return; sendmsg(source, "_notice_thread_iterator", "[_iterator] blog entries have been requested " "since creation.", ([ @@ -135,7 +135,7 @@ cmd(a, args, b, source, vars) { #endif case "deblog": case "delentry": - unless (qAide(SNICKER)) return; + unless (canPost(SNICKER)) return; // ist das ein typecheck ob args ein int is? if (sizeof(regexp( ({ args[1] }) , "^[0-9][0-9]*$"))) { unless (delEntry(to_int(args[1]), source, vars)) { @@ -273,7 +273,8 @@ addComment(text, unick, entry_id) { "_comment" : text, "_nick" : unick, ]) ); - return save(); + save(); + return 1; } return -1; } @@ -288,7 +289,7 @@ delEntry(int number, source, vars) { unless (size = sizeof(entries)) return 0; if (number >= size) return 0; - if (qAide(unick = lower_case(SNICKER))) { + if (canPost(unick = lower_case(SNICKER))) { unless (lower_case(entries[number]["author"]) == unick) return 0; } @@ -349,7 +350,7 @@ htget(prot, query, headers, qs, data) { // return 1; } #ifdef OWNED - if (qAide(nick)) { + if (canPost(nick)) { #endif #if 0 sendmsg(target, "_request_authentication", "please auth me!", @@ -628,3 +629,7 @@ displayHeader() { displayFooter() { w("_HTML_tail_threads", ""); } + +canPost(snicker) { + return qAide(snicker); +} diff --git a/world/net/place/userthreads.c b/world/net/place/userthreads.c index b9a1c70..7a6e99b 100644 --- a/world/net/place/userthreads.c +++ b/world/net/place/userthreads.c @@ -2,14 +2,64 @@ #include #include +#define BLAME "!configuration" +#define DONT_REWRITE_NICKS + inherit NET_PATH "place/threads"; +volatile mixed lastTry; + +volatile string owner; +volatile string channel; + load(name, keep) { - P3((">> userthreads:load(%O, %O)\n", name, keep)) - string nick; + P3((">> userthreads:load(%O, %O)\n", name, keep)) - if (sscanf(name, "~%s#updates", nick)) - vSet("owners", ([ nick: 0 ])); + sscanf(name, "~%s#%s", owner, channel); + vSet("owners", ([ owner: 0 ])); - return ::load(name, keep); + vSet("_restrict_invitation", BLAME); + vSet("_filter_conversation", BLAME); + + return ::load(name, keep); +} + +enter(source, mc, data, vars) { + P3((">> userthreads:enter(%O, %O, %O, %O)\n", source, mc, data, vars)) + object p = summon_person(owner, NET_PATH "user"); + string src = psyc_name(source); + + unless (p && (p == source || qAide(src) || p->qFriend(source) || p->qFollower(source))) { + sendmsg(source, "_error_place_enter_necessary_invitation", + "[_nick_place] can only be entered upon invitation.", + ([ "_nick_place" : qName() ]) ); + if (source != lastTry) { + castmsg(ME, "_failure_place_enter_necessary_invitation", + "Admission into [_nick_place] denied for uninvited user [_nick].", + vars); + lastTry = source; + } + return 0; + } + + if (p == source) { + p->sChannel(MYNICK); + } + + return ::enter(source, mc, data, vars); +} + +cmd(a, args, b, source, vars) { + P3((">> threads:cmd(%O, %O, %O, %O, %O)", a, args, b, source, vars)) + + switch (a) { + case "add": // or similar + // add follower to this channel, TODO + } + + return ::cmd(a, args, b, source, vars); +} + +canPost(snicker) { + return qOwner(snicker); } diff --git a/world/net/user.c b/world/net/user.c index fec9a8b..1ffda0b 100644 --- a/world/net/user.c +++ b/world/net/user.c @@ -284,7 +284,7 @@ htDescription(anonymous, query, headers, qs, variant, vars) { // \n\ // - object u = find_place("~" + nick + "#updates"); + object u = find_place("~" + nick + "#follow"); //TODO string updates = objectp(u) ? u->htMain(10) : ""; return psyctext(page, vars + ([ From cde31fce59386d03e173fe4990c92f8f4d3637dc Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 20 Feb 2010 23:28:17 +0100 Subject: [PATCH 3/3] accept friendship fix - insert_member new friend & add to friends mapping - set proper user availability on both sides after friendship established --- world/net/usercmd.i | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/world/net/usercmd.i b/world/net/usercmd.i index b7d074f..9a5bd50 100644 --- a/world/net/usercmd.i +++ b/world/net/usercmd.i @@ -2422,6 +2422,12 @@ friend(rm, entity, ni, trustee) { // if (member(ppl, t)) switch(ppl[t][PPL_NOTIFY]) { switch (member(ppl, t) ? ppl[t][PPL_NOTIFY] : PPL_NOTIFY_NONE) { case PPL_NOTIFY_OFFERED: + sPerson(t, PPL_NOTIFY, PPL_NOTIFY_DEFAULT); + friends[entity, FRIEND_NICK] = ni || 1; + if (objectp(entity)) + insert_member(entity); + else + insert_member(entity, parse_uniform(entity, 1)[URoot]); // this used to imply a symmetric request for // friendship, but we prefer to make it an // informational message instead. the protocol @@ -2438,7 +2444,9 @@ friend(rm, entity, ni, trustee) { // within psyc.. even jabber should // normally auto-acknowledge this request sendmsg(entity, "_request_friendship_implied", - 0, ([ "_nick": MYNICK ]) ); + 0, ([ "_nick": MYNICK, "_degree_availability": availability ]) ); + sendmsg(entity, "_request_status_person", + 0, ([ "_nick": MYNICK ]) ); // did i just say something about symmetry? #ifdef TRY_THIS // currently friend() only gets called from @@ -2450,7 +2458,6 @@ friend(rm, entity, ni, trustee) { // carrying _presence be enough? well, we // don't have _presence yet #endif - sPerson(t, PPL_NOTIFY, PPL_NOTIFY_DEFAULT); return 1; case PPL_NOTIFY_NONE: sPerson(t, PPL_NOTIFY, PPL_NOTIFY_PENDING);