These handle all game-specific data.
The two primary functions of interest are
bool sendNetMessage(NS_FRPG::FrpgSessionManagerImp *sessionman,ConnectedPlayerData *playerdata, uint64_t type, byte *data, int size) @1405098A0
and
ulonglong getNetMessage(NS_FRPG::FrpgSessionManagerImp *session_man,ConnectedPlayerData *player, uint type, byte *store_data_here, uint max_message_size) @140509560
This list is a Work-In-Progress. Underlined types are fully understood. The functions which handle each type are labeled ``sendTypeXNetMessage`` and ``readparseTypeXNetMessage``
0. TestMessage.
1. PlayerFrameUpdate
3. WorldChrSyncLocation
4. WorldChrSyncHealth
5. PlayerNumber
6. PlayerData
7. RequestPlayerNumber
8. RequestWorldChrSyncInitInfo
9. TeamChrType
10. PlayerEquipment
11. WeaponChange
12. MsgMapList
13. CompleteEvent
14. EventInit
15. WorldInit
16. Grab
17. GoodsSfxUpdate
18. PvPDamage
19. PvEDamage
20. WorldChrSyncRemoteToHostEnemyAI
21. WorldChrSyncHostToRemoteEnemyAI
23. One of the packets sent early on when summoning. Precedes type 51.
32. Unknown
33. EnemyAction
34. NPCSpEffectSync
Synchronises NPC SpEffects between players. It is used to tell all other players what SpEffect an NPC has. Packet size is 8, it contains:
35. ApplyEffectToPlayer
38. Unknown
39. EnemyInit
40. ObjDestroy
41. ObjUnknown
42. ItemSync
43. ActionObjSync
44. ActionObjFlagUnknown
45. ActionObjFlag
46. Unknown
47. EmvdSync
48. NPCSummon
49. NPCLeave
50. WorldChrSyncFlags
51. NetNeatoDb
52. ApplyEnemyEffect * WorldChrSync for enemy/NPC effects
53. WorldChrSyncEffect
54. Unknown
55. SkipCutscene
56. HumanityUpdate
Only received by remote players, the host does not listen for this packet. The size is 2 bytes, and will affect whoever receives the packet.
57. NetVagrantSync
58. SpEffectInitAlloc
59. SpEffectInitApply
60. BOSStartMatch
61. BOSRegisterPlayer
62. BOSBattleInformation
63. Unknown
64. BOSUpdateScore
66. Unknown
67. Unknown
68. BOSTimestamp
69. Unknown
70. KarmicJustice
74. ResponseSteamId
75. RequestSteamId
76. PCSpEffectSync
Synchronises SpEffects between players. It is used to tell all other players what SpEffect you have on yourself. Packet size is 8, it contains:
DSR has a glitch where your first action after a backstab cancel is invisible. The explanation and fix for this is as follows.
The thread which sends the attack a player is currently doing (the ezstate info field in type 1 packets) is separate from the thread which sets what attack the player is doing. So, in rare situations the attacker could go into the backstab animation, then have it canceled, and only the packet which says “attacker in no animation” is sent, when instead both the “attacker in backstab animation” and then “attacker in no animation” packets should be sent.
But why, from the defender's view, do they see the attacker in the backstab animation? Well, it's because there is a 2nd packet type sent! When the attacker triggers the backstab, the game IMMEDIATELY sends a packet saying “i'm backstabbing this player now” (the throw id in type 16 packets). The defender receives it, and sets both the defender and attacker animations on their client side to reflect this. This occurs even if the defender doesn't also receive the “attacker in backstab animation” packet, because that should be redundant in this case, right? ;)
Ok, but why doesn’t the visual go away when the defender does later receive the “attacker in no animation” packet? The “attacker in backstab animation” packet must be setting up some special flags. In the case of a normal backstab cancel, where the “attacker in no animation” packet is just sent sooner than expected, it does cancel the visual. So “attacker in backstab animation” packet must be allowing the visual to be cancelable somehow.
Why, if we remove the code in the “i'm backstabbing this player now” throw type receiving packet function, which sets the attacker animation, does the attacker animation not get set later by the “attacker in backstab animation” packet when it’s received (in a good backstab case)? Because backstab doesn’t use ezstate. The ezstate state id for backstabs doesn’t set any animation id like other states do (via ChangeGeneralAnimCategorized, etc).
The way to fix this is to always send the “attacker in backstab animation” ezstate packet right after the “i'm backstabbing this player now” throw packet. Need to ensure the ezstate packet is actually sending type 225 (backstab). With dropping packets, this bug can still happen. If the forced sent backstab ezstate animation packet gets dropped repeatedly and doesn't arrive before the 0 ezstate animation packet. To be safe we should not have to even send the backstab ezstate packet, and just have that performed when the backstab throw packet is received.
In some circumstances, spell visuals can be desynced from the spells themselves in PvP, causing invisible bullets. This only occurs during any homing bullets. The explanation and fix for this is as follows.
This problem is due to the fact that, while spell casting is synced across clients by the type 1 packet, homing bullets don't actually fire off when the spell itself is cast. So while the bullet appearance is synced, when they fire is computed client side based on distance and other factors. And if the two clients don't have the exact same calculation for when the homing bullet is triggered, one side may see the visual for bullet firing when the other doesn't. The side that sees the visual sends a type 18 packet to be sent when the bullet on one client hits the other, and thus damage is taken by invisible bullet.
The code at 0x14042816a, in the HomingBullet_HandleAI function, is hit when a homing bullet is actually fired. Not when the spell itself is cast, but when the bullet actually shots out with a hitbox. We inject code there that gets the attacker and defender player's entity handles, along with the bullet number which is used to identify which of the bullets being rendered is actually fired off. This data is packed into a custom type 1 packet struct along with a magic header to indicate it's special.
The injected code then calls the sendType1NetMessage function, and the custom packet is then passed as an argument to it.
We also inject into the function which receives the type 1 packet, so we can check to see if the received packet is our special spell struct. If so, extract the handles and data, and store it off in an array.
Finally, inject into a bit earlier in the HomingBullet_HandleAI function. This function is called on every active bullet, every frame. We inject at the part which checks if the passed in bullet should be fired, and check if the bullet id and bullet owner are present in our list of received bullet packets. If it is, we set the bullet's target to the one provided by the packet, and it's fired off. We also don't allow any bullet we haven't gotten a packet for to be fired. This effectively syncs the bullet with the netcode.