XPilot..

BTW, get a look at an example about the worst case and the proposed way of contributing patches to gents@xpilot.org e.g.
If you set up a patched server, you really should change the STATUS-field in the Local.config.

The following (old stuff) is snooping for 3.6.2, turned on by messages typed in. So only the server is changed.

Then i wrote a better version, that uses two unused keys in the client. just pressing them switches the snooping......
Finally, in 4.0.0 there is an option -allowViewing , that let's you watch other players if you are paused or dead.

Altogether, the minimum change concerns object.h frame.c player.c

short pieces for your interest:

object.h:
=========
	struct player {
	...
	    int id;               /* Unique id */
	    charname[MAX_CHARS];  /* Nick-name of player */
	    struct {
		...
	        int pl_id;        /* the locked player */
            } lock;

	...
	    int snoop;            /* added attribute */
	    int war_id;           /* you don't want to know.. */
	...
	...
	}




/*
   in the following:
   Players[]    the field of pointers to the player structures
                (one for every player).
   pl           Players[index_of_one_player].

   note:       index_of_one_player is the index for the field, 
               pl->pl_id           is the id of the player.
*/

frame.c:
========
Frame_radar():
	...
    if (playersOnRadar || BIT(World.rules->mode, TEAM_PLAY)) {
        for (i = 0; i < NumPlayers; i++) {
            /*
             * Don't show on the radar:
             *          Ourselves (not necassarily same as who we watch).
             * oops, we have to! (snooping) 
             *          People who are not playing.
             *          People in other teams if;
             *                  no playersOnRadar or if not visible
             */
            if (Players[i]->conn == conn && Players[i]->snoop == i
                || BIT(Players[i]->status, PLAYING|PAUSE|GAME_OVER) != PLAYING
                || (!TEAM(i, ind)
                    && (!playersOnRadar || !pl->visibility[i].canSee))) {
                continue;
            }

	...


Frame_update():
         ...
         * This is done by using two indexes, one
         * determining which data should be used (ind, set below) and
         * one determining which connection to send it to (conn).
         */
        /* normal team mode snooping */
         if ((BIT(pl->status, (GAME_OVER|PLAYING)) == (GAME_OVER|PLAYING))
                || (BIT(pl->status, PAUSE)
                && BIT(World.rules->mode, TEAM_PLAY)
                && pl->team != TEAM_NOT_SET
                && pl->team == Players[GetInd[pl->lock.pl_id]]->team)) {
            if (BIT(World.rules->mode, TEAM_PLAY)
                 && BIT(pl->lock.tagged, LOCK_PLAYER)) {
                ind = GetInd[pl->lock.pl_id];
            } else {
                ind = i;
            }
	...
        /* additional snooping */
	
        } else if ( pl->snoop != i ){
                ind = pl->snoop;
        } else {
	
            ind = i;
	...

Set_message(const char *message):

    ...
    
    /* msg: "/s" */
    } else if ( msg[POS1] == snoop_CHAR){
        snoop_flag = 1;

    ...

    } else if ( snoop_flag ){
        if ( len == MIN_LEN ){
                if ( BIT(Players[sender_ind]->lock.tagged,
                         LOCK_PLAYER | LOCK_VISIBLE)){
                    Players[sender_ind]->snoop =
                     GetInd[Players[sender_ind]->lock.pl_id];
                    printf("-- snoop_lock: %s->%s\n",
                        Players[sender_ind]->name,
                        Players[Players[sender_ind]->snoop]->name);
                } else {
                    Send_message(Players[sender_ind]->conn,
                        "   snoop: NOT LOCKED!!");
                }
        } else ...
	...
    }
    
    ...

player.c:
========
e.g. Init_player()

     pl->snoop = ind;

 ... diverse initializations...
 ... swapping of id's at playerleaving


home