![](http://www.chasehutchens.com/wp/wp-content/uploads/2016/01/CNetGameObjectCodeSample.png)
The CNetGameObject is a component that allows our game objects that are associated with one of these components to send particular networked information. Utilizing this component and a particular module that is associated with particular behavior, this enables the behavior to execute accordingly over the network. Essentially, the CNetGameObject provides the foundation for the attached network modules to utilize.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
/* Author : Chase Hutchens Date : 8/7/15 - 4/3/16 */ // Copyright: All content © 2016 DigiPen (USA) Corporation, all rights reserved. #pragma once // Local Modules #include "Export.h" #include "NetBaseObject.h" // Other Engine Modules #include "../Engine/IComponent.h" #include "../Network/NetworkMessages.h" // 3rd Party Modules #include <memory> #define REGISTER_NETOBJ_MODULE(x, y) x, // NOTE: // Always add new modules to the end enum class NetObjModule { NONE, #include "NetObjectModuleRegistration.h" MODULECOUNT, }; #undef REGISTER_NETOBJ_MODULE #define REGISTER_NETOBJ_MODULE(x, y) #x, static const char* NetObjModuleNames[(unsigned)NetObjModule::MODULECOUNT] { "NONE", #include "NetObjectModuleRegistration.h" }; #undef REGISTER_NETOBJ_MODULE #define REGISTER_NETOBJ_MODULE(x, className) \ case NetObjModule::##x : \ objectBehavior = std::make_shared<className>(*this); \ break; class CNetGameObject : public IComponent { private: // has this CNetGameObject sent it's information to the server bool sentMyInfo; // does this CNetGameObject send it's ID to the server bool generateID; // does this CNetGameObject need to store an ID but the server doesn't need to know about it bool generateClientID; // do we send and/or receive network packets? bool sender, receiver; // this indicates that the associated object will persist on level initialization for the non-main client bool nonMainClientKeep; // the unique Id that is associated with this object std::string netObjId; // the particular net module behavior identification NetObjModule gameObjectModule; // the actual NetBaseObject associated with the module behavior std::shared_ptr<NetBaseObject> objectBehavior; private: void SetGenID(bool val) { generateID = val; } bool IsGenID() const { return generateID; } void SetGenClientID(bool val) { generateClientID = val; } bool IsGenClientID() const { return generateClientID; } void SetObjModule(int val) { gameObjectModule = (NetObjModule)val; } bool IsSender() const { return sender; } bool IsReceiver() const { return receiver; } void SetNonMainClientKeep(bool val) { nonMainClientKeep = val; } public: GAM_EXPORT CNetGameObject(); GAM_EXPORT virtual ~CNetGameObject(); GAM_EXPORT virtual void OnInit() override; GAM_EXPORT virtual void Free() override; GAM_EXPORT virtual IComponent* Copy() override; // return format : // !<msgID> <netObjId>: GAM_EXPORT std::string GenerateMessageID(NetworkMessages msgID); GAM_EXPORT std::string DataMsgToSend(); GAM_EXPORT std::string GetNetObjID(); GAM_EXPORT void HandleReceivedMsg(const std::string& msgId, const std::vector<std::string>& msgData); GAM_EXPORT bool IsAbleToSend(); GAM_EXPORT bool HasSentInfo(); GAM_EXPORT void SetNetObjID(const std::string& id); GAM_EXPORT NetBaseObject* GetNetObjectBehaviorModule(); GAM_EXPORT int GetObjModule() const { return (int)gameObjectModule; } GAM_EXPORT void SetSender(bool val) { sender = val; } GAM_EXPORT void SetReceiver(bool val) { receiver = val; } GAM_EXPORT bool IsNonMainClientKeep() const { return nonMainClientKeep; } INTROSPECTION_DECLARE(CNetGameObject); }; |
Implementation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
/* Author : Chase Hutchens Date : 8/7/15 - 4/3/16 */ // All content © 2014-2015 DigiPen (USA) Corporation, all rights reserved. // Local Modules #include "Precompiled.h" #include "CNetGameObject.h" #include "NetworkGameService.h" #include "NetPlayerObject.h" #include "NetItemObject.h" #include "NetProjectileObject.h" #include "NetPressureSwitchObject.h" #include "NetEnemyObject.h" #include "NetLevelTransitionObject.h" #include "NetTurretObject.h" #include "NetDroneEliteObject.h" #include "NetOracleBossObject.h" #include "NetOracleBossNodeObject.h" #include "NetLaserGridObject.h" #include "NetDynamicItemObject.h" #include "NetObjectTransformInterpolator.h" #include "NetGameObjectManager.h" // Other Engine Modules #include "../Engine/CompManager.h" #include "../Engine/GameObject.h" #include "../Engine/GSM.h" #include "../Engine/IGameState.h" #include "../Engine/Space.h" #include "../Network/NetworkManager.h" #include "../Network/CNetworkDataLogger.h" #include "../Network/CNetLogTransformData.h" #include "../Network/ParseUtilities.h" #include "../Physics/CRigidBody.h" // 3rd Party Modules #include <random> #include <ctime> #include <sstream> #include <iostream> INTROSPECTION_DEFINE(CNetGameObject) .base<IComponent>() .PROPERTY_DEFINE_INFO(CNetGameObject, gameObjectModule, GetObjModule, SetObjModule, MemberInfo::MIEnumeration(&NetObjModuleNames[0], (int)NetObjModule::MODULECOUNT)) .PROPERTY_DEFINE(CNetGameObject, GenerateID, IsGenID, SetGenID) .PROPERTY_DEFINE(CNetGameObject, GenerateClientID, IsGenClientID, SetGenClientID) .PROPERTY_DEFINE(CNetGameObject, SendsData, IsSender, SetSender) .PROPERTY_DEFINE(CNetGameObject, ReceivesData, IsReceiver, SetReceiver) .PROPERTY_DEFINE(CNetGameObject, NonMainClientKeep, IsNonMainClientKeep, SetNonMainClientKeep); REGISTER_TYPENAME(CNetGameObject, "CNetGameObject"); REGISTER_COMPMANAGER(CNetGameObject); // PRIVATE // ----- // PUBLIC CNetGameObject::CNetGameObject() : IComponent() { sentMyInfo = false; REFERENCE_REGISTRATION(CNetGameObject); } CNetGameObject::~CNetGameObject() { } void CNetGameObject::OnInit() { // we don't want to send our objIds if we are not the main client sentMyInfo = false; int customSetting = 0; ActiveNetworkGameManager::GetInstance().AttachData<EnumEvent>(EventList::NetObjectCreated)->enumVal = &customSetting; ActiveNetworkGameManager::GetInstance().DispatchEvent(EventList::NetObjectCreated); //std::cout << "Relayed Module: " << relayedModule << std::endl; // we don't need any more information for this particular CNetGameObject // such as a temporary objects that are being created for another client if (customSetting == -1) { return; } switch (gameObjectModule) { #include "NetObjectModuleRegistration.h" default: objectBehavior = nullptr; break; } // possible configuration problem warning if (generateID && generateClientID) { std::cerr << "WARNING: Archetype | " << this->GetParent()->GetArchName() << " | CNetGameObject | generateID == true && generateClientID == true | " << "Undefined Behavior When Both Are True\n"; } // if this object generates an ID, we are the main client and // we are connected to the server // or we just need a temporary netId to use, but // we don't need to tell the server about us (generateClientID == true) if (((generateID && ActiveNetworkGameManager::GetInstance().IsMainClient()) || generateClientID) && NetworkManager::GetInstance().IsActiveConnection()) { std::uniform_int_distribution<uint32_t> cRnd(97, 122); for (unsigned i = 0; i < 16; ++i) { netObjId += (char)cRnd(ActiveNetworkGameManager::GetInstance().GetRandSeed()); } // Objects that the server needs to know about if (generateID && ActiveNetworkGameManager::GetInstance().IsMainClient()) { NetGameObjectManager::GetInstance().AddNetGameObject(netObjId, this->GetParent(), true, (customSetting == DYNAMIC_NET_OBJECT) ? true : false); } else if (generateClientID) // Objects that utilize this system, but only client needs to know about { NetGameObjectManager::GetInstance().AddNetGameObject(netObjId, this->GetParent(), false); } } } void CNetGameObject::Free() { NetGameObjectManager::GetInstance().SafeRemoveNetGameObject(netObjId); } IComponent* CNetGameObject::Copy() { CNetGameObject* netGameObj = CREATE_COMP(CNetGameObject); netGameObj->gameObjectModule = this->gameObjectModule; netGameObj->generateID = this->generateID; netGameObj->generateClientID = this->generateClientID; netGameObj->sender = this->sender; netGameObj->receiver = this->receiver; netGameObj->nonMainClientKeep = this->nonMainClientKeep; return netGameObj; } // return format : // !<msgID> <netObjId>: std::string CNetGameObject::GenerateMessageID(NetworkMessages msgID) { NetworkMessageManager& msgManager = NetworkMessageManager::GetInstance(); return msgManager.CreateNetMsg(msgID) + netObjId + NMS; } std::string CNetGameObject::DataMsgToSend() { return objectBehavior->ObjSender(); } std::string CNetGameObject::GetNetObjID() { return netObjId; } void CNetGameObject::HandleReceivedMsg(const std::string& msgId, const std::vector<std::string>& msgData) { objectBehavior->ObjReceiver(msgId, msgData); } bool CNetGameObject::IsAbleToSend() { if (!sender || !objectBehavior) return false; return objectBehavior->ObjCanSend(); } bool CNetGameObject::HasSentInfo() { // we can send if we aren't generating our own ID if (!generateID) return true; return sentMyInfo; } void CNetGameObject::SetNetObjID(const std::string& id) { netObjId = id; } NetBaseObject* CNetGameObject::GetNetObjectBehaviorModule() { return objectBehavior.get(); } // ----- |