Author Topic: I3 mudlist fix  (Read 1817 times)

Offline quixadhal

  • BFF
  • ***
  • Posts: 618
    • View Profile
    • A Waste of Time
I3 mudlist fix
« on: September 10, 2012, 09:37:56 PM »
So, for those brave few who might be trying to coax the ancient Discworld into life, with the old distribution that Cratylus has so kindly placed in his respository... here's a fix that's the result of a change to the way mudlist packets are handled on I3.

If I remember correctly, we had gotten to a point somewhere along the line where the mudlist was rather large (many muds, even if most of them had no players).  I believe around the time of the DikuMUD exodus from IMC2, it was discovered that the giant mudlist packets would overflow the fixed-size buffers of some of the Dikurivative codebases.

In an attempt to remedy the situation, the router was made to split the mudlist up into multiple packets, the theory being that if you get multiple packets, you handle each seperatly, and since you're supposed to add new muds onto your local list when you see them, and only remove them when the router says they're gone (or the data gets old enough)... it should work, right?

Well, one line of extra error checking stops that from working in the Discworld distribution.  The idea, if I'm reading this right, is that the router will send out an ID along with the mudlist packet, which tells you if this has changed since the last time you saw it.  If the ID is the same as it was last time, nothing has changed so no need to process it.  Good idea.  Problem is, NOW you get multiple packets in a row with the same ID because the list is sent in chunks.

The router-side solution is to increment the ID for each packet, but keep track of the starting point unless there *IS* a change... so if you break the list into 12 packets, starting from ID 2000, the clients would see ID's 2000 through 2011, and then again 2000 through 2011.  The clients would then change their check from seeing if packet->ID == last_seen_id, to if packet->ID <= largest_seen_id.  So, for 2000, it's new.. process, for 2011, process, now when you see 2000 again, you've seen 2011 so ignore it until 2012.

That fix isn't here... but this is the place you'd put it for Discworld.  The fix here just ignores the ID so you always process it, which solves the problem at the expense of a bit of extra CPU.

/net/intermud3/intermud.c:
Code: [Select]
protected void eventRead(int fd, mixed *packet) {
...
  case "mudlist":
    if( sizeof(packet) != 8 ) return;
    /* DS has this check commented out, perhaps because of
     * the new fragmented mudlist packets?
     */
    /* if( packet[6] == MudList->ID ) return;  */
    if( packet[2] != Nameservers[0][0] ) return;
    MudList->ID = packet[6];
    foreach(cle, val in packet[7]) {
      if( !val && MudList->List[cle] != 0 )
        map_delete(MudList->List, cle);
      else if( val ) MudList->List[cle] = val;
    }
    unguarded((: save_object, SAVE_INTERMUD, 2 :));
    return;
...
}

Offline wodan

  • BFF
  • ***
  • Posts: 434
  • Drink and code, you know you want to!
    • View Profile
Re: I3 mudlist fix
« Reply #1 on: September 11, 2012, 05:19:37 PM »
ah, we still had that in (until just now) thanks for finding that :)