Advertisement
Guest User

Untitled

a guest
Jan 24th, 2020
527
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.34 KB | None | 0 0
  1. // Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
  2.  
  3. /*=============================================================================
  4.     DataChannel.h: Unreal datachannel class.
  5. =============================================================================*/
  6.  
  7. #pragma once
  8. #include "Engine/ChildConnection.h"
  9.  
  10. /*-----------------------------------------------------------------------------
  11.     UControlChannel base class.
  12. -----------------------------------------------------------------------------*/
  13.  
  14. /** network control channel message types
  15.  *
  16.  * to add a new message type, you need to:
  17.  * - add a DEFINE_CONTROL_CHANNEL_MESSAGE_* for the message type with the appropriate parameters to this file
  18.  * - add IMPLEMENT_CONTROL_CHANNEL_MESSAGE for the message type to DataChannel.cpp
  19.  * - implement the fallback behavior (eat an unparsed message) to UControlChannel::ReceivedBunch()
  20.  *
  21.  * @warning: modifying control channel messages breaks network compatibility (update GEngineMinNetVersion)
  22.  */
  23. template<uint8 MessageType> class FNetControlMessage
  24. {
  25. };
  26. /** contains info about a message type retrievable without static binding (e.g. whether it's a valid type, friendly name string, etc) */
  27. class ENGINE_API FNetControlMessageInfo
  28. {
  29. public:
  30.     static inline const TCHAR* GetName(uint8 MessageIndex)
  31.     {
  32.         CheckInitialized();
  33.         return Names[MessageIndex];
  34.     }
  35.     static inline bool IsRegistered(uint8 MessageIndex)
  36.     {
  37.         CheckInitialized();
  38.         return Names[MessageIndex][0] != 0;
  39.     }
  40.     template<uint8 MessageType> friend class FNetControlMessage;
  41. private:
  42.     static void CheckInitialized()
  43.     {
  44.         static bool bInitialized = false;
  45.         if (!bInitialized)
  46.         {
  47.             for (int32 i = 0; i < ARRAY_COUNT(Names); i++)
  48.             {
  49.                 Names[i] = TEXT("");
  50.             }
  51.             bInitialized = true;
  52.         }
  53.     }
  54.     static void SetName(uint8 MessageType, const TCHAR* InName)
  55.     {
  56.         CheckInitialized();
  57.         Names[MessageType] = InName;
  58.     }
  59.  
  60.     static const TCHAR* Names[256];
  61. };
  62.  
  63. #define DEFINE_CONTROL_CHANNEL_MESSAGE_ZEROPARAM(Name, Index) \
  64.     enum { NMT_##Name = Index }; \
  65.     template<> class FNetControlMessage<Index> \
  66.     { \
  67.     public: \
  68.         static uint8 Initialize() \
  69.         { \
  70.             FNetControlMessageInfo::SetName(Index, TEXT(#Name)); \
  71.             return 0; \
  72.         } \
  73.         /** sends a message of this type on the specified connection's control channel */ \
  74.         static void Send(UNetConnection* Conn) \
  75.         { \
  76.             static_assert(Index < 256, "Control channel message must be a byte."); \
  77.             checkSlow(!Conn->IsA(UChildConnection::StaticClass())); /** control channel messages can only be sent on the parent connection */ \
  78.             if (Conn->Channels[0] != NULL && !Conn->Channels[0]->Closing) \
  79.             { \
  80.                 FControlChannelOutBunch Bunch(Conn->Channels[0], false); \
  81.                 uint8 MessageType = Index; \
  82.                 Bunch << MessageType; \
  83.                 Conn->Channels[0]->SendBunch(&Bunch, true); \
  84.             } \
  85.         } \
  86.     };
  87. #define DEFINE_CONTROL_CHANNEL_MESSAGE_ONEPARAM(Name, Index, TypeA) \
  88.     enum { NMT_##Name = Index }; \
  89.     template<> class FNetControlMessage<Index> \
  90.     { \
  91.     public: \
  92.         static uint8 Initialize() \
  93.         { \
  94.             FNetControlMessageInfo::SetName(Index, TEXT(#Name)); \
  95.             return 0; \
  96.         } \
  97.         /** sends a message of this type on the specified connection's control channel \
  98.          * @note: const not used only because of the FArchive interface; the parameters are not modified \
  99.          */ \
  100.         static void Send(UNetConnection* Conn, TypeA& ParamA) \
  101.         { \
  102.             static_assert(Index < 256, "Control channel message must be a byte."); \
  103.             checkSlow(!Conn->IsA(UChildConnection::StaticClass())); /** control channel messages can only be sent on the parent connection */ \
  104.             if (Conn->Channels[0] != NULL && !Conn->Channels[0]->Closing) \
  105.             { \
  106.                 FControlChannelOutBunch Bunch(Conn->Channels[0], false); \
  107.                 uint8 MessageType = Index; \
  108.                 Bunch << MessageType; \
  109.                 Bunch << ParamA; \
  110.                 Conn->Channels[0]->SendBunch(&Bunch, true); \
  111.             } \
  112.         } \
  113.         /** receives a message of this type from the passed in bunch */ \
  114.         static void Receive(FInBunch& Bunch, TypeA& ParamA) \
  115.         { \
  116.             Bunch << ParamA; \
  117.         } \
  118.         /** throws away a message of this type from the passed in bunch */ \
  119.         static void Discard(FInBunch& Bunch) \
  120.         { \
  121.             TypeA ParamA; \
  122.             Receive(Bunch, ParamA); \
  123.         } \
  124.     };
  125. #define DEFINE_CONTROL_CHANNEL_MESSAGE_TWOPARAM(Name, Index, TypeA, TypeB) \
  126.     enum { NMT_##Name = Index }; \
  127.     template<> class FNetControlMessage<Index> \
  128.     { \
  129.     public: \
  130.         static uint8 Initialize() \
  131.         { \
  132.             FNetControlMessageInfo::SetName(Index, TEXT(#Name)); \
  133.             return 0; \
  134.         } \
  135.         /** sends a message of this type on the specified connection's control channel \
  136.          * @note: const not used only because of the FArchive interface; the parameters are not modified \
  137.          */ \
  138.         static void Send(UNetConnection* Conn, TypeA& ParamA, TypeB& ParamB) \
  139.         { \
  140.             static_assert(Index < 256, "Control channel message must be a byte."); \
  141.             checkSlow(!Conn->IsA(UChildConnection::StaticClass())); /** control channel messages can only be sent on the parent connection */ \
  142.             if (Conn->Channels[0] != NULL && !Conn->Channels[0]->Closing) \
  143.             { \
  144.                 FControlChannelOutBunch Bunch(Conn->Channels[0], false); \
  145.                 uint8 MessageType = Index; \
  146.                 Bunch << MessageType; \
  147.                 Bunch << ParamA; \
  148.                 Bunch << ParamB; \
  149.                 Conn->Channels[0]->SendBunch(&Bunch, true); \
  150.             } \
  151.         } \
  152.         static void Receive(FInBunch& Bunch, TypeA& ParamA, TypeB& ParamB) \
  153.         { \
  154.             Bunch << ParamA; \
  155.             Bunch << ParamB; \
  156.         } \
  157.         /** throws away a message of this type from the passed in bunch */ \
  158.         static void Discard(FInBunch& Bunch) \
  159.         { \
  160.             TypeA ParamA; \
  161.             TypeB ParamB; \
  162.             Receive(Bunch, ParamA, ParamB); \
  163.         } \
  164.     };
  165. #define DEFINE_CONTROL_CHANNEL_MESSAGE_THREEPARAM(Name, Index, TypeA, TypeB, TypeC) \
  166.     enum { NMT_##Name = Index }; \
  167.     template<> class FNetControlMessage<Index> \
  168.     { \
  169.     public: \
  170.         static uint8 Initialize() \
  171.         { \
  172.             FNetControlMessageInfo::SetName(Index, TEXT(#Name)); \
  173.             return 0; \
  174.         } \
  175.         /** sends a message of this type on the specified connection's control channel \
  176.          * @note: const not used only because of the FArchive interface; the parameters are not modified \
  177.          */ \
  178.         static void Send(UNetConnection* Conn, TypeA& ParamA, TypeB& ParamB, TypeC& ParamC) \
  179.         { \
  180.             static_assert(Index < 256, "Control channel message must be a byte."); \
  181.             checkSlow(!Conn->IsA(UChildConnection::StaticClass())); /** control channel messages can only be sent on the parent connection */ \
  182.             if (Conn->Channels[0] != NULL && !Conn->Channels[0]->Closing) \
  183.             { \
  184.                 FControlChannelOutBunch Bunch(Conn->Channels[0], false); \
  185.                 uint8 MessageType = Index; \
  186.                 Bunch << MessageType; \
  187.                 Bunch << ParamA; \
  188.                 Bunch << ParamB; \
  189.                 Bunch << ParamC; \
  190.                 Conn->Channels[0]->SendBunch(&Bunch, true); \
  191.             } \
  192.         } \
  193.         static void Receive(FInBunch& Bunch, TypeA& ParamA, TypeB& ParamB, TypeC& ParamC) \
  194.         { \
  195.             Bunch << ParamA; \
  196.             Bunch << ParamB; \
  197.             Bunch << ParamC; \
  198.         } \
  199.         /** throws away a message of this type from the passed in bunch */ \
  200.         static void Discard(FInBunch& Bunch) \
  201.         { \
  202.             TypeA ParamA; \
  203.             TypeB ParamB; \
  204.             TypeC ParamC; \
  205.             Receive(Bunch, ParamA, ParamB, ParamC); \
  206.         } \
  207.     };
  208. #define DEFINE_CONTROL_CHANNEL_MESSAGE_FOURPARAM(Name, Index, TypeA, TypeB, TypeC, TypeD) \
  209.     enum { NMT_##Name = Index }; \
  210.     template<> class FNetControlMessage<Index> \
  211.     { \
  212.     public: \
  213.         static uint8 Initialize() \
  214.         { \
  215.             FNetControlMessageInfo::SetName(Index, TEXT(#Name)); \
  216.             return 0; \
  217.         } \
  218.         /** sends a message of this type on the specified connection's control channel \
  219.          * @note: const not used only because of the FArchive interface; the parameters are not modified \
  220.          */ \
  221.         static void Send(UNetConnection* Conn, TypeA& ParamA, TypeB& ParamB, TypeC& ParamC, TypeD& ParamD) \
  222.         { \
  223.             static_assert(Index < 256, "Control channel message must be a byte."); \
  224.             checkSlow(!Conn->IsA(UChildConnection::StaticClass())); /** control channel messages can only be sent on the parent connection */ \
  225.             if (Conn->Channels[0] != NULL && !Conn->Channels[0]->Closing) \
  226.             { \
  227.                 FControlChannelOutBunch Bunch(Conn->Channels[0], false); \
  228.                 uint8 MessageType = Index; \
  229.                 Bunch << MessageType; \
  230.                 Bunch << ParamA; \
  231.                 Bunch << ParamB; \
  232.                 Bunch << ParamC; \
  233.                 Bunch << ParamD; \
  234.                 Conn->Channels[0]->SendBunch(&Bunch, true); \
  235.             } \
  236.         } \
  237.         static void Receive(FInBunch& Bunch, TypeA& ParamA, TypeB& ParamB, TypeC& ParamC, TypeD& ParamD) \
  238.         { \
  239.             Bunch << ParamA; \
  240.             Bunch << ParamB; \
  241.             Bunch << ParamC; \
  242.             Bunch << ParamD; \
  243.         } \
  244.         /** throws away a message of this type from the passed in bunch */ \
  245.         static void Discard(FInBunch& Bunch) \
  246.         { \
  247.             TypeA ParamA; \
  248.             TypeB ParamB; \
  249.             TypeC ParamC; \
  250.             TypeD ParamD; \
  251.             Receive(Bunch, ParamA, ParamB, ParamC, ParamD); \
  252.         } \
  253.     };
  254.  
  255. #define DEFINE_CONTROL_CHANNEL_MESSAGE_SEVENPARAM(Name, Index, TypeA, TypeB, TypeC, TypeD, TypeE, TypeF, TypeG) \
  256.     enum { NMT_##Name = Index }; \
  257.     template<> class FNetControlMessage<Index> \
  258.     { \
  259.     public: \
  260.         static uint8 Initialize() \
  261.         { \
  262.             FNetControlMessageInfo::SetName(Index, TEXT(#Name)); \
  263.             return 0; \
  264.         } \
  265.         /** sends a message of this type on the specified connection's control channel \
  266.          * @note: const not used only because of the FArchive interface; the parameters are not modified \
  267.          */ \
  268.         static void Send(UNetConnection* Conn, TypeA& ParamA, TypeB& ParamB, TypeC& ParamC, TypeD& ParamD, TypeE& ParamE, TypeF& ParamF, TypeG& ParamG) \
  269.         { \
  270.             static_assert(Index < 256, "Control channel message must be a byte."); \
  271.             checkSlow(!Conn->IsA(UChildConnection::StaticClass())); /** control channel messages can only be sent on the parent connection */ \
  272.             if (Conn->Channels[0] != NULL && !Conn->Channels[0]->Closing) \
  273.             { \
  274.                 FControlChannelOutBunch Bunch(Conn->Channels[0], false); \
  275.                 uint8 MessageType = Index; \
  276.                 Bunch << MessageType; \
  277.                 Bunch << ParamA; \
  278.                 Bunch << ParamB; \
  279.                 Bunch << ParamC; \
  280.                 Bunch << ParamD; \
  281.                 Bunch << ParamE; \
  282.                 Bunch << ParamF; \
  283.                 Bunch << ParamG; \
  284.                 Conn->Channels[0]->SendBunch(&Bunch, true); \
  285.             } \
  286.         } \
  287.         static void Receive(FInBunch& Bunch, TypeA& ParamA, TypeB& ParamB, TypeC& ParamC, TypeD& ParamD, TypeE& ParamE, TypeF& ParamF, TypeG& ParamG) \
  288.         { \
  289.             Bunch << ParamA; \
  290.             Bunch << ParamB; \
  291.             Bunch << ParamC; \
  292.             Bunch << ParamD; \
  293.             Bunch << ParamE; \
  294.             Bunch << ParamF; \
  295.             Bunch << ParamG; \
  296.         } \
  297.         /** throws away a message of this type from the passed in bunch */ \
  298.         static void Discard(FInBunch& Bunch) \
  299.         { \
  300.             TypeA ParamA; \
  301.             TypeB ParamB; \
  302.             TypeC ParamC; \
  303.             TypeD ParamD; \
  304.             TypeE ParamE; \
  305.             TypeF ParamF; \
  306.             TypeG ParamG; \
  307.             Receive(Bunch, ParamA, ParamB, ParamC, ParamD, ParamE, ParamF, ParamG); \
  308.         } \
  309.     };
  310.  
  311. #define DEFINE_CONTROL_CHANNEL_MESSAGE_EIGHTPARAM(Name, Index, TypeA, TypeB, TypeC, TypeD, TypeE, TypeF, TypeG, TypeH) \
  312.     enum { NMT_##Name = Index }; \
  313.     template<> class FNetControlMessage<Index> \
  314.     { \
  315.     public: \
  316.         static uint8 Initialize() \
  317.         { \
  318.             FNetControlMessageInfo::SetName(Index, TEXT(#Name)); \
  319.             return 0; \
  320.         } \
  321.         /** sends a message of this type on the specified connection's control channel \
  322.          * @note: const not used only because of the FArchive interface; the parameters are not modified \
  323.          */ \
  324.         static void Send(UNetConnection* Conn, TypeA& ParamA, TypeB& ParamB, TypeC& ParamC, TypeD& ParamD, TypeE& ParamE, TypeF& ParamF, TypeG& ParamG, TypeH& ParamH) \
  325.         { \
  326.             static_assert(Index < 256, "Control channel message must be a byte."); \
  327.             checkSlow(!Conn->IsA(UChildConnection::StaticClass())); /** control channel messages can only be sent on the parent connection */ \
  328.             if (Conn->Channels[0] != NULL && !Conn->Channels[0]->Closing) \
  329.             { \
  330.                 FControlChannelOutBunch Bunch(Conn->Channels[0], false); \
  331.                 uint8 MessageType = Index; \
  332.                 Bunch << MessageType; \
  333.                 Bunch << ParamA; \
  334.                 Bunch << ParamB; \
  335.                 Bunch << ParamC; \
  336.                 Bunch << ParamD; \
  337.                 Bunch << ParamE; \
  338.                 Bunch << ParamF; \
  339.                 Bunch << ParamG; \
  340.                 Bunch << ParamH; \
  341.                 Conn->Channels[0]->SendBunch(&Bunch, true); \
  342.             } \
  343.         } \
  344.         static void Receive(FInBunch& Bunch, TypeA& ParamA, TypeB& ParamB, TypeC& ParamC, TypeD& ParamD, TypeE& ParamE, TypeF& ParamF, TypeG& ParamG, TypeH& ParamH) \
  345.         { \
  346.             Bunch << ParamA; \
  347.             Bunch << ParamB; \
  348.             Bunch << ParamC; \
  349.             Bunch << ParamD; \
  350.             Bunch << ParamE; \
  351.             Bunch << ParamF; \
  352.             Bunch << ParamG; \
  353.             Bunch << ParamH; \
  354.         } \
  355.         /** throws away a message of this type from the passed in bunch */ \
  356.         static void Discard(FInBunch& Bunch) \
  357.         { \
  358.             TypeA ParamA; \
  359.             TypeB ParamB; \
  360.             TypeC ParamC; \
  361.             TypeD ParamD; \
  362.             TypeE ParamE; \
  363.             TypeF ParamF; \
  364.             TypeG ParamG; \
  365.             TypeH ParamH; \
  366.             Receive(Bunch, ParamA, ParamB, ParamC, ParamD, ParamE, ParamF, ParamG, ParamH); \
  367.         } \
  368.     };
  369.  
  370. #define IMPLEMENT_CONTROL_CHANNEL_MESSAGE(Name) static uint8 Dummy##_FNetControlMessage_##Name = FNetControlMessage<NMT_##Name>::Initialize();
  371.  
  372. // message type definitions
  373. DEFINE_CONTROL_CHANNEL_MESSAGE_TWOPARAM(Hello, 0, uint8, uint32); // initial client connection message
  374. DEFINE_CONTROL_CHANNEL_MESSAGE_THREEPARAM(Welcome, 1, FString, FString, FString); // server tells client they're ok'ed to load the server's level
  375. DEFINE_CONTROL_CHANNEL_MESSAGE_ONEPARAM(Upgrade, 2, uint32); // server tells client their version is incompatible
  376. DEFINE_CONTROL_CHANNEL_MESSAGE_ONEPARAM(Challenge, 3, FString); // server sends client challenge string to verify integrity
  377. DEFINE_CONTROL_CHANNEL_MESSAGE_ONEPARAM(Netspeed, 4, int32); // client sends requested transfer rate
  378. DEFINE_CONTROL_CHANNEL_MESSAGE_THREEPARAM(Login, 5, FString, FString, FUniqueNetIdRepl); // client requests to be admitted to the game
  379. DEFINE_CONTROL_CHANNEL_MESSAGE_ONEPARAM(Failure, 6, FString); // indicates connection failure
  380. DEFINE_CONTROL_CHANNEL_MESSAGE_ZEROPARAM(Join, 9); // final join request (spawns PlayerController)
  381. DEFINE_CONTROL_CHANNEL_MESSAGE_TWOPARAM(JoinSplit, 10, FString, FUniqueNetIdRepl); // child player (splitscreen) join request
  382. DEFINE_CONTROL_CHANNEL_MESSAGE_ONEPARAM(Skip, 12, FGuid); // client request to skip an optional package
  383. DEFINE_CONTROL_CHANNEL_MESSAGE_ONEPARAM(Abort, 13, FGuid); // client informs server that it aborted a not-yet-verified package due to an UNLOAD request
  384. DEFINE_CONTROL_CHANNEL_MESSAGE_ONEPARAM(PCSwap, 15, int32); // client tells server it has completed a swap of its Connection->Actor
  385. DEFINE_CONTROL_CHANNEL_MESSAGE_ONEPARAM(ActorChannelFailure, 16, int32); // client tells server that it failed to open an Actor channel sent by the server (e.g. couldn't serialize Actor archetype)
  386. DEFINE_CONTROL_CHANNEL_MESSAGE_ONEPARAM(DebugText, 17, FString); // debug text sent to all clients or to server
  387. DEFINE_CONTROL_CHANNEL_MESSAGE_TWOPARAM(NetGUIDAssign, 18, FNetworkGUID, FString); // Explicit NetworkGUID assignment. This is rare and only happens if a netguid is only serialized client->server (this msg goes server->client to tell client what ID to use in that case)
  388.  
  389. //          Beacon control channel flow
  390. // Client                                               Server
  391. //  Send<Hello>
  392. //                                                      Receive<Hello> - compare version / game id
  393. //                                                          Send<Upgrade> if incompatible
  394. //                                                          Send<Failure> if wrong game
  395. //                                                          Send<BeaconWelcome> if good so far
  396. //  Receive<BeaconWelcome>
  397. //      Send<NetSpeed>
  398. //      Send<BeaconJoin> with beacon type
  399. //                                                      Receive<Netspeed>
  400. //                                                      Receive<BeaconJoin> - create requested beacon type and create NetGUID
  401. //                                                          Send<Failure> if unable to create or bad type
  402. //                                                          Send<BeaconAssignGUID> with NetGUID for new beacon actor
  403. //  Receive<BeaconAssignGUID> - assign NetGUID to client actor
  404. //      Send<BeaconNetGUIDAck> acknowledging receipt of NetGUID
  405. //                                                      Receive<BeaconNetGUIDAck> - connection complete
  406.  
  407. DEFINE_CONTROL_CHANNEL_MESSAGE_ZEROPARAM(BeaconWelcome, 25); // server tells client they're ok to attempt to join (client sends netspeed/beacontype)
  408. DEFINE_CONTROL_CHANNEL_MESSAGE_ONEPARAM(BeaconJoin, 26, FString);  // server tries to create beacon type requested by client, sends NetGUID for actor sync
  409. DEFINE_CONTROL_CHANNEL_MESSAGE_ONEPARAM(BeaconAssignGUID, 27, FNetworkGUID); // client assigns NetGUID from server to beacon actor, sends NetGUIDAck
  410. DEFINE_CONTROL_CHANNEL_MESSAGE_ONEPARAM(BeaconNetGUIDAck, 28, FString); // server received NetGUIDAck from client, connection established successfully
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement