| Message |
I think using luasocket is the way to go, it is pretty easy, considering the complexities of the underlying problem. I got David's example to work, with a bit of modification:
require 'socket'
local port = 4000
local host = "localhost" -- or wherever it is
local conn = socket.connect (host, port)
assert (conn:send ("playername\n"))
socket.sleep (1)
assert (conn:send ("password\n"))
socket.sleep (1)
assert (conn:send ("\n\n\n")) -- if you have a MOTD you need to skip for instance
socket.sleep (1)
for i = 1, 10 do
conn:send ("tell admin hi\n")
conn:send ("look\n")
conn:send ("north\n")
conn:send ("west\n")
socket.sleep (1)
-- whatever
end
I threw in a few sleeps, partly because you would want to anyway (no player types that fast!) - and partly because it didn't work without them. According to the documentation for "send" the output is not buffered - effectively that means that if it can't be sent immediately, it is not sent at all.
Any sort of TCP/IP application needs to take into account that nothing is instantaneous. The connection defaults to blocking, I think, which is why you get away with sending the player name right after connecting, however remember that connecting, in itself, takes time.
If you can't get luasocket to work, read this thread:
http://www.gammon.com.au/forum/?id=8319
Once it is basically working, you should be able to run it outside MUSHclient. I did it from the command line, and basicallly to do that you do "lua <filename>" (eg. "lua stresstest.lua").
What programs like MUSHclient do (to send stuff) is something like this:
- When you need to send, if stuff is outstanding, add it to the back of the queue
- When the previous send completes (you use "select" to test for this) you take the first item from the queue, and do a "send".
- The call to "send" tells you how much actually got sent (quite possibly less than you wanted), so you re-add the unsent part to the head of the queue.
I did a tiny client a while ago, see:
http://www.gammon.com.au/forum/?id=2206
That is quite a small C program that nonetheless shows the general technique. Its main loop (the processoutput function) basically loops around indefinitely, pausing on the "select" statement (there is select in the luasocket as well).
The select function is specifically designed to wait for "timeout" seconds, or until you can do something with your connection, whichever comes sooner. In this case, "doing something" could mean "ready to send more stuff". That is where you pull things out of your queue and send them, if required. The timeout can be used to gradually pump more stuff out, even if there is nothing outstanding.
A suitably designed script could set up dozens of connections, and then loop around checking if any of them are ready to do something (since select can check more than one socket at once).
I am reluctant to release a finished script that would do that, as it could be used by "script kiddies" to launch a denial-of-service attack on a MUD server with minimal effort.
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | top |
|