mirror of
https://github.com/ChronosX88/psyced.git
synced 2024-12-05 00:22:19 +00:00
multiple connections per user
This commit is contained in:
parent
ecc5bd32e6
commit
3c782db411
@ -152,7 +152,8 @@ sendmsg(target, mc, data, vars, source, showingLog, callback) {
|
||||
//
|
||||
// great, if I ping xmpp:fippo@amessage.de this makes
|
||||
// is xmpp:fippo@amessage.de/foo, but I DONT WANT THAT!
|
||||
target = t;
|
||||
if (!objectp(target) || (objectp(target) && target->vQuery("scheme") != "psyc"))
|
||||
target = t;
|
||||
}
|
||||
#endif //}}}
|
||||
#ifdef FORK //{{{
|
||||
|
@ -36,7 +36,7 @@
|
||||
#ifdef RELAY
|
||||
# define ONLINE (availability != 0)
|
||||
#else
|
||||
# define ONLINE (ME && (interactive(ME) || v("locations")[0]))
|
||||
# define ONLINE (ME && (interactive(ME) || (member(v("locations"), 0) && sizeof(v("locations")[0]))))
|
||||
#endif
|
||||
|
||||
#ifdef NO_NEWBIES
|
||||
|
@ -473,7 +473,8 @@ qDescription(source, vars, profile, itsme) {
|
||||
|
||||
qLocation(string service) {
|
||||
ASSERT("qLocation", v("locations"), v("locations"))
|
||||
return v("locations")[service];
|
||||
// which location should we return? it just returns one for now. (only used from sip/udp)
|
||||
if (member(v("locations"), service) && sizeof(v("locations")[service])) return m_indices(v("locations")[service])[0];
|
||||
}
|
||||
|
||||
// returns 0 if that was just an update. 1 on success.
|
||||
@ -485,13 +486,18 @@ sLocation(string service, mixed data) {
|
||||
// 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;
|
||||
if (member(v("locations"), service) && member(v("locations")[service], data)) return 0;
|
||||
unless (data) {
|
||||
string retval = v("locations")[service];
|
||||
//string retval = v("locations")[service];
|
||||
m_delete(v("locations"), service);
|
||||
return retval;
|
||||
return 1; //retval;
|
||||
}
|
||||
return v("locations")[service] = data;
|
||||
if (member(v("locations"), service)) {
|
||||
v("locations")[service] += ([ data ]);
|
||||
} else {
|
||||
v("locations")[service] = ([ data ]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static linkSet(service, location, source) {
|
||||
@ -501,7 +507,11 @@ static linkSet(service, location, source) {
|
||||
unless (location) location = source;
|
||||
else unless (source) unless (source = location)
|
||||
raise_error("You have to provide either source or location!\n");
|
||||
v("locations")[service] = location;
|
||||
if (member(v("locations"), service)) {
|
||||
v("locations")[service] += ([ location ]);
|
||||
} else {
|
||||
v("locations")[service] = ([ location ]);
|
||||
}
|
||||
register_location(location, ME);
|
||||
if (service) sendmsg(source, "_notice_link_service", 0,
|
||||
([ "_service" : service,
|
||||
@ -527,33 +537,44 @@ static linkSet(service, location, source) {
|
||||
// <lynX> psyced acts indeed too complicated
|
||||
// for simple clients on link when a place is set
|
||||
}
|
||||
P2(("locations after linkSet: %O\n", v("locations")))
|
||||
}
|
||||
static linkDel(service, source, variant) {
|
||||
P3(("linkDel(%O, %O, %O) called in %O!\n", service, source, variant, ME))
|
||||
string mc = "_notice_unlink";
|
||||
string candidate = v("locations")[service];
|
||||
unless (candidate) {
|
||||
service = service || 0;
|
||||
|
||||
unless (member(v("locations"), service)) {
|
||||
P3(("linkDel(%O, %O) called in %O: no such candidate!\n",
|
||||
service, source, ME));
|
||||
return 0;
|
||||
}
|
||||
P2(("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 (variant) mc += variant;
|
||||
if (service) sendmsg(source, mc, 0,
|
||||
([ "_service" : service,
|
||||
"_location_service" : candidate,
|
||||
"_identification" : v("_source") ]));
|
||||
else sendmsg(source, mc, 0,
|
||||
([ "_location" : candidate,
|
||||
"_identification" : v("_source") ]));
|
||||
return candidate;
|
||||
|
||||
int n = 0;
|
||||
foreach(string candidate : v("locations")[service]) {
|
||||
if ((objectp(source) && find_target_handler(candidate) != source) ||
|
||||
(source && !objectp(source) && candidate != source)) continue;
|
||||
P2(("linkDel(%O, %O) called in %O: unlinking %O.\n",
|
||||
service, source, ME, 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], candidate);
|
||||
unless (sizeof(v("locations")[service]))
|
||||
m_delete(v("locations"), service);
|
||||
if (variant) mc += variant;
|
||||
if (service) sendmsg(candidate, mc, 0,
|
||||
([ "_service" : service,
|
||||
"_location_service" : candidate,
|
||||
"_identification" : v("_source") ]));
|
||||
else sendmsg(candidate, mc, 0,
|
||||
([ "_location" : candidate,
|
||||
"_identification" : v("_source") ]));
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
static linkCleanUp(variant) {
|
||||
mixed type, loc;
|
||||
@ -976,21 +997,26 @@ case "_request_location":
|
||||
return 0;
|
||||
}
|
||||
if (vars["_service"] && member(v("locations"), vars["_service"])) {
|
||||
// service
|
||||
sendmsg(source, "_info_location_"+ vars["_service"],
|
||||
"[_service] has location [_location].",
|
||||
([
|
||||
"_service" : vars["_service"],
|
||||
"_tag" : vars["_tag"],
|
||||
"_location" : v("locations")[vars["_service"]],
|
||||
]));
|
||||
} else
|
||||
sendmsg(source, "_info_location", 0,
|
||||
([
|
||||
"_nick" : MYNICK,
|
||||
"_tag" : vars["_tag"],
|
||||
"_location" : v("locations")[0]
|
||||
]));
|
||||
foreach (string location : v("locations")[vars["_service"]]) {
|
||||
// service
|
||||
sendmsg(source, "_info_location_"+ vars["_service"],
|
||||
"[_service] has location [_location].",
|
||||
([
|
||||
"_service" : vars["_service"],
|
||||
"_tag" : vars["_tag"],
|
||||
"_location" : location,
|
||||
]));
|
||||
}
|
||||
} else {
|
||||
foreach (string location : v("locations")[0]) {
|
||||
sendmsg(source, "_info_location", 0,
|
||||
([
|
||||
"_nick" : MYNICK,
|
||||
"_tag" : vars["_tag"],
|
||||
"_location" : location
|
||||
]));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
case "_request_link":
|
||||
case "_set_password":
|
||||
@ -1011,14 +1037,13 @@ case "_set_password":
|
||||
// TODO? add support for integer _service means multiple
|
||||
// catch-all clients possible. do we want this?
|
||||
if (vars["_service"]) {
|
||||
linkDel(vars["_service"]);
|
||||
//linkDel(vars["_service"]);
|
||||
linkSet(vars["_service"], vars["_location"], source);
|
||||
return 0;
|
||||
}
|
||||
// this code should also run for _service, but it
|
||||
// needs a reorg
|
||||
t = v("locations")[0];
|
||||
if (t && t != source) {
|
||||
if (member(v("locations"), 0) && sizeof(v("locations")[0]) && !member(v("locations")[0], source)) {
|
||||
// alright. we have another client
|
||||
// already, or it is a ghost.
|
||||
if (!vars["_password"] && ONLINE) {
|
||||
@ -1030,7 +1055,7 @@ case "_set_password":
|
||||
}
|
||||
// we are a legitimate new client.
|
||||
// lets inform the old one
|
||||
linkDel(0, t);
|
||||
//linkDel(0, t);
|
||||
// now we leave the old client circuit
|
||||
// to die off.. let's hope that's safe
|
||||
}
|
||||
@ -1207,7 +1232,7 @@ case "_set_password":
|
||||
// _request_do_exit currently logs out clients anyway
|
||||
// don't use this:
|
||||
case "_request_exit":
|
||||
if (itsme && source == v("locations")[0]) {
|
||||
if (itsme && member(v("locations"), 0) && member(v("locations")[0], source)) {
|
||||
linkDel(0, source);
|
||||
quit();
|
||||
return 0;
|
||||
@ -1221,9 +1246,9 @@ case "_request_unlink_disconnect":
|
||||
case "_request_unlink":
|
||||
if (vars["_service"] &&
|
||||
member(v("locations"), vars["_service"])) {
|
||||
if (source == v("locations")[vars["_service"]]
|
||||
if (member(v("locations")[vars["_service"]], source)
|
||||
|| checkPassword(vars["_password"])) {
|
||||
linkDel(vars["_service"]);
|
||||
linkDel(vars["_service"], source);
|
||||
return 0;
|
||||
} else {
|
||||
// report?
|
||||
@ -1231,8 +1256,8 @@ case "_request_unlink":
|
||||
ME, mc, source, vars["_service"]))
|
||||
}
|
||||
} else if (member(v("locations"), 0)
|
||||
&& source == v("locations")[0]) {
|
||||
linkDel(0);
|
||||
&& member(v("locations")[0], source)) {
|
||||
linkDel(0, source);
|
||||
if (mc == "_request_unlink_disconnect" && !ONLINE) {
|
||||
// manually calling disconnected() .. hmmm
|
||||
disconnected();
|
||||
@ -1893,8 +1918,9 @@ case "_notice_presence_here_busy":
|
||||
// messages from here though, we do it from w().
|
||||
// the other solution would be to forward in user.c
|
||||
// then we dont have to split the switches
|
||||
t = v("locations")[0];
|
||||
if (t && t != source) {
|
||||
//P2((">>>> locations: %O\n", v("locations")))
|
||||
foreach (t : v("locations")[0]) {
|
||||
if (t && t != source) {
|
||||
// no psyctext rendering happening in this variant
|
||||
# ifdef _flag_enable_circuit_proxy_multiplexing
|
||||
vars["_target_forward"] = t;
|
||||
@ -1904,6 +1930,7 @@ case "_notice_presence_here_busy":
|
||||
// net/user:msg shouldn't work on this any further,
|
||||
// should it?
|
||||
display = 0;
|
||||
}
|
||||
}
|
||||
// here we can filter things that do not belong into the lastlog
|
||||
// but shouldn't we simply log _message's only?
|
||||
@ -2267,9 +2294,9 @@ checkAuthentication(source, vars) {
|
||||
mixed *u;
|
||||
|
||||
// we should probably foreach this too TODO
|
||||
if (v("locations")[0] == vars["_location"]) return 5;
|
||||
if (member(v("locations")[0], vars["_location"])) return 5;
|
||||
// assumes v("locations")[X] is lower_case according to policy
|
||||
if (v("locations")[0] == lower_case(vars["_location"]))
|
||||
if (member(v("locations")[0], lower_case(vars["_location"])))
|
||||
return 4;
|
||||
unless (u = parse_uniform(vars["_location"])) return -1;
|
||||
|
||||
@ -2559,8 +2586,9 @@ quit(immediate, variant) {
|
||||
|
||||
P3(("person:QUIT(%O,%O) in %O\n", immediate,variant, ME))
|
||||
// keeping services running while logging out should be possible.. but
|
||||
// we currently don't do that
|
||||
//linkDel(0);
|
||||
// we currently don't do that -- now we do
|
||||
linkDel(0, previous_object());
|
||||
#if 0
|
||||
if (sizeof(v("locations"))) { // this should only trigger at first pass
|
||||
linkCleanUp();
|
||||
#if 1 //def PARANOID
|
||||
@ -2573,6 +2601,7 @@ quit(immediate, variant) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
if (immediate == 1 || (immediate && find_call_out(#'quit) != -1)) {
|
||||
rc = save();
|
||||
if (sizeof(places)) {
|
||||
@ -2677,12 +2706,15 @@ quit(immediate, variant) {
|
||||
#endif
|
||||
logged_on = 0;
|
||||
}
|
||||
|
||||
if (immediate) {
|
||||
destruct(ME);
|
||||
} else {
|
||||
vDel("scheme");
|
||||
remove_interactive(ME);
|
||||
leaving = 0;
|
||||
// return if there are some services/clients left
|
||||
if (sizeof(v("locations"))) return rc;
|
||||
vDel("scheme");
|
||||
call_out(#'quit, 20, 1, variant);
|
||||
return rc;
|
||||
}
|
||||
|
@ -787,7 +787,7 @@ case "_status_description_place":
|
||||
switch (variant) {
|
||||
default:
|
||||
// client doesn't want HTML
|
||||
if (v("locations")[0]) sendmsg(v("locations")[0],
|
||||
if (sizeof(v("locations")[0])) sendmsg(m_indices(v("locations")[0])[0],
|
||||
mc, data, ([
|
||||
"_tag_reply": t,
|
||||
"_source_relay": source,
|
||||
@ -796,7 +796,7 @@ case "_status_description_place":
|
||||
return 1;
|
||||
case "_HTML":
|
||||
// client wants HTML
|
||||
if (v("locations")[0]) sendmsg(v("locations")[0],
|
||||
if (sizeof(v("locations")[0])) sendmsg(m_indices(v("locations")[0])[0],
|
||||
mc+"_HTML", htDescription(), ([
|
||||
"_type_data": "text/html",
|
||||
"_tag_reply": t,
|
||||
@ -916,21 +916,23 @@ 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
|
||||
#if 0 //def ALPHA
|
||||
string loc;
|
||||
foreach (t, loc : v("locations"))
|
||||
if (vars["_source_relay"] == loc) {
|
||||
foreach (t, loc : v("locations")s)
|
||||
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
|
||||
// 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);
|
||||
}
|
||||
foreach (string type, mapping locs : v("locations")) {
|
||||
if (member(locs, vars["_source_relay"])) {
|
||||
P0(("%O got %O, deleting %O from %O\n", ME, mc, vars["_source_relay"], v("locations")))
|
||||
m_delete(locs, vars["_source_relay"]);
|
||||
unless (sizeof(locs)) m_delete(v("locations"), type);
|
||||
}
|
||||
}
|
||||
P4(("locations left: %O\n", v("locations")))
|
||||
#endif
|
||||
// fall thru - not strictly necessary but adds a feature
|
||||
case "_failure_redirect_permanent":
|
||||
@ -1260,6 +1262,7 @@ pr(mc, fmt, a,b,c,d,e,f,g,h,i,j,k) {
|
||||
//
|
||||
w(string mc, string data, mapping vars, mixed source, int showingLog) {
|
||||
string template, output, type, loc;
|
||||
mapping locs;
|
||||
mapping di = printStyle(mc); // display infos
|
||||
int t;
|
||||
|
||||
@ -1286,13 +1289,13 @@ w(string mc, string data, mapping vars, mixed source, int showingLog) {
|
||||
|
||||
//PT(("%O user:w(%O,%O..%O) - %O\n", ME,mc,data,source, template))
|
||||
P4(("%O user:w locations %O\n", ME, v("locations")))
|
||||
foreach (type, loc : v("locations")) {
|
||||
foreach (type, locs : v("locations")) {
|
||||
// check uniformness of location here?
|
||||
// no! no broken location should have made it into the
|
||||
// mapping at this point. if you need to check it, check
|
||||
// it in sLocation()
|
||||
#if DEBUG > 0
|
||||
if (!loc) {
|
||||
if (!sizeof(locs)) {
|
||||
// oh.. happens on beta?
|
||||
P1(("%O late deletion of a %O zero location - should never happen\n", ME, type))
|
||||
//m_delete(v("locations"), type);
|
||||
@ -1363,25 +1366,27 @@ w(string mc, string data, mapping vars, mixed source, int showingLog) {
|
||||
#else
|
||||
# echo No LPC? Wow. Good luck!
|
||||
#endif
|
||||
foreach (loc : locs) {
|
||||
#ifdef _flag_enable_circuit_proxy_multiplexing
|
||||
// this is necessary when a single proxy is emulating
|
||||
// several clients for several users. to figure out
|
||||
// which context stuff is forwarded to which client
|
||||
// we need to add this _target_forward. this is not the
|
||||
// way psyc should operate in the long term. psyc clients
|
||||
// should be integrated into the context distribution
|
||||
// tree themselves, thus the proxy would manage a cslave
|
||||
// for them instead of accepting forwards from each UNI
|
||||
vars["_target_forward"] = loc;
|
||||
// maybe this can be avoided when no _context is set...?
|
||||
P3(("%O user:w forwarding %O to %O\n", ME, mc, vars["_target_forward"]))
|
||||
// this is necessary when a single proxy is emulating
|
||||
// several clients for several users. to figure out
|
||||
// which context stuff is forwarded to which client
|
||||
// we need to add this _target_forward. this is not the
|
||||
// way psyc should operate in the long term. psyc clients
|
||||
// should be integrated into the context distribution
|
||||
// tree themselves, thus the proxy would manage a cslave
|
||||
// for them instead of accepting forwards from each UNI
|
||||
vars["_target_forward"] = loc;
|
||||
// maybe this can be avoided when no _context is set...?
|
||||
P3(("%O user:w forwarding %O to %O\n", ME, mc, vars["_target_forward"]))
|
||||
#endif
|
||||
sendmsg(loc, mc, nudata, vars);
|
||||
// PT(("PSYCW: %s -> %O (%O)\n", mc, loc, vars))
|
||||
sendmsg(loc, mc, nudata, vars);
|
||||
// PT(("PSYCW: %s -> %O (%O)\n", mc, loc, vars))
|
||||
#if DEBUG > 1
|
||||
log_file("PSYCW", "%s(%O) %O » %O\n", mc, type,
|
||||
nudata, type && loc);
|
||||
log_file("PSYCW", "%s(%O) %O » %O\n", mc, type,
|
||||
nudata, type && loc);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1701,6 +1706,11 @@ quit(immediate, variant) {
|
||||
//
|
||||
// we also call this manually from _request_unlink_disconnect
|
||||
disconnected(remainder) {
|
||||
P2(("disconnected(%O) called in %O\nlocations: %O\n", remainder, ME, v("locations")))
|
||||
// if there are any catch-all connections left don't quit, just delete link
|
||||
if (member(v("locations"), 0) && sizeof(v("locations")[0]) > 1)
|
||||
return linkDel(0, previous_object());
|
||||
|
||||
// user did not detach his client properly. we'll make a wild guess
|
||||
// at how many messages he may have missed - enough to make the user
|
||||
// check the lastlog if that's not enough.
|
||||
|
@ -2191,8 +2191,8 @@ protected speak(a, dest, room) {
|
||||
// sayvars["_nick_long"] = v("longname");
|
||||
#ifdef VOLATILE
|
||||
// what about peer scheme, host and -port
|
||||
sayvars["_location"] = v("locations")[0] ||
|
||||
v("scheme")+"://"+v("host")+":-"+query_mud_port();
|
||||
sayvars["_location"] = (member(v("locations"), 0) && sizeof(v("locations")[0])) ?
|
||||
m_indices(v("locations")[0])[0] : v("scheme")+"://"+v("host")+":-"+query_mud_port();
|
||||
#endif
|
||||
}
|
||||
#ifndef NO_PUBLIC_QUESTIONS
|
||||
|
Loading…
Reference in New Issue
Block a user