Author
Topic: Driver control flow before and after connect.c (Read 1811 times)

Long story short, I'm working on a modification of connect.c to allow importing characters from file for admins. Character importing happens in-between a correct admin password being provided and the admin logging in. The imported players are not loaded until logging in as them.

I've gotten it all working with one caveat. If I take the server down after importing characters, but before logging into the them, they are genderless without a space in their name, among other issues. This is happening because whatever function the new player object is returned to is calling pointers to the capitalized name and gender, stored with CapNamen and Gendre in connect.c. If the server is still up, these remain in memory and the correct values are written to the player save file. Other fields such as race are unaffected.

The last line that's executed in connect.c prior to successful world entry is

CapName "Firstlast"Gender "Neuter"So it's definitely something called after connect.c that dumps the pointer data to the player save. According to http://lpmuds.net/smf/index.php?topic=584.0 the driver calls master object (master.c) to ultimately call connect.c, but the details of what, when, and how the driver executes everything from start to master and then from there are very vague. I know that when an object is first loaded, the create function in it is first called...but then what? The create function simply initializes variables and performs other base state setup, but it doesn't make function calls itself. The object calling it generally calls a function to execute within, but when the previous object is flat out destructed, where does the flow of control go?

The driver doesn't "run" a player the way a DikuMUD works. The driver has a handful of applies that get called when network level things happen. The call the exec() tells the driver that when input arrives at the socket from now on, it should be sent to the Player object instead of this_object().

Player, in this case, is a global variable in connect.c which is set in the InputPassword() method by Player = master()->player_object(Name);

The last piece of code the driver (via connect) runs is Player->SetTeloptIp(0). A that point, the player object exists, has been initialized or restored, and exec() has transferred processing to that object. Text send to that object will be sent to the socket associated with the connection, and input received on that socket will be sent to the receive function of the object for processing.

The "magic" part happens in the master object. That's where it takes the player name and restores the saved data via a call to load_object(), returning the new object if it worked.

Note that there is security in place to prevent arbitrary code from calling this function, as it would be a nasty security hole if anyone could do this... effectively you could become anyone (including admins) without needing the login with their password.