25 Oct, 2008, Runter wrote in the 121st comment:
Votes: 0
Yeah, std::map let's you access elements through []. A rom version could look like:
std::map<int, ROOM_INDEX_DATA *>   room_index;

while(more_rooms_to_load)
room_index[vnum_to_load] = new_room;

However, it's a non-intrusive container class that implements by default a self balancing binary tree. (Which is perfect for this problem.) Since we all know a balance binary tree gives us logarithmic search times.

Another interesting feature of a map in C++ is being able to assign it multiple types to be the "key". Such as

std::map<char *, ROOM_INDEX_DATA *> room_index;

room_index["A chessboard tile"] = new_room;

Not really practical for our case, but still interesting.


Multimaps are also interesting. It allows a single key to point to multiple instances of a type. Such as the key being a room vnum, and the multiple objects being the CHAR_DATA*'s inside of said room. boost library uses a 2way map that I actually employ that lets you lookup the key by value or, like one way maps, value by key.
25 Oct, 2008, quixadhal wrote in the 122nd comment:
Votes: 0
It's nice to know that drugs and/or alcohol were cheaper and easier to come by in our youth….

/*
* Set time and weather.
*/
{
int lhour,
lday,
lmonth;

lhour = ( current_time - 650336715 ) / ( PULSE_TICK / PULSE_PER_SECOND );


Anyone want to guess why 650336715 is significant? Birthday? Date DikuMUD Alpha went live? Date developers got accepted to Diku University? PostgreSQL says:

wiley=> SELECT TIMESTAMP WITH TIME ZONE 'epoch' + 650336715 * INTERVAL '1 second';
?column?
————————
1990-08-10 21:05:15-04
(1 row)


Anyone know their history?
25 Oct, 2008, quixadhal wrote in the 123rd comment:
Votes: 0
Heh, while I'm ragging on the devs….
/*
* Check age and reset.
* Note: Mud School resets every 3 minutes (not 15).
*/


but…

<: 2008-10-25 19:23:57.004 : BOOT     (comm.c;main,208)
: RaM is ready to rock on port 4000.
<: 2008-10-25 19:23:57.005 : RESET : mud school has just been reset.
<: 2008-10-25 19:25:57.970 : RESET : mud school has just been reset.
<: 2008-10-25 19:27:58.935 : RESET : mud school has just been reset.
<: 2008-10-25 19:28:07.091 : FATAL (comm.c;proper_exit,2207)
: Shutdown by SYSTEM – Received SIGINT or SIGTERM.


Unless my math is really bad, that's every 2 minutes, not every 3.
Just sayin'…..
25 Oct, 2008, David Haley wrote in the 124th comment:
Votes: 0
Having the abstraction layer of collection types is one of the most important contributors toward programmer-time efficiency, I have found.

FWIW, with some discipline, you can do it in C too, as long as you force yourself (and everybody else…) to talk to the container object through a function interface. (C++ just makes it easier to encapsulate and enforce this interface.)
26 Oct, 2008, quixadhal wrote in the 125th comment:
Votes: 0
Also, while I'm in seek & destroy mode…. here's a long-standing bug that's been with us since Diku Alpha.

Allow me to quote from the Gospel of TELNET, RFC 854:

Quote
The sequence "CR LF", as defined, will cause the NVT to be
positioned at the left margin of the next print line (as would,
for example, the sequence "LF CR"). However, many systems and
terminals do not treat CR and LF independently, and will have to
go to some effort to simulate their effect. (For example, some
terminals do not have a CR independent of the LF, but on such
terminals it may be possible to simulate a CR by backspacing.)
Therefore, the sequence "CR LF" must be treated as a single "new
line" character and used whenever their combined action is
intended; the sequence "CR NUL" must be used where a carriage
return alone is actually desired; and the CR character must be
avoided in other contexts. This rule gives assurance to systems
which must decide whether to perform a "new line" function or a
multiple-backspace that the TELNET stream contains a character
following a CR that will allow a rational decision.


Now, from our 2nd grade C classes, we'll remember that the symbol "\n" is a linefeed character, and the "\r" symbol is a carriage return. Those of us on UNIX-style systems generally only use LF, and those on really old Macs only use CR, while those on MS_DOS actually use CRLF as a single unit.

So, you'll note that pretty much EVERY SINGLE DIKU-derived MUD has thousands of "\n\r" sequences scattered throughout the code. That's LFCR, and is doubly-wrong! First, it should be "\r\n", and secondly – even if you did want to send LFCR – you'd send it as "\n\r\0", which is a PITA for C, but there you have it.

I first ran into this back in 1993 when I couldn't get triggers to work properly in TinyFugue, because I was anchoring them to the beginning of the line. But since the order was backwards, the line actually looked like "blah$^\rfoo", where there's an extra leading CR. The developer of a popular Java MUD actually got annoyed at me for trying to point out how this was wrong, and invoked the "it can't be wrong because every other MUD out there does it that way" rule.

I'd rather fix it here, if you guys don't mind. :)

EDIT: Oh, and there are actually a few places it was done right! egrep reports 1629 occurances of it the wrong way, and 9 the right way! Of course, two of those are lies, as they're double lines.
26 Oct, 2008, Runter wrote in the 126th comment:
Votes: 0
Can you show which lines it was done correctly on?
26 Oct, 2008, quixadhal wrote in the 127th comment:
Votes: 0
quixadhal@virt2:~/svn/ram-project/src$ egrep '\\r\\n' *.c        
act_info.c: "\n\r============================================================\n\r\n\r" );
act_wiz.c: send_to_char( "You cannot abbreviate the prefix command.\r\n", ch );
act_wiz.c: send_to_char( "You have no prefix to clear.\r\n", ch );
act_wiz.c: send_to_char( "Prefix removed.\r\n", ch );
act_wiz.c: sprintf( buf, "Prefix changed to %s.\r\n", argument );
act_wiz.c: sprintf( buf, "Prefix set to %s.\r\n", argument );
alias.c: send_to_char( "Line to long, prefix not processed.\r\n", ch );
alias.c: send_to_char( "Alias substitution too long. Truncated.\r\n", ch );
fight.c: send_to_char( "You have been KILLED!!\n\r\n\r", victim );


The one in act_info.c, and the one in fight.c are false positives… it's hitting on the middle of the 4-character LFCRLFCR sequence.
26 Oct, 2008, David Haley wrote in the 128th comment:
Votes: 0
I would argue that the server should only send \n and forget the \r silliness. Clients these days are quite able to figure that one out on their own.
26 Oct, 2008, Runter wrote in the 129th comment:
Votes: 0
Quote
I would argue that the server should only send \n and forget the \r silliness. Clients these days are quite able to figure that one out on their own.


That's what I was thinking. I'm just not authoritative enough on the subject to be the first one to say it. ;)

I've never really seen a problem with just \n. Although I guess it could still be relevant for some users?
26 Oct, 2008, David Haley wrote in the 130th comment:
Votes: 0
It would only be relevant for users with clients who only understand one of the other conventions (\r\n or just \r). The latter category are Mac users, and I believe that Mac clients have known for a long time that most servers don't speak \r and have dealt with it. The former category are Windows people, but many Windows clients know that they have to talk to Unix servers and so understand \n on its own as well. Furthermore, many (MUD) clients go to some effort to handle line endings correctly, because they have to deal with the correct \r\n and the incorrect \n\r. In the end of the day, from what I have heard, most clients only look for \n and ignore \r because it's too confusing to deal with it.
26 Oct, 2008, quixadhal wrote in the 131st comment:
Votes: 0
Just so you know…. your arguments break down to:

Most telnet clients are broken, so we should make the server broken too, since it's less work.

I will NOT promote broken telnet clients, ever. In fact, if there weren't so much else on the plate, I'd suggest properly implementing a full telnet stack. If we don't want to follow the TELNET protocol, then we need to develop and maintain a custom client. I've advocated abandoning telnet in favor of a custom protocol for a while now, but as has been pointed out in those discussions, to many folk that moves us out of the realm of "MUD" and into a seperate "online text game" space.

Probably not a proper fit for a project whose stated goal is to produce a server which acts like ROM, but is technically superior.

I'd actually argue the opposite… detect if a client sends an LFCR sequence (or a CR that is NOT followed by a NULL) and send them a line back saying

***NOTICE: You are using a BROKEN telnet client! Things may not work properly, and it's YOUR FAULT, not ours. ****
26 Oct, 2008, David Haley wrote in the 132nd comment:
Votes: 0
I don't think it's entirely unreasonable to follow the Unix convention for line endings. I think you are exaggerating a wee bit when you say that our only choices are to either (a) implement a full telnet stack or (b) develop and maintain a custom client. That's a false dilemma if I've ever seen one. :wink:

I'm all for yelling at clients that don't implement things properly, but that will accomplish next to nothing and will mainly irritate players who are stuck with non-conforming clients.

Incidentally, if you really want to get nitty-gritty about it, the servers should all be sending the GA code at the appropriate times.

Anyhow, this could also be solved by having a "NEWLINE" define that has the correct value, and then all strings that want to use a newline do this:

"Hello there" NEWLINE "How are you?"
26 Oct, 2008, Runter wrote in the 133rd comment:
Votes: 0
I say let's assume the terminal width is 80 characters and just pad everything with spaces til it wraps around to the desired formats.
26 Oct, 2008, quixadhal wrote in the 134th comment:
Votes: 0
It's unreasonable to follow the UNIX convention when people are using the TELNET protocol to connect to the game.

I never said those were the only two choices. In fact, I said if there weren't other, more important, things to fix first, I'd suggest a full telnet stack… but changing the line endings is a global search and replace that I've already done on my working copy, with no ill effects.

I think the GA sequence is one of the extensions to the protocol, but it probably would be useful to send one after a prompt, since that won't be terminated by a newline. In fact, the code does do this IF a bit on the character is set, but AFAIK no negotiation is done to determine if the client supports it (which means, only people who think about it get to use it).

As for a NEWLINE definition (which will ALWAYS be CRLF, because it's the standard… regardless of what your local architecture uses – hence the reason for a standard). that's already done for C++ (endl), assuming whomever overloaded socket streams did their job properly… good luck convincing anyone to use sprintf(tmp, "You died again.%s", NEWLINE); send_to_char(tmp, ch); Being able to concatonate adjacent strings is, I think, a GNU specific extension to C (unless it's part of C99, perhaps)?

I guess I've worked in production environments for too many years, so I can't see the value in NOT following an established standard correctly, especially when it's trivial to do so. Do you have any compelling reasons to deviate from the standard, other than it being less typing, or because everyone else does it wrong too?
26 Oct, 2008, David Haley wrote in the 135th comment:
Votes: 0
quixadhal said:
I never said those were the only two choices. In fact, I said if there weren't other, more important, things to fix first, I'd suggest a full telnet stack…

That was one of the choices :wink: (choice a to be precise)

quixadhal said:
Being able to concatonate adjacent strings is, I think, a GNU specific extension to C (unless it's part of C99, perhaps)?

No, I don't believe it's an extension. I've used it in ANSI C, IIRC.

quixadhal said:
I guess I've worked in production environments for too many years, so I can't see the value in NOT following an established standard correctly, especially when it's trivial to do so. Do you have any compelling reasons to deviate from the standard, other than it being less typing, or because everyone else does it wrong too?

I think it's somewhat wishful thinking to believe that the MUD world actually follows the telnet standard. Everybody follows some strange mashup of telnet and other things. Basically, the MUD world uses a line-by-line protocol, and people get bonus points for supporting telnet negotiation.

I think it's dangerous to try to stick to a standard – without additional help like a wrapper around sending data – when empirical evidence suggests that people are terrible at following it.
26 Oct, 2008, quixadhal wrote in the 136th comment:
Votes: 0
So, you've had problems logging into a real telnet server using a telnet client? I've never had any issues doing so. I've found tinyfugue and tintin both worked fine unless you tried to run full-screen apps (neither client would do the negotiation that would allow single-character mode or curses support).

How can doing things the right way be MORE dangerous than doing it the wrong way?
26 Oct, 2008, David Haley wrote in the 137th comment:
Votes: 0
quixadhal said:
So, you've had problems logging into a real telnet server using a telnet client?

I'm not sure what you're referring to here.

Well, this is a whole lot of tempest in a pretty small teapot. I agree that there are far more important things to be worrying about…
26 Oct, 2008, quixadhal wrote in the 138th comment:
Votes: 0
/agreed that it's too small to worry about. :)

I meant a real, honest-to-goodness telnet server… IE: telnetd, probably not running on port 23. On most systems nowadays, you'd have to go enable it, but that USED to be the way you connected to other machines, before ssh existed, and before rsh was popular. THAT is the only reason MUD's used telnet back in the day, because everybody had a telnet client.

Heck, if we really had extra time, I'd say let's implement the server side of ssh on another port. That way, you could allow players to use it if they wanted, but require it for immortals.
27 Oct, 2008, Vassi wrote in the 139th comment:
Votes: 0
quixadhal said:
/agreed that it's too small to worry about. :)

I meant a real, honest-to-goodness telnet server… IE: telnetd, probably not running on port 23. On most systems nowadays, you'd have to go enable it, but that USED to be the way you connected to other machines, before ssh existed, and before rsh was popular. THAT is the only reason MUD's used telnet back in the day, because everybody had a telnet client.

Heck, if we really had extra time, I'd say let's implement the server side of ssh on another port. That way, you could allow players to use it if they wanted, but require it for immortals.


It seems to me the only way to 'sneak in' a new client model is to make a working Telnet client that also just happens to support this new protocol (whatever it is), and make sure said client is available on multiple platforms.

Of course, some would be quick to point out what happened with MXP, or that it's already happened with Aardwolf\MUSHClient, but that is a whole different case - I think. I wish Nick and Lasher had taken things a notch higher with the Aardwolf integration, I really feel it would have made a bigger difference. In both cases they were\are trying to ride Telnet - which is arguably not a bad idea, subnegotiation (if you rigged it to work both ways) is pretty awesome. The problem of course comes back to how most existing implementations are just good enough to get by (most often by just ignoring everything except a few select things).

Anyway, I feel I shot myself in the foot somewhere in there but I'm not sure where. It's been a long day.
31 Oct, 2008, Runter wrote in the 140th comment:
Votes: 0
Telnet

Yakk Deculture.
120.0/267