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