ID:1409854
 
(See the best response by Ter13.)
I always wondered.. What does Login(), Logout(), and "world or src or usr <<" look like..? How were they programmed?
Can you clarify? I'm not sure I understand your question.
What makes Login() work, pretty much. What is it made of. What's behind it. It's a question that's always been bothering me.
Best response
Well, internally, the Client notifies the server that a new connection has been requested. The Client validates the user's key, and then the server determines whether the connection is accepted.

Then, the server, on the back-end, will send the required resource package to the player, and client/New() is called. If a mob exists with the client's matching key, connect the client to that mob, and call mob.Login(), also assigns client.mob, and mob.client. If no mob is found, create a new one of type world.mob.

Login(), then checks of the mob has a location. If the mob does not have a location, it will search from 1,1,1 until it finds a position that permits Move(). If no position is found, location will stay null. If Move() returns one, the loop breaks, and your location is assigned to that turf.

Logout() is called by client.Del(), or when client.mob changes.

Logout() by default, does nothing.

Client.Del() is called whenever the connection between the world and the client is terminated, or dies.

Their base behavior is written in C++, I believe, and the top-level ..() supercall will trigger the base behavior.


So the order goes:

Client.New()->mob.Login()
client.mob = newmob -> newmob.Login() -> oldmob.Logout()
Client.Del()->mob.Logout()
Then, the server, on the back-end, will send the required resource package to the player, and client/New() is called. If a mob exists with the client's matching key, connect the client to that mob, and call mob.Login(), also assigns client.mob, and mob.client. If no mob is found, create a new one of type world.mob.

Just sparked my interest.. What if there was no mob/Login() in a source?

world/New()
spawn()
FalseLogin()

mob/var/loggedin

proc/FalseLogin()
for(var/mob/M in world)
if(!M.loggedin)
//Do something you'd normally do in a mob/Login()
M.loggedin = 1


Usually when you log in and it says, "Another ... logged in with your key. You have been disconnected," or whatever.. Then it resets your progress. I presume this is from Logout() or client/Del() having del(src) in it?

So, not including del(src) would in turn allow the newly logged in player to take control of the mob that was never deleted. If or if not, would the above code also work in a similar way?
In response to Xirre
Xirre wrote:
What is it made of.

Cupcake sprinkles, a dash of fairy dust, and a meadow full of flowers.
In response to Keeth
In response to Xirre
Xirre wrote:
Usually when you log in and it says, "Another ... logged in with your key. You have been disconnected," or whatever.. Then it resets your progress. I presume this is from Logout() or client/Del() having del(src) in it?

Nope. Neither. Key collisions for connections are a feature handled by Dream Seeker internally.

Also, Logout() does nothing, and client/Del() just disconnects the mob (if I recall).
In response to Xirre
Xirre wrote:
Just sparked my interest.. What if there was no mob/Login() in a source?
Built-in procs that aren't overridden do their default behavior by default. It's not like you actually define mob/Login() anywhere.
Dang.. Thought I was going to discover something. Guess I have to try something else.
In response to Kaiochao
Kaiochao wrote:
Xirre wrote:
Just sparked my interest.. What if there was no mob/Login() in a source?
Built-in procs that aren't overridden do their default behavior by default. It's not like you actually define mob/Login() anywhere.

The way I understand it, it's actually the other way around, sorta.

Basically, the built-in functions look at the class tree, which is generated as part of the DMB format. It finds the current class in the tree, then locates a function matching the handle of the current function.

It then . is set in the stack to the current function, and .. is set in the stack to the parent function. The parent function is a look-up search. It will essentially look upward until it finds another function with the same handle. If the function belongs to the same class, the parent function will be the one that came before the current one according to the compiler's parsing of your source code. Generally speaking, it's based on the #include order of your dm files, and tends to be generated in alphabetical order in the DME --This, however, can be overridden by explicitly lacing #includes throughout your code, rather than using the built-in linker.

If no function handle with a matching name is found, it will move upward into the superclass, searching for another match. If no superclass is found, or has been explicitly injected into the scheduler, the default function will continue.
In response to Ter13
My point was that you never actually define built-in procs anywhere; they can only be overridden, because they're built into the BYOND engine and pretty much exist outside of your source.

I'm not sure what part of what I said you think is backwards.

For example, in a fresh environment, this is effectively equivalent to an empty code file.
mob/Login() ..()


However, this prevents the default behavior to occur (the mob cannot move with Move()).
mob/Move()
The way the VM functions. My understanding is that while what you said was correct, it's kind of the reverse of what happens. Maybe I shouldn't have chipped in there, because without having written a VM of your own, it's hard to understand how they work.