Added public files
Roughly added all public files. Probably missed some, though.
diff --git a/p/daemon/moneylog.c b/p/daemon/moneylog.c
new file mode 100644
index 0000000..f3a59bf
--- /dev/null
+++ b/p/daemon/moneylog.c
@@ -0,0 +1,246 @@
+// Log-Daemon, um Geldbugs zu finden.
+//
+// Noch experimentell, ich feile noch fleissig an den Werten&Co.
+// Wer mir ohne triftigen Grund daran herumpfuscht, der wird standesrechtlich
+// mit faulen Eiern beworfen. ]:->
+//
+// Tiamak
+
+#pragma strong_types,save_types
+#pragma no_clone,no_shadow
+
+#include <wizlevels.h>
+#include <money.h>
+
+#define LOGNAME "ADDMONEY"
+#define SAVEFILE "/p/daemon/save/moneylog"
+
+#define THRESHOLD_HOURLY 10000 // wieviel Geld darf man an einer Stelle pro
+#define THRESHOLD_DAILY 50000 // Stunde/Tag bekommen, ohne dass geloggt wird?
+
+
+private mapping mon, grenzen;
+private int check, next_reset;
+
+
+public void create()
+{
+ // wir muessen Savefile schreiben duerfen
+ seteuid(getuid());
+
+ if ( !restore_object(SAVEFILE) ){
+ mon = m_allocate( 0, 2 );
+ grenzen = m_allocate( 0, 2 );
+ check = 0;
+ next_reset = 3600;
+ }
+
+ if ( next_reset > 3600 )
+ next_reset = 3600;
+
+ if ( next_reset < 60 )
+ next_reset = 60;
+
+ // Auswertung jede Stunde
+ set_next_reset( next_reset );
+ next_reset += time();
+}
+
+
+// Sortierfunktionen
+
+static int _sort_hourly( string fn1, string fn2 )
+{
+ return mon[fn1, 0] > mon[fn2, 0];
+}
+
+
+static int _sort_daily( string fn1, string fn2 )
+{
+ return mon[fn1, 1] > mon[fn2, 1];
+}
+
+
+// im reset() wird die Auswertung vorgenommen
+public void reset()
+{
+ int i;
+ string *files, txt;
+
+ // keinen Aufruf per Hand bitte
+ if ( time() < next_reset )
+ return;
+
+ // Auswertung jede Stunde
+ set_next_reset(3600);
+ next_reset = time() + 3600;
+ check++;
+ txt = "";
+
+ files = sort_array( m_indices(mon), #'_sort_hourly/*'*/ );
+
+ for ( i = sizeof(files); i--; ){
+ if ( !(grenzen[files[i], 0] < 0) &&
+ (grenzen[files[i], 0] && mon[files[i], 0] > grenzen[files[i], 0])
+ || (!grenzen[files[i], 0] && mon[files[i], 0] > THRESHOLD_HOURLY) )
+ txt += sprintf( "%12d --- %s\n", mon[files[i], 0], files[i] );
+
+ mon[files[i], 0] = 0;
+ }
+
+ // nur loggen, wenn es auch etwas zu loggen gibt
+ if ( txt != "" )
+ log_file( LOGNAME, sprintf( "%s: =================================="
+ "==============(stuendlich)===\n",
+ ctime(time())[4..15] ) + txt );
+
+ // der "grosse" Check kommt nur einmal pro Tag
+ if ( check < 24 ){
+ save_object(SAVEFILE);
+ return;
+ }
+
+ check = 0;
+ txt = "";
+ files = sort_array( m_indices(mon), #'_sort_daily/*'*/ );
+
+ for ( i = sizeof(files); i--; )
+ if ( !(grenzen[files[i], 1] < 0) &&
+ (grenzen[files[i], 1] && mon[files[i], 1] > grenzen[files[i], 1])
+ || (!grenzen[files[i], 1] && mon[files[i], 1] > THRESHOLD_DAILY) )
+ txt += sprintf( "%12d --- %s\n", mon[files[i], 1], files[i] );
+
+ if ( txt != "" )
+ log_file( LOGNAME, sprintf( "%s: =================================="
+ "==============(taeglich)=====\n",
+ ctime(time())[4..15] ) + txt );
+
+ mon = m_allocate( 1, 2 );
+ save_object(SAVEFILE);
+}
+
+
+// die eigentliche Logg-Funktion
+public void AddMoney( object ob, int amount )
+{
+ string fn;
+
+ // keine Manipulationen per Hand bitte
+ if ( !objectp(ob) || amount < 0 || !previous_object() ||
+ (!query_once_interactive(previous_object()) &&
+ load_name(previous_object()) != GELD)
+ || IS_LEARNER(previous_object()) )
+ return;
+
+ fn = explode( object_name(ob), "#" )[0];
+
+ mon[fn, 0] += amount;
+ mon[fn, 1] += amount;
+}
+
+
+// Savefile noch schnell abspeichern - wir wollen ja keine Daten verlieren ;-)
+public int remove()
+{
+ next_reset = query_next_reset(this_object()) - time();
+ save_object(SAVEFILE);
+
+ destruct(this_object());
+ return 1;
+}
+
+
+// fuer bestimmte Files kann man die Grenzwerte einzeln setzen
+public varargs int modify_threshold( string fn, int amount1, int amount2 )
+{
+ if ( !this_interactive() || this_interactive() != this_player() ||
+ !IS_ARCH(this_interactive()) || process_call() )
+ return -1;
+
+ if ( !stringp(fn) || !intp(amount1) || !intp(amount2) )
+ return -2;
+
+ if ( !amount1 && !amount2 ){
+ m_delete( grenzen, fn );
+ write( "Eintrag " + fn + " geloescht.\n" );
+ return 1;
+ }
+
+ grenzen[fn, 0] = amount1;
+ grenzen[fn, 1] = amount2;
+
+ write( break_string( "Die Grenzen fuer " + fn + " betragen jetzt " +
+ ((amount1 < 0) ? "unendlich viele" :
+ to_string(amount1)) + " Muenzen fuer den "
+ "stuendlichen und " +
+ ((amount2 < 0) ? "unendlich viele" :
+ to_string(amount2)) + " Muenzen fuer den taeglichen "
+ "Check.", 78 ) );
+
+ save_object(SAVEFILE);
+ return 1;
+}
+
+
+// einzeln gesetzte Grenzwerte abfragen
+public varargs mixed query_thresholds( string str )
+{
+ int i;
+ string *files, txt;
+
+ if ( !this_player() )
+ return deep_copy(grenzen);
+
+ if ( stringp(str) && member( grenzen, str ) ){
+ write( break_string( "Die Grenzen fuer " + str + " betragen " +
+ ((grenzen[str, 0] < 0) ? "unendlich viele" :
+ to_string(grenzen[str, 0])) + " Muenzen fuer den "
+ "stuendlichen und " +
+ ((grenzen[str, 1] < 0) ? "unendlich viele" :
+ to_string(grenzen[str, 1])) +
+ " Muenzen fuer den taeglichen Check.", 78 ) );
+ return 0;
+ }
+
+ if ( stringp(str) && str != "" ){
+ write( "Es sind keine Grenzen fuer " + str + " eingetragen!\n" );
+ return 0;
+ }
+
+ files = sort_array( m_indices(grenzen), #'</*'*/ );
+ txt = "Eingetragene Grenzwerte:\n================================="
+ "=============================================\n";
+
+ for ( i = sizeof(files); i--; )
+ txt += sprintf( "%'.'-48s : %8d (h) %10d (d)\n",
+ files[i], grenzen[files[i], 0], grenzen[files[i], 1] );
+
+ this_player()->More( txt );
+ return 1;
+}
+
+
+// bisher geloggte Daten abfragen
+public mixed query_status()
+{
+ int i;
+ string *files, txt;
+
+ if ( !this_player() )
+ return deep_copy(mon);
+
+ files = sort_array( m_indices(mon), #'</*'*/ );
+ txt = "Geldquellen:\n================================="
+ "=============================================\n";
+
+ for ( i = sizeof(files); i--; )
+ txt += sprintf( "%'.'-48s : %8d (h) %10d (d)\n",
+ files[i], mon[files[i], 0], mon[files[i], 1] );
+
+ this_player()->More( txt );
+ return 1;
+}
+
+
+// keine Shadows bitte
+public varargs int query_prevent_shadow( object ob ) { return 1; }