1
###############################################################################
4
# Adds the 'snoop' command to NakedMUD. It relays all input from the target
5
# to the snooper. You can snoop multiple players. Snooping persists if a
6
# snooped player logs off (except during reboots). If the snooper logs off,
7
# their snooping is cleared.
9
# Author: Andrew Venzor (andrew@andrewvenzor.com)
11
###############################################################################
13
import mud, mudsys, mudsock, hooks
15
_snooptbl = {} # snooper : [snoopees,...] table
17
def cmd_snoop(admin, cmd, arg):
18
"""Usage: snoop [ <player name> | off | listall ]
20
Relays all input from the snoopee player(s) to you. Type snoop without any
21
arguments to see who you are currently snooping. Specifying a player name
22
will toggle snooping on that player. 'Off' will turn off all snooping.
23
'Listall' will show who is snooping who.
26
snoopers = get_snoopers()
28
if arg.lower() == "off":
29
# Turn off all snooping
30
if admin in get_snoopers():
31
admin.send("You stop all snooping.")
34
admin.send("You are not snooping anyone.")
36
elif arg.lower() == "listall":
39
for snooper in snoopers:
40
buf += "%s snooping:\r\n" % \
41
('You are' if snooper is admin else snooper.name + ' is')
42
buf += " " + ", ".join([ch.name for ch in snoopers[snooper]]) + \
44
admin.send(buf if buf != '' else 'Nobody is snooping right now.')
45
############################################################################
46
# DEBUGGING - REMOVE ME
47
elif arg.lower() == 'debug':
49
buf.append("_snooptbl: %r" % _snooptbl)
50
buf.append("get_snoopers: %r" % get_snoopers(False, False))
51
buf.append("get_snoopees: %r" % get_snoopees(False, False))
53
buf.append(" Snoopers:")
54
for snooper in snoopers:
55
buf.append(" %s: %r" % (snooper.name,
56
[ch.name for ch in snoopers[snooper]]))
57
buf.append(" Snoopees:")
58
snoopees = get_snoopees()
59
for snoopee in get_snoopees():
60
buf.append(" %s: %r" % (snoopee.name,
61
[ch.name for ch in snoopees[snoopee]]))
62
admin.send("\r\n".join(buf))
64
############################################################################
66
# Show your snoopers if you are snooping
68
admin.send("You are snooping:\r\n" +
69
" " + ", ".join([ch.name for ch in snoopers[admin]]))
71
admin.send("Who would you like to snoop?")
75
tgt, = mud.parse_args(admin, True, cmd, arg,
76
"[on] ch.world.noself")
79
if del_snoop(admin, tgt):
80
admin.send("You stop snooping %s." % tgt.name)
82
admin.send("Do you really need help snooping yourself?")
83
#elif tgt.isInGroup("admin"):
84
# admin.send("I doubt the other admin would appreciate that.")
85
elif tgt and tgt.sock:
87
admin.send("You begin snooping %s." % tgt.name)
89
admin.send("%s is not a valid character or not online." %
90
(arg[0].upper() + arg[1:].lower()))
93
"""Performs the relaying to the appropriate individuals and cleanup of the
95
ch, cmd = hooks.parse_info(info)
96
snoopees = get_snoopees(False)
98
if ch not in snoopees:
99
# Remove orphaned hooks
100
# This is here because the way I have things set up, I cannot remove a
101
# hook while a char is offline (ch.name is unavailable)
102
hooks.remove("snoop_%s" % ch.name, snoop_hook)
105
# Send the snooped text
106
for snooper in snoopees[ch]:
107
snooper.send("[SNOOP] %s: %s" % (ch.name, cmd))
110
"""Checks for orphaned snoopees and cleans up the table."""
111
chars_online = [sock.ch for sock in mudsock.socket_list()]
112
snoopers = get_snoopers(False)
114
# Remove inactive snoopers
115
for char in snoopers:
116
if char not in chars_online:
119
def get_snoopees(snoopees_online=True, snooper_online=True):
120
"""Returns a dict of all online players being snoopees, with their snoopers
121
contained in the value as a list.
122
It's essentially the inverse of _snooptbl.
123
snoop(ed/er)_online set to False will return offline character objects for
124
each respectively."""
126
online_chs = [sock.ch for sock in mudsock.socket_list()]
127
for snooper in _snooptbl:
128
if snooper_online and snooper not in online_chs: continue
129
for char in _snooptbl[snooper]:
130
if snoopees_online and char not in online_chs: continue
131
if char not in result:
132
result[char] = [snooper]
134
result[char].append(snooper)
137
def get_snoopers(snooper_online=True, snoopees_online=True):
138
"""Returns a dict of all online snooping players, with the snoopee player(s)
139
contained in the value as a list.
140
snoop(er/ed)_online set to False will return offline character objects for
141
each respectively."""
143
online_chs = [sock.ch for sock in mudsock.socket_list()]
144
for snooper in _snooptbl:
145
if snooper_online and snooper not in online_chs: continue
146
for char in _snooptbl[snooper]:
147
if snoopees_online and char not in online_chs: continue
148
if snooper not in result:
149
result[snooper] = [char]
151
result[snooper].append(char)
154
def add_snoop(snooper, snoopee):
155
"""Adds a snoop pair to the snoop table and activates the snooping hook for
156
the snooped character"""
157
if snoopee not in get_snoopees(False):
158
hooks.add("snoop_%s" % snoopee.name, snoop_hook)
159
if snooper in _snooptbl:
160
_snooptbl[snooper].append(snoopee)
162
_snooptbl[snooper] = [snoopee]
165
def del_snoop(snooper, snoopee=None):
166
"""Removes a snoop pair from the snoop table, and removes the hook if
168
If snoopee is None, it will remove the snooper completely from the table.
170
Returns True if something was deleted, else False"""
171
snoopees = get_snoopees()
173
if not snooper in _snooptbl:
176
for char in _snooptbl[snooper]:
178
hooks.remove("snoop_%s" % char.name, snoop_hook)
179
del _snooptbl[snooper]
181
elif snoopee in _snooptbl[snooper]:
182
if snoopee in snoopees:
183
hooks.remove("snoop_%s" % snoopee.name, snoop_hook)
184
_snooptbl[snooper].remove(snoopee)
185
# Was that the last one? If so, clean up
186
if len(_snooptbl[snooper]) == 0:
187
del _snooptbl[snooper]
192
def check_snoop_enter_game(info):
193
ch, = hooks.parse_info(info)
196
snptable = get_snoopees()
198
for snooper in snptable[ch]:
199
snooper.send('[SNOOP: %s has come online. Snooping resumed.]'
202
def check_snoop_leave_game(info):
203
ch, = hooks.parse_info(info)
206
snoopees = get_snoopees(False, True)
207
snoopers = get_snoopers(False)
210
for snooper in snoopees[ch]:
211
snooper.send('[SNOOP: %s has gone offline. Snooping suspended.]'
216
mudsys.add_cmd("snoop", None, cmd_snoop, "admin", False)
218
hooks.add("char_to_game", check_snoop_enter_game)
219
hooks.add("char_from_game", check_snoop_leave_game)