====== DSR Server Communication ====== Authors: metal-crow ===== Function control-flow used for the server-client communications ===== ==== Sending (last to first): ==== * SFSocketManager::Send * SVFW::SFStreamManagerTCP::SendToServer * SVFW::SFRPCManagerImpl::BuildClientTypeXRequestPacket * This is what encases the packet in layer 2 structure and encrypts it * Some async level between this and SendToServer * RPCSystem::LoginPacket/CommonPacket * QueueGeneralRequestTask takes the created packet, and puts it in the send queue * The class responsible for this level (from here to RPCSystem is an async queue) is FromNet::RequestManager * Build_X_GeneralRequestTask takes in the raw data for type X, makes it a flatbuffer, and sends to QueueGeneralRequestTask * These built the flatbuffer from back to front, putting the type in nearly last ==== Receiving (first to last): ==== * Recv * SVFW::SFStreamManagerTCP:RecvServerPacket * This encrypted data is copied out via MoveDataFromStreamConnection_To_Array * SVFW::SFRPCManagerImpl::RecvServerTypeXandPassToDecode gets the packet data and depending on the layer 2 packet type selects a decode * SVFW::SFRPCManagerImpl::DecodeServerTypeXPacket loads the SVFW::SFEncryptorSodium class and calls it method to decrypt the packet * SFSharedKeyEncryptor::Decryptor * FromNet::RPCSystem::ResponseFunctionArgs_Load_Flatbuffer finishes with the flatbuffer at FromNet::RPCSystem::ResponseFunctionArgs->GeneralRequestContext->ResponseArgs->GeneralRequestResult->sub->message_bytes_start * Load_Flatbuffer_Into_GeneralRequestContext * Get_Layer1Data_from_Flatbuffer * Load_Flatbuffer_Into_GeneralRequestContext_Parent * SVFW::SFRPCManagerImpl::ParseServerTypeXFlatbuffer * The string for the packet being received is in array @141b0f580 (for parent type 6) * This filters based on FlatbufferWrapper to the next function * SVFW::SFRPCManagerImpl::ParseServerFlatbuf_X * This unwraps the outer FlatbufferWrapper layer, checks the length and packet number, and passes on the flatbuffer For responses to Requests * FromNet::RPCSystem::ResponseFunctionArgs_Load_Flatbuffer * Load_Flatbuffer_Into_GeneralRequestContext * Load_Flatbuffer_Into_GeneralRequestContext_Parent * This creates a FromNet::GeneralRequestTask_Data class from the flatbuffer (via copy) * FromNet::RPCSystem::ResponseArg::Copy_into_Self * Saves the FromNet::GeneralRequestTask_Data into the RPCSystem class, specifically FromNet::RPCSystem::GeneralRequestContext::ResponseArgs->GeneralRequestResult For Push Requests * PushRequest_Recv * ProcessPushRequestType_() ==== Container ==== [[https://timleonard.uk/2022/06/18/reverse-engineering-dark-souls-3-networking-part-5 |This]] is a good overview [[https://google.github.io/flatbuffers/ | Flatbuffers]] are used for the data storage itself. Examples of this at a byte-level are at [[https://docs.google.com/spreadsheets/d/1Zbn81mgqxLDmlcyrvvC5Wwr2r3RHTD11J7zeYGmw2o4/ | this speadsheet]]. Of note, the raw flatbuffer itself is not sent to the server. It is wrapped in another struct before being sent. This is of the form: FlatbufferWrapper { uint8_t: Packet type. Sending = 4, 5, 6, 7. Type 4 is normal client packet, type 7 does not have any main data and is used as the client heartbeat. Other 2 are login, logout Receiving = 5 6 ? ?. Type 5 is normal client packet response. 6 is PushRequest type, and doesn’t have a packet number, and is a uint16_t uint32_t: packet number. Incremented per packet, response has the matching number. flatbuffer itself } [[https://github.com/mildsunrise/protobuf-inspector | Protobuf Inspector]] (online as https://protobuf-decoder.netlify.app/) is a good tool to RE the packets. ==== Message Types ==== The first header in the data/flatbuffer always contains a byte representing the message type. A mapping for these to their string names is embedded in the binary. For Requests (client initiates communication with server), it's ''FromNet::RequestManager::RequestFunctionNameList'' at address 141a73420. For Push Requests (Server initiates communication with client), it's ''FromNet::RequestManager::PushRequestFunctionNameList'' at address 141a735a0. ==== Requests ==== 7. RequestCreateBloodMessage * Actually for orange soapstone, not bloodstains. 17. RequestGetBreakInTargetList * Get the players you can invade in your area. * The player includes a number of their settings, like SL, weapon level, NatType, AreaId, etc. * The server then responds with a list of users you can connect to that fit the given settings. 27. RequestGetSignList * Gets type 25 as response from server 33. RequestUpdatePlayerStatus * Includes a large number of player flags, such as stats, equipment, and other character info. * Not all flags need be included. * This also includes anti-cheat triggered flags and game version flags.