cmd_admin.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. '''
  2. cmd_admin.py
  3. commands available only to admins.
  4. '''
  5. import mudsys, inform, string, mudsock, mud, hooks, display
  6. import room as mudroom
  7. import char as mudchar
  8. import obj as mudobj
  9. ################################################################################
  10. # local variables
  11. ################################################################################
  12. # a list of current instances, and their source zones
  13. curr_instances = [ ]
  14. ################################################################################
  15. # game commands
  16. ################################################################################
  17. def cmd_shutdown(ch, cmd, arg):
  18. '''Shuts the mud down.'''
  19. mudsys.do_shutdown()
  20. def cmd_shutdown_net(ch, cmd, arg):
  21. '''A trap to make sure we spell shutdown out completely.'''
  22. ch.send("You must spell out shutdown completely!")
  23. def cmd_copyover(ch, cmd, arg):
  24. '''Restarts the mud, and keep all sockets connected.'''
  25. mudsys.do_copyover()
  26. def cmd_copyover_net(ch, cmd, arg):
  27. '''A trap to make sure we spell copyover out completely.'''
  28. ch.send("You must spell out copyover completely!")
  29. def cmd_repeat(ch, cmd, arg):
  30. '''Usage: repeat <times> <command>
  31. Attempts to perform a single command multiple times. For example, one
  32. may want to load 20 copies of an item:
  33. > repeat 20 load obj beer@drinks
  34. '''
  35. try:
  36. times, arg = mud.parse_args(ch, True, cmd, arg, "int(times) string(command)")
  37. except: return
  38. if times < 1:
  39. ch.send("Commands may only be repeated a positive number of times.")
  40. else:
  41. for i in range(times):
  42. ch.act(arg, True)
  43. def cmd_pulserate(ch, cmd, arg):
  44. '''Usage: pulserate <pulses>
  45. Changes the number of pulses the mud experiences each second. The mud
  46. makes one loop through the main game handler each pulse.
  47. '''
  48. if arg == '':
  49. ch.send("The mud currently has "+mudsys.sys_getval("pulses_per_second")+
  50. "pulses per second.")
  51. else:
  52. pulserate = string.atoi(arg)
  53. if pulserate == 0 or 1000 % pulse != 0:
  54. ch.send("The number of pulses per second must divide 1000.")
  55. else:
  56. mudsys.sys_setval("pulses_per_second", str(pulserate))
  57. ch.send("The mud's new pulse rate is %d pulses per second." %
  58. pulserate)
  59. def cmd_lockdown(ch, cmd, arg):
  60. '''Usage: lockdown [allowed groups | off]
  61. Locks the game for anyone not a member of one of the user groups
  62. specified. No argument will list all the user groups locked out of the
  63. mud. The off argument will remove all lockdowns.'''
  64. if arg == '':
  65. lockdown = mudsys.sys_getval("lockdown")
  66. if lockdown == '':
  67. ch.send("Lockdown is currently off.")
  68. else:
  69. ch.send("Lockdown is currently to members not of: " + lockdown)
  70. ch.send("To turn off lockdown, use {clockdown off{n")
  71. elif arg.lower() == "off":
  72. ch.send("Lockdown disabled.")
  73. mudsys.sys_setval("lockdown", "")
  74. # make sure we're not locking ourself out
  75. elif not ch.isInGroup(arg):
  76. ch.send("You cannot lock yourself out!")
  77. else:
  78. ch.send("MUD locked down to everyone not in groups: " + arg)
  79. mudsys.sys_setval("lockdown", arg)
  80. # kick out everyone who we've just locked out
  81. for ch in mudchar.char_list():
  82. if ch.is_pc and not ch.isInGroup(arg):
  83. ch.send("The mud has just been locked down to you.")
  84. mudsys.do_save(ch)
  85. mudsys.do_disconnect(ch)
  86. extract(ch)
  87. def cmd_at(ch, cmd, arg):
  88. '''Usage: at <person | place> <command>
  89. Perform a command at another room or person while never leaving your
  90. current room.'''
  91. try:
  92. found, type, arg = mud.parse_args(ch, True, cmd, arg,
  93. "{ room ch.world.noself } string(command)")
  94. except: return
  95. # figure out what room we're doing the command at
  96. if type == "char":
  97. room = found.room
  98. else:
  99. room = found
  100. # transfer us over to the new room, do the command, then transfer back
  101. old_room = ch.room
  102. ch.room = room
  103. ch.act(arg, True)
  104. ch.room = old_room
  105. def try_force(ch, vict, cmd):
  106. '''tries to force a person to do something'''
  107. if ch == vict:
  108. ch.send("Why don't you just try doing it?")
  109. elif vict.isInGroup("admin"):
  110. ch.send("But " + ch.see_as(vict) + " has just as many priviledges as you!")
  111. else:
  112. ch.send("You force " + vict.name + " to '" + cmd + "'")
  113. vict.send(vict.see_as(ch) + " forces you to '" + cmd + "'")
  114. vict.act(cmd, False)
  115. def cmd_force(ch, cmd, arg):
  116. '''Usage: force <person> <command>
  117. Attempts to make the specified perform a command of your choosing.'''
  118. try:
  119. found, multi, arg = mud.parse_args(ch, True, cmd, arg,
  120. "ch.world.noself.multiple string(command)")
  121. except: return
  122. if multi == False:
  123. try_force(ch, found, arg)
  124. else:
  125. for vict in found:
  126. try_force(ch, vict, arg)
  127. def cmd_goto(ch, cmd, arg):
  128. '''Usage: goto <person | place | thing>
  129. Transfer yourself to a specified room, object, or person in game. Rooms
  130. are referenced by their zone key.
  131. '''
  132. try:
  133. found, type = mud.parse_args(ch, True, cmd, arg, "{ room ch.world.noself }")
  134. except: return
  135. # what did we find?
  136. if type == "char":
  137. dest = found.room
  138. else:
  139. dest = found
  140. mud.message(ch, None, None, None, True, "to_room",
  141. "$n disappears in a puff of smoke.")
  142. ch.room = dest
  143. ch.act("look")
  144. mud.message(ch, None, None, None, True, "to_room",
  145. "$n appears in a puff of smoke.")
  146. hooks.run("enter", hooks.build_info("ch rm", (ch, ch.room)))
  147. def do_transfer(ch, tgt, dest):
  148. '''ch transfers tgt to dest'''
  149. if tgt.room == dest:
  150. ch.send(ch.see_as(tgt) + " is already there")
  151. else:
  152. tgt.send(tgt.see_as(ch) + " has transferred you to " + dest.name)
  153. mud.message(tgt, None, None, None, True, "to_room",
  154. "$n disappears in a puff of smoke.")
  155. tgt.room = dest
  156. tgt.act("look", False)
  157. mud.message(tgt, None, None, None, True, "to_room",
  158. "$n arrives in a puff of smoke.")
  159. def cmd_transfer(ch, cmd, arg):
  160. '''Usage: transfer <person> [[to] room]
  161. The opposite of goto. Instead of moving to a specified location, it
  162. takes the target to the user. If an additional argument is supplied,
  163. instead transfers the target to the specifie room.'''
  164. try:
  165. found, multi, dest = mud.parse_args(ch, True, cmd, arg,
  166. "ch.world.multiple.noself | [to] room")
  167. except: return
  168. # if we didn't supply a room, use our own
  169. if dest == None:
  170. dest = ch.room
  171. # do our transfers
  172. if multi == False:
  173. do_transfer(ch, found, dest)
  174. else:
  175. for tgt in found:
  176. do_transfer(ch, tgt, dest)
  177. def cmd_eval(ch, cmd, arg):
  178. '''Usage: eval <python statement>
  179. Evaluates a Python statement and sends its return value to the user.
  180. For example:
  181. > eval "Your name is " + ch.name
  182. Evaluation: Your name is Alister
  183. > eval dir()
  184. Evaluation: ['arg', 'ch', 'cmd']
  185. > eval dir(ch)
  186. '''
  187. if arg == "":
  188. ch.send("What python statement do you want to evaluate?")
  189. else:
  190. ret = eval(arg)
  191. ch.send("Evaluation: " + str(ret))
  192. def cmd_exec(ch, cmd, arg):
  193. '''Usage: exec <python statement>
  194. Execute any one-line python statement.'''
  195. if arg == "":
  196. ch.send("What python statement do you want to evaluate?")
  197. else:
  198. exec arg
  199. ch.send("Command executed.")
  200. def cmd_instance(ch, cmd, arg):
  201. '''Create an instanced version of the specified room'''
  202. try:
  203. source, dest = mud.parse_args(ch, True, cmd, arg, "word(source) [as] word(dest)")
  204. except: return
  205. room = mudroom.instance(source, dest)
  206. ch.send("You instance " + source + " as " + room.proto + ".")
  207. def do_zinstance(zone):
  208. '''create a new instance of the specified zone.'''
  209. # sanitize the zone key
  210. if sum([(not v in string.ascii_letters+string.digits+"_") for v in zone]):
  211. return None
  212. elif len(zone) == 0:
  213. return None
  214. # find all of our room keys
  215. rnames = mudsys.list_zone_contents(zone, "rproto")
  216. if len(rnames) == 0:
  217. return None
  218. to_instance = [ ]
  219. for name in rnames:
  220. key = name + "@" + zone
  221. if not mudroom.is_abstract(key):
  222. to_instance.append(name)
  223. # instantiate and reset all of the relevant rooms
  224. uid = mudsys.next_uid()
  225. inszone = zone + str(uid)
  226. for name in to_instance:
  227. key = name + "@" + zone
  228. ins = name + "@" + inszone
  229. rm = mudroom.instance(key, ins)
  230. rm.reset()
  231. # append this to the list of instanced zones
  232. curr_instances.append((inszone, zone))
  233. # success
  234. return inszone
  235. def cmd_zinstance(ch, cmd, arg):
  236. '''create an instanced copy of the specified zone.'''
  237. if arg == "":
  238. if len(curr_instances) == 0:
  239. ch.send("No zones currently instanced.")
  240. else:
  241. ch.send("{w %-40s %36s " % ("Instance", "Source"))
  242. ch.send("{b" + display.seperator)
  243. for pair in curr_instances:
  244. ch.send("{c %-40s %36s{n" % pair)
  245. return
  246. # try creating the instance, and returning the zone key
  247. instance = do_zinstance(arg)
  248. if instance != None:
  249. ch.send("Zone has been instanced with zone key, %s. zinstance for a list of current instances." % instance)
  250. elif sum([(not v in string.ascii_letters+string.digits+"_") for v in arg]):
  251. ch.send("Invalid zone key.")
  252. elif len(mudsys.list_zone_contents(arg, "rproto")):
  253. ch.send("Source zone contained no rooms to instance.")
  254. else:
  255. ch.send("Zone instance failed for unknown reason.")
  256. def cmd_connections(ch, cmd, arg):
  257. '''lists all of the currently connected sockets, their status, and where
  258. they are connected from.'''
  259. tosend = [ ]
  260. fmt = " %2s %-11s %-11s %-11s %s"
  261. tosend.append(("{w"+fmt) % ("Id", "Character", "Account", "Status", "Host"))
  262. tosend.append("{b" + display.seperator + "{c")
  263. for sock in mudsock.socket_list():
  264. chname = "none"
  265. accname = "none"
  266. state = sock.state
  267. host = sock.hostname
  268. id = sock.uid
  269. if sock.ch != None:
  270. chname = sock.ch.name
  271. if sock.account != None:
  272. accname = sock.account.name
  273. tosend.append(fmt % (id, chname, accname, state, host))
  274. tosend.append("{n")
  275. ch.page("\r\n".join(tosend))
  276. def cmd_disconnect(ch, cmd, arg):
  277. """Usage: disconnect <uid>
  278. Disconnects a socket with the given uid. Use 'connections' to see
  279. current connected sockets."""
  280. try:
  281. uid, = mud.parse_args(ch, True, cmd, arg, "int(uid)")
  282. except: return
  283. for sock in mudsock.socket_list():
  284. if sock.uid == uid:
  285. ch.send("You disconnect socket %d." % uid)
  286. sock.close()
  287. break
  288. ################################################################################
  289. # add our commands
  290. ################################################################################
  291. mudsys.add_cmd("shutdow", None, cmd_shutdown_net, "admin", False)
  292. mudsys.add_cmd("shutdown", None, cmd_shutdown, "admin", False)
  293. mudsys.add_cmd("copyove", None, cmd_copyover_net, "admin", False)
  294. mudsys.add_cmd("copyover", None, cmd_copyover, "admin", False)
  295. mudsys.add_cmd("at", None, cmd_at, "wizard", False)
  296. mudsys.add_cmd("lockdown", None, cmd_lockdown, "admin", False)
  297. mudsys.add_cmd("pulserate", None, cmd_pulserate, "admin", False)
  298. mudsys.add_cmd("repeat", None, cmd_repeat, "wizard", False)
  299. mudsys.add_cmd("force", None, cmd_force, "wizard", False)
  300. mudsys.add_cmd("goto", None, cmd_goto, "wizard", False)
  301. mudsys.add_cmd("transfer", None, cmd_transfer, "wizard", False)
  302. mudsys.add_cmd("eval", None, cmd_eval, "admin", False)
  303. mudsys.add_cmd("exec", None, cmd_exec, "admin", False)
  304. mudsys.add_cmd("connections", None, cmd_connections, "admin", False)
  305. mudsys.add_cmd("disconnect", None, cmd_disconnect, "admin", False)
  306. mudsys.add_cmd("instance", None, cmd_instance, "admin", False)
  307. mudsys.add_cmd("zinstance", None, cmd_zinstance, "admin", False)