Login/out Callbacks zusammenfassen
Beim Login/Logout/Ende Callbacks an andere Objekte
in einer Funktion zusammenfassen, damit der Kram
einfacher zu finden ist und nicht mehr an verschiedenen
Stellen steht.
Change-Id: I0d39877f1c45bd9405ef51ebc7803aad7c0bd7ad
diff --git a/std/player/base.c b/std/player/base.c
index bd2d0c8..347a695 100644
--- a/std/player/base.c
+++ b/std/player/base.c
@@ -491,27 +491,107 @@
}
/** Teilt den Gilden und anderen Spielern mit, wer reingekommen ist.
Ausserdem wird ggf. PlayerQuit() im Environment gerufen.
- \param[in] rein int - wahr, wenn der Spieler einloggt.
+ \param[in] flags int - Flags fuer Rein/Raus/Ende
*/
-protected void call_notify_player_change(int rein)
+protected void call_notify_player_change(int flags)
{
- string wer = getuid(ME);
- // erst die Gilde informieren
+ // Flag fuer Callbacks woanders hin. 1 wenn reinkommend, 0 sonst
+ // TODO: Flags komplett durchreichen an Gilden und Spielerobjekte.
+ int rein = flags & CNP_FLAG_ENTER;
+
+ if (rein) // Spieler kommt rein
+ {
+ // Login-event ausloesen
+ EVENTD->TriggerEvent(EVT_LIB_LOGIN, ([
+ E_OBJECT: ME,
+ E_PLNAME: getuid(ME),
+ E_ENVIRONMENT: environment() ]) );
+
+ // falls Gegenstaende mit 'upd -ar' upgedated wurden, muessen die
+ // "verloren gegangenen" init()'s nachgeholt werden
+ if ( query_once_interactive(ME) && !IS_LEARNER(ME) )
+ call_out( "inits_nachholen", 0, Query(P_LAST_LOGOUT),
+ all_inventory(ME) );
+
+ // jetzt die ganzen BecomesNetAlive() rufen.
+ object *inv;
+ if (ndead_location)
+ {
+ catch( ndead_location->BecomesNetAlive(ME);publish );
+ inv = all_inventory(ndead_location);
+ ndead_location = 0;
+ }
+ else
+ inv = ({});
+
+ inv += deep_inventory(ME);
+
+ //ZZ foreach statt call_other(), damit nen bug in BNA nicht die anderen
+ //BNA verhindert.
+ foreach(object ob: inv) {
+ //es ist nicht auszuschliessen, dass Items durch BecomesNetAlive()
+ //eines anderen zerstoert werden.
+ if (objectp(ob))
+ catch( call_other(ob, "BecomesNetAlive", ME);publish );
+ }
+
+ // Und Meldung ans Environment. Erst an dieser Stelle, weil der Spieler
+ // u.U. durch ein BecomesNetAlive() noch bewegt wurde.
+ if ( !(flags & CNP_FLAG_SILENT) && environment()
+ && object_name(environment()) != NETDEAD_ROOM )
+ {
+ if(query_hc_play()<=1)
+ tell_room(environment(),QueryProp(P_NAME)
+ + " weilt wieder unter den Lebenden.\n",({ME}) );
+ else
+ tell_room(environment(),QueryProp(P_NAME)
+ + " weilt wieder unter den Verstorbenen.\n",({ME}) );
+ }
+ }
+ else // Spieler geht raus (schlafe ein, ende)
+ {
+ // Logout-event ausloesen
+ EVENTD->TriggerEvent(EVT_LIB_LOGOUT, ([
+ E_OBJECT: ME,
+ E_PLNAME: getuid(ME),
+ E_ENVIRONMENT: environment() ]) );
+ // Dann die BecomesNetDead() rufen
+ object *inv = deep_inventory(ME);
+ if (environment())
+ {
+ catch(environment()->BecomesNetDead(ME);publish);
+ inv += all_inventory(environment());
+ }
+ foreach(object ob: inv)
+ {
+ if (objectp(ob)) //man weiss nie was BND() macht...
+ catch( call_other(ob, "BecomesNetDead", ME);publish );
+ }
+ // Bei Ende auch noch PlayerQuit() im Environment rufen.
+ if ((flags & CNP_FLAG_QUIT) && environment())
+ catch(environment()->PlayerQuit(ME);publish);
+ }
+
+ // Die Gilde informieren...
string gilde = QueryProp(P_GUILD);
if (stringp(gilde) && (find_object("/gilden/"+gilde)
|| file_size("/gilden/"+gilde+".c")>0))
catch(("/gilden/"+gilde)->notify_player_change(ME, rein); publish);
- // dann die anderen Spieler
- int mag = IS_LEARNER(ME);
- int invis = QueryProp(P_INVIS);
- object *u = users() - ({ME}); // sich selber nicht melden
- if (mag && invis) { // Invismagier nur Magiern melden
- u = filter(u, function int (object o)
- { return query_wiz_level(o) >= LEARNER_LVL; }
- );
+ // und wenn nicht silent: dann noch die anderen Spieler informieren
+ if (!(flags & CNP_FLAG_SILENT))
+ {
+ string wer = getuid(ME);
+ int mag = IS_LEARNER(ME);
+ int invis = QueryProp(P_INVIS);
+ object *u = users() - ({ME}); // sich selber nicht melden
+ if (mag && invis) { // Invismagier nur Magiern melden
+ u = filter(u, function int (object o)
+ { return query_wiz_level(o) >= LEARNER_LVL; }
+ );
+ }
+ u->notify_player_change(capitalize(wer),rein,invis);
}
- u->notify_player_change(capitalize(wer),rein,invis);
}
/** Ruft im uebergebenen Objekt ein init() auf, sofern notwendig.
@@ -567,17 +647,19 @@
/** Belebt einen Netztoten wieder.
Wird im Login gerufen, wenn der Spieler netztot war. Aequivalent zu
start_player()
- @param[in] silent Wenn Flag gesetzt, werden keine Meldung an den Raum
- ausgegeben.
+ @param[in] silent Wenn Flag gesetzt, werden div. Callbacks nicht gerufen und
+ Meldungen nicht ausgegeben. Wird vom Loginobjekt gesetzt, wenn das
+ Spielerobjekt bereits interaktiv ist und nur die Netzverbindung durch
+ Reconnect wechselt. *Nicht* zu verwechseln mit dem 'silent' von move & Co
+ oder durch P_INVIS!
@param[in] ip Textuelle Repraesentation der IP-Adresse, von der der Spieler
- kommt.
+ kommt.
@see start_player()
*/
varargs void Reconnect( int silent )
{
int num;
string called_from_ip;
- object *inv;
if ( query_once_interactive(ME) )
{
@@ -610,18 +692,15 @@
if ( ndead_currently )
ndead_revive();
- if ( !silent && interactive(ME) )
- call_notify_player_change(1);
+ if ( interactive(ME) )
+ {
+ call_notify_player_change(
+ CNP_FLAG_ENTER | (silent ? CNP_FLAG_SILENT : 0 ) );
+ }
if ( query_once_interactive(ME) )
modify_prompt();
- // Login-event ausloesen
- EVENTD->TriggerEvent(EVT_LIB_LOGIN, ([
- E_OBJECT: ME,
- E_PLNAME: getuid(ME),
- E_ENVIRONMENT: environment() ]) );
-
catch( num = "secure/mailer"->FingerMail(geteuid());publish );
if ( num )
@@ -649,11 +728,6 @@
Set( P_CALLED_FROM_IP, query_ip_number(ME) );
- // falls Gegenstaende mit 'upd -ar' upgedated wurden, muessen die
- // "verloren gegangenen" init()'s nachgeholt werden
- if ( query_once_interactive(ME) && !IS_LEARNER(ME) )
- call_out( "inits_nachholen", 0, Query(P_LAST_LOGOUT),
- all_inventory(ME) );
// noch nicht geclonte Autoloader "nach"clonen
while ( remove_call_out("load_auto_objects") != -1 )
@@ -662,35 +736,6 @@
if ( sizeof(autoload_rest) )
call_out( "load_auto_objects", 0, autoload_rest );
- if (ndead_location) {
- catch( ndead_location->BecomesNetAlive(ME);publish );
- inv = all_inventory(ndead_location);
- ndead_location = 0;
- }
- else
- inv = ({});
-
- inv += deep_inventory(ME);
-
- //ZZ foreach statt call_other(), damit nen bug in BNA nicht die anderen
- //BNA verhindert.
- foreach(object ob: inv) {
- //es ist nicht auszuschliessen, dass Items durch BecomesNetAlive()
- //eines anderen zerstoert werden.
- if (objectp(ob))
- catch( call_other(ob, "BecomesNetAlive", ME);publish );
- }
-
- // Erst an dieser Stelle, weil der Spieler u.U. durch ein BecomesNetAlive()
- // noch bewegt wurde.
- if ( !silent && environment() && object_name(environment()) != NETDEAD_ROOM )
- {
- if(query_hc_play()<=1)
- tell_room(environment(),QueryProp(P_NAME) + " weilt wieder unter den Lebenden.\n",({ME}) );
- else
- tell_room(environment(),QueryProp(P_NAME) + " weilt wieder unter den Verstorbenen.\n",({ME}) );
- }
-
NewbieIntroMsg();
if ( query_once_interactive(ME) )
@@ -704,8 +749,6 @@
*/
void NetDead()
{
- object *inv;
-
catch(RemoveChannels();publish);
if(query_hc_play()>1)
@@ -724,13 +767,7 @@
ndead_location = environment();
if (query_once_interactive(ME))
- call_notify_player_change(0);
-
- // Logout-event ausloesen
- EVENTD->TriggerEvent(EVT_LIB_LOGOUT, ([
- E_OBJECT: ME,
- E_PLNAME: getuid(ME),
- E_ENVIRONMENT: environment() ]) );
+ call_notify_player_change(CNP_FLAG_SLEEP);
set_next_reset(900);
/* Bei Nicht-Magier-Shells wird comm::reset() aufgerufen, das prueft, ob
@@ -738,16 +775,6 @@
Die Methode wird von /std/shells/magier.c ueberschrieben, netztote
Magier (die eigentlich schon anderweitig beseitigt worden sein sollten)
werden remove()d und destruct()ed. --Amynthor 05.05.2008 */
-
- if (environment()) {
- catch(environment()->BecomesNetDead(ME);publish);
- inv = deep_inventory(ME)+all_inventory(environment());
- }
- else inv=deep_inventory(ME);
- foreach(object ob: inv) {
- if (objectp(ob)) //man weiss nie was BND() macht...
- catch( call_other(ob, "BecomesNetDead", ME);publish );
- }
}
@@ -1519,15 +1546,13 @@
tell_object(ME,"Speichere "+QueryProp(P_NAME)+".\n");
}
- if (interactive(ME)) {
- call_notify_player_change(0);
- if(environment())
- catch(environment()->PlayerQuit(ME);publish);
- }
-
remove_living_name();
- // EVT_LIB_LOGOUT wird in remove() getriggert.
- if(catch(remove();publish)) destruct(ME);
+
+ // call_notify_player_change wird in remove() gerufen.
+
+ if(catch(remove();publish))
+ destruct(ME);
+
return 1;
}
@@ -2454,9 +2479,6 @@
catch( "/std/gilde"->try_player_advance(this_object()) ;publish );
}
- if ( interactive(ME) )
- call_notify_player_change(1);
-
if ( interactive(this_object()) ) {
cat( "/etc/NEWS" );
@@ -2522,12 +2544,6 @@
// Die Shell muss FinalSetup() nicht implementieren. Daher Callother
catch( ME->FinalSetup();publish );
- // Login-event ausloesen
- EVENTD->TriggerEvent(EVT_LIB_LOGIN, ([
- E_OBJECT: ME,
- E_PLNAME: getuid(ME),
- E_ENVIRONMENT: environment() ]) );
-
// erst jetzt GMCP freigeben und zu verhandeln.
gmcp::startup_telnet_negs();
@@ -2601,6 +2617,11 @@
else
set_is_wizard( ME, 0 );
#endif
+
+ // Objekte informieren, Loginevent etc.
+ if ( interactive(ME) )
+ call_notify_player_change(CNP_FLAG_ENTER);
+
if ( query_once_interactive(ME) )
ListAwaited();
diff --git a/std/player/moving.c b/std/player/moving.c
index 19b7497..a59d954 100644
--- a/std/player/moving.c
+++ b/std/player/moving.c
@@ -52,16 +52,24 @@
// autoload and nodrop object may not fall into the environment
static varargs int remove( int silent )
{
+ // Andere wollen auch informiert werden ueber den (ggf. impliziten)
+ // Logout.
+ // Achtung: *kein* CNP_FLAG_SILENT - das hat eine andere Bedeutung als das
+ // argument silent hier!
+ if ( interactive(ME) )
+ call_notify_player_change(CNP_FLAG_QUIT);
+
+ // Inventar aufraeumen
object* dest_obj = filter( deep_inventory(ME) - ({0}), "_to_remove" );
filter_objects( dest_obj, "remove" );
filter( dest_obj - ({0}), #'destruct );
if ( !QueryProp(P_INVIS) && !silent )
catch( say( name(WER, 1) + " verlaesst diese Welt.\n", ME );publish );
-
if ( ME && !silent )
tell_object( ME, "Bis bald!\n" );
+ // Logmeldung, wenn jemand einen Spieler zerstoert.
// Im Falle des Resets ist previous_object() == ME, aber
// previous_object(0) == 0. Ausserdem ist der Caller-Stack leer. Also
// schauen, ob es ein PO gibt, was nicht gleich dem Objekt selber ist, TI
@@ -75,13 +83,7 @@
dtime(time()), ME, previous_object(),
this_interactive(), this_player() ) );
- // Logout-event ausloesen
- EVENTD->TriggerEvent(EVT_LIB_LOGOUT, ([
- E_OBJECT: ME,
- E_PLNAME: getuid(ME),
- E_ENVIRONMENT: environment() ]) );
-
- return ::remove();
+ return ::remove(silent);
}
public string NotifyDestruct(object caller) {