27 Feb, 2009, quixadhal wrote in the 21st comment:
Votes: 0
Scandum said:
quixadhal said:
Hence my suggestion to either use snprintf (length-limited, since you don't seen to get it), or better yet, use varargs which are far simpler to maintain than countless "%c%s%c%s" cut-and-paste strings.

I see nowhere in the telnet protocol that it's alright to send incomplete negotiations if you run out of buffer space. Can you show me the rfc?

Yeah, it's the RFC that says when your game server crashes due to a seg fault, it will have STILL sent an incomplete negotiation. Or, maybe not, since it might not have sent anything at all yet. Of course, since the connection has gone away, it probably doesn't matter much at that point.

Scandum said:
quixadhal said:
Ok, I'll inflate your ego a bit more (maybe it'll burst!) and bite. HOW does my suggesting the use of d_printf() imply that I've never dealt with advanced telnet option negotiation? I can't wait to hear this one.

For starters the silly notion of automatically escaping IAC characters, most muds are English and don't use it unless they're dealing with telnet.

How does the use of d_printf() automatically escape anything? The only thing it does is allow you to NOT have to sprintf() to a temporary buffer BEFORE you send it to the outbound socket buffer. It has nothing to do with the content you're sending out.

Scandum said:
Next it's silly to create 2 utility functions that are only used in one function while the advantage to a general purpose function is close to zero.

The advantage is clarity. If lumping some random number of options into single sprintf() calls is such a good idea, why not just use one big sprintf? I mean, you don't care about buffer overruns, right?

Scandum said:
And obviously you didn't think of handling NUL bytes.

I thought about it as much as you did, since sprintf() will do exactly the same thing with a NUL byte as vsnprintf() will from a varargs function.
27 Feb, 2009, elanthis wrote in the 22nd comment:
Votes: 0
I seem to be missing whatever post includes quixdhal's printf_descriptor() implementation…

You're right that failing to deal with running out of buffer space is a real problem. Any implementation of a buffered output protocol (or dealing with syscalls that can end up doing partial writes, like the BSD sockets protocol) has to deal with making sure that ALL output goes out or that some sensible error handling takes place.

My implementations generally keep a small output buffer (say, 1K). When that fills, it attempts to do a non-blocking send() of the buffer to the client. If that fails to free up enough buffer space, I allocate a larger buffer (say, 16K). If that fills up, we try the non-blocking send() again. If/when the large buffer is flushed, it gets deallocated and we revert to using the small buffer. If the large buffer fills up and we can't flush the data, then the code gives up and disconnects the player; the player obviously isn't doing much playing at that point anyway.

Keep in mind that while the kernel has its own socket buffers too, they're pretty small. (On Linux, it'll be somewhere between 4K and 16K unless you manually override it.) If your MUD is heavy on the output, you may want to increase those buffer sizes accordingly… you really don't want to drop players just because their network connection started dropping packets for a couple seconds.

snprintf() makes it easy to deal with buffers, thankfully. Pass it a pointer to the end of the data in the buffer and the number of bytes remaining, and check the return value. If the return value exceeds the number of remaining bytes, it got cut off. Do not update the number tracking the used bytes in the buffer if it gets cut off; that makes recovering very hard! The safest/easiest way to deal with running out of buffer space is to just flush the old data or resize the buffer and then call snprintf() again with the new buffer information. If snprintf() indicates that it wanted to generate more output than your maximum buffer size, log it with a huge "[BUG] CODE OVERFLOWS BUFFERS LOLZ" message. Then you can fix the code to not generate reams of output or increase your buffer sizes, whichever is most appropriate.

Of course, if you're using Java of C# or something that has one of those fancy BufferedStreamWriter classes, they're already doing something like the above for you… hopefully.

Quote
Besides eor, terminal type, naws, and new environ, is there anything else that is of particular use to muds or mud clients?


MCCP, ZMP, MSP all use TELNET commands. MCCP and ZMP use sub-negotation.

Quote
For starters the silly notion of automatically escaping IAC characters, most muds are English and don't use it unless they're dealing with telnet


It seems silly up until the point that you realize that you weren't stopping players from sending IAC bytes to you and some dipstick decides to start typing in "say " IAC IAC SB and causing all the other players in the room to get hung terminals (a correct TELNET implementation would turn IAC IAC SB into just IAC SB in the command buffer). Which they can also easily do with ANSI escape sequences, too. While you should be filtering input for safety, keep in mind that the IAC byte is perfectly valid in ISO-8859-1 and in win-1252, which are still quite common in the real world. Even if you refuse to accept IAC in your command buffer, anyone with a clue about security and safety in software design knows – never take the chance. Filter the input, escape the output. "Better safe than sorry."
27 Feb, 2009, David Haley wrote in the 23rd comment:
Votes: 0
Dikurivatives at least, and AFAIK, reject any input character that isn't strictly ASCII printable, so I think the issue of "bad characters" goes away.
27 Feb, 2009, KaVir wrote in the 24th comment:
Votes: 0
Scandum said:
The only codebase that really comes to mind right now is Emlen which doesn't have classes and has a skill tree that is available to all races, though skills tend to have stat requirements that are more easily met by some races than others.

But do you consider it an open skill system because anyone can learn any skill, or because of the degree of choice each character has?

If I ran an Emlen mud and labelled all of the stock skills "warrior skills", then added the same number and variety of skills for each of wizard, cleric and thief - so that there was just as much choice within each class as there was for any character in a stock Emlen mud - would that still be an open skill system?

Alternatively, what if I kept the current skills available to everyone, but added a few race-specific skills. The races would effectively become classes, but would it still be an open skill system?

What about ROM, where you can customise your skills and spells during character creation, regardless of class? Would you consider that an open skill system, or does the fact that you're pidgeon-holed after creation make it a closed skill system?

What about the classes in Rolemaster, which can theoretically learn any skill - although each class learns certain skills far more cheaply than others, to that point that it's not practical to learn certain skills.

Even in a classless mud, you might have mutually exclusive abilities - and if you can only choose one of "Combat Reflexes", "Arcane Aptitute", "Blessed Existence" and "Naturally Stealthy", is that really any different from having warrior, mage, cleric and thief classes?

If you want to indicate which muds have skill trees, perhaps it would be simpler just to have a "SKILL-TREE" option. Would you want to distinguish between skill trees and skill webs?

Scandum said:
Then again, classless will do, and even if you consider your mud classless, seeing how mages are a race in Tolkien's works, the races function as classes if each has their own skill group.

I don't consider my mud classless, no, for the very reason you just gave - there are different classifications of character (not necessarily even races), each with their own abilities. However I do consider it a fairly open skill system, in that each class can be designed and played in a wide variety of different ways (even emulating each other to a certain degree if desired).

Scandum said:
I can't readily think of a worldless mud though, but it'd avoid muds accidentally listing themselves as 0 instead of 1.

If there's no game world, can it even be classified as a MUD?

Scandum said:
"SKILLS" Number of skills, use "0" if skill-less.

Would that include spells as well, or should they have their own category? What about other abilities that fall somewhere between skills and spells?
27 Feb, 2009, Grimble wrote in the 25th comment:
Votes: 0
Looking at all the "official" variables, and the follow-on discussions in this thread and the other on variations and exceptions to those variables, it seems that the data is moving beyond "status".

There are a lot of variables that are relatively static (and there's no need for the IP address and port variables given that they need to be known in advance anyway), whereas I thought the point of MSSP was to report "status", which implies dynamic variables.

Certainly uptime, statistics, who, motd, and variables of that nature fall into this category, whereas the majority of the rest are static (and descriptive) and are often part of the MUDs registration data on a given MUD site.

I think some pruning may be order.
27 Feb, 2009, Scandum wrote in the 26th comment:
Votes: 0
quixadhal said:
How does the use of d_printf() automatically escape anything? The only thing it does is allow you to NOT have to sprintf() to a temporary buffer BEFORE you send it to the outbound socket buffer. It has nothing to do with the content you're sending out.

As far as I know both sprintf and vsprintf require a temporary buffer. Care to explain?

KaVir said:
If you want to indicate which muds have skill trees, perhaps it would be simpler just to have a "SKILL-TREE" option. Would you want to distinguish between skill trees and skill webs?

The more I think about it the less alluring it becomes to add.

KaVir said:
If there's no game world, can it even be classified as a MUD?

Probably not.


Probably not.

[quote=KaVirWould that include spells as well, or should they have their own category? What about other abilities that fall somewhere between skills and spells?[/quote]
Easier to lump them for most muds I think. DikuMUDs simply report MAX_SKILL.

[quote=Grimble]There are a lot of variables that are relatively static (and there's no need for the IP address and port variables given that they need to be known in advance anyway), whereas I thought the point of MSSP was to report "status", which implies dynamic variables.[/quote]
Changed ports, IP addresses, etc, can be updated through this mechanism.

[quote=Grimble]Certainly uptime, statistics, who, motd, and variables of that nature fall into this category, whereas the majority of the rest are static (and descriptive) and are often part of the MUDs registration data on a given MUD site.[/quote]
Part of the appeal is supposed to be that you update the MSSP report and mud listing sites automatically adjust their data. It also creates the option for a mud statistics site that allows sorting by players, uptime, and connectivity.
27 Feb, 2009, Mister wrote in the 27th comment:
Votes: 0
Grimble said:
it seems that the data is moving beyond "status".
Certainly. And I don't see any point to the "IAC DONT MSSP" client command, as it doesn't change the server state whatsoever.
The "IAC DO MSSP" command should be changed to be able to ask for specific data such as "FULL" or just "STATUS".

However, this:
Quote
If a variable is omitted it is assumed the previously reported value for that value should be used
What? How does the mud server knows it has already reported some data so that it doesn't need to repeat itself? Will it need to store all ips that have asked for mssp data so that it doesn't need to send it over again?

And from the client's pov, is there anyway to know if the server is the same as last time? Maybe the mud was taken down, and replaced by another with the same codebase and a different name, or it's the same mud that changed names. Or maybe the codebase version was pumped up; it's a new mud now?

The server should return a 'signature' to identify itself to avoid this problem, or change CREATED to return a full date (how to make new mud-owners to update that field is left as an exercise)
Also, the client should assume that if a variable is omitted, it no longer exists.
27 Feb, 2009, Grimble wrote in the 28th comment:
Votes: 0
Scandum said:
Grimble said:
There are a lot of variables that are relatively static (and there's no need for the IP address and port variables given that they need to be known in advance anyway), whereas I thought the point of MSSP was to report "status", which implies dynamic variables.

Changed ports, IP addresses, etc, can be updated through this mechanism.

This doesn't make sense. The client that initiates the telnet session to the MUD server has to know in advance the correct IP address and port to do so. Sending the client that same information back via MSSP is redundant. Or, are you suggesting that MSSP may run on a different IP address and/or port than the MUD server? That got shot down earlier.
27 Feb, 2009, Scandum wrote in the 29th comment:
Votes: 0
Mister said:
The "IAC DO MSSP" command should be changed to be able to ask for specific data such as "FULL" or just "STATUS".

We're following the telnet protocol here, so that's no option. That would require a two way sub negotiation, and that's incompatible with the primitive MCCP implementation most muds have. The total data send will generally be less than half of the actual login screen, so I don't see a big issue there.

Mister said:
What? How does the mud server knows it has already reported some data so that it doesn't need to repeat itself? Will it need to store all ips that have asked for mssp data so that it doesn't need to send it over again?

Were I to be king of the world there would be some drastic changes, but as it is I'm not going to dictate how servers handle things behind the scenes. Servers could send out full information only on the first day of the week, but honestly I don't care.

Mister said:
And from the client's pov, is there anyway to know if the server is the same as last time? Maybe the mud was taken down, and replaced by another with the same codebase and a different name, or it's the same mud that changed names. Or maybe the codebase version was pumped up; it's a new mud now?

That's the crawler's concern, not mine.

Mister said:
The server should return a 'signature' to identify itself to avoid this problem, or change CREATED to return a full date (how to make new mud-owners to update that field is left as an exercise)
Also, the client should assume that if a variable is omitted, it no longer exists.

A variable can be omitted by providing 0 or an empty string. Guess I should make a mention for strings in the protocol description.

Grimble said:
This doesn't make sense. The client that initiates the telnet session to the MUD server has to know in advance the correct IP address and port to do so. Sending the client that same information back via MSSP is redundant. Or, are you suggesting that MSSP may run on a different IP address and/or port than the MUD server? That got shot down earlier.

No, crawler connects to bobmud.com 4321, MSSP reports that domain is bubbamud.com and the port is 1234. Crawler updates list. Next day crawler connects to bubbamud.com 1234. Capisc?
27 Feb, 2009, Grimble wrote in the 30th comment:
Votes: 0
Scandum said:
Grimble said:
Certainly uptime, statistics, who, motd, and variables of that nature fall into this category, whereas the majority of the rest are static (and descriptive) and are often part of the MUDs registration data on a given MUD site.

Part of the appeal is supposed to be that you update the MSSP report and mud listing sites automatically adjust their data. It also creates the option for a mud statistics site that allows sorting by players, uptime, and connectivity.

Then if this is to be a true protocol, I would suggest different request types for the different types of data sets. In this case, there's profile data (relatively static stuff like genre, codebase, etc) and real-time data (dynamic stuff like uptime, connected players, statistics, etc). Then each of the identified applications requests and gets only what it wants.
27 Feb, 2009, Grimble wrote in the 31st comment:
Votes: 0
Scandum said:
No, crawler connects to bobmud.com 4321, MSSP reports that domain is bubbamud.com and the port is 1234. Crawler updates list. Next day crawler connects to bubbamud.com 1234. Capisc?

You're making a big assumption that either the MUD server will run on both addresses/ports until all the MUD crawlers have migrated to the new address/port, or that all the MUD crawlers poll the MUD server often enough (i.e, at least daily) that the MUD server can safely cut over to a new address/port at any time.
27 Feb, 2009, Noplex wrote in the 32nd comment:
Votes: 0
No offense to anyone who has worked hard on this already, but I don't see the point in this idea.

At some point you're going to need to list the games somewhere and instead of going through the hassle of writing some extensive protocol to query all of the games available online that someone is just going to end of extending because you forgot about something (e.g. IMC2, I3) how about you work on developing a better listing service?

Its all and well to have the ability to finger a MUD to get all its information, but if I don't know where that MUD is located in the first place it kind of defeats the purpose, doesn't it?

Just my two cents. Go back to your quarrels.
27 Feb, 2009, Scandum wrote in the 33rd comment:
Votes: 0
Noplex said:
(e.g. IMC2, I3)

Forgot about those, are those the names they go by?

Noplex said:
Its all and well to have the ability to finger a MUD to get all its information, but if I don't know where that MUD is located in the first place it kind of defeats the purpose, doesn't it?

This way anyone can add a mud to a new database by only entering a domain and a port. Verification is trivial, update is automatic, fraud is impossible, and if needed you can generate a list from TMC and add every mud that support MSSP.
27 Feb, 2009, Noplex wrote in the 34th comment:
Votes: 0
Scandum said:
This way anyone can add a mud to a new database by only entering a domain and a port. Verification is trivial, update is automatic, fraud is impossible, and if needed you can generate a list from TMC and add every mud that support MSSP.

So you're talking about making a generic protocol to facilitate the non-generic listing service - do you plan on working on that as well? It just seems like a waste of time to me, but it is your time to waste.
27 Feb, 2009, Scandum wrote in the 35th comment:
Votes: 0
Noplex said:
It just seems like a waste of time to me, but it is your time to waste.

So is sleeping, but alas.
27 Feb, 2009, Mister wrote in the 36th comment:
Votes: 0
Scandum said:
Mister said:
The "IAC DO MSSP" command should be changed to be able to ask for specific data such as "FULL" or just "STATUS".
We're following the telnet protocol here, so that's no option. That would require a two way sub negotiation, and that's incompatible with the primitive MCCP implementation most muds have.
What's the problem with MCCP? If the server reads "IAC SB SEND_STATUS IAC SE", it sends only status; if it reads "IAC SB SEND_FULL IAC SE", it sends everything. Since the server doesn't receive mccp'd data, it shoudn't be a problem. (my telnet-fu has been weakening over time, so any correction is welcome)

Scandum said:
Servers could send out full information only on the first day of the week, but honestly I don't care.
Most likely, all servers will send the full information each time, just to be sure (if they care at all.)
27 Feb, 2009, Scandum wrote in the 37th comment:
Votes: 0
MCCP goes like this: Server: WILL MCCP, Client: DO MCCP, Server: IAC SB MSSP IAC SE.
MSSP goes like this: Server: WILL MSSP, Client: DO MSSP, Server: IAC SB MSSP <stuff> IAC SE.

As you can see it should be fairly easy for servers that support MCCP to add MSSP support because the protocols are nearly identical.

Quote
Most likely, all servers will send the full information each time, just to be sure (if they care at all.)

It's only a handful of bytes though some programmers are likely to go into anal mode when it comes to stuff like that while their uber colored score and login screen burn bytes like Phelps burns calories. But for the sake of keeping it small and making dealing with packet fragmentation optional I'm not keen on adding MOTDs and other stuff that will push it over 1Kb.
28 Feb, 2009, quixadhal wrote in the 38th comment:
Votes: 0
Scandum said:
As far as I know both sprintf and vsprintf require a temporary buffer. Care to explain?

No.
man snprintf. Note the "n". Read about how to handle buffer overflows. Now, compare and contrast doing it properly with all the temp buffers in the open, vs. having a clean API that only has to do it in one place.
28 Feb, 2009, quixadhal wrote in the 39th comment:
Votes: 0
Scandum said:
MCCP goes like this: Server: WILL MCCP, Client: DO MCCP, Server: IAC SB MSSP IAC SE.
MSSP goes like this: Server: WILL MSSP, Client: DO MSSP, Server: IAC SB MSSP <stuff> IAC SE.
Quote
Most likely, all servers will send the full information each time, just to be sure (if they care at all.)


Why not just?

Server: WILL MSSP
Client: DO MSSP
and later…
Client: IAC SB MSSP SEND_VALUE foo IAC SE
Server: IAC SB MSSP bar IAC SE

In other words, why must the server be the one doing the sending? Why not let it wait for the client to ask for it? Just because the client agreed that it wants to do MSSP, doesn't mean it has to do it right then and there.
28 Feb, 2009, elanthis wrote in the 40th comment:
Votes: 0
Scandum said:
Were I to be king of the world there would be some drastic changes, but as it is I'm not going to dictate how servers handle things behind the scenes. Servers could send out full information only on the first day of the week, but honestly I don't care.


Aside from the stupidity of only sending data based on something like day of week (what if the MUD was down Sunday?), the fact that you don't even have a well-defined use case for the feature is 100% absolute undeniable proof that the feature should not exist.

Seriously. If you don't need it, DONT ADD IT.

Quote
No, crawler connects to bobmud.com 4321, MSSP reports that domain is bubbamud.com and the port is 1234. Crawler updates list. Next day crawler connects to bubbamud.com 1234. Capisc?


No, not at all. If the MUD is no longer on bobmud.com 4321, then the client will attempt to connect and the connection will fail, and it will never be able to get the MSSP data telling it where the new address is. The only way this works is if somebody leaves an empty temp server running on the old host or port (rare in the MUD world, as a move usually implies that the old account was lost), or if they somehow have it listening on both ports (most MUDs cannot do that, and almost no hosts will set up DNAT for it).

That is yet another advantage of a Web-based approach to this: the crawlers can quickly learn that an old server is gone (because it can't connect to the host/port), but new MUDs can be found with regular web crawling – soon as a MUD operator links to his MUD in his blog on LiveJournal, the new MUD has become reachable, and can be picked up within weeks without even having to manually register the MUD. If the protocol required a file with a particular name (e.g. mssp-manifest.rdf) then a clever crawler could even cheat and leverage Google to narrow the crawlers search space considerably, e.g. by searching on "inurl:mssp-manifest.rdf" (which will still reeturn a lot of false positives, but it's definitely a greatly reduced search space). You can still allow MUD owners to manually register as well, of course.
20.0/154