mirror of
git://git.psyced.org/git/psyced
synced 2024-08-15 03:25:10 +00:00
let the past begone in cvs land. welcome to igit igit!
This commit is contained in:
commit
4e601cf1c7
509 changed files with 77963 additions and 0 deletions
25
world/net/place/.cvsignore
Normal file
25
world/net/place/.cvsignore
Normal file
|
@ -0,0 +1,25 @@
|
|||
.cvsignore
|
||||
_hesmo.c
|
||||
_hsmo.c
|
||||
_smo.c
|
||||
_hemo.c
|
||||
_hmo.c
|
||||
_mo.c
|
||||
_heso.c
|
||||
_hso.c
|
||||
_so.c
|
||||
_heo.c
|
||||
_ho.c
|
||||
_o.c
|
||||
_hesm.c
|
||||
_hsm.c
|
||||
_sm.c
|
||||
_hem.c
|
||||
_hm.c
|
||||
_m.c
|
||||
_hes.c
|
||||
_hs.c
|
||||
_s.c
|
||||
_he.c
|
||||
_h.c
|
||||
_.c
|
5
world/net/place/_.c
Normal file
5
world/net/place/_.c
Normal file
|
@ -0,0 +1,5 @@
|
|||
// model '_' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
|
||||
#include "archetype.gen"
|
6
world/net/place/_h.c
Normal file
6
world/net/place/_h.c
Normal file
|
@ -0,0 +1,6 @@
|
|||
// model '_h' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_HISTORY
|
||||
|
||||
#include "archetype.gen"
|
7
world/net/place/_he.c
Normal file
7
world/net/place/_he.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
// model '_he' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_HISTORY_EXPORT
|
||||
|
||||
#include "archetype.gen"
|
8
world/net/place/_hem.c
Normal file
8
world/net/place/_hem.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
// model '_hem' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_HISTORY_EXPORT
|
||||
#define PLACE_MASQUERADE
|
||||
|
||||
#include "archetype.gen"
|
9
world/net/place/_hemo.c
Normal file
9
world/net/place/_hemo.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
// model '_hemo' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_HISTORY_EXPORT
|
||||
#define PLACE_MASQUERADE
|
||||
#define PLACE_OWNED
|
||||
|
||||
#include "archetype.gen"
|
8
world/net/place/_heo.c
Normal file
8
world/net/place/_heo.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
// model '_heo' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_HISTORY_EXPORT
|
||||
#define PLACE_OWNED
|
||||
|
||||
#include "archetype.gen"
|
8
world/net/place/_hes.c
Normal file
8
world/net/place/_hes.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
// model '_hes' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_HISTORY_EXPORT
|
||||
#define PLACE_SCRATCHPAD
|
||||
|
||||
#include "archetype.gen"
|
9
world/net/place/_hesm.c
Normal file
9
world/net/place/_hesm.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
// model '_hesm' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_HISTORY_EXPORT
|
||||
#define PLACE_SCRATCHPAD
|
||||
#define PLACE_MASQUERADE
|
||||
|
||||
#include "archetype.gen"
|
10
world/net/place/_hesmo.c
Normal file
10
world/net/place/_hesmo.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
// model '_hesmo' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_HISTORY_EXPORT
|
||||
#define PLACE_SCRATCHPAD
|
||||
#define PLACE_MASQUERADE
|
||||
#define PLACE_OWNED
|
||||
|
||||
#include "archetype.gen"
|
9
world/net/place/_heso.c
Normal file
9
world/net/place/_heso.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
// model '_heso' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_HISTORY_EXPORT
|
||||
#define PLACE_SCRATCHPAD
|
||||
#define PLACE_OWNED
|
||||
|
||||
#include "archetype.gen"
|
7
world/net/place/_hm.c
Normal file
7
world/net/place/_hm.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
// model '_hm' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_MASQUERADE
|
||||
|
||||
#include "archetype.gen"
|
8
world/net/place/_hmo.c
Normal file
8
world/net/place/_hmo.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
// model '_hmo' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_MASQUERADE
|
||||
#define PLACE_OWNED
|
||||
|
||||
#include "archetype.gen"
|
7
world/net/place/_ho.c
Normal file
7
world/net/place/_ho.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
// model '_ho' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_OWNED
|
||||
|
||||
#include "archetype.gen"
|
7
world/net/place/_hs.c
Normal file
7
world/net/place/_hs.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
// model '_hs' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_SCRATCHPAD
|
||||
|
||||
#include "archetype.gen"
|
8
world/net/place/_hsm.c
Normal file
8
world/net/place/_hsm.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
// model '_hsm' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_SCRATCHPAD
|
||||
#define PLACE_MASQUERADE
|
||||
|
||||
#include "archetype.gen"
|
9
world/net/place/_hsmo.c
Normal file
9
world/net/place/_hsmo.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
// model '_hsmo' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_SCRATCHPAD
|
||||
#define PLACE_MASQUERADE
|
||||
#define PLACE_OWNED
|
||||
|
||||
#include "archetype.gen"
|
8
world/net/place/_hso.c
Normal file
8
world/net/place/_hso.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
// model '_hso' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_SCRATCHPAD
|
||||
#define PLACE_OWNED
|
||||
|
||||
#include "archetype.gen"
|
6
world/net/place/_m.c
Normal file
6
world/net/place/_m.c
Normal file
|
@ -0,0 +1,6 @@
|
|||
// model '_m' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_MASQUERADE
|
||||
|
||||
#include "archetype.gen"
|
7
world/net/place/_mo.c
Normal file
7
world/net/place/_mo.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
// model '_mo' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_MASQUERADE
|
||||
#define PLACE_OWNED
|
||||
|
||||
#include "archetype.gen"
|
6
world/net/place/_o.c
Normal file
6
world/net/place/_o.c
Normal file
|
@ -0,0 +1,6 @@
|
|||
// model '_o' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_OWNED
|
||||
|
||||
#include "archetype.gen"
|
6
world/net/place/_s.c
Normal file
6
world/net/place/_s.c
Normal file
|
@ -0,0 +1,6 @@
|
|||
// model '_s' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_SCRATCHPAD
|
||||
|
||||
#include "archetype.gen"
|
7
world/net/place/_sm.c
Normal file
7
world/net/place/_sm.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
// model '_sm' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_SCRATCHPAD
|
||||
#define PLACE_MASQUERADE
|
||||
|
||||
#include "archetype.gen"
|
8
world/net/place/_smo.c
Normal file
8
world/net/place/_smo.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
// model '_smo' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_SCRATCHPAD
|
||||
#define PLACE_MASQUERADE
|
||||
#define PLACE_OWNED
|
||||
|
||||
#include "archetype.gen"
|
7
world/net/place/_so.c
Normal file
7
world/net/place/_so.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
// model '_so' generated by '/home/lynx/bin/psyconf'
|
||||
|
||||
#define ESSENTIALS
|
||||
#define PLACE_SCRATCHPAD
|
||||
#define PLACE_OWNED
|
||||
|
||||
#include "archetype.gen"
|
2558
world/net/place/archetype.gen
Normal file
2558
world/net/place/archetype.gen
Normal file
File diff suppressed because it is too large
Load diff
101
world/net/place/archetype.pl
Normal file
101
world/net/place/archetype.pl
Normal file
|
@ -0,0 +1,101 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# generator of psyced place models using combinations of archetype flags.
|
||||
# lynX 2007
|
||||
|
||||
my @opts, @predef, %map;
|
||||
open(I, "archetype.gen") or die <<X;
|
||||
|
||||
$0: Cannot open archetype.gen. Need to be in my directory!
|
||||
|
||||
X
|
||||
while (<I>) {
|
||||
if (m!define\s(\w+)\s*//\s\[(.)\]!) {
|
||||
if ($2 eq '+') {
|
||||
push @predef, $1;
|
||||
} else {
|
||||
$map{$2} = $1;
|
||||
push(@opts, $2);
|
||||
}
|
||||
} elsif (/^#endif/) {
|
||||
last;
|
||||
}
|
||||
}
|
||||
close I;
|
||||
print "Generating archetype models...\n";
|
||||
|
||||
# print join("\n", @opts), "\n\n";
|
||||
# print "$_\n" foreach ( %map );
|
||||
|
||||
open (O, ">../include/place.i") or die $!;
|
||||
print O <<X;
|
||||
// generated by '$0': place.i for place.gen
|
||||
|
||||
X
|
||||
my $file = '';
|
||||
foreach $o (@opts) {
|
||||
print O <<X;
|
||||
#ifdef $map{$o}
|
||||
# define O$o "$o"
|
||||
#else
|
||||
# define O$o ""
|
||||
#endif
|
||||
|
||||
X
|
||||
$file .= " O$o";
|
||||
}
|
||||
print O <<X;
|
||||
inherit NET_PATH "place/_"$file;
|
||||
X
|
||||
$predef = '';
|
||||
foreach $p (@predef) {
|
||||
$predef .= "#define $p\n";
|
||||
}
|
||||
|
||||
open(IG, ">.cvsignore") or print <<X;
|
||||
Warning: cannot create .cvsignore. Well, doesn't matter.
|
||||
X
|
||||
# funny how it likes to see itself in there
|
||||
print IG ".cvsignore\n";
|
||||
|
||||
my $bits = 1 + $#opts;
|
||||
for ($v = 1 << $bits; $v;) {
|
||||
$v--;
|
||||
$f = '';
|
||||
$model = '';
|
||||
|
||||
for ($i = 0; $i < $bits; $i++) {
|
||||
if ($v & 1 << $i) {
|
||||
my $o = $opts[$i];
|
||||
$f .= $o;
|
||||
$model .= "#define $map{$o}\n";
|
||||
}
|
||||
}
|
||||
|
||||
# special case: skip all exports without history
|
||||
next if $f =~ /^e/;
|
||||
# same special case is also handled in place.gen
|
||||
|
||||
printf " (%02d _%s)", $v, $f;
|
||||
#print " ($v _$f)";
|
||||
|
||||
print IG "_$f.c\n";
|
||||
open (O, ">_$f.c") or die $!;
|
||||
# proud and noisy.. for a week or two at least ;)
|
||||
#echo loading model '_$f' generated by '$0'
|
||||
print O <<X;
|
||||
// model '_$f' generated by '$0'
|
||||
|
||||
#define ESSENTIALS
|
||||
$model
|
||||
#include "archetype.gen"
|
||||
X
|
||||
# used to output $predef but it's easier to
|
||||
# have archetype.gen sort out ESSENTIALS
|
||||
close O;
|
||||
}
|
||||
close IG;
|
||||
|
||||
print "\nModel creation completed successfully.\n";
|
||||
|
||||
1; # this just so that psyconf can use it
|
4
world/net/place/basic.c
Normal file
4
world/net/place/basic.c
Normal file
|
@ -0,0 +1,4 @@
|
|||
// $Id: basic.c,v 1.356 2007/09/08 21:18:07 lynx Exp $ // vim:syntax=lpc
|
||||
|
||||
#define BASIC
|
||||
#include "archetype.gen"
|
7
world/net/place/default.c
Normal file
7
world/net/place/default.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
// $Id: default.c,v 1.2 2007/09/08 21:25:20 lynx Exp $
|
||||
//
|
||||
// the room that gets cloned when there is no specific program available.
|
||||
// don't inherit this.
|
||||
//
|
||||
#define DEFAULT
|
||||
#include "archetype.gen"
|
82
world/net/place/gamespy.c
Normal file
82
world/net/place/gamespy.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
// $Id: gamespy.c,v 1.13 2008/01/05 12:42:17 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
// gamespy gateway in a room, or something
|
||||
//
|
||||
#include <net.h>
|
||||
#include <person.h>
|
||||
#include <status.h>
|
||||
inherit NET_PATH "place/owned";
|
||||
|
||||
mapping servers;
|
||||
|
||||
void create() {
|
||||
if (!servers) servers = ([]);
|
||||
::create();
|
||||
}
|
||||
|
||||
cmd(a, args, b, source, vars) {
|
||||
// TODO: multiline-sachen irgendwie
|
||||
D2(D("===========================\n");)
|
||||
//unless (source) source = previous_object();
|
||||
switch (a) {
|
||||
case "add":
|
||||
unless (qAide(SNICKER)) return;
|
||||
if(!add(args)) {
|
||||
sendmsg(source, "_warning_usage_gamespy_add",
|
||||
"Usage: /add «gametype» «ip»:«port» [«name»]");
|
||||
} else {
|
||||
castmsg(source, "_notice_gamespy_added",
|
||||
"Successfully added [_type]-Server [_host]",
|
||||
([ "_type" : args[1],
|
||||
"_host" : args[2],
|
||||
]));
|
||||
}
|
||||
return 1;
|
||||
case "delete":
|
||||
case "del":
|
||||
|
||||
return 1;
|
||||
case "server":
|
||||
case "serverinfo":
|
||||
if(sizeof(args) < 2) {
|
||||
sendmsg(source, "_warning_usage_gamespy_info",
|
||||
"Usage: /info «ip»:«port» OR: /info «name»");
|
||||
return 1;
|
||||
} else {
|
||||
mapping info = DAEMON_PATH "gameserv"->info(args[1]);
|
||||
if(!sizeof(m_indices(info))) {
|
||||
sendmsg(source, "_error_gamespy_info",
|
||||
"I dont know that gameserver! Use /add to add it!");
|
||||
return 1;
|
||||
}
|
||||
sendmsg(source, "_notice_gamespy_info",
|
||||
"================\nhost\t[_host]:[_port]\n"
|
||||
"name\t[_name]\nmapname\t[_map]\n"
|
||||
"players\t[_players]/[_maxplayers]",
|
||||
info);
|
||||
return 1;
|
||||
}
|
||||
case "servers":
|
||||
case "listservers":
|
||||
D2(D(DAEMON_PATH "gameserv"->list_servers());)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ::cmd(a, args, b, source, vars);
|
||||
}
|
||||
|
||||
add(args) {
|
||||
array(string) host;
|
||||
if(sizeof(args) < 3)
|
||||
return 0;
|
||||
host = explode(args[2],":");
|
||||
if(sizeof(host) != 2)
|
||||
return 0;
|
||||
if(sizeof(args) >= 4) {
|
||||
DAEMON_PATH "gameserv"->add_server(args[1],host[0],to_int(host[1]),args[3]);
|
||||
} else {
|
||||
DAEMON_PATH "gameserv"->add_server(args[1],host[0],to_int(host[1]));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
71
world/net/place/junction.c
Normal file
71
world/net/place/junction.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
// $Id: junction.c,v 1.22 2008/03/28 20:05:44 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
// quick attempt at glueing up master and slave to obtain a junction
|
||||
// node in a simple tree-form multicast structure. it is more advanced
|
||||
// than irc, because each place has its own tree, but it's
|
||||
// still not as smart as a routing multicast approach.. -lynX
|
||||
|
||||
#include <net.h>
|
||||
#include <person.h>
|
||||
#include <status.h>
|
||||
|
||||
inherit NET_PATH "place/master";
|
||||
inherit NET_PATH "place/slave";
|
||||
|
||||
histClear(a, b, source, vars) { return "master"::histClear(a, b, source, vars); }
|
||||
|
||||
memberInfo(person) { return "slave"::memberInfo(person); }
|
||||
|
||||
mixed isValidRelay(mixed x) {
|
||||
return "slave"::isValidRelay(x) || "master"::isValidRelay(x); }
|
||||
|
||||
#ifndef QUIET_REMOTE_MEMBERS
|
||||
|
||||
castmsg(source, mc, data, vars) {
|
||||
if (objectp(source)
|
||||
&& (abbrev("_request_place_enter", mc)
|
||||
|| abbrev("_request_enter", mc)
|
||||
|| abbrev("_request_context", mc)
|
||||
|| abbrev("_notice_context", mc)
|
||||
|| abbrev("_notice_place_enter", mc)
|
||||
|| abbrev("_notice_place_leave", mc)
|
||||
|| abbrev("_request_leave", mc))) {
|
||||
return "slave"::castmsg(source, mc, data, vars);
|
||||
}
|
||||
|
||||
return "master"::castmsg(source, mc, data, vars);
|
||||
}
|
||||
|
||||
castPresence(source, mc, data, vars) {
|
||||
if (source == master || vars["_source_relay"] == master) {
|
||||
return "master"::castmsg(ME, mc, data
|
||||
? data
|
||||
: "[_nick] enters [_nick_place].",
|
||||
vars + (stringp(source) && is_formal(source)
|
||||
? ([]) : ([ "_source_relay" : source ])));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
msg(source, mc, data, vars) {
|
||||
P1(("junction:msg(%O, %O, %O, %O)\n", source, mc, data, vars))
|
||||
unless (source == master
|
||||
|| vars["_source_relay"] == master
|
||||
|| vars["_context"] == master
|
||||
|| mc == "_request_link") {
|
||||
return "slave"::msg(source, mc, data, vars);
|
||||
} else {
|
||||
return "master"::msg(source, mc, data, vars);
|
||||
}
|
||||
// going thru both probably results in calling "storic"::msg twice
|
||||
}
|
||||
|
||||
reboot(reason, restart, pass) {
|
||||
"master"::reboot(reason, restart, pass);
|
||||
return "slave"::reboot(reason, restart, pass);
|
||||
}
|
||||
|
||||
qJunction() {
|
||||
return 1;
|
||||
}
|
69
world/net/place/mailcast.c
Normal file
69
world/net/place/mailcast.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
// $Id: mailcast.c,v 1.7 2008/01/05 12:42:17 lynx Exp $
|
||||
|
||||
#include <net.h>
|
||||
#include <person.h>
|
||||
#include <status.h>
|
||||
|
||||
inherit NET_PATH "place/basic";
|
||||
|
||||
// noch nicht ganz klar ob das nicht einfach ein job der /history ist..
|
||||
// und wir ganz generell hin und wieder mehrfache histories brauchen
|
||||
//
|
||||
array(mapping) mails = ({ });
|
||||
//
|
||||
// wieviele mails sollen gespeichert bleiben?
|
||||
// ...waer gut, wenn man das im raumfile definieren koennt und hier bleibts..
|
||||
//
|
||||
#ifndef _limit_amount_history_mailcast
|
||||
#define _limit_amount_history_mailcast 7
|
||||
#endif
|
||||
|
||||
msg(source, mc, data, mapping vars) {
|
||||
if (abbrev("_notice_email_delivered", mc)) {
|
||||
// eine _notice_email_delivered wird im server-fenster angezeigt, nicht im raum..
|
||||
// naja, der raum ist eh nicht zum chatten da..
|
||||
// net/irc sollte das problem geschickter lösen dann..
|
||||
// und nicht hier sowas komisches da:
|
||||
castmsg(source, "_message_public_mail",
|
||||
vars["_subject"]+":\n"+vars["_content"],
|
||||
vars);
|
||||
if (sizeof(mails) >= _limit_amount_history_mailcast) {
|
||||
mails[0] = 0;
|
||||
mails -= ({ 0 });
|
||||
}
|
||||
mails += ({ ([
|
||||
"_source" : source,
|
||||
"_subject" : vars["_subject"],
|
||||
"_content" : vars["_content"]
|
||||
]) });
|
||||
save();
|
||||
return;
|
||||
}
|
||||
return ::msg(source, mc, data, vars);
|
||||
}
|
||||
|
||||
htget(prot, query, headers, qs, data, noprocess) {
|
||||
htok(prot);
|
||||
|
||||
#ifndef STYLESHEET
|
||||
# define STYLESHEET (v("_uniform_style") || "http://www.psyced.org/mail.css")
|
||||
#endif
|
||||
write("<link rel='stylesheet' type='text/css' href='"+
|
||||
STYLESHEET +"'>\n");
|
||||
|
||||
// typically use textdb here to obtain different layouts
|
||||
//
|
||||
// write("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n"
|
||||
// " <tr>\n <td>Source</td>\n <td>Subject</td>\n <td>Content</td>\n </tr>\n");
|
||||
for (int i=sizeof(mails)-1; i>=0; i--) {
|
||||
mapping mail = mails[i];
|
||||
string t = htquote(mail["_content"]);
|
||||
t = replace(t, "\n", "<br/>\n");
|
||||
|
||||
// write(" <tr>\n <td>"+ mail["_source"] +"</td>\n <td>"+ mail["_subject"] +"</td>\n <td>"+ t +"</td>\n </tr>\n");
|
||||
write("<ul>\n<li>"+ mail["_source"] +"</li>\n<li>"+ mail["_subject"] +"</li>\n<li>"+ t +"</li>\n</ul>\n");
|
||||
}
|
||||
// write("</table>");
|
||||
return 1;
|
||||
}
|
||||
|
337
world/net/place/master.c
Normal file
337
world/net/place/master.c
Normal file
|
@ -0,0 +1,337 @@
|
|||
// $Id: master.c,v 1.67 2008/01/05 12:42:17 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
// part of the PSYC multicast implementation strategy. accepts remote slave
|
||||
// rooms to link into here. the point is to not have the traffic of every
|
||||
// single user entering and leaving. if you like that, the automatic and
|
||||
// transparent group/master and slave does the job for you. these two
|
||||
// distribution systems co-exist and in fact together create a very
|
||||
// scalable multicast solution without using the "IP Multicast" protocol.
|
||||
//
|
||||
#include <net.h>
|
||||
#ifdef ORIGINAL_MASTERS
|
||||
|
||||
#include <status.h>
|
||||
#include <driver.h>
|
||||
#ifdef WE_PROBABLY_DONT_NEED_THIS
|
||||
# include <url.h>
|
||||
#endif
|
||||
|
||||
virtual inherit NET_PATH "place/storic";
|
||||
|
||||
private volatile mapping l;
|
||||
private volatile int netppl;
|
||||
|
||||
qJunction() { return 0; }
|
||||
|
||||
isLink(source) {
|
||||
P2(("isLink %O in %O: %O\n", source, l, l[source]))
|
||||
return member(l, source);
|
||||
}
|
||||
|
||||
histClear(a, b, source, vars) {
|
||||
if (b < 50) return;
|
||||
netmsg(ME, "_notice_place_history_cleared", "--", ([
|
||||
"_amount_messages" : a ]) );
|
||||
// invisible msg
|
||||
return ::histClear(a, b, source, vars);
|
||||
}
|
||||
|
||||
netsize() { return netppl+size(); }
|
||||
|
||||
save() {
|
||||
if (l) {
|
||||
vSet("links", l);
|
||||
P2(("saving links: %O\n", v("links")))
|
||||
}
|
||||
return ::save();
|
||||
}
|
||||
|
||||
reboot(reason, restart, pass) {
|
||||
if (mappingp(l)) {
|
||||
if (restart)
|
||||
netmsg(ME, "_notice_unlink_shutdown_temporary",
|
||||
"Server restart in progress. Connection to [_source] dismantled.",
|
||||
([]));
|
||||
else
|
||||
netmsg(ME, "_notice_unlink_shutdown",
|
||||
"Server shutdown in progress. Connection to [_source] dismantled.",
|
||||
([]));
|
||||
l = 0;
|
||||
}
|
||||
// would destruct junctions before slave::reboot() has been called?
|
||||
// no.. because we no longer selfdestruct in reboot
|
||||
return ::reboot(reason, restart, pass);
|
||||
}
|
||||
|
||||
load(a) {
|
||||
mixed rc;
|
||||
rc = ::load(a);
|
||||
unless(l) {
|
||||
netppl=0;
|
||||
#if 1
|
||||
// die frage lautet: wollen wir das?
|
||||
// ja, dann bleiben alle slaves up to date
|
||||
// und sollte ein temporärer dabei sein, fliegt er hiermit raus
|
||||
l = v("links");
|
||||
if (mappingp(l)) {
|
||||
P2(("reestablishing links: %O\n", l))
|
||||
netmsg(ME, "_notice_unlink_restart_complete",
|
||||
"Connection to [_source] reestablished.", ([]));
|
||||
}
|
||||
// wir lassen uns jeden link mit nem _request_link vom slave bestätigen
|
||||
// also wird "l" nach gebrauch gelöscht!
|
||||
#endif
|
||||
l = ([]);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
static eachppl(link, size) { netppl += to_int(size); }
|
||||
|
||||
msg(source, mc, data, mapping vars) {
|
||||
P2(("master:msg(%O, %O, %O, %O)\n", source, mc, data, vars))
|
||||
if (stringp(source)) {
|
||||
string relay;
|
||||
int isli = member(l, source);
|
||||
P2(("%O isli:%O source:%O links:%O\n", ME, isli, source, l))
|
||||
#if 1 // is this stuff doing something useful?
|
||||
if (!(qJunction() && stringp(vars["_source_relay"])
|
||||
&& is_formal(vars["_source_relay"]))
|
||||
&& isli && (relay = vars["_source_relay"])) {
|
||||
//if (isli && (relay = vars["_source_relay"])) {
|
||||
#if 0 //def WIR_TESTEN
|
||||
P0(("%O: source %O (%O) und relay %O (%O) vertauscht\n", ME,
|
||||
source, vars["_source"], relay, vars["_source_relay"]))
|
||||
#else
|
||||
P1(("%O: source %O und relay %O vertauscht\n", ME,
|
||||
source, relay))
|
||||
#endif
|
||||
// one day we will have to take heed who has the
|
||||
// privilege of linking us, as this is again a
|
||||
// nice chance for spoofing.. but then again if someone
|
||||
// dares to, he quickly ends up on the blacklist
|
||||
// TODO: we need to check when exactly we need that
|
||||
// or optimize on source == source_relay
|
||||
// on link level
|
||||
vars["_source_relay"] = source;
|
||||
source = relay;
|
||||
} else
|
||||
#endif
|
||||
switch(mc) {
|
||||
// should also handle _request_enter i suppose
|
||||
case "_request_link":
|
||||
// when source is an ip number we could do a 10 second
|
||||
// call_out and retry after resolving that ip number..
|
||||
// or we expect all links to resolve at psyc negotiation
|
||||
// time before getting here.. better solution..
|
||||
unless(isli) {
|
||||
// save();
|
||||
//unless (qSilent()) // || v("quiet"))
|
||||
monitor_report("_notice_link_report",
|
||||
S("%O linked by %s (%O)", ME, source, l[source]));
|
||||
// let ppl in room see what's happening..?
|
||||
// this also goes out to all links, thus serves also as echo
|
||||
// but this requires fiddling around on the linked slave whether its an
|
||||
// controlmsg... so we simply send it separately
|
||||
// reminds of _notice_place_enter* in place/basic
|
||||
// could send identification here for junctions?
|
||||
unless(v("_filter_presence"))
|
||||
castmsg(source, "_notice_link_topic",
|
||||
"Link to [_source] established. [_topic]",
|
||||
([ "_topic" : (v("topic") || "") ]) );
|
||||
sendmsg(source, "_notice_link",
|
||||
"Link to [_source] established.", ([
|
||||
"_topic" : v("topic") || "",
|
||||
// "_filter_conversation" : v("_filter_conversation"),
|
||||
"_filter_presence" : v("_filter_presence")
|
||||
]));
|
||||
} else {
|
||||
P1(("%O link update: %s in %s\n", ME,l[source],source))
|
||||
}
|
||||
l[source] = vars["_amount_members"];
|
||||
unless(isli) save();
|
||||
// netppl=0; walk_mapping(l, "eachppl", ME);
|
||||
return 1;
|
||||
case "_error_rejected_message_membership":
|
||||
// TODO: the place does not remember us...
|
||||
// maybe it does not want to get our news.
|
||||
// treat it like an unlink?
|
||||
case "_request_unlink":
|
||||
if (member (l, source)) {
|
||||
P1(("%O unlinked by %s (%O)\n", ME,source,l[source]))
|
||||
m_delete(l, source);
|
||||
save();
|
||||
sendmsg(source, "_notice_unlink",
|
||||
"Link to [_source] dropped.");
|
||||
} else
|
||||
D(S("%O got unexpected unlink from %s (%O)\n",
|
||||
ME, source, vars));
|
||||
netppl=0; walk_mapping(l, "eachppl", ME);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WE_PROBABLY_DONT_NEED_THIS
|
||||
if (stringp(source)) {
|
||||
string host;
|
||||
|
||||
host = parse_uniform(source, 1)[UHost];
|
||||
|
||||
unless (chost(host)) {
|
||||
dns_resolve(host,
|
||||
(:
|
||||
register_host($6, $1);
|
||||
|
||||
if ($1 != -1) {
|
||||
::msg($2, $3, $4, $5);
|
||||
debug_message(sprintf("MASTER: %O resolves to %O\n", $6, $1));
|
||||
} else {
|
||||
debug_message(sprintf("MASTER: %O does not resolve. ignoring. (closure).\n", $6));
|
||||
}
|
||||
return; :), source, mc, data, vars, host);
|
||||
return;
|
||||
} else if (chost(host) == -1) {
|
||||
P1(("MASTER: %O does not resolve. ignoring.\n", host))
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ::msg(source, mc, data, vars);
|
||||
}
|
||||
|
||||
volatile string lastlink;
|
||||
|
||||
localmsg(source, mc, data, mapping vars) {
|
||||
if (mappingp(vars)) {
|
||||
m_delete(vars, "_amount_members");
|
||||
m_delete(vars, "_amount_servers");
|
||||
} else vars = ([]);
|
||||
::castmsg(source, mc, data, vars);
|
||||
}
|
||||
|
||||
#if 1
|
||||
static eachlink(link, size, source, mc, data, vars) {
|
||||
// we don't send to empty slaves..
|
||||
// but for now we let them stay linked
|
||||
// we could as well delete them.. hmm TODO
|
||||
// and what about keeping history, topic and
|
||||
// other control information in sync?
|
||||
// okay.. it's not that simple
|
||||
//unless (size) return;
|
||||
|
||||
unless (sendmsg(link, mc, data, vars, source)) {
|
||||
// when send_udp fails, we get to know this at the *next* attempt
|
||||
// to send a message. at least that's what the linux kernel seems to do
|
||||
// most important thing, if it happens we need to resend the packet!
|
||||
//P0(("%O: transmission damaged to %s (%O)\n", ME, link, size))
|
||||
monitor_report("_failure_damaged_transmission", S("%O: transmission damaged to %s (%O)", ME, link, size));
|
||||
unless (sendmsg(link, mc, data, vars, source)) {
|
||||
D2( D("ERROR! resend failed a priori. this shouldn't happen.\n"); )
|
||||
// if we got here, then we are probably not running linux
|
||||
// let's assume this link is really broken and remove it
|
||||
m_delete(l, link);
|
||||
} else if (lastlink) {
|
||||
// resend was successful, supposedly, or it didnt generate an immediate error
|
||||
// so we can look into deleting the link that actually caused the problem
|
||||
// on linux that's the one we sent something to *before*
|
||||
|
||||
if (l[lastlink]) {
|
||||
l[lastlink] = 0; // give it one more try
|
||||
} else {
|
||||
P0(("transmission damaged to %s, removed probable cause of trouble: %s\n", link, lastlink))
|
||||
m_delete(l, lastlink);
|
||||
}
|
||||
}
|
||||
}
|
||||
lastlink = link;
|
||||
}
|
||||
#endif
|
||||
|
||||
netmsg(source, mc, data, mapping vars) {
|
||||
mapping myv;
|
||||
|
||||
#if 0 //def DRIVER_HAS_INLINE_CLOSURES
|
||||
vars["_amount_members"] = netppl+size();
|
||||
vars["_amount_servers"] = 1+sizeof(l);
|
||||
walk_mapping(l, (: sendmsg($1, $3,$4,$5,$6) :),
|
||||
mc,data,vars,source );
|
||||
D("using closure\n");
|
||||
#else
|
||||
|
||||
#ifdef QUIET_REMOTE_MEMBERS
|
||||
if (abbrev("_notice_place_enter", mc)) return;
|
||||
if (abbrev("_notice_place_leave", mc)) return;
|
||||
#endif
|
||||
|
||||
myv = vars + ([
|
||||
"_amount_members": netppl+size(),
|
||||
"_amount_servers": 1+sizeof(l),
|
||||
]);
|
||||
lastlink = 0;
|
||||
// here you can see some pre-foreach LPC code :)
|
||||
walk_mapping(l, #'eachlink, source, mc, data, myv);
|
||||
#endif
|
||||
}
|
||||
|
||||
castmsg(source, mc, data, mapping vars) {
|
||||
// TODO: psyc 1.1 / context oriented thingies will want to set
|
||||
// context for the delivery to the slaves
|
||||
// WHAT about junctions? will they set themselves as context
|
||||
// aswell?
|
||||
if (l) {
|
||||
P2(("master:castmsg(%O,%O) w/_context %O and _nick_place %O\n",
|
||||
source, mc, vars["_context"], vars["_nick_place"]))
|
||||
// why is this necessary here again?
|
||||
// and shouldn't it be the identification rather than ME?
|
||||
vars["_context"] = ME;
|
||||
// this one's even worse
|
||||
vars["_nick_place"] = MYNICK;
|
||||
netmsg(source, mc, data, vars);
|
||||
}
|
||||
localmsg(source, mc, data, vars);
|
||||
}
|
||||
|
||||
memberInfo(person) {
|
||||
if (netppl) {
|
||||
unless (person) person = previous_object();
|
||||
sendmsg(person, "_status_place_net_members_amount",
|
||||
"[_nick_place] contains [_amount_members] people \
|
||||
on [_amount_servers] servers.", ([
|
||||
"_nick_place": MYNICK,
|
||||
"_amount_members": netppl+size(),
|
||||
"_amount_servers": 1+sizeof(l),
|
||||
]) );
|
||||
// return 0;
|
||||
}
|
||||
return ::memberInfo(person);
|
||||
}
|
||||
|
||||
#if 0
|
||||
showStatus(person, al, mc, data, vars) {
|
||||
::showStatus(person, al, mc, data, vars);
|
||||
if (l && al) walk_mapping(l, "eachstatus", ME, person);
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
cmd(a, args, b, source, vars) {
|
||||
if (b) switch(a) {
|
||||
case "links":
|
||||
case "li":
|
||||
if (sizeof(args) > 1) return 0;
|
||||
if (l) walk_mapping(l, "eachstatus", ME, source);
|
||||
return 1;
|
||||
}
|
||||
return ::cmd(a, args, b, source, vars);
|
||||
}
|
||||
#endif
|
||||
static eachstatus(link, size, person) {
|
||||
sendmsg(person, "_status_place_link_slave",
|
||||
"Link [_link] has [_amount_members] members.",
|
||||
([ "_link": link, "_amount_members": size ]) );
|
||||
}
|
||||
|
||||
mixed isValidRelay(mixed x) { return x == ME || member(l, x); }
|
||||
|
||||
#else
|
||||
# include "storic.c"
|
||||
#endif
|
217
world/net/place/news.c
Normal file
217
world/net/place/news.c
Normal file
|
@ -0,0 +1,217 @@
|
|||
// $Id: news.c,v 1.99 2008/02/09 15:15:41 lynx Exp $ // vim:syntax=lpc
|
||||
/*
|
||||
* a place that polls an RSS / RDF xml page that
|
||||
* contains "news" from sites like slashdot, heise.de, etc
|
||||
* for a compilation of available RSS feeds take a look at
|
||||
* http://www.webreference.com/services/news/
|
||||
*
|
||||
* technical information on RSS:
|
||||
* http://docs.kde.org/en/3.1/kdenetwork/knewsticker/introduction.html#rssfiles
|
||||
*
|
||||
* TODO: check version tag and parse according to that
|
||||
*
|
||||
* Examples for qNewsfeed()
|
||||
* "http://www.heise.de/newsticker/heise.rdf"
|
||||
* "http://slashdot.org/slashdot.rss"
|
||||
*
|
||||
* Cool feeds:
|
||||
* "http://www.webreference.com/services/news/index.html"
|
||||
*/
|
||||
|
||||
#include <net.h>
|
||||
#include <status.h>
|
||||
#include <storage.h>
|
||||
#include <xml.h>
|
||||
#include <text.h> // NO_INHERIT, but virtual takes care of that
|
||||
|
||||
inherit NET_PATH "place/master";
|
||||
inherit NET_PATH "xml/parse";
|
||||
|
||||
protected mapping _news; // ein wenig mehr ordnung im .o file
|
||||
protected mapping known; // links of known news
|
||||
volatile object feed;
|
||||
volatile string prefix, modificationtime2;
|
||||
|
||||
handleNews(buffer);
|
||||
|
||||
// always show amount, never names.
|
||||
makeMembers() { return ::makeMembers(1); }
|
||||
|
||||
publish(link, headline, channel) {
|
||||
#if 1
|
||||
// this is specific to shortnews.de who do a little privacy
|
||||
// intrusion by tagging their rss feeds with personalized "u_id"
|
||||
int uid = strstr(link, "&u_id");
|
||||
if (uid != -1) link = link[0 .. uid-1];
|
||||
#endif
|
||||
PT(("%O publish %O\n", ME, link))
|
||||
// this could move out into a NEWS_PUBLISH() for torrents
|
||||
if (trail(".torrent", link))
|
||||
castmsg(ME, "_notice_offered_file_torrent",
|
||||
"([_nick_place]) [_file_title] [_uniform_torrent]",
|
||||
([ "_file_title": headline,
|
||||
"_uniform_torrent": link,
|
||||
"_channel_title": channel ])
|
||||
);
|
||||
else castmsg(ME, "_notice_headline_news",
|
||||
"([_nick_place]News) [_headline] [_page_news]",
|
||||
([ "_headline": headline,
|
||||
"_page_news": link,
|
||||
"_channel": channel ])
|
||||
);
|
||||
}
|
||||
|
||||
connect() {
|
||||
unless (feed) {
|
||||
feed = qNewsfeed() -> load();
|
||||
feed -> sAgent(SERVER_VERSION " builtin RSS to PSYC gateway - We'd prefer you to push your news in realtime instead of having us poll for it! See http://about.psyc.eu/Newscasting about that.");
|
||||
feed->content(#'handleNews, 1);
|
||||
} else {
|
||||
feed->refetch(#'handleNews);
|
||||
}
|
||||
}
|
||||
|
||||
handleNews(buffer) {
|
||||
// called when connection is closed
|
||||
// put your logic here
|
||||
int i;
|
||||
mapping new, diff, items;
|
||||
string href;
|
||||
XMLNode item;
|
||||
prefix = "";
|
||||
// D2(D("strlen(buffer) = " + strlen(buffer) + "\n");)
|
||||
|
||||
if (intp(_news = xmlparse(buffer))) {
|
||||
P0(("%O could not parse %O\n", ME, qNewsfeed()))
|
||||
return;
|
||||
}
|
||||
|
||||
unless(v("channel")) {
|
||||
XMLNode c;
|
||||
|
||||
// net/place/news.c:67: (s)printf(): BUFF_SIZE overflowed...
|
||||
// program: net/place/news.c, object: place/gmaps line 67
|
||||
// _news is too big to debug this way! :(
|
||||
P4(("%O got _news %O\n", ME, _news))
|
||||
if (c = _news["/channel"]) {
|
||||
vSet("channel", ([ "title" : c["/title"][Cdata],
|
||||
"link" : c["/link"][Cdata],
|
||||
"description" : c["/description"][Cdata] ]));
|
||||
}
|
||||
else {
|
||||
P0(("%O cannot find channel data in %O\n", ME, qNewsfeed()))
|
||||
return;
|
||||
}
|
||||
}
|
||||
// compare and see if there is new data
|
||||
new = ([ ]);
|
||||
items = ([ ]);
|
||||
unless(known) known = ([ ]);
|
||||
P2(("known: %O\n", known))
|
||||
foreach(item : (_news["/item"] || _news["/channel"]["/item"])) {
|
||||
// breaks here sometimes, but then the RSS must be stupid
|
||||
href = item["/link"][Cdata];
|
||||
new[href] = 1;
|
||||
items[href] = item;
|
||||
}
|
||||
foreach(href : new) {
|
||||
unless(known[href]) {
|
||||
string l = items[href]["/link"][Cdata];
|
||||
string t = items[href]["/title"][Cdata];
|
||||
|
||||
if (strlen(l) > 5 && stringp(t))
|
||||
publish(l, replace(t, "\n", " "), v("channel")["title"]);
|
||||
else {
|
||||
PT(("%O encountered funny link %O or title %O\n",
|
||||
ME, l, t))
|
||||
}
|
||||
}
|
||||
}
|
||||
known = new;
|
||||
save(); // to be discussed if we really need this
|
||||
}
|
||||
|
||||
showStatus(verbosity, al, person, mc, data, vars) {
|
||||
if (mappingp(_news) && verbosity & VERBOSITY_NEWSFEED && _news[prefix + "_title"])
|
||||
sendmsg(person, "_status_place_description_news_rss",
|
||||
"RSS Newsfeed for [_news_channel_title]: \"[_news_channel_description]\"\n"
|
||||
"Available from [_link_news_rss]."
|
||||
" Last check: [_time_fetch]. Last change: [_time_modification]", ([
|
||||
"_news_channel_title" : v("channel")["_title"],
|
||||
"_news_channel_description" : v("channel")["_description"],
|
||||
"_time_modification" : feed->qHeader("modificationtime") || modificationtime2,
|
||||
"_time_fetch" : feed->qHeader("_fetchtime"),
|
||||
"_link_news_rss" : qNewsfeed()
|
||||
]) );
|
||||
return ::showStatus(verbosity, al, person, mc, data, vars);
|
||||
}
|
||||
|
||||
// overrides mayLog in storic.c
|
||||
mayLog(mc) {
|
||||
return abbrev("_notice_headline", mc) ||
|
||||
mc == "_notice_offered_file_torrent";
|
||||
}
|
||||
|
||||
//#if 0
|
||||
cmd(a, args, b, source, vars) {
|
||||
switch (a) {
|
||||
case "news":
|
||||
connect();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ::cmd(a, args, b, source, vars);
|
||||
}
|
||||
//#endif
|
||||
|
||||
msg(source, mc, data, vars) {
|
||||
// receive pings from blogs etc.
|
||||
if (abbrev("_notice_update", mc)) {
|
||||
// mixed *u;
|
||||
//
|
||||
// unless(vars["_location_feed"]) return;
|
||||
// u = parse_uniform(vars["_location_feed"]);
|
||||
if(qAllowExternal(source, mc, vars))
|
||||
connect();
|
||||
// would be better if the blog delivered the whole story
|
||||
// then we wouldn't even need a "news" room for this
|
||||
return;
|
||||
}
|
||||
return ::msg(source, mc, data, vars);
|
||||
}
|
||||
|
||||
// new: receive and process http://www.xmlrpc.com/weblogsCom pings
|
||||
//
|
||||
// the bad news about pings: they contain 0 information other than
|
||||
// some unspecified event happened.
|
||||
// the good news about pings: they aren't worthy of parsing them
|
||||
htpost(prot, query, headers, qs, data, noprocess) {
|
||||
if (headers["content-type"] == "text/xml") {
|
||||
string s, t;
|
||||
|
||||
// parses both unworthy trashy formats:
|
||||
if (stringp(data)) sscanf(data, "%s>http://%s</%s", t, s, t);
|
||||
htok(prot);
|
||||
if (stringp(data) && strstr(data, "SOAP-ENV") != -1) {
|
||||
//sscanf(data, "%s>http://%s</weblogurl>%s", t, s, t);
|
||||
write(T("_XML_RPC_weblog_pong_SOAP", 0));
|
||||
} else {
|
||||
//sscanf(data, "%s<value>http://%s</value>%s", t, s, t);
|
||||
write(T("_XML_RPC_weblog_pong", 0));
|
||||
}
|
||||
// now check the credentials and do the update
|
||||
unless (same_host(query_ip_number(), qNewsfeed()->qHost())) {
|
||||
P0(("%O got unsolicited XML from %O promoting %O\n",
|
||||
ME, query_ip_name(), s || data))
|
||||
return 1;
|
||||
}
|
||||
P0(("%O got XML from %O promoting %O\n",
|
||||
ME, query_ip_name(), s || data))
|
||||
connect();
|
||||
// not disabling reset yet. TODO
|
||||
return 1;
|
||||
}
|
||||
P0(("%O got htpost from %O containing %O\n", ME, query_ip_name(), data))
|
||||
//return ::htpost(prot, query, headers, qs, data, noprocess);
|
||||
}
|
||||
|
18
world/net/place/owned.c
Normal file
18
world/net/place/owned.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
// $Id: owned.c,v 1.101 2007/09/08 21:25:20 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
// a room that has an owner and friends to help him
|
||||
// traditional psycmuve set-up, just in case old place code uses it
|
||||
// don't use this for new code
|
||||
//
|
||||
#define BASIC
|
||||
|
||||
#define PLACE_FILTERS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_HISTORY_EXPORT
|
||||
#define PLACE_SCRATCHPAD
|
||||
#define PLACE_LOGGING
|
||||
#define PLACE_OWNED
|
||||
#define PLACE_STORE_COMMAND
|
||||
#define PLACE_STYLE_COMMAND
|
||||
|
||||
#include "archetype.gen"
|
7
world/net/place/public.c
Normal file
7
world/net/place/public.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
// $Id: public.c,v 1.30 2008/03/29 17:25:35 lynx Exp $ // vim:syntax=lpc
|
||||
#include <net.h>
|
||||
|
||||
#define BASIC
|
||||
#define PLACE_FILTERS
|
||||
#define PLACE_LOGGING
|
||||
#include "archetype.gen"
|
276
world/net/place/slave.c
Normal file
276
world/net/place/slave.c
Normal file
|
@ -0,0 +1,276 @@
|
|||
// $Id: slave.c,v 1.64 2008/03/28 20:05:44 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
#define TIME_UPDATE_MINWAIT 33 // 33 seconds
|
||||
|
||||
#include <net.h>
|
||||
#include <status.h>
|
||||
|
||||
virtual inherit NET_PATH "place/storic";
|
||||
|
||||
protected volatile string master, mastertrail;
|
||||
protected volatile int members, servers;
|
||||
private volatile int lastup;
|
||||
|
||||
histClear(a, b, source, vars) { if (b > 49) return ::histClear(a, b, source, vars); }
|
||||
|
||||
// the flag allows forced update and avoids call_out loops
|
||||
#define UPDATE_NOW 0
|
||||
#define UPDATE_SOON 1
|
||||
#define UPDATE_REMINDER 2
|
||||
|
||||
qJunction() { return 0; }
|
||||
|
||||
update(flag) {
|
||||
int t;
|
||||
unless(master) return;
|
||||
t = time() - lastup;
|
||||
P2(("update(%O) - %O to go.\n", flag, TIME_UPDATE_MINWAIT - t))
|
||||
|
||||
if (flag == UPDATE_NOW || t > TIME_UPDATE_MINWAIT) {
|
||||
lastup = time();
|
||||
sendmsg(master, "_request_link", 0,
|
||||
([ "_amount_members": to_string(size()) ]) );
|
||||
} else if (flag == UPDATE_SOON)
|
||||
call_out(#'update, TIME_UPDATE_MINWAIT+1-t, UPDATE_REMINDER);
|
||||
}
|
||||
|
||||
void create() {
|
||||
lastup = time(); // delay linkup by 7 seconds (see below)
|
||||
::create();
|
||||
}
|
||||
|
||||
#if 0
|
||||
void reset(int again) {
|
||||
if (again) update(UPDATE_SOON); // just in case..
|
||||
else lastup = time(); // delay linkup by 7 seconds (see below)
|
||||
return ::reset(again);
|
||||
}
|
||||
#endif
|
||||
|
||||
sIdentification(it) {
|
||||
identification = it;
|
||||
}
|
||||
|
||||
sMaster(link, modflag) {
|
||||
unless (abbrev("psyc:", link))
|
||||
link = "psyc://"+ link +"/"+ psycName();
|
||||
mastertrail = master = lower_case(link); // lower_case UNI policy
|
||||
identification = link;
|
||||
set_context(ME, link);
|
||||
// some kinda kludge until the psyc layer gives us the true UNI
|
||||
// if (abbrev("psyc://ve.", master)) mastertrail = master[10..];
|
||||
// P2(("mastertrail = %O\n", mastertrail))
|
||||
//call_out(#'update, 7, UPDATE_NOW);
|
||||
update(UPDATE_NOW);
|
||||
}
|
||||
|
||||
mixed isValidRelay(mixed x) { return x == master || x == ME; }
|
||||
|
||||
msg(source, mc, data, vars) {
|
||||
P2(("slave:msg(%O, %O, %O, %O)\n", source, mc, data, vars))
|
||||
// if (vars["_context"]) return -1; // may not happen
|
||||
// status update from master / identification
|
||||
if (master && source == master ||
|
||||
identification && source == identification) {
|
||||
/* a message from our master / identification to us
|
||||
* usually a status update or some other kind of control msg
|
||||
* this control msg logic has moved around, but hasn't changed
|
||||
*/
|
||||
switch(mc) {
|
||||
case "_notice_place_topic":
|
||||
vSet("topic-user", vars["_nick"]);
|
||||
// fall thru
|
||||
case "_notice_place_topic_official":
|
||||
vSet("topic", vars["_topic"]);
|
||||
break;
|
||||
case "_notice_place_topic_removed":
|
||||
vSet("topic-user", vars["_nick"]);
|
||||
break;
|
||||
case "_notice_link_topic":
|
||||
vSet("topic", vars["_topic"]);
|
||||
// fall thru
|
||||
case "_notice_link":
|
||||
if (vars["_filter_presence"] &&
|
||||
to_int(vars["_filter_presence"]) != 0)
|
||||
vSet("_filter_presence", source);
|
||||
else
|
||||
vDel("_filter_presence");
|
||||
//m_delete(vars, "_filter_presence");
|
||||
break;
|
||||
case "_notice_place_topic_removed_official":
|
||||
vDel("topic");
|
||||
break;
|
||||
case "_error_necessary_link_place":
|
||||
case "_error_rejected_message_membership":
|
||||
// add protection from loops?
|
||||
castmsg(ME, "_warning_place_link_lost",
|
||||
"Master link [_master] has forgotten about us. Hold on.",
|
||||
([ "_master" : master ]) );
|
||||
// fall thru
|
||||
case "_notice_unlink_restart":
|
||||
case "_notice_unlink_restart_complete":
|
||||
// update (UPDATE_NOW);
|
||||
update (UPDATE_SOON);
|
||||
return 1;
|
||||
case "_notice_place_history_cleared":
|
||||
::histClear(vars["_amount_messages"], 60, source, vars);
|
||||
return 1;
|
||||
case "_status_place_filter_presence":
|
||||
if (vars["_filter_presence"] &&
|
||||
to_int(vars["_filter_presence"]) != 0)
|
||||
vSet("_filter_presence", source);
|
||||
else
|
||||
vDel("_filter_presence");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (abbrev("_notice_place_enter", mc)) {
|
||||
// master notifies us that _source_relay was allowed
|
||||
// to enter - kind of fake
|
||||
string relay = vars["_source_relay"];
|
||||
m_delete(vars, "_source_relay");
|
||||
vars["_nick_place"] = MYNICK;
|
||||
return ::msg(relay, mc, data, vars);
|
||||
}
|
||||
if (abbrev("_notice_place_leave", mc)) {
|
||||
string relay = vars["_source_relay"];
|
||||
m_delete(vars, "_source_relay");
|
||||
vars["_nick_place"] = MYNICK;
|
||||
return ::msg(relay, mc, data, vars);
|
||||
}
|
||||
return castmsg(source, mc, data, vars);
|
||||
}
|
||||
// someone is sending a message via us.
|
||||
// we may send it to the master and if we dont return will pass
|
||||
// it on to local msg()
|
||||
// TODO: need to do some kind of checks if we want to forward
|
||||
// sth for the sender
|
||||
if ((!vars["_context"] // should not happen, but...
|
||||
// things not to forward
|
||||
&& !(abbrev("_request_leave", mc)
|
||||
|| abbrev("_request_context_leave", mc))
|
||||
// things we want to forward
|
||||
||abbrev("_message", mc)
|
||||
|| !v("_filter_presence") && (abbrev("_request_enter", mc)
|
||||
|| abbrev("_request_context_enter", mc))
|
||||
)
|
||||
) { // source != master implied above
|
||||
|
||||
// we let upstream handle it
|
||||
// TODO: we _must_ be linked to do this
|
||||
// looks like a job for the notorious queue
|
||||
//
|
||||
// otherwise a slave may send an _request_enter to
|
||||
// the master which is silent and should therefore
|
||||
// drop the packet.
|
||||
// and the user is left alone
|
||||
// the master could catch such behaviour... but...
|
||||
// complicates things and is more harmful than useful
|
||||
//
|
||||
// hrmpf. IMHO we should send it via master, if
|
||||
// this does not work then debug it!
|
||||
// hey, its lynX who told me to do that :)
|
||||
#if 0
|
||||
sendmsg(master, mc, data, vars + ([
|
||||
"_location": query_ip_name(source),
|
||||
"_source_relay": ME,
|
||||
]), source);
|
||||
#else
|
||||
sendmsg(identification, mc, data, vars + ([
|
||||
// what about peer scheme, host and -port
|
||||
// ah, did just that in usercmd sayvars
|
||||
"_location": objectp(source) ?
|
||||
query_ip_name(source) : source,
|
||||
"_source_relay": vars["_source_relay"] || source
|
||||
]));
|
||||
#endif
|
||||
// if (abbrev("_message", mc)) return 1;
|
||||
return 1;
|
||||
#if 0 // wo war der Sinn von dem Code?
|
||||
D3(else D(S("slave:msg from %O master %O, mastertrail %O\n",
|
||||
source, master, mastertrail));)
|
||||
if (source == master || (vars["_source"] == master &&
|
||||
stringp(source) && trail(mastertrail, source))) {
|
||||
string relay = vars["_source_relay"];
|
||||
|
||||
// if this were psyc 1.1, we wouldnt receive messages
|
||||
// relayed, but have proper _context. i guess we want
|
||||
// to implement both forms and maybe one day disallow
|
||||
// one or the other on a per-room basis.
|
||||
if (relay) {
|
||||
// dieser teil war auskommentiert..
|
||||
// was will mir das sagen? ich werde bugs auslösen?
|
||||
// jopp
|
||||
// vars["_source_relay"] = master;
|
||||
// master could spoof local objects
|
||||
// source = psyc_object(relay) || relay;
|
||||
// geht das? hu?
|
||||
vars["_source_relay"] = vars["_source"];
|
||||
P2(("slave:msg(%O,%O,%O) relay=%O\n",
|
||||
source, mc, data, relay))
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// hm... can we simply do that?
|
||||
return ::msg(source, mc, data, vars);
|
||||
}
|
||||
|
||||
castmsg(source, mc, data, vars) {
|
||||
P2(("slave:castmsg(%O, %O, %O, %O)\n",
|
||||
source, mc, data, vars))
|
||||
|
||||
if (member(vars, "_amount_members")) {
|
||||
members = to_int(vars["_amount_members"]);
|
||||
m_delete(vars, "_amount_members");
|
||||
}
|
||||
if (member(vars, "_amount_servers")) {
|
||||
servers = to_int(vars["_amount_servers"]);
|
||||
m_delete(vars, "_amount_servers");
|
||||
}
|
||||
::castmsg(source, mc, data, vars);
|
||||
}
|
||||
|
||||
enter(source,mc,data,vars) {
|
||||
update (UPDATE_SOON);
|
||||
return ::enter(source,mc,data,vars);
|
||||
}
|
||||
leave(source,mc,data,vars) {
|
||||
update (UPDATE_SOON);
|
||||
return ::leave(source,mc,data,vars);
|
||||
}
|
||||
|
||||
memberInfo(person) {
|
||||
unless (members && servers) return ::memberInfo(person);
|
||||
unless (person) person = previous_object();
|
||||
|
||||
sendmsg(person, "_status_place_net_members_amount",
|
||||
"[_nick_place] contains [_amount_members] people \
|
||||
on [_amount_servers] servers.", ([
|
||||
"_nick_place": MYNICK,
|
||||
"_amount_members": members,
|
||||
"_amount_servers": servers,
|
||||
]) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
showStatus(verbosity, al, source, mc, data, vars) {
|
||||
if (members && master) {
|
||||
sendmsg(source, "_status_place_link",
|
||||
"Network link to [_link] active.",
|
||||
([ "_link": master ]) );
|
||||
}
|
||||
return ::showStatus(verbosity, al, source, mc, data, vars);
|
||||
}
|
||||
|
||||
qAllowExternal(source, mc) {
|
||||
if (source == master) return 1;
|
||||
}
|
||||
|
||||
reboot(reason, restart, pass) {
|
||||
if (master) {
|
||||
sendmsg(master, "_request_unlink");
|
||||
master = 0;
|
||||
}
|
||||
return ::reboot(reason, restart, pass);
|
||||
}
|
14
world/net/place/standard.c
Normal file
14
world/net/place/standard.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
// $Id: standard.c,v 1.52 2007/09/08 21:25:20 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
// the room that used to get cloned when there is no specific program available.
|
||||
// it has no owners and it is private by default.
|
||||
//
|
||||
// this is no longer the default place code. it is kept here in case you
|
||||
// need to go back to the old style. don't inherit this.
|
||||
|
||||
#define BASIC
|
||||
#define PLACE_MASQUERADE
|
||||
#define PLACE_MASQUERADE_COMMAND
|
||||
#define PLACE_PUBLIC_COMMAND
|
||||
//#define PLACE_STORE_COMMAND
|
||||
#include "archetype.gen"
|
16
world/net/place/storic.c
Normal file
16
world/net/place/storic.c
Normal file
|
@ -0,0 +1,16 @@
|
|||
// $Id: storic.c,v 1.102 2007/09/08 21:25:20 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
// dont ask what "storic" is supposed to mean..
|
||||
// it's a room object that keeps a lastlog, a history of the last messages
|
||||
//
|
||||
// this is the old storic implementation, used in inheritance chains.
|
||||
// some old code may need it, but don't write new code on top of this.
|
||||
|
||||
#define BASIC
|
||||
|
||||
#define PLACE_FILTERS
|
||||
#define PLACE_HISTORY
|
||||
#define PLACE_HISTORY_EXPORT
|
||||
#define PLACE_LOGGING
|
||||
#define PLACE_STORE_COMMAND
|
||||
#include "archetype.gen"
|
580
world/net/place/threads.c
Normal file
580
world/net/place/threads.c
Normal file
|
@ -0,0 +1,580 @@
|
|||
// $Id: threads.c,v 1.41 2008/01/05 12:42:17 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
#include <net.h>
|
||||
#include <person.h>
|
||||
#include <status.h>
|
||||
|
||||
inherit NET_PATH "place/owned";
|
||||
|
||||
#ifndef DEFAULT_BACKLOG
|
||||
# define DEFAULT_BACKLOG 5
|
||||
#endif
|
||||
|
||||
// datenstruktur für threads?
|
||||
//
|
||||
// bestehende struktur ist: großes array von entries.
|
||||
//
|
||||
// wie wärs mit mapping mit key=threadname und value=array-of-entries
|
||||
// subjects werden abgeschafft: sie sind der name des threads
|
||||
// wer einen thread in seinem reply umnennen will legt in wirklichkeit
|
||||
// einen neuen thread an, meinetwegen mit "was: old thread"
|
||||
//
|
||||
// der nachteil an solch einer struktur wäre, dass man neue comments
|
||||
// in alten threads nicht so schnell findet - man ist auf die notification
|
||||
// angewiesen, was andererseits die stärke von psycblogs ist.
|
||||
// man könnte die notifications zudem noch in die history einspeisen..
|
||||
//
|
||||
// nachteile an der bestehenden struktur ist: 1. threadname in jeder
|
||||
// entry, 2. threads nur mittels durchlauf des ganzen blogs darstellbar
|
||||
//
|
||||
// momentmal.. das was du "comments" nennst sind doch schon die threads!
|
||||
|
||||
protected mapping* _thread;
|
||||
|
||||
volatile int last_modified;
|
||||
volatile string webact;
|
||||
|
||||
create() {
|
||||
::create();
|
||||
unless (pointerp(_thread)) _thread = ({ });
|
||||
}
|
||||
|
||||
cmd(a, args, b, source, vars) {
|
||||
// TODO: multiline-sachen irgendwie
|
||||
mapping entry;
|
||||
int i = 0;
|
||||
int num_entries;
|
||||
//unless (source) source = previous_object();
|
||||
switch (a) {
|
||||
case "entries":
|
||||
num_entries = sizeof(args) >= 2 ? to_int(args[1]) : DEFAULT_BACKLOG;
|
||||
// _thread[<5..]
|
||||
foreach( entry : _thread[<num_entries..] ) {
|
||||
sendmsg(source, "_list_thread_item",
|
||||
// hier auch noch den text?
|
||||
"([_number]) \"[_thread]\", [_author]",
|
||||
([
|
||||
"_thread" : entry["thread"],
|
||||
"_text" : entry["text"],
|
||||
"_author" : entry["author"],
|
||||
"_date" : entry["date"],
|
||||
"_number" : i++,
|
||||
"_nick_place" : MYNICK ]) );
|
||||
}
|
||||
return 1;
|
||||
case "thread":
|
||||
unless (sizeof(args) > 2){ // num + thread
|
||||
sendmsg(source, "_warning_usage_thread",
|
||||
"Usage: /thread <threadid> <title>", ([ ]));
|
||||
return 1;
|
||||
}
|
||||
return setSubject(to_int(args[1]), ARGS(2));
|
||||
case "blog":
|
||||
case "submit":
|
||||
case "addentry":
|
||||
unless (qAide(SNICKER)) return;
|
||||
unless (sizeof(args) >= 2) {
|
||||
sendmsg(source, "_warning_usage_submit",
|
||||
"Usage: /submit <title> <text>", ([ ]));
|
||||
return 1;
|
||||
}
|
||||
return addEntry(ARGS(2), SNICKER, args[1]);
|
||||
// TODO: append fuer multiline-sachen
|
||||
#if 0
|
||||
case "iterator":
|
||||
unless (qAide(SNICKER)) return;
|
||||
sendmsg(source, "_notice_thread_iterator",
|
||||
"[_iterator] blog entries have been requested "
|
||||
"since creation.", ([
|
||||
// i suppose this wasn't intentionally using
|
||||
// MMP _count so i rename it to _iterator
|
||||
"_iterator" : v("iterator")
|
||||
]) );
|
||||
return 1;
|
||||
#endif
|
||||
case "deblog":
|
||||
case "delentry":
|
||||
unless (qAide(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)) {
|
||||
sendmsg(source,"_error_invalid_thread_item",
|
||||
"There is no such thread item.", ([ ]));
|
||||
} else {
|
||||
sendmsg(source, "_notice_thread_item_removed",
|
||||
"Thread item [_number] has been removed.",
|
||||
([ "_number" : ARGS(1) ]) );
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return ::cmd(a, args, b, source, vars);
|
||||
}
|
||||
|
||||
msg(source, mc, data, mapping vars){
|
||||
P2(("blog.c's msg: mc %O, source %O\n", mc, source))
|
||||
// TODO: die source muss hierbei uebereinstimmen mit dem autor
|
||||
if (abbrev("_notice_authentication", mc)){
|
||||
sendmsg(source, "_notice_place_blog_authentication_success", "([_entry]) has been authenticated",
|
||||
([ "_entry" : "1" ]) );
|
||||
return;
|
||||
}
|
||||
if (abbrev("error_invalid_authentication", mc)) {
|
||||
sendmsg(source, "_notice_place_blog_authentication_failure", "Warning, someone pretends to blog as you", ([ ]) );
|
||||
return;
|
||||
}
|
||||
return ::msg(source, mc, data, vars);
|
||||
}
|
||||
|
||||
#if 0
|
||||
listLastEntries(number) {
|
||||
mapping* entries;
|
||||
int i;
|
||||
entries = _thread || ({ });
|
||||
|
||||
unless (sizeof(entries)) return 1;
|
||||
|
||||
i = v("iterator") || 0;
|
||||
vSet("iterator", i + 1);
|
||||
|
||||
return entries[<number..];
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
allEntries(source) {
|
||||
mapping* entries;
|
||||
mapping ar;
|
||||
int i = 0;
|
||||
|
||||
entries = _thread || ({ });
|
||||
|
||||
unless (sizeof(entries)) return 1;
|
||||
|
||||
foreach (ar : entries) {
|
||||
sendmsg(source, "_message_", "([_number]) \"[_topic]\", [_author]", ([ // ??
|
||||
"_topic" : ar["topic"],
|
||||
"_text" : ar["text"],
|
||||
"_author" : ar["author"],
|
||||
"_date" : ar["date"],
|
||||
"_number" : i++,
|
||||
"_nick_place" : MYNICK ]) );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
addForum() {
|
||||
// suggested protocol message for the buha forum
|
||||
// (creation of a new thread)
|
||||
|
||||
:_target psyc://psyced.org/@buha
|
||||
:_encoding utf-8
|
||||
|
||||
:_nick_forum morpheus
|
||||
:_category Test-Forum
|
||||
:_thread Test-Thread_
|
||||
:_page_thread https://www.buha.info/board/showthread.php?t=1
|
||||
|
||||
_notice_thread
|
||||
[_nick_forum] hat einen neuen Thread in [_category] erstellt: [_thread] ([_page_thread])
|
||||
.
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
setSubject(num, thread) {
|
||||
mapping* entries;
|
||||
|
||||
entries = _thread || ({ });
|
||||
// TODO: das hier muss sicherer
|
||||
entries[num]["thread"] = thread;
|
||||
_thread = entries;
|
||||
save();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO: topic uebergeben
|
||||
addEntry(text, unick, thread) {
|
||||
mapping* entries;
|
||||
mapping newentry = ([ "text" : text,
|
||||
"author" : unick,
|
||||
"date" : isotime(ctime(), 1),
|
||||
"thread" : thread || "",
|
||||
]);
|
||||
entries = _thread || ({ });
|
||||
entries += ({ newentry });
|
||||
_thread = entries;
|
||||
save();
|
||||
castmsg(ME, "_notice_thread_item",
|
||||
"[_nick] adds an entry in \"[_thread]\" of [_nick_place].", ([
|
||||
"_entry" : text,
|
||||
"_thread" : thread,
|
||||
"_nick" : unick,
|
||||
]) );
|
||||
return 1;
|
||||
}
|
||||
|
||||
addComment(text, unick, entry_id) {
|
||||
mapping entry;
|
||||
|
||||
if (sizeof(_thread) > entry_id) {
|
||||
entry = _thread[entry_id];
|
||||
unless (entry["comments"]) {
|
||||
entry["comments"] = ({ });
|
||||
}
|
||||
entry["comments"] += ({ (["text" : text, "nick" : unick ]) });
|
||||
// vSet("entries", entries);
|
||||
castmsg(ME, "_notice_thread_comment",
|
||||
"[_nick] adds a comment in \"[_thread]\" of [_nick_place].", ([
|
||||
"_entry" : entry["text"],
|
||||
"_thread" : entry["thread"],
|
||||
"_comment" : text,
|
||||
"_nick" : unick,
|
||||
]) );
|
||||
return save();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
delEntry(int number, source, vars) {
|
||||
array(string) entries, authors, a;
|
||||
string unick;
|
||||
int size;
|
||||
|
||||
entries = _thread || ({ });
|
||||
|
||||
unless (size = sizeof(entries)) return 0;
|
||||
if (number >= size) return 0;
|
||||
|
||||
if (qAide(unick = lower_case(SNICKER))) {
|
||||
unless (lower_case(entries[number]["author"]) == unick) return 0;
|
||||
}
|
||||
|
||||
_thread = entries[0..number-1] + entries[number+1..];
|
||||
save();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
htget(prot, query, headers, qs, data) {
|
||||
mapping entrymap;
|
||||
mixed target;
|
||||
string nick;
|
||||
int i;
|
||||
int a;
|
||||
mapping* entries;
|
||||
|
||||
int num_entries = query["last"] ? to_int(query["last"]) : DEFAULT_BACKLOG;
|
||||
unless (webact) webact = PLACE_PATH + MYLOWERNICK;
|
||||
// shouldnt it be "html" here?
|
||||
sTextPath(query["layout"] || MYNICK, query["lang"], "ht");
|
||||
|
||||
// Kommentare anzeigen
|
||||
if (query["comments"]) {
|
||||
htok(prot);
|
||||
// kommentare + urspruengliche Nachricht anzeigen
|
||||
displayHeader();
|
||||
displayComments(_thread[to_int(query["comments"])]);
|
||||
// eingabeformular ohne betreff
|
||||
write("<form action='" + webact + "' method='GET'>\n"
|
||||
"<input type='hidden' name='request' value='post'>\n"
|
||||
"PSYC Uni: <input type='text' name='uni'><br>\n"
|
||||
"<input type='hidden' name='reply' value='" + query["comments"] +"'>\n"
|
||||
"<textarea name='text' rows='14' cols='80'>Enter your text here</textarea><br>\n"
|
||||
"<input type='submit' value='submit'>\n"
|
||||
"</form>\n");
|
||||
write("<br><hr><br>");
|
||||
logView(a < 24 ? a : 12, "html", 15);
|
||||
displayFooter();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// formularbehandlung
|
||||
if (query["request"] == "post" && query["uni"]) {
|
||||
htok(prot);
|
||||
/*
|
||||
sendmsg uni -> _request_authentication mit thread und text drin
|
||||
dann auf die antwort warten die nen vars mapping mit thread + text hat wieder
|
||||
*/
|
||||
if (nick = legal_name(target = query["uni"])) {
|
||||
target = summon_person(nick);
|
||||
nick = target->qNick();
|
||||
} else {
|
||||
nick = target;
|
||||
// write("Hello " + query["uni"] + "<br>\n");
|
||||
// write("Remote auth doesn't work yet. TODO!!!\n");
|
||||
// return 1;
|
||||
}
|
||||
#ifdef OWNED
|
||||
if (qAide(nick)) {
|
||||
#endif
|
||||
#if 0
|
||||
sendmsg(target, "_request_authentication", "please auth me!",
|
||||
(["_host_IP" : query_ip_number(),
|
||||
"_blog_thread" : query["thread"],
|
||||
"_blog_text" : query["text"] ]));
|
||||
write("your submit is avaiting authentication by " + query["uni"] + "<br>\n");
|
||||
#endif // 0
|
||||
if (target->checkAuthentication(ME, ([ "_host_IP" : query_ip_number() ]) ) > 0) {
|
||||
// check ob reply auf irgendwas ist...
|
||||
if (query["reply"]) {
|
||||
addComment(query["text"], query["uni"], to_int(query["reply"]));
|
||||
} else {
|
||||
addEntry(query["text"], query["uni"], query["thread"]);
|
||||
}
|
||||
write("authentication successful!\n");
|
||||
} else {
|
||||
write("not authenticated!\n");
|
||||
}
|
||||
#ifdef OWNED
|
||||
} else {
|
||||
write("You are not owner or aide of this place.\n");
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
// neuen Eintrag verfassen
|
||||
if (query["request"] == "form") {
|
||||
htok(prot);
|
||||
displayHeader();
|
||||
write("<form action='" + webact + "' method='GET'>\n"
|
||||
"<input type='hidden' name='request' value='post'>\n"
|
||||
"PSYC Identity:<br><input type='text' name='uni' size=60><br>\n"
|
||||
"Thread:<br><input type='text' name='thread' size=60><br>\n"
|
||||
"Text:<br>\n<textarea name='text' rows='14' cols='64'></textarea><br>\n"
|
||||
"<input type='submit' value='CREATE MESSAGE'>\n"
|
||||
"</form>\n");
|
||||
displayFooter();
|
||||
return 1;
|
||||
}
|
||||
::htget(prot, query, headers, qs, data, 1); // no processing, just info
|
||||
// javascript-export
|
||||
if (query["export"] == "javascript") {
|
||||
// check If-Modified-Since header
|
||||
htok3(prot, "application/x-javascript", "Cache-Control: no-cache\n");
|
||||
jscriptExport(num_entries);
|
||||
} else if (query["export"] == "rss" || query["export"] == "rdf") {
|
||||
// export als RSS
|
||||
// scheinbar gibt es ein limit von 15 items / channel
|
||||
// htquote auch hier anwenden
|
||||
// check If-Modified-Since header
|
||||
htok3(prot, "text/xml", "");
|
||||
rssExport(num_entries);
|
||||
} else {
|
||||
// normaler Export
|
||||
P2(("all entries: %O\n", _thread))
|
||||
htok3(prot, "text/html", "Cache-Control: no-cache\n");
|
||||
displayHeader();
|
||||
// display the blog
|
||||
displayMain(num_entries);
|
||||
// display the chatlog
|
||||
logView(a < 24 ? a : 12, "html", 15);
|
||||
displayFooter();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
rssExport(last) {
|
||||
int i;
|
||||
int len;
|
||||
|
||||
len = sizeof(_thread);
|
||||
if (last > len) last = len;
|
||||
write("<?xml version=\"1.0\" encoding=\"" SYSTEM_CHARSET "\" ?>\n"
|
||||
"<rdf:RDF\n"
|
||||
"xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n"
|
||||
"xmlns=\"http://purl.org/rss/1.0/\">\n\n"
|
||||
"<channel>\n"
|
||||
"\t<title>PSYC - Protocol for Synchronous Conferencing</title>\n"
|
||||
"\t<link>http://www.psyc.eu</link>\n"
|
||||
"\t<description>News about the PSYC project</description>\n"
|
||||
"</channel>\n");
|
||||
for (i = len - last; i < len; i++) {
|
||||
write("\n<item>\n"
|
||||
"\t<title>"+ _thread[i]["thread"] +"</title>\n"
|
||||
"\t<link>http://" + SERVER_HOST + ":33333" + webact + "?comments=" + i + "</link>\n"
|
||||
"\t<description>" + _thread[i]["text"] + "</description>\n"
|
||||
"\t<dc:date>" + _thread[i]["date"] + "</dc:date>\n"
|
||||
"\t<dc:creator>" + _thread[i]["author"] + "</dc:creator>\n");
|
||||
write("</item>\n");
|
||||
}
|
||||
|
||||
write("</rdf:RDF>\n");
|
||||
}
|
||||
|
||||
|
||||
jscriptExport(last) {
|
||||
mapping item;
|
||||
string buf = "";
|
||||
|
||||
// htok3(prot, "application/x-javascript", "Cache-Control: no-cache\n");
|
||||
write("function Entry(thread, author, date, text) {\n"
|
||||
"\tthis.thread = thread;\n"
|
||||
"\tthis.author = author;\n"
|
||||
"\tthis.date = date;\n"
|
||||
"\tthis.text = text;\n"
|
||||
"}\n\n"
|
||||
"document.blogentries = new Array(\n");
|
||||
foreach (item : _thread[<last..]) {
|
||||
buf += "new Entry(\"" + item["thread"] + "\", \""
|
||||
+ item["author"] + "\", \""
|
||||
+ item["date"] + "\", \""
|
||||
+ item["text"] + "\"),\n";
|
||||
}
|
||||
buf = buf[..<3] + ");";
|
||||
|
||||
write(buf);
|
||||
}
|
||||
|
||||
#if 0
|
||||
displayMain(last) {
|
||||
int i;
|
||||
int len;
|
||||
|
||||
len = sizeof(_thread);
|
||||
if (last > len) last = len;
|
||||
P2(("len %d, last %d\n", len, last))
|
||||
for (i = len - last; i < len; i++) {
|
||||
write("<table><tr><td class='blogthread'>" + _thread[i]["thread"]
|
||||
+ "</td>"
|
||||
"<td class='blogauthor'>" + _thread[i]["author"] + "</td>"
|
||||
"<td class='blogdate'>" + _thread[i]["date"] + "</td></tr>"
|
||||
"<tr><td class='blogtext' colspan=3>" + _thread[i]["text"]
|
||||
+ "</td></tr>"
|
||||
"<tr><td colspan=3 align='right'>");
|
||||
write("<a href='" + webact + "?comments=" + i + "'>there are " + sizeof(_thread[i]["comments"]) + " comments</a>");
|
||||
write("</td></tr></table>\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
displayMain(last) {
|
||||
int i;
|
||||
int len;
|
||||
string t;
|
||||
|
||||
len = sizeof(_thread);
|
||||
if (last > len) last = len;
|
||||
|
||||
// reverse order
|
||||
for (i = len-1; i >= len - last; i--) {
|
||||
t = htquote(_thread[i]["text"]);
|
||||
t = replace(t, "\n", "<br>\n");
|
||||
write("<table class='newsTable' width='560px'>\n"
|
||||
"<tr>"
|
||||
"<td class='newsAuthor' width='20%'>" + _thread[i]["author"] + "</td>"
|
||||
"<td class='newsTime' nowrap width='20%'>" + _thread[i]["date"] + "</td>"
|
||||
"<td class='newsSubject' width='60%'>" + htquote(_thread[i]["thread"]) + "</td>"
|
||||
"</tr>\n"
|
||||
"<tr>"
|
||||
"<td colspan='3' class='newsText'>" + t + "</td>"
|
||||
"</tr>\n"
|
||||
"<tr>"
|
||||
"<td colspan='3' class='newsLink'><a href='" + webact + "?comments"
|
||||
"=" + i + "'>" + sizeof(_thread[i]["comments"]) + " comments</a></td>"
|
||||
"</tr>\n"
|
||||
"</table>\n");
|
||||
}
|
||||
}
|
||||
|
||||
displayComments(data) {
|
||||
mapping item;
|
||||
|
||||
write("Ursprüngliche Nachricht:<br>"
|
||||
"<b>" + data["author"] + "</b>: " + data["text"] + "<br><br>\n");
|
||||
if (data["comments"]) {
|
||||
foreach(item : data["comments"]) {
|
||||
write("<b>" + item["nick"] + "</b>: " + item["text"] + "<br>\n");
|
||||
}
|
||||
} else {
|
||||
write("no comments...<br>\n");
|
||||
}
|
||||
}
|
||||
|
||||
nntpget(cmd, args) {
|
||||
mapping item;
|
||||
int i;
|
||||
P2(("calling nntpget %s with %O\n", cmd, args))
|
||||
switch(cmd) {
|
||||
case "LIST":
|
||||
write(MYNICK + " 0 1 n\n");
|
||||
break;
|
||||
case "ARTICLE":
|
||||
i = to_int(args) - 1;
|
||||
P2(("i is: %d\n", i))
|
||||
P2(("entries: %O\n", _thread))
|
||||
item = _thread[i];
|
||||
write(S("220 %d <%s%d@%s> article\n",
|
||||
i + 1, MYNICK, i + 1, SERVER_HOST));
|
||||
write(S("From: %s\n", item["author"]));
|
||||
write(S("Newsgroups: %s\n", MYNICK));
|
||||
write(S("Subject: %s\n", item["thread"]));
|
||||
write(S("Date: %s\n", item["date"]));
|
||||
write(S("Xref: %s %s:%d\n", SERVER_HOST, MYNICK, i + 1));
|
||||
write(S("Message-ID: <%s$%d@%s>\n", MYNICK, i+1, SERVER_HOST));
|
||||
write("\n");
|
||||
write(item["text"]);
|
||||
write("\n.\n");
|
||||
break;
|
||||
case "GROUP":
|
||||
write(S("211 %d 1 %d %s\n", sizeof(_thread),
|
||||
sizeof(_thread), MYNICK));
|
||||
break;
|
||||
case "XOVER":
|
||||
for (i = 0; i < sizeof(_thread); i++) {
|
||||
item = _thread[i];
|
||||
P2(("item: %O\n", item))
|
||||
write(S("%d\t%s\t%s\t%s <%s%d@%s>\t1609\t22\tXref: news.t-online.com\t%s:%d\n",
|
||||
i+1, item["thread"],
|
||||
item["author"], item["date"],
|
||||
MYNICK, i+1,
|
||||
SERVER_HOST, MYNICK, i+1));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
P2(("unimplemented nntp command: %s\n", cmd))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef STYLESHEET
|
||||
# define STYLESHEET (v("_uniform_style") || "http://www.psyc.eu/blog.css")
|
||||
#endif
|
||||
|
||||
// wir können zwei strategien fahren.. die technisch einfachere ist es
|
||||
// die reihenfolge der elemente festzulegen und für jedes ein w(_HTML_xy
|
||||
// auszuspucken. flexibler wär's stattdessen wenn jede seite ein einziges
|
||||
// w(_PAGES_xy ausgeben würde in dem es per [_HTML_list_threads] oder
|
||||
// ähnlichem die blog-elemente per psyctext-vars übergibt ... dann kann
|
||||
// es immernoch per {_HTML_head_threads} header und footer einheitlich
|
||||
// halten. womöglich kann man auch nachträglich plan A in plan B
|
||||
// umwandeln..... hmmm -lynX
|
||||
//
|
||||
displayHeader() {
|
||||
w("_HTML_head_threads",
|
||||
"<link rel='stylesheet' type='text/css' href='"+
|
||||
STYLESHEET +"'>\n"+
|
||||
"<style type='text/css'>\n"
|
||||
"<!--\n"
|
||||
"body { font-family: lucida,verdana,geneva; }\n"
|
||||
"td { font-family: lucida,verdana,geneva; }\n"
|
||||
"table.newsTable {border: 1px solid #6f6; padding:4px; margin:6px;}\n"
|
||||
"table td.newsAuthor {color:#fff; font-weight:bold;"
|
||||
" border: 1px solid #6f6;"
|
||||
" background-color:#041;}\n"
|
||||
"table td.newsTime {color:#ddd;border: 1px solid #6f6;"
|
||||
" background-color:#030;}\n"
|
||||
"table td.newsSubject {color:#ddd; border: 1px solid #6f6;"
|
||||
" background-color:#030;}\n"
|
||||
"table td.newsLink {background-color:#030;}\n"
|
||||
"table td.newsText {}\n"
|
||||
"//-->\n"
|
||||
"</style>\n"
|
||||
"<body bgcolor='#002200' text='#33ff33' link='#ffdf00'"
|
||||
"vlink='#ffaf00' alink='#00ff00'>\n\n");
|
||||
}
|
||||
displayFooter() {
|
||||
w("_HTML_tail_threads", "</body>");
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue