marzo

16

Utenti Online?

Qualche tempo fa un vecchio giocatore di MUD ora in pensione (Arthedain) parlando su ICQ mi raccontava che una features che gli sarebbe sempre piaciuto trovare sul sito di questo o quel mud era la visualizzare via web degli utenti correntemente connessi al gioco.

Esempio di webwho

Personalmente trovo la cosa abbastanza futile, tuttavia appena ho avuto occasione ho voluto provare a realizzare tale funzionalità a scopo puramente ricreativo avvalendomi  della linea guida suggeritami dallo stesso Arthedain:

Arthedain, 09/02/2010:
…quello che dico io e’ semplicemente: Il tuo mud fa’ un chi e salva i dati su un file, poi manda il file al mio server, e abbiamo finito.

L’idea mi pare sensata anche se probabilmente potrebbero essere sviluppate meccaniche più funzionali ed economiche, ad esempio producendo la lista degli utenti connessi solo su richiesta e non magari periodicamente: ciò, nel caso dei mud italiani in cui l’utenza è  esigua, ridurrebbe senz’altro il carico di trasmissione dati tra mud-server e web-server. Per contro però l’utenza web potrebbe influenzare in modo indefinito il carico di richieste verso il mud-server, salvo ricorrere a strategie di controllo che esulano dalla mia competenza di programmatore dilettante.

L’implementazione che segue è basata sul sorgente smaug 1.4 usato da RDA e operativo su server Linux, ma credo possa essere facilmente adattato ad altri sorgenti o piattaforme. Si tenga conto tra l’altro che lo smaug a quanto pare aveva abbozzato una simile funzionalità, che potrebbe persino essere stata completata nelle versioni più recenti del codice. Troviamo infatti nella funzione do_who, responsabile della visualizzazione degli utenti connessi mentre si è in gioco, la variabile fShowHomepage che permette la stampa sul file degli utenti connessi.

Codice C

La prima cosa da fare quindi è scrivere una funzione che stampi su file la lista degli utenti connessi, e io per comodità ho fatto in modo che il file generato sia già in formato html di modo che possa essere incluso facilmente in qualunque pagina web con la direttiva include o readfile di php. Ecco come potrebbe apparire la funzione di base:

#define WHOWEB_FILE SYSTEM_DIR "whoweb.php"
void whoweb_check( )
{
  DESCRIPTOR_DATA *d; CHAR_DATA *wch; int count = 0;
  FILE *fp = fopen( WHOWEB_FILE, "w" );
  if ( !fp )
  { bug( "Impossibile scrivere il file whoweb.php!", 0 ); return; }
  fprintf( fp, "Utenti connessi...<hr>" );
  for (d = last_descriptor; d; d = d->prev)
  {
    if ( !d ) continue;
    if (d->connected != CON_PLAYING && d->connected != CON_EDITING)
    continue;
    wch = (d->original ? d->original : d->character);
    if ( IS_NPC(wch) || xIS_SET(wch->act, PLR_WIZINVIS) )
    continue;
    count += 1;
    fprintf( fp, "%s<br>", wch->name );
  }
  fprintf( fp, "%s<hr>Giocatori: %d | %.24s | <a style=\"href=\"#\"
  onclick=\"javascript:window.location.reload(true)\">Aggiorna</a>",
  count ? "" : "Nessuno.", count, ctime(&current_time)  );
  fclose( fp );
  return;
}

Come si può notare, in questo esempio, ho predisposto semplicemente la stampa del nome del giocatore online e, in fondo a seguire, il loro numero complessivo,  il riferimento alla data e ora in cui il listato è stato generato, e un link per il refresh della pagina web. Chiaramente, volendo, si potranno registrare per ciascun utente ben piu’ informazioni del nome. Nel caso di RDA, ad esempio, ho incluso la razza, l’età, l’altezza, il peso, la classe d’appartenenza, il livello, il luogo in cui il pg si trova al momento, etc… Per fornire tutte queste informazioni in modo compatto mi sono servito dei cosiddetti tooltips multiline in javascript di cui ho inserito la sintassi specifica direttamente nella funzione whoweb_check() (…nb: il tooltips usato da me è reperibile QUI).

ATTENZIONE! Tra le info del pg che potrete stampare su file sconsiglio vivamente d’inserire: il titolo, la biografia, o in generale elementi che il pg può modificare più o meno a piacere, salvo introdurre funzioni di sicurezza specifiche che blocchino eventuali tag inseriti dal giocatore e che sappiano rielaborare anche eventuali codici colori utilizzati. La ragione è semplice: cosa accadrebbe se un pg scrivesse nel proprio titolo una cosa come “<div>“?

Ora la domanda è: “dove inserire nel codice la chiamata alla nostra funzione whoweb_check()?”. La mia scelta è stata di farlo ogni due tick, generando dunque indicativamente un aggiornamento del listato ogni due minuti e mezzo. Nulla vieta comunque d’invocare la funzione con differente frequenza,  ma in ogni caso la zona d’inserimento della nostra procedura cadrà quasi senz’altro all’interno della update_handler(), ovvero la funzione che gestisce la maggior parte degli update periodici nello smaug.

Codice Linux

Giunti a questo punto, se il web-server coincide col computer sul quale gira il nostro mud la storia si può dire conclusa. Basterà infatti porre in una qualunque pagina web del nostro sito un get_file_content, un include, o un readfile che punti al nostro neonato file whoweb.php. Diversamente dovremmo preoccuparci di inviare il file al nostro web-server ogni tot tempo, che di regola dovrebbe corrispondere all’intervallo di tempo con cui il listato viene prodotto. Su server linux creeremo dunque un file whowebloop a cui attribuiremo permessi d’esecuzione e nel quale inseriremo uno script di questo tipo:

#!/bin/bash
while :
do
#Aggiornamento ogni 90 secondi
sleep 90 & pid=$!
 curl -m 30 --connect-timeout 30 -s -T /directory/mud_server/whoweb.php
 ftp://host.web.server --user nome_utente:password
 wait $pid
done

Chiaramente /directory/mud_server dovrà coincidere col percorso ove è collocato il vostro file whoweb.php, l’host.web.server sarà l’indirizzo di connessione ftp al server in cui risidere il vostro sito e a cui vi autenticherete tramite il vostro nome_utente e password.

Codice Web

Un aspetto ulteriore da tenere in conto è l’eventualità che un utente acceda alla pagina web contenente il nostro listato mentre questo viene aggiornato. Il mio consiglio in questo caso è di inserire, tramite la whoweb_check(), un tag commento di verifica in coda al file whoweb.php come segue: <!--WHOWEBEOF--> ed effettuare poi il caricamento del file whoweb.php in modo tradizionale invece che tramite include. Ecco come:

<?php
  if (is_file("whoweb.php"))
  { $handle = fopen ("whoweb.php", "r");
    $whowebtxt = fread($handle, filesize("whoweb.php"));
    fclose($handle);
  }
  $checkEOF=substr($whowebtxt, -16);
  if ( $checkEOF == "<!--WHOWEBEOF-->" )
  { echo $whowebtxt; }
  else 
  { echo "Attendere: la lista dei giocatori sta temporaneamente aggiornandosi.";
    echo "<script>var t; t=setTimeout('window.location.reload(true)',7500)
          </script>";}
?>

Potete vedere QUI lo script in azione ed eventualmente studiare la sintassi completa impiegata sul sito di RDA visualizzando l’origine della pagina. Se non ci sono giocatori connessi – mannaggia – entrate voi stessi e ricaricate la pagina dopo 2 minuti circa per vedere il risultato. Gli aggiornamenti da me imposti sono ogni 2,5 minuti per la precisione, valore che ritengo un buon compromesso tra informazioni fornite e “privacy” per chi gioca. Per dubbi o commenti: rdamud@gmail.com.

Un saluto,
Matteo (Alek)

RSS Feed

« | »