Plugin to throttle commands to the MUD

Posted by Nick Gammon on Thu 01 May 2008 12:04 AM — 4 posts, 25,632 views.

Australia Forum Administrator #0
This plugin follows on from a discussion in the thread:

http://www.gammon.com.au/forum/?id=8626

The request was to make it possible to slow the rate at which commands were sent to the MUD to 5 per second maximum, for MUDs that penalize you for entering commands too quickly.

This plugin does that - it uses a plugin callback OnPluginSend to detect all commands sent to the MUD (whether from directly typing it, a speedwalk, or a scripted "send"), and places them into a queue.

A timer which fires every 0.2 seconds pulls the earliest command from the queue and sends it to the MUD. This effectively means that you send a maximum of 5 commands per second.

Change the timer interval below from 0.20 to something else to send commands more slowly or more quickly. For example, 0.10 would send commands every 10th of a second.

Also make sure that under File menu -> Global Preferences -> Timers, the "Timer Interval" field is set to 0, so that MUSHclient checks for timers firing every 0.1 seconds, rather than every second.

There are three aliases inside the plugin:

  • show_queue : shows the outstanding commands queue
  • empty_queue : deletes all items from the queue
  • Command_Throttler:help : shows plugin help


You might use "empty_queue" if you accidentally typed something that caused hundreds of commands to be queued.


<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Saved on Thursday, May 01, 2008, 9:38 AM -->
<!-- MuClient version 4.23 -->

<!-- Plugin "Command_Throttler" generated by Plugin Wizard -->

<muclient>
<plugin
   name="Command_Throttler"
   author="Nick Gammon"
   id="40b23d22e34074ddefa98f09"
   language="Lua"
   purpose="Sends commands to the MUD gradually"
   date_written="2008-05-01 09:34:22"
   requires="4.18"
   version="1.0"
   >
<description trim="y">
<![CDATA[
"Throttles" your output to an acceptable rate.

Aliases:

show_queue  --> display outstanding queue

empty_queue --> discard entire queue

Command_Throttler:help --> this help
]]>
</description>

</plugin>


<!--  Aliases  -->

<aliases>
  <alias
   match="empty_queue"
   enabled="y"
   send_to="12"
   sequence="100"
  >
  <send>

ColourNote ("gray", "", "Deleted " .. #queue .. " outstanding item(s) from the queue.")

queue = {}  -- queue is now empty

</send>
  </alias>

  <alias
   match="show_queue"
   enabled="y"
   send_to="12"
   sequence="100"
  >
  <send>

if #queue == 0 then
  ColourNote ("gray", "", "Pending command queue is empty")
  return
end -- if

ColourNote ("gray", "", "Command queue:")
for k, v in ipairs (queue) do
  ColourNote ("gray", "", k .. ": " .. v) 
end -- for

ColourNote ("gray", "", #queue .. " outstanding item(s) in the command queue.")
</send>
  </alias>
</aliases>

<!--  Timers  -->

<timers>
  <timer 
    enabled="y" 
    second="0.20" 
    offset_second="0.00"    
    send_to="12"
>
  <send>

-- no queued commands? just exit

if next (queue) == nil then
  return
end -- if empty

-- send the earliest item

send_now = true  -- don't requeue it

Send (table.remove (queue, 1))

send_now = false -- queue if not from this plugin

</send>

  </timer>
</timers>

<!--  Script  -->


<script>
<![CDATA[

require "getlines"

queue = {}
send_now = false

function OnPluginInstall ()
  if GetOption ("enable_timers") ~= 1 then
    ColourNote ("white", "red", "Timers not enabled - commands will not be sent")
  end -- if timers not enabled

  if GetGlobalOption ("TimerInterval") ~= 0 then
    ColourNote ("white", "red", 
[[
Please go to the File menu -> Global Preferences Timers (Ctrl+Alt+G),
navigate to the Timers tab, and set the value for "Timer Interval" to be zero, 
in order for this plugin to work correctly. 
]])
  end -- if timer interval not zero

end -- function OnPluginInstall

function OnPluginSend (s)

  if send_now then
    return true -- yes we can send it
  end -- if sending from within the plugin

  -- queue the command - broken into individual lines
  for line in getlines (s) do
    table.insert (queue, line)
  end -- for loop

  return false

end -- function OnPluginSend
]]>
</script>


<!--  Plugin help  -->

<aliases>
  <alias
   script="OnHelp"
   match="Command_Throttler:help"
   enabled="y"
  >
  </alias>
</aliases>

<script>
<![CDATA[
function OnHelp ()
  world.Note (world.GetPluginInfo (world.GetPluginID (), 3))
end
]]>
</script> 

</muclient>



To use this, save between the lines to disk as Command_Throttler.xml in the MUSHclient "plugins" directory, and then use File -> Plugins to install it.
Amended on Thu 01 May 2008 08:53 PM by Nick Gammon
#1
You might want to change the 'required' part to 4.18 instead of 4.00, as the function GetGlobalOption wasn't added until 4.18. Using a prior version will return the following error:


[string "Plugin"]:11: attempt to call global 'GetGlobalOption' (a nil value)
stack traceback:
	[string "Plugin"]:11: in function <[string "Plugin"]:6>
Called by: Function/Sub: OnPluginInstall called by Plugin Command_Throttler
Reason: Executing plugin Command_Throttler sub OnPluginInstall


Works great, though, thanks!
Amended on Thu 01 May 2008 08:15 PM by Mccane
Australia Forum Administrator #2
Done, thanks for noticing. As you can see from the comments at the start I used version 4.23 to make it, but set the required version back a bit so it would work with earlier versions. I forgot which version the GetGlobalOption appeared in though. :)
#3
This was an incredible help with some of my longer scripts. Before I had to split certain scripts up to avoid being booted for too many commands. Awesome work!!!