Advertisement
quixadhal

MUD code spelunking

Aug 19th, 2019
209
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.54 KB | None | 0 0
  1. This was an amusing process, which someone might enjoy reading.
  2. My old DikuMUD has a message board system that saves all the messages to files, and it was next
  3. on the chopping block for SQL conversion, so of course, I had to figure out how it actually worked.
  4.  
  5. Unlike MOST things, the board system uses a built-in line editor, and in a DikuMUD that means
  6. it has to save state information across the main loop. Rather than put the user into a special
  7. connection state, they did something very odd instead, which let them reuse the same editor
  8. for anything, but which also means the code involved doesn't know what is being edited.
  9.  
  10. These are simply the comments I put in the code while figuring out what the hell it was
  11. doing, so I could plan a way to replace it.
  12.  
  13. // OK, so now we need the player data structure to have buffers to store
  14. // the subject line, and relocate a bunch of stuff that's probably in nanny()
  15. // here, so it's all in one place.
  16. //
  17. // The message date will be generated by the database itself.
  18. // The owner is GET_NAME(ch)
  19. // The subject is provided by arg.
  20. // The body will be provided by the nanny() state after the user exits the editor.
  21. // The message_id will simply be MAX(message_id) + 1 WHERE vnum = this board's vnum.
  22. //
  23. // Presumably, this is where the message will be captured.
  24. // ch->desc->str = &b->msgs[b->msg_num];
  25. // ch->desc->max_str = MAX_MESSAGE_LENGTH;
  26. //
  27. // So convoluted....
  28. // Rather than using a proper connection state like nanny() does,
  29. // There's a custom check on descriptor->str. If it isn't NULL,
  30. // it calls string_add(), passing it the descriptor and socket input.
  31. // line 557 comm.c
  32. // The socket input was obtained via get_from_q()
  33. // line 541 comm.c
  34. // That code however, only runs if get_from_q() returns 1, which happens
  35. // when there was some input to process, which happened in process_input()
  36. // in the loop above this one.
  37. // line 518 comm.c
  38. // The question is... what uses descriptor->str BEFORE it gets NULL'd
  39. // away in string_add(), which sets it to NULL when it sees the terminator
  40. // line (an '@' by itself)?
  41. // line 104 modify.c
  42. // line 130 modify.c
  43. // AHA!
  44. // board_save_board() is called from command_interpreter()
  45. // if board_kludge_char is set.
  46. // line 236 interpreter.c
  47. //
  48. // SOOOO, desc->str is a pointer to the board message array element that
  49. // holds the message body.
  50. //
  51. // string_add() uses strcat() to append every line of input to that array
  52. // element until the terminaitor is found.
  53. //
  54. // At that point desc->str is set to NULL, and board_save_board() is called
  55. // to write the changed array to disk.
  56. //
  57. // The tricky part here is that we don't KNOW what string_add() was modifying
  58. // since it's used for anything that uses the built-in editor. We only have
  59. // the point that board_save_board() is called.
  60. //
  61. // What we probably need to do is make a board_message_data structre in the
  62. // descriptor strcture, and simply check that. We can set desc->str to point
  63. // at that element or be NULL, to work with the existing code, and the check
  64. // for board_kludge_char will simply be changed to check if the message structure
  65. // has a non-zero message_id and vnum.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement