Server Data Flow
Outlined here are several scenarios. The internal processes are briefly touched upon. You can think of it as 2 main threads at work: the Zone Thread and the Packet Thread. The first handles internal workings which do not rely on user input e.g. effects of poison, ticking of the Vana'diel day, roaming monsters, etc. The second handles direct requests from the client(s), e.g. request to attack a monster, request to trade with someone, sending a /tell, etc.
- This is initialised when the server starts.
- zone.cpp -> ZoneServer(tick) - The main thread of execution is located here. This checks status effects, handles AI ticks, handles instances and handles treasure pools. This is slept for 500ms (half a second) every round.
- packet_system.cpp - After a request is made to the server, the first major hurdle is deciding what the request it. The raw bytes are decoded into meaningful actions. Of particular interest is Packets/0x1A which governs many different actions.
- Some requests are handled immediately, e.g. calling for help simply sets a flag and returns the "You've called for help!" message, nice and simple.
- Other requests require the AI to actually do something, like start using a weaponskill. The action is set in the AI and started in this thread initially. An example of such an action:
uint16 WSkillID = RBUFW(data,(0x0C)); //grab the Weaponskill ID from the actual request packet PChar->PBattleAI->SetCurrentWeaponSkill(WSkillID); //Store that PChar->PBattleAI->SetCurrentAction(ACTION_WEAPONSKILL_START, TargID); //Tell the AI to start using a WS (state change) PChar->PBattleAI->CheckCurrentAction(gettick()); //Activate the state change, e.g. this will call ActionWeaponskillStart()
- The return is usually in the form of pushed packets, perhaps it's a message, or perhaps it's an entity update packet:
- The thread then blocks until it receives another request.
Performing a Weaponskill on Monster A
Z = Zone Thread, P = Packet Thread, the number indicates the 'round' (or tick) of the thread
- Z1: Zone server ticking away, character is in ACTION_ATTACK state and waiting for their weapon delay to be up.
- P1: packet_system.cpp receives a request packet for WS.
- P1: Character AI set to ACTION_WEAPONSKILL_START.
- P1: CheckCurrentAction is called.
- P1: ActionWeaponskillStart logic is checked, e.g. do you have enough TP, right distance from mob, etc.
- P1: All checks passed, state change to ACTION_WEAPONSKILL_FINISH.
- Z2: Zone server checks AI logic some time later (<500ms), sees you're in ACTION_WEAPONSKILL_FINISH state and handles logic (e.g. readying time passed, calculation of damage via LUA call, etc)
- Z2: Sends weaponskill action packet back to client.
- Z2: Transfers state back to ACTION_ATTACK.
Performing a zone
Z = Zone Thread, P = Packet Thread, the number indicates the 'round' (or tick) of the thread. That is to say, some time has elapsed between P1 and P2.
- P1: Server receives client position update (SmallPacket0x015) and sets new position.
- <Some time elapses between P1 and P2...>
- P2: Server receives client position update (SmallPacket0x015) and sets new position.
- P3: Server receives client position update (SmallPacket0x015) and sets new position.
- P4: Server receives client position update (SmallPacket0x015) and sets new position.
- P5: Server receives request to zone (yes, the client magically knows this) (SmallPacket0x05E).
- P5: Server responds with OK (0x0b -> CServerIPPacket) if it's okay and sets PChar->loc.destination to the new zone id, and PChar->loc.p (position) to the right zoneline.
- P6: Server receives a farewell packet (SmallPacket0x00D) from the client. This packet is always sent when you leave a zone, including when you logoff. If you disconnect, the packet isn't sent obviously, but the server will cleanup your character by faking a farewell packet from your session. This saves your stuff to the database and calls zone::DecreaseZoneCounter. At this point you can distinguish between a zone and a logoff/dc by looking at PChar->loc.destination which will be 0 if you're logging off or disconnecting.
- P7: Server receives a greeting packet (SmallPacket0x00A). This calls zone::IncreaseZoneCounter.
- P7: Server responds to the character as normal, after handling zone in stuff in IncreaseZoneCounter.