The muf Den

@ports in ProtoMUCK
by Akari

As of ProtoMUCK 1.5 and newer, there has been the ability to open additional ports than the standard 3 defined by the @tune options, which feature we refer to as @ports support. Though the ability to have extra telnet, Pueblo, or WWW ports may be trivial, the real meat of this option is the MUF ports, which came into being in 1.60, allowing one to "bind" a particular port directly to a MUF program. This article will talk about how to take advantage of @ports support, as well as go over some points that should be kept in mind when writing MUF programs to go along with it.

The first step is to open a new port for the MUCK. This is the only step of the process that requires a shutdown of the server. In order to add an additional port, go to the proto script located in the proto directory by default. In that script is a line:

PORTS="";

In order to add more open ports to the MUCK, all you have to do is add a list of the additional ports you want between the quote marks. The list is space deliminated, so if you want more than one, simply place a space between each port in the list, up to a total of ten ports. For example, let's say my MUCK already has the following ports:

ServicePort
Telnet8000
WWW8001
Pueblo8002

and I want to add 8003 and 8004 to it. I would edit the line in the proto script to read:

PORTS="8003 8004";

Once I have saved the changed script, I would shut the MUCK down, and bring it back up by typing ./proto start in the proto directory. For those that don't use the proto script (such as WinProto), or use their own version of the script, you'll want to just make sure to alter your command line arguments to the protomuck binary to include the list of ports you want on the end. For example:

./protomuck data/proto.db data/proto.new 8003 8004

Once the MUCK comes back up, you now have two more open ports on it, 8003, and 8004. If you do nothing further at this point, those ports will just be normal telnet ports that people could connect to and login to the MUCK just as if they had connected to port 8000, but that's not very interesting. :)

Here's where the customization comes in. The directory that controls the @ports is located on #0 and is simply called @ports. First we must decide on what types we want the port to be. There are currently four kinds of ports: Telnet, WWW, Pueblo, MUF. Let's say that we want port 8003 to be another Pueblo port, and port 8004 to be a MUF port. We control the port type by setting a prop on #0 as follows:

@propset #0=int:@ports/port/type:type number

The type numbers are:

TypeNumber
Telnet0
Web1
Pueblo2
MUF3

For our example, we would use:

@propset #0=int:@ports/8003/type:2
@propset #0=int:@ports/8004/type:3

Now that we have determined the type, there is a little more customization we can set. With the Pueblo port, we can set a max login-idle that is unique to that port with @ports/port/idle:time in seconds. If no such prop is set, then the login max idle will default to the connidle @tune. For example, let's say we want to let people idle for no more than a minute on the login screen of 8003, we would type:

@propset #0=int:@ports/8003/idle:60

Note that the idle time setting does not apply to MUF ports or Web ports, only to normal and Pueblo ports.

For the MUF port, another prop is used to indicate which MUF program to call when a connection comes in:

@propset #0=dbref:@ports/port/MUF:program

For example, let's say our MUF program is #123 in this case. We would type:

@propset #0=dbref:@ports/8084/MUF:#123

And now both of our new ports are configured. You do not have to reboot after configuring them to get them to work as you want. Once the ports are open, you can change their settings in those props without having to reboot. Now all this manual prop setting may seem like a pain, and that's why I've written a MUF program to take away the hassle. ^^ It can be found here listed as cmd-ports.muf. You will also need the $lib/strings listed there as well however.

And there you go, you're now familiar with how to open additional ports for your MUCK and configure them. Be careful, though. If you are on a commercial server, there is likely a limit to the ports you are allowed to open, so make sure you stay within the guidelines of whoever is hosting your MUCK before you go off opening additional ports. Also, if you try to open a port that is already in use, your MUCK will error out during startup, but will indicate why in your logs/protomuck.err file.

Now for some information about how to program using MUF ports. When a connection is made to a properly configured MUF port, instead of getting the usual login screen that normal ports provide, the MUF program designated is immediately called and the connection belongs to it. The connection can stay open for as long as the MUF program is running, but once the MUF program ends, the connection is immediately dropped (there is an exception to this, as we'll get into later).

Prims that will be of use here are notify_descriptor, ansi_notify_descriptor, descr, and a few others. There is no character to notify to, no dbref to reference with me @ (me @ returns #-1, BTW), so instead, you have to write directly to the descriptor. That's what the descr notify prims are for. They work just like normal notify prims. For example, I would use "some string" descr swap notify_descriptor to notify to the connection. You can always get the descriptor of the connection using the descr prim. Think of that as your me @. Neon ANSI color can be used if desired, but first the DF_COLOR flag must be set on the descriptor, by using the descr_set prim.

descr "DF_COLOR" descr_set

and then the ansi_notify_descriptor prim will parse the Neon ANSI correctly instead of stripping it.

Input can be obtained from the connection by using the read or tread prims. tread is usually handy for this, since you can use it to keep a connection from idling indefinitely.

The final prim of interest will be descr_setuser. Using this prim, you can connect to a character via the MUF port, and the connection will stay alive even after the program has ended. So yes, it is possible to create your entirely customized login screens via MUF ports. Note that players connected this way will not trigger the @login propqueue, nor will they trigger the @disclogin propqueue when the connection is dropped, but they will trigger the normal _connect and _disconnect queues just like any other player. If @login and @disclogin propqueues are desired, just add support into them in the MUF program you write using the PROPQUEUE prim.

You can always see what port a player has connected via as a wizard by typing WHO !. And typing WHO !! will indicate what type of port a connection is using. Note, however, that players connected via a MUF port will be listed as using a Text Port under WHO !!, because that is what their connection is changed to during the descr_setuser process.

Also remember that if a program you own is set PROG_DEBUG and DEBUG, you will see debug output even if you are not the one using it. This feature can be particularly handy when working with MUF port code, since there's no other way that you would be able to see the output. :)

Note that you cannot override the @tuned mainport with @ports props. Also, if you want to shut off an @tuned port (other than the main port), simply @tune it to 0 and @restart the MUCK. E.g., @tune puebloport=0, then @restarting the MUCK will bring your site up without an open Pueblo port.

That concludes my piece on @ports support. Reminder information can be found via HELP @PORTS, HELP @PORTS2, HELP MUF PORTS, MAN NOTIFY_DESCRIPTOR, HELP DESCRIPTOR FLAGS, and MAN DESCR_SET.

If you need further help, you are welcome to visit the ProtoMUCK mailing list or post questions to The MUF Den message board.