#include <wizlevels.h>#include <player.h>#include <properties.h>#include <rooms.h>#include <moving.h>
gehe zum Quellcode dieser Datei
Makrodefinitionen | |
| #define | LOGNAME "PATHD" |
| #define | SAVEFILE "/p/daemon/save/pathd" |
| #define | DEBUG |
| #define | NEEDED 10 |
| #define | TIMEOUT_NEW 604800 |
| #define | TIMEOUT_OLD 2592000 |
| #define | NORMAL 0 |
| #define | SPECIAL 1 |
| #define | COMMAND 2 |
| #define | COST_EXITS ({ 1, 10, 100 }) |
| #define | COST_MANY 3 |
| #define | COST_FEW 5 |
| #define | COST_ONE 10 |
| #define | DBG(x) |
| #define | LOG(x) log_file( "PATHD", (x), 100000 ); |
| #define | ALLOWED ({"zook","vanion","rumata","zesstra"}) |
| #define | MATCH(x, y) (sizeof(regexp(x,y))) |
Funktionen | |
| public void | create () |
| public void | add_paths (string *connections) |
| public int | search_for_path (string from, string to) |
| public varargs void | show_pathmap (string path) |
| public varargs int | show_statistic (int verbose, int silent) |
| public int | change_pathmap (string pfad, mixed *verbindungen) |
| public mapping | get_pathmap () |
| public void | reset () |
| public varargs int | remove (int silent) |
| public varargs int | query_prevent_shadow (object ob) |
| static int | insert_paths (mixed *path) |
| static mixed * | format_paths (string path) |
| static void | _search (string fname, string start) |
| private string | _get_prefix (string path) |
| private void | _add_deadend (string fname, string sackgasse) |
| private int | _is_deadend (string fname, string room) |
| private void | _rate_path (string fname, string *path, int *idx) |
| private int | _connection_okay (string fname, mixed *connection, int idx, string from) |
| static void | cleanup_data (string *names, int idx) |
| public mapping | get_rooms () |
Variablen | |
| mapping | pathmap |
| static mapping | searchlist |
| static int | time_to_clean_up |
| static int | rooms_checked |
| static int | conns_checked |
| #define COMMAND 2 |
Definiert in Zeile 31 der Datei pathd.c.
Wird benutzt von format_paths() und udp_channel().
| #define COST_EXITS ({ 1, 10, 100 }) |
Definiert in Zeile 34 der Datei pathd.c.
Wird benutzt von _rate_path().
| #define COST_FEW 5 |
Definiert in Zeile 36 der Datei pathd.c.
Wird benutzt von _rate_path().
| #define COST_MANY 3 |
Definiert in Zeile 35 der Datei pathd.c.
Wird benutzt von _rate_path().
| #define COST_ONE 10 |
Definiert in Zeile 37 der Datei pathd.c.
Wird benutzt von _rate_path().
| #define DBG | ( | x | ) |
Definiert in Zeile 43 der Datei pathd.c.
Wird benutzt von _connection_okay(), _rate_path(), _search(), do_update(), RemoveTmpProp() und SetTmpProp().
Definiert in Zeile 242 der Datei pathd.c.
Wird benutzt von get_pathmap().
| #define NEEDED 10 |
Definiert in Zeile 24 der Datei pathd.c.
Wird benutzt von insert_paths().
| #define NORMAL 0 |
Definiert in Zeile 29 der Datei pathd.c.
Wird benutzt von format_paths() und x_long().
| #define SPECIAL 1 |
Definiert in Zeile 30 der Datei pathd.c.
Wird benutzt von format_paths().
| #define TIMEOUT_NEW 604800 |
Definiert in Zeile 25 der Datei pathd.c.
Wird benutzt von cleanup_data().
| #define TIMEOUT_OLD 2592000 |
Definiert in Zeile 26 der Datei pathd.c.
Wird benutzt von cleanup_data().
| private void _add_deadend | ( | string | fname, | |
| string | sackgasse | |||
| ) |
Definiert in Zeile 560 der Datei pathd.c.
Benutzt searchlist.
Wird benutzt von _search().
00561 { 00562 if ( sizeof(searchlist[fname, 8]) < 9999 ) 00563 searchlist[fname, 8] += ({sackgasse}); 00564 else if ( sizeof(searchlist[fname, 9]) < 9999 ) 00565 searchlist[fname, 9] += ({sackgasse}); 00566 else 00567 searchlist[fname, 10] += ({sackgasse}); 00568 }

| private int _connection_okay | ( | string | fname, | |
| mixed * | connection, | |||
| int | idx, | |||
| string | from | |||
| ) |
Definiert in Zeile 634 der Datei pathd.c.
Benutzt _is_deadend(), DBG und searchlist.
Wird benutzt von _search().
00636 { 00637 int i; 00638 00639 // Eine Verbindung in eine (schon getestete) Sackgasse brauchen wir 00640 // nicht noch einmal zu testen. 00641 if ( _is_deadend(fname, connections[idx][0]) ){ 00642 DBG( sprintf( "Raum %O ->| %O!", from, connections[idx][0] ) ); 00643 return 0; 00644 } 00645 00646 // Kann der Spieler diese Verbindung ueberhaupt nutzen (Seherlevel)? 00647 if ( pointerp(connections[idx][2][ searchlist[fname, 3] ]) && 00648 !sizeof(connections[idx][2][ searchlist[fname, 3] ]) ) 00649 return 0; 00650 00651 // Ist der Spieler in der richtigen (Para-)Welt? 00652 if ( connections[idx][5] != searchlist[fname, 4] ) 00653 return 0; 00654 00655 // Wenn es zu einem Verb mehrere Zielraeume gibt, kann mit dem Ausgang 00656 // keine Route geplant werden. 00657 for ( i = sizeof(connections); i--; ) 00658 if ( i != idx && connections[i][1] == connections[idx][1] 00659 && connections[i][5] == connections[idx][5] ){ 00660 DBG( sprintf( "Mehrdeutiges Verb %O in Raum %O!", 00661 connections[i][1], from ) ); 00662 return 0; 00663 } 00664 00665 return 1; 00666 }


| private string _get_prefix | ( | string | path | ) |
Definiert in Zeile 541 der Datei pathd.c.
Wird benutzt von _rate_path(), _search(), change_pathmap(), insert_paths() und show_pathmap().
00542 { 00543 string *tmp; 00544 00545 tmp = explode( path, "/" ); 00546 00547 // Bei Raeumen unterhalb von /d/* wird /d/region/magiername benutzt 00548 if ( path[0..2] == "/d/" ) 00549 return implode( tmp[0..3], "/" ); 00550 // Ansonsten die ersten beiden Teilpfade, falls soviele vorhanden sind 00551 else if ( sizeof(tmp) < 4 ) 00552 return implode( tmp[0..1], "/" ); 00553 else 00554 return implode( tmp[0..2], "/" ); 00555 }

| private int _is_deadend | ( | string | fname, | |
| string | room | |||
| ) |
Definiert in Zeile 572 der Datei pathd.c.
Benutzt searchlist.
Wird benutzt von _connection_okay().
00573 { 00574 return sizeof( ({room}) & (searchlist[fname, 8] + searchlist[fname, 9] 00575 + searchlist[fname, 10]) ); 00576 }

| private void _rate_path | ( | string | fname, | |
| string * | path, | |||
| int * | idx | |||
| ) |
Definiert in Zeile 580 der Datei pathd.c.
Benutzt _get_prefix(), COST_EXITS, COST_FEW, COST_MANY, COST_ONE, DBG, pathmap und searchlist.
Wird benutzt von _search().
00581 { 00582 int cost, size, i, tmp; 00583 mixed buf; 00584 00585 for ( i = 0, size = sizeof(path) - 1; i < size; i++ ){ 00586 buf = pathmap[ _get_prefix(path[i]) ][ path[i] ][ idx[i] ]; 00587 // Die Art des benutzten Ausgangs zaehlt hinein ... 00588 tmp = COST_EXITS[ buf[3] ]; 00589 00590 // ... sowie die Zahl der Benutzer (selten benutzte Ausgaenge koennten 00591 // Haken haben) 00592 switch ( pointerp(buf[2][ searchlist[fname, 3] ]) ? 00593 sizeof(buf[2][ searchlist[fname, 3] ]) : -1 ){ 00594 case 0: 00595 // Wenn den Ausgang noch keiner benutzt hat, ist das keine gueltige 00596 // Verbindung. Also schoen teuer machen. 00597 tmp = 100000; 00598 break; 00599 00600 case 1..2: 00601 tmp *= COST_ONE; 00602 break; 00603 00604 case 3..5: 00605 tmp *= COST_FEW; 00606 break; 00607 00608 case 6..10: 00609 tmp *= COST_MANY; 00610 break; 00611 00612 default: 00613 // -1 fuer viel benutzte Ausgaenge sowie alles andere bei Bugs ;^) 00614 break; 00615 } 00616 00617 cost += tmp; 00618 } 00619 00620 DBG( sprintf( "Route mit %O Raeumen gefunden, Kosten %O.", 00621 sizeof(path), cost ) ); 00622 00623 // Bei Erfolg die Route sowie ihre Kosten speichern 00624 if ( cost < searchlist[fname, 7] ){ 00625 DBG( "Die Route ist die bisher kuerzeste!" ); 00626 searchlist[fname, 5] = path[0..]; 00627 searchlist[fname, 6] = idx[0..]; 00628 searchlist[fname, 7] = cost; 00629 } 00630 }


| static void _search | ( | string | fname, | |
| string | start | |||
| ) | [static] |
Definiert in Zeile 453 der Datei pathd.c.
Benutzt _add_deadend(), _connection_okay(), _get_prefix(), _rate_path(), call_out(), conns_checked, DBG, m_delete(), pathmap, rooms_checked und searchlist.
Wird benutzt von search_for_path().
00454 { 00455 string from, to, *path; 00456 int lvl, *idx; 00457 mixed *tmp; 00458 00459 from = start; 00460 path = searchlist[fname, 0]; 00461 idx = searchlist[fname, 1]; 00462 to = searchlist[fname, 2]; 00463 lvl = searchlist[fname, 3]; 00464 00465 // Eigentlich macht man sowas mit einer handlichen kleinen eleganten 00466 // Rekursion. Leider begrenzt der Driver die maximale Rekursionstiefe 00467 // aber auf einen indiskutablen Wert. Deshalb bauen wir also eine 00468 // grosse lange haessliche Schleife ... 00469 do { 00470 if ( from == to ) 00471 // Ist die gefundene Verbindung die kuerzeste? 00472 _rate_path( fname, path + ({ from }), idx ); 00473 else if ( !sizeof(path & ({ from })) ){ 00474 // Sofern wir keinen Kreis gelaufen sind, neuen Raum uebernehmen. 00475 DBG( sprintf( "Uebernehme Raum %O.", from ) ); 00476 path += ({ from }); 00477 idx += ({ -1 }); 00478 rooms_checked++; 00479 } 00480 else 00481 DBG( sprintf( "In Raum %O war ich schon!", from ) ); 00482 00483 do { 00484 // So lange der aktuelle Raum keine noch nicht getesteten Ausgaenge 00485 // mehr hat, wieder einen Raum zurueck gehen. 00486 while ( sizeof(idx) && idx[<1] + 1 >= 00487 sizeof(pathmap[ _get_prefix(path[<1]) ][ path[<1] ]) ){ 00488 // Den Raum als "Sackgasse" markieren ... 00489 DBG( sprintf( "Markiere %O als Sackgasse.", path[<1] ) ); 00490 _add_deadend( fname, path[<1] ); 00491 // ... und einen Schritt zurueck gehen. 00492 path[<1..<1] = ({}); 00493 idx[<1..<1] = ({}); 00494 } 00495 00496 // Den kleinsten noch nicht getesteten Ausgang nehmen. 00497 if ( sizeof(idx) ){ 00498 tmp = pathmap[ _get_prefix(path[<1]) ][ path[<1] ]; 00499 from = tmp[ ++idx[<1] ][0]; 00500 DBG( sprintf( "Teste Verbindung nach %O.", from ) ); 00501 conns_checked++; 00502 } 00503 00504 // Das Spielchen geht so lange, bis wir einen 'gueltigen' Ausgang 00505 // gefunden haben. 00506 } while ( sizeof(idx) && 00507 !_connection_okay( fname, tmp, idx[<1], path[<1] ) ); 00508 00509 // Es wird so lange getestet, bis es keinen Raum mehr gibt, zu dem 00510 // man zurueckgehen koennte. 00511 } while ( sizeof(idx) && get_eval_cost() > 600000 ); 00512 00513 // Ist eigentlich nicht notwendig, da wir mit Referenzen arbeiten. 00514 // Aber sicher ist sicher. ;^) 00515 searchlist[fname, 0] = path; 00516 searchlist[fname, 1] = idx; 00517 00518 // Erst, wenn wir saemtliche moeglichen Verbindungen durchgetestet haben, 00519 // sind wir fertig. Ansonsten sind nur die Evalticks ausgegangen. 00520 if ( sizeof(idx) ){ 00521 DBG( sprintf( "Splitte bei %O Evalticks. Pfad hat momentan %O Raeume.", 00522 get_eval_cost(), sizeof(path) ) ); 00523 DBG( sprintf( "Getestete Raeume %O, Verbindungen %O, Sackgassen %O", 00524 rooms_checked, conns_checked, 00525 sizeof(searchlist[fname, 8] + searchlist[fname, 9] 00526 + searchlist[fname, 10]) ) ); 00527 call_out( "_search", 0, fname, from ); 00528 } 00529 else { 00530 DBG( sprintf("Suche fertig! Gefundener Weg: %O, Kosten: %O\n", 00531 searchlist[fname, 5], searchlist[fname, 7] ) ); 00532 00533 efun::m_delete( searchlist, fname ); 00534 } 00535 }


| public void add_paths | ( | string * | connections | ) |
Definiert in Zeile 96 der Datei pathd.c.
00097 { 00098 mixed *paths; 00099 00100 // keinen Aufruf per Hand bitte 00101 if ( !previous_object() || !this_player() 00102 || this_interactive() && getuid(this_interactive()) != "tiamak" 00103 || file_size( "/std/shells" + 00104 explode( object_name(previous_object()), ":" )[0] 00105 + ".c" ) < 1 ) 00106 return; 00107 00108 // Doppelte Wege rauswerfen 00109 paths = m_indices( mkmapping(connections) ); 00110 // Daten zusammensuchen 00111 paths = map( paths, #'format_paths/*'*/ ) - ({0}); 00112 // Neue Raeume eintragen 00113 filter( paths, #'insert_paths/*'*/ ); 00114 }
| public int change_pathmap | ( | string | pfad, | |
| mixed * | verbindungen | |||
| ) |
Definiert in Zeile 219 der Datei pathd.c.
Benutzt _get_prefix() und pathmap.
00220 { 00221 if ( !this_interactive() || getuid(this_interactive()) != "tiamak" 00222 || !previous_object() || getuid(previous_object()) != "tiamak" ) 00223 return -1; 00224 00225 if ( mappingp(verbindungen) ){ 00226 if ( !pathmap[_get_prefix(pfad)] ) 00227 return 0; 00228 00229 pathmap[_get_prefix(pfad)] = verbindungen; 00230 } 00231 else { 00232 if ( !pathmap[_get_prefix(pfad)][pfad] ) 00233 return 0; 00234 00235 pathmap[_get_prefix(pfad)][pfad] = verbindungen; 00236 } 00237 00238 return 1; 00239 }

| static void cleanup_data | ( | string * | names, | |
| int | idx | |||
| ) | [static] |
Definiert in Zeile 670 der Datei pathd.c.
Benutzt call_out(), dtime(), LOG, m_delete(), pathmap, show_statistic(), time_to_clean_up, TIMEOUT_NEW und TIMEOUT_OLD.
00671 { 00672 int size, i, j, k, verbindungen; 00673 string *rooms; 00674 mixed *paths; 00675 00676 size = sizeof(names); 00677 00678 // Ein bisserl mitloggen, damit wir Schwachstellen im System auch finden. 00679 if ( !idx ){ 00680 LOG( sprintf("=== %s: Starte cleanup_data(): %O Gebiete, %O Raeume " 00681 + "...\n", dtime(time())[5..], size, 00682 show_statistic(1, 1) ) ); 00683 } 00684 else { 00685 LOG( sprintf("%s: Setze cleanup_data() fort.\n", dtime(time()))[5..] ); 00686 } 00687 00688 // Brav gesplittet, damit es kein Lag gibt. 00689 // Die Grenze ist recht hoch angesetzt, da immer gleich komplette 00690 // Teilbaeume aufgeraeumt werden. 00691 while ( get_eval_cost() > 600000 && idx < size ){ 00692 rooms = sort_array( m_indices(pathmap[names[idx]]), #'</*'*/ ); 00693 00694 for ( i = sizeof(rooms); i--; ){ 00695 paths = pathmap[names[idx]][rooms[i]]; 00696 verbindungen = sizeof(paths); 00697 00698 for ( j = verbindungen; j--; ){ 00699 for ( k = 0; k < 2; k++ ){ 00700 // Diese Verbindung hat noch keiner genutzt bisher 00701 if ( !paths[j][4][k] ) 00702 continue; 00703 00704 if ( paths[j][2][k] == -1 // 'bekanntes' Gebiet 00705 && time() - paths[j][4][k] > TIMEOUT_OLD ){ 00706 // LOG( sprintf("*** Loesche alte " 00707 // + (k ? "Seher" : "Spieler") 00708 // + "-Verbindung %O.\n", paths[j]) ); 00709 paths[j][2][k] = ({}); 00710 paths[j][4][k] = 0; 00711 } 00712 else if ( paths[j][2][k] != -1 // 'neues' Gebiet 00713 && time() - paths[j][4][k] > TIMEOUT_NEW ){ 00714 paths[j][2][k] = ({}); 00715 paths[j][4][k] = 0; 00716 } 00717 } 00718 00719 // Wenn eine Verbindung weder von Spielern noch von Sehern 00720 // benutzt wurde in letzter Zeit, Verbindung ganz loeschen. 00721 if ( !paths[j][4][0] && !paths[j][4][1] ){ 00722 paths[j..j] = ({}); 00723 verbindungen--; 00724 } 00725 } 00726 00727 // Ein Raum ohne Verbindungen frisst nur Platz in der Datenbank 00728 if ( !verbindungen ){ 00729 // LOG( sprintf("*** Loesche kompletten Raum %O\n", rooms[i]) ); 00730 efun::m_delete( pathmap[names[idx]], rooms[i] ); 00731 } 00732 else 00733 pathmap[names[idx]][rooms[i]] = paths; 00734 } 00735 00736 idx++; 00737 } 00738 00739 if ( idx >= size ){ 00740 time_to_clean_up = 95; // in ~24h wieder aufräumen 00741 LOG( sprintf("=== %s: Beende cleanup_data()! Uebrig: %O Raeume.\n", 00742 dtime(time())[5..], show_statistic(1, 1) ) ); 00743 } 00744 else { 00745 call_out( "cleanup_data", 20, names, idx ); 00746 LOG( sprintf("%s: WARTE 20s bei Evalcost %O\n", 00747 dtime(time())[5..], get_eval_cost()) ); 00748 } 00749 }

| public void create | ( | ) |
Definiert in Zeile 76 der Datei pathd.c.
Benutzt destruct(), pathmap, restore_object(), SAVEFILE und searchlist.
00077 { 00078 // es darf nur einen daemon geben 00079 if ( clonep(this_object()) ){ 00080 destruct(this_object()); 00081 return; 00082 } 00083 00084 // wir muessen das Savefile schreiben duerfen 00085 seteuid(getuid()); 00086 00087 if ( !restore_object(SAVEFILE) ){ 00088 pathmap = ([]); 00089 } 00090 00091 searchlist = ([]); 00092 }

| static mixed * format_paths | ( | string | path | ) | [static] |
Definiert in Zeile 309 der Datei pathd.c.
Benutzt buf, COMMAND, crypt, exits, IS_LEARNER, M_GO, M_NOCHECK, M_TPORT, NORMAL, ob(), P_EXITS, P_IDS, P_SPECIAL_EXITS, P_TESTPLAYER, Query(), query_wiz_level() und SPECIAL.
00310 { 00311 string tmp, uid, *buf; 00312 object ob; 00313 mapping exits; 00314 int art; 00315 00316 // Magier und Testspieler koennen auch in nicht angeschlossene Gebiete 00317 // und werden deshalb nicht beachtet. 00318 if ( IS_LEARNER(previous_object(1)) || 00319 IS_LEARNER(lower_case( previous_object(1)->Query(P_TESTPLAYER)||"" )) ) 00320 return 0; 00321 00322 // Alle Daten kommen als ein String mit '#' als Trenner an. 00323 // Muster: Startraum#Zielraum#Verb#Methode der Bewegung#Parawelt 00324 buf = explode( path, "#" ); 00325 // Falls im Verb auch # vorkam (unwahrscheinlich, aber moeglich): 00326 buf[2..<3] = ({ implode( buf[2..<3], "#" ) }); 00327 00328 // Beim Verb endstaendige Leerzeichen sowie " 0" (kommt bei 00329 // _unparsed_args(), wenn keine weiteren Argumente vorhanden waren) 00330 // abschneiden. 00331 tmp = buf[2]; 00332 if ( tmp[<1] == ' ' ) 00333 tmp = tmp[0..<2]; 00334 else if ( tmp[<2..] == " 0" ) 00335 tmp = tmp[0..<3]; 00336 00337 // Wenn der Zielraum als String angegeben wurde, kann der fuehrende 00338 // Slash fehlen! 00339 if ( buf[1][0] != '/' ) 00340 buf[1] = "/" + buf[1]; 00341 00342 // Zum Abfragen der zusaetzlichen Daten brauchen wir das Objekt selber 00343 if ( !objectp(ob = find_object(buf[0])) ){ 00344 catch( load_object( buf[0]);publish ); 00345 ob = find_object(buf[0]); 00346 } 00347 00348 // Kleiner Hack - bei Transportern etc. ist 'ob' die nicht initialisierte 00349 // Blueprint. Jede Abfrage von P_EXITS wuerde nett auf -Debug scrollen. 00350 // Da P_IDS im create() auf jeden Fall auf ein Array gesetzt wird, 00351 // missbrauche ich das hier als "Ist initialisiert"-Flag. 00352 if ( !objectp(ob) || !ob->QueryProp(P_IDS) ) 00353 return 0; 00354 00355 // Art des Ausgangs feststellen. 00356 if ( mappingp(exits = ob->QueryProp(P_EXITS)) && exits[tmp] ) 00357 art = NORMAL; // "normaler" Ausgang 00358 else if ( mappingp(exits = ob->QueryProp(P_SPECIAL_EXITS)) && exits[tmp] ) 00359 art = SPECIAL; // SpecialExit 00360 else { 00361 // Kommandos, die einen in einen anderen Raum bringen 00362 art = (int) buf[3]; 00363 00364 // Es zaehlen aber nur Bewegungen, die halbwegs "normal" aussehen 00365 if ( art & (M_TPORT | M_NOCHECK) || !(art & M_GO) ) 00366 return 0; 00367 else 00368 art = COMMAND; 00369 } 00370 00371 // Die UID der Spieler/Seher wird verschluesselt. 00372 // Schliesslich brauchen wir sie nur fuer statistische Zwecke und nicht, 00373 // um Bewegungsprofile zu erstellen. 00374 uid = getuid(previous_object(1)); 00375 uid = crypt( uid, "w3" ); 00376 00377 // Start, Ziel, Verb, Wizlevel(TP), UID(TP), Art des Ausgangs, Parawelt 00378 return ({ buf[0], buf[1], tmp, query_wiz_level(previous_object(1)) ? 1 : 0, 00379 uid, art, (int) buf[4] }); 00380 }

| public mapping get_pathmap | ( | ) |
| public mapping get_rooms | ( | ) |
Definiert in Zeile 259 der Datei pathd.c.
00260 { 00261 string *submaps; 00262 mapping roommap; 00263 int i; 00264 00265 roommap=([]); 00266 00267 submaps=m_indices(pathmap); 00268 00269 i=sizeof(submaps); 00270 00271 while (i--) 00272 if (sizeof(m_indices(pathmap[submaps[i]]))) 00273 roommap[submaps[i]]=m_indices(pathmap[submaps[i]]); 00274 00275 return roommap; 00276 }
| static int insert_paths | ( | mixed * | path | ) | [static] |
Definiert in Zeile 384 der Datei pathd.c.
Benutzt _get_prefix(), i, NEEDED und pathmap.
00385 { 00386 string pre; 00387 mixed *conn, *tmp, *tme; 00388 int i; 00389 00390 pre = _get_prefix(path[0]); 00391 00392 // Falls noch gar kein Eintrag existiert, neu initialisieren 00393 if ( !mappingp(pathmap[pre]) ) 00394 pathmap[pre] = ([]); 00395 00396 if ( !pointerp(pathmap[pre][path[0]]) ) 00397 pathmap[pre][path[0]] = ({}); 00398 00399 // Aufbau von 'path': 00400 // ({ Start, Ziel, Verb, Wizlevel(TP), UID(TP), Art des Ausgangs, Para }) 00401 // Aufbau von 'conn': 00402 // ({ Ziel, Verb, ({ Spieler-UIDs, Seher-UIDs }), Art des Ausgangs, 00403 // ({ Letztes Betreten durch Spieler, durch Seher }), Parawelt }) 00404 00405 // Alle Verbindungen des Raumes durchgehen 00406 conn = pathmap[pre][path[0]]; 00407 for ( i = sizeof(conn); i--; ) 00408 // Wenn Zielraum, Verb und Parawelt passen ... 00409 if ( conn[i][0] == path[1] && conn[i][1] == path[2] 00410 && conn[i][5] == path[6] ){ 00411 00412 // Wenn schon genug Leute diese Verbindung genutzt haben, einfach 00413 // nur die Zeit der letzten Benutzung aktualisieren. 00414 if ( conn[i][2][path[3]] == -1 ){ 00415 conn[i][4][path[3]] = time(); 00416 break; 00417 } 00418 // Ansonsten die (neue?) UID hinzufuegen und die Zeit aktualisieren. 00419 else { 00420 conn[i][2][path[3]] = 00421 conn[i][2][path[3]] - ({ path[4] }) + ({ path[4] }); 00422 if ( sizeof(conn[i][2][path[3]]) >= NEEDED ) 00423 conn[i][2][path[3]] = -1; 00424 00425 conn[i][4][path[3]] = time(); 00426 break; 00427 } 00428 } 00429 00430 // Falls keine Verbindung gepasst hat, eine neue erzeugen. 00431 if ( i < 0 ) { 00432 tmp = ({ ({}), ({}) }); 00433 tmp[path[3]] = ({ path[4] }); 00434 tme = ({ 0, 0 }); 00435 tme[path[3]] = time(); 00436 00437 // Aufbau siehe oben 00438 conn += ({ ({ path[1], path[2], tmp, path[5], tme, path[6] }) }); 00439 } 00440 00441 // Ist eigentlich notwendig, da wir mit Referenzen arbeiten. 00442 // Aber sicher ist sicher. ;^) 00443 pathmap[pre][path[0]] = conn; 00444 00445 // Ob 0 oder 1 ist eigentlich total egal, da das Ergebnis-Array sowieso 00446 // verworfen wird. 00447 return 0; 00448 }

| public varargs int query_prevent_shadow | ( | object | ob | ) |
| public varargs int remove | ( | int | silent | ) |
Definiert in Zeile 291 der Datei pathd.c.
Benutzt destruct(), save_object() und SAVEFILE.
00292 { 00293 // Vor dem Entfernen noch schnell die Datenbank sichern 00294 save_object(SAVEFILE); 00295 destruct(this_object()); 00296 00297 return 1; 00298 }

| public void reset | ( | void | ) |
Definiert in Zeile 278 der Datei pathd.c.
Benutzt call_out(), pathmap, save_object(), SAVEFILE, set_next_reset() und time_to_clean_up.
00279 { 00280 if ( time_to_clean_up <= 0 ) 00281 // Einmal pro Tag Reset zum Aufraeumen der Datenbank 00282 call_out( "cleanup_data", 5, 00283 sort_array(m_indices(pathmap), #'</*'*/), 0 ); 00284 00285 save_object(SAVEFILE); 00286 time_to_clean_up--; 00287 set_next_reset(900); 00288 }

| public int search_for_path | ( | string | from, | |
| string | to | |||
| ) |
Definiert in Zeile 118 der Datei pathd.c.
Benutzt _search(), conns_checked, P_PARA, query_wiz_level(), rooms_checked und searchlist.
00119 { 00120 // Es laeuft schon eine Suche fuer diesen Spieler 00121 if ( !this_interactive() || searchlist[getuid(this_interactive())] ) 00122 return -1; 00123 00124 // UID, Raeume, Ausgangsnummern, Zielraum, Wizlevel, Parawelt, 00125 // kuerzeste Verbindung, Ausgangsnummern fuer die Verbindung, 00126 // Kosten der Verbindung, Sackgassen (drei Arrays wegen der 10k-Grenze) 00127 searchlist += ([ getuid(this_interactive()): ({ }); ({ }); to; 00128 (query_wiz_level(this_interactive()) ? 1 : 0); 00129 this_interactive()->QueryProp(P_PARA); 00130 ({}); ({}); 100000000; ({}); ({}); ({}) ]); 00131 00132 // Die eigentliche Suche starten 00133 rooms_checked = 0; 00134 conns_checked = 0; 00135 _search( getuid(this_interactive()), from ); 00136 00137 return 1; 00138 }

| public varargs void show_pathmap | ( | string | path | ) |
Definiert in Zeile 145 der Datei pathd.c.
Benutzt _get_prefix() und pathmap.
00146 { 00147 string pre; 00148 00149 if ( path ){ 00150 pre = _get_prefix(path); 00151 00152 if ( pre == path ) 00153 // Ganzen Teilbaum ausgeben 00154 printf( "Pathmap[%O]: %O\n", path, pathmap[path] ); 00155 else 00156 // Nur Infos ueber einen Raum ausgeben 00157 printf( "Pathmap[%O]: %O\n", path, 00158 pathmap[pre] ? pathmap[pre][path] : 0 ); 00159 } 00160 else 00161 // Ohne Argument wird die gesamte Map ausgegeben. 00162 // Klappt aber eher nicht (mehr) wegen Buffer overflow. ;^) 00163 printf( "Pathmap: %O\n", pathmap ); 00164 }

| public varargs int show_statistic | ( | int | verbose, | |
| int | silent | |||
| ) |
Definiert in Zeile 170 der Datei pathd.c.
Wird benutzt von cleanup_data().
00171 { 00172 int i, ges; 00173 string *ind, name; 00174 mapping m; 00175 00176 if ( verbose ){ // Stur jeden Eintrag auflisten 00177 ind = sort_array( m_indices(pathmap), #'</*'*/ ); 00178 for ( i = sizeof(ind); i--; ){ 00179 if ( !silent ) 00180 printf( "%-30s: %4d\n", ind[i], sizeof(pathmap[ind[i]]) ); 00181 ges += sizeof(pathmap[ind[i]]); 00182 } 00183 } 00184 else { // Regionen zusammenfassen 00185 ind = m_indices(pathmap); 00186 m = ([]); 00187 00188 for ( i = sizeof(ind); i--; ){ 00189 if ( ind[i][0..8] == "/players/" ) 00190 // Alle Playerverzeichnisse zusammenfassen ... 00191 name = "/players"; 00192 else 00193 // ... den Rest jeweils nach zwei Teilpfaden 00194 name = implode( explode( ind[i], "/" )[0..2], "/" ); 00195 00196 if ( !m[name] ) 00197 m[name] = sizeof( pathmap[ind[i]] ); 00198 else 00199 m[name] += sizeof( pathmap[ind[i]] ); 00200 } 00201 00202 ind = sort_array( m_indices(m), #'</*'*/ ); 00203 for ( i = sizeof(ind); i--; ){ 00204 if ( !silent ) 00205 printf( "%-30s: %4d\n", ind[i], m[ind[i]] ); 00206 ges += m[ind[i]]; 00207 } 00208 } 00209 00210 if ( !silent ) 00211 printf( "\nGesamt: %d Raeume.\n", ges ); 00212 00213 return ges; 00214 }

int conns_checked [static] |
Definiert in Zeile 51 der Datei pathd.c.
Wird benutzt von _search() und search_for_path().
| mapping pathmap |
Definiert in Zeile 49 der Datei pathd.c.
Wird benutzt von _rate_path(), _search(), call_out(), change_pathmap(), cleanup_data(), create(), get_pathmap(), get_rooms(), insert_paths(), reset(), show_pathmap() und show_statistic().
int rooms_checked [static] |
Definiert in Zeile 51 der Datei pathd.c.
Wird benutzt von _search() und search_for_path().
mapping searchlist [static] |
Definiert in Zeile 50 der Datei pathd.c.
Wird benutzt von _add_deadend(), _connection_okay(), _is_deadend(), _rate_path(), _search(), create() und search_for_path().
int time_to_clean_up [static] |
Definiert in Zeile 51 der Datei pathd.c.
Wird benutzt von cleanup_data() und reset().
1.6.3