Server Data Flow
From DSP Wiki
Revision as of 22:49, 24 July 2012 by Kegsay (Talk | contribs) (Created page with "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 Th...")
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.
Zone Thread
- 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 Thread
- 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:
PChar->pushPacket(new CMessageBasicPacket(PChar,PChar,0,0,22));
- The thread then blocks until it receives another request.
Examples
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.