Added public files
Roughly added all public files. Probably missed some, though.
diff --git a/secure/syntaxdb.c b/secure/syntaxdb.c
new file mode 100644
index 0000000..572eae6
--- /dev/null
+++ b/secure/syntaxdb.c
@@ -0,0 +1,223 @@
+// MorgenGrauen MUDlib
+/** \file /file.c
+* merkt sich Syntaxen und deren Erfolg
+* Kommt gar nicht mit geschachtelten Befehlen klar...
+* \author Zesstra
+*/
+
+#pragma strong_types,save_types,rtt_checks
+#pragma no_clone,no_inherit,no_shadow
+#pragma pedantic, range_check
+
+#include <defines.h>
+#include <events.h>
+#include <wizlevels.h>
+#include <player/base.h>
+#include <userinfo.h>
+#include <driver_info.h>
+#include <regexp.h>
+
+#define HOME(x) (__PATH__(0)+x)
+#define ZDEBUG(x) tell_room("/players/zesstra/workroom",\
+ sprintf("syntax: %O\n",x));
+
+mapping blacklist;
+
+struct cmd_s {
+ string verb;
+ string cmd;
+ string uid;
+ int success;
+ int fp;
+ int evalno;
+ string tp_uid;
+ int finished;
+};
+
+// LIste der letzten Kommandos, Queue zum speichern in die DB.
+// Das letzte Element ist das letzte Kommando (ggf. noch nicht abgeschlossen)
+private struct cmd_s *commands = ({});
+
+protected void create()
+{
+ seteuid(getuid());
+ if (sl_open(HOME("ARCH/syntaxen.sqlite")) != 1)
+ {
+ raise_error("Datenbank konnte nicht geoeffnet werden.\n");
+ }
+ // Tabellen und Indices anlegen, falls die nicht existieren.
+ sl_exec("CREATE TABLE IF NOT EXISTS syntaxen("
+ "cmd TEXT UNIQUE, "
+ "verb TEXT NOT NULL, envuid TEXT NOT NULL, "
+ "success INTEGER, count INTEGER, fp INTEGER);");
+ sl_exec("CREATE INDEX IF NOT EXISTS idx_verb ON syntaxen(verb);");
+ // dieses Objekt darf nur per hand (mit this_player()) geladen werden, weil
+ // da ein Teil der Blacklist herkommt... Man beachte, dass dies auch das
+ // ist, was die ueblichen Kommunikationsbefehle ausfiltert.
+ string *tmp = map(this_player()->QueryProp(P_LOCALCMDS),
+ function string (mixed val)
+ {return val[0];}
+ );
+ blacklist = mkmapping(tmp
+ - ({ "toete","schnupper", "schnuppere", "suche","such",
+ "unt", "untersuche","untersuch", "riech",
+ "rieche", "lausch", "lausche", "taste",
+ "fuehl", "fuehle, beruehre", "schau", "schaue",
+ "les", "lies", "betrachte", "betr", "betracht",
+ "teile" // wird per regexp gefiltert!
+ })
+ + ({"mail","frage","frag", "xload", "xeval", "xcall",
+ "gruppe", "g", "team", "frufe", "fruf", "fwer",
+ "femote", "rknuddel", "knuddel", "nick", "nicke",
+ "rnick", "rnicke", "knuddel", "knuddele",
+ "rknuddel", "rknuddele","denke","denk",
+ "ffix","fnotiz","fuebertrage", "chaoskontrolle",
+ "kreis", // Matrixkristall
+ })
+ );
+}
+
+private void write_db()
+{
+ foreach(struct cmd_s c : commands)
+ {
+ int** row=sl_exec("SELECT rowid, success, count, fp from syntaxen "
+ "WHERE cmd=?1;",
+ c->cmd);
+ if (row)
+ {
+ sl_exec("UPDATE syntaxen SET success=?2, count=?3, fp=?4"
+ "WHERE rowid=?1;", row[0][0],
+ c->success || row[0][1],
+ ++row[0][2], c->fp || row[0][3] );
+ }
+ else
+ {
+ sl_exec("INSERT INTO syntaxen(verb, cmd, envuid, success, count, fp) "
+ "VALUES(?1,?2,?3,?4,?5,?6);",
+ c->verb, c->cmd, c->uid, c->success, 1, c->fp);
+ }
+ }
+ commands = ({});
+}
+
+// Beendet ein Kommando, wird nur intern gerufen
+private void commit(struct cmd_s c)
+{
+ c->finished = 1;
+ //printf("Kommando abgeschlossen: %O\n", c);
+ if (get_eval_cost() > 1000000
+ && sizeof(commands) > 5
+ && find_call_out(#'write_db) == -1)
+ {
+ // In DB wegschreiben
+ call_out(#'write_db, 1);
+ }
+}
+
+public varargs int remove(int silent)
+{
+ write_db();
+ destruct(this_object());
+ return 1;
+}
+
+// gerufen, wenn ein Spieler ein Kommando eingetippt hat, aus modify_command()
+// heraus. Nach Parsen und Kommandoblock, aber vor allem anderen.
+// ACHTUNG: wenn ein Kommando erfolgreich ist, wird KEIN end_cmd() von aussen
+// gerufen...
+public void start_cmd(string cmdstr)
+{
+ if (!interactive(previous_object()))
+ return;
+ cmdstr = lower_case(cmdstr);
+ // letztes Kommando notfalls abschliessen
+ struct cmd_s cmd;
+ if (sizeof(commands))
+ {
+ cmd = commands[<1];
+ if (!cmd->finished)
+ {
+ // wir betrachten es uebrigens als erfolgreich!
+ commit(cmd);
+ }
+ }
+ // teile- mit und Ebenen und alle Kommandos, die nur aus verb und einem Wort
+ // bestehen, sind auch unnuetz.
+ //printf("%O\n",cmdstr);
+ if (sizeof(explode(cmdstr, " ")) < 3
+ || sizeof(cmdstr) > 100
+ || regmatch(cmdstr,"^teile.*mit",RE_PCRE)
+ || regmatch(cmdstr,"^-[[:alpha:]-]*[' :]{1}",RE_PCRE)
+ || regmatch(cmdstr,"^[.']", RE_PCRE)
+ )
+ {
+ return;
+ }
+ cmd = (<cmd_s> verb: explode(cmdstr, " ")[0],
+ cmd: cmdstr,
+ uid: getuid(environment(this_player())),
+ evalno: driver_info(DI_EVAL_NUMBER),
+ success: 1,
+ tp_uid: getuid(previous_object()),
+ );
+ // sonstige Blacklist
+ if (member(blacklist, cmd->verb))
+ return;
+
+ commands += ({cmd});
+ //printf("Kommandostart: %O\n", cmd);
+}
+
+// gerufen von _auswerten() im Spielerobjekt - das kommt ziemlich am Ende der
+// Kommandoverarbeitung - wenn es noch gerufen wird und uns ruft, betrachten
+// wir das Kommando als NICHT erfolgreich.
+public void cmd_unsuccessful()
+{
+ if (!sizeof(commands))
+ return;
+ struct cmd_s cmd = commands[<1];
+ // Darf nur vom Spielerobjekt gerufen werden, welches das letzte Kommando
+ // angefangen hat.
+ if (cmd->tp_uid != getuid(previous_object()))
+ return;
+ // und dies gehoert nur zum letzten Kommando, wenn Verb und Eval-No
+ // uebereinstimmen.
+ if (cmd->verb == query_verb()
+ || cmd->evalno == driver_info(DI_EVAL_NUMBER))
+ {
+ cmd->success = 0;
+ //printf("Kommando nicht erfolgreich: %O\n", cmd);
+ commit(cmd);
+ }
+ // Wenn nicht, war das letzte Kommando offenbar doch erfolgreich. Aus
+ // irgendnem Grund haben wir aber den Start des neuen Kommandos verpasst.
+ // Daher verwerfen wir das jetzt. Das alte Kommando war aber offenbar
+ // erfolgreich, daher wird es jetzt abgeschlossen.
+ else
+ {
+ commit(cmd);
+ }
+}
+
+public void LogEP(int type)
+{
+ if (!sizeof(commands))
+ return;
+ struct cmd_s cmd = commands[<1];
+ // Darf nur vom Spielerobjekt gerufen werden, welches das letzte Kommando
+ // angefangen hat.
+ if (cmd->tp_uid != getuid(previous_object()))
+ return;
+ //printf("FP gefunden: %O\n", cmd);
+ // und dies gehoert nur zum letzten Kommando, wenn Verb und Eval-No
+ // uebereinstimmen.
+ if (cmd->verb == query_verb()
+ || cmd->evalno == driver_info(DI_EVAL_NUMBER))
+ {
+ cmd->fp = type+1;
+ // Und wenn es nen FP gab, ist das Kommando auch erfolgreich.
+ commit(cmd);
+ }
+}
+