Leviathan  0.8.0.0
Leviathan game engine
GameSpecificPacketHandler.cpp
Go to the documentation of this file.
1 // ------------------------------------ //
3 
4 #include "Exceptions.h"
5 #include "../Utility/Convert.h"
6 using namespace Leviathan;
7 using namespace std;
8 // ------------------------------------ //
10  IsVectorSorted(false)
11 {
12  Staticaccess = this;
13 }
14 
16  Staticaccess = NULL;
17 }
18 
20  return Staticaccess;
21 }
22 
24 // ------------------------------------ //
26  datatosend, sf::Packet &packet)
27 {
28  // Try to find a handler for this //
29  auto handlerobject = _FindFactoryForType(datatosend->TypeIDNumber, datatosend->IsRequest);
30 
31  // Now that there is a factory it's safe to start putting it together by adding the TypeID first //
32  packet << datatosend->TypeIDNumber << datatosend->IsRequest;
33 
34  // Now the actual data //
35 
36  // Factory already knows what it does so let it do it //
37  if(!handlerobject->SerializeToPacket(datatosend, packet)){
38 
39  throw InvalidArgument("invalid custom request packet for writing to packet");
40  }
41 
42 
43  // The packet should now be fine //
44 }
45 
47  bool responsepacket, sf::Packet &packet)
48 {
49  // Get the basic data from the packet //
50  int typeidnumber = -1;
51  bool packetisrequest;
52 
53  if(!(packet >> typeidnumber)){
54 
55  throw InvalidAccess("invalid received custom packet base format");
56  }
57 
58  if(!(packet >> packetisrequest)){
59 
60  throw InvalidAccess("invalid received custom packet base format");
61  }
62 
63  if(packetisrequest != !responsepacket){
64 
65  // The packet might be corrupted or something //
66  Logger::Get()->Warning("GameSpecificPacketHandler: packet has inconsistent request identifier, expected "+
67  Convert::ToString(responsepacket)+" but packet was "+
68  Convert::ToString(packetisrequest));
69  return NULL;
70  }
71 
72  // Try to find a handler for this //
73  auto handlerobject = _FindFactoryForType(typeidnumber, packetisrequest);
74 
75  if(!handlerobject){
76 
77  Logger::Get()->Warning("GameSpecificPacketHandler: couldn't find a handler for a packet of type "+
78  Convert::ToString(typeidnumber)+" and"
79  " request state: "+Convert::ToString(packetisrequest));
80  return NULL;
81  }
82 
83  // Factory already knows what it does so let it do it //
84  return handlerobject->UnSerializeObjectFromPacket(packet);
85 }
86 // ------------------------------------ //
88  newdfactoryobject)
89 {
90  // Check does it exist already //
91  if(_FindFactoryForType(newdfactoryobject->TypeIDNumber, newdfactoryobject->HandlesRequests)){
92 
93  assert(0 && "Trying to register a type that is already registered for custom packages");
94  }
95 
96  // Add //
97  AllPacketFactories.push_back(shared_ptr<BaseGameSpecificPacketFactory>(newdfactoryobject));
98 
99  // Mark as unsorted //
100  IsVectorSorted = false;
101 }
102 // ------------------------------------ //
103 shared_ptr<BaseGameSpecificPacketFactory> Leviathan::GameSpecificPacketHandler::_FindFactoryForType(int typenumber,
104  bool requesttype)
105 {
106  // We can do some optimization if it is sorted //
107  if(!IsVectorSorted){
108  // Just search the old fashion way //
109 
110  for(size_t i = 0; i < AllPacketFactories.size(); i++){
111  // Check does it match //
112  if(AllPacketFactories[i]->TypeIDNumber == typenumber &&
113  AllPacketFactories[i]->HandlesRequests == requesttype)
114 
115  return AllPacketFactories[i];
116  }
117 
118  // Nothing found //
119  return NULL;
120  }
121 
122  // The elements are sorted so that the smallest ID is first so search until the id is higher
123  // than the wanted one
124  for(size_t i = 0; i < AllPacketFactories.size(); i++){
125  // Store some data for checking after it doesn't match //
126  auto tmpobj = AllPacketFactories[i].get();
127  int currenttype = tmpobj->TypeIDNumber;
128 
129  // Check does it match //
130  if(currenttype == typenumber && tmpobj->HandlesRequests == requesttype)
131  return AllPacketFactories[i];
132 
133  // Check can we end now //
134  if(currenttype > typenumber)
135  return NULL;
136  }
137 
138  // Nothing found //
139  return NULL;
140 }
141 // ------------------------------------ //
142 bool SharedPtrVecSortComparison(const std::shared_ptr<BaseGameSpecificPacketFactory> &first,
143  const std::shared_ptr<BaseGameSpecificPacketFactory> &second)
144 {
145  return first->TypeIDNumber < second->TypeIDNumber;
146 }
147 
149  // Return if already sorted //
150  if(IsVectorSorted)
151  return;
152 
153  // Sort the vector //
154  sort(AllPacketFactories.begin(), AllPacketFactories.end(), &SharedPtrVecSortComparison);
155 
156 
157  // Mark as sorted //
158  IsVectorSorted = true;
159 }
160 // ------------------ BaseGameSpecificRequestPacket ------------------ //
162  TypeIDNumber(typenumber)
163 {
164 
165 }
166 
168 
169 }
170 // ------------------ BaseGameSpecificResponsePacket ------------------ //
172  TypeIDNumber(typenumber)
173 {
174 
175 }
176 
178 
179 }
180 // ------------------ GameSpecificPacketData ------------------ //
182  BaseGameSpecificResponsePacket* newddata) :
183  IsRequest(false), RequestBaseData(NULL), ResponseBaseData(newddata),
184  TypeIDNumber(newddata->TypeIDNumber)
185 {
186 
187 }
188 
190  IsRequest(true), RequestBaseData(newddata), ResponseBaseData(NULL),
191  TypeIDNumber(newddata->TypeIDNumber)
192 {
193 
194 }
195 
197  SAFE_DELETE(ResponseBaseData);
198  SAFE_DELETE(RequestBaseData);
199  TypeIDNumber = -1;
200 }
201 // ------------------ BaseGameSpecificFactory ------------------ //
203  TypeIDNumber(typenumber), HandlesRequests(isrequesttype)
204 {
205 
206 }
207 
209 
210 }
211 
Base class for all user defined response packets.
static DLLEXPORT GameSpecificPacketHandler * Get()
DLLEXPORT GameSpecificPacketHandler(NetworkInterface *usetoreport)
bool HandlesRequests
Specifies are the TypeIDNumbers corresponding to request or response packets.
STL namespace.
DLLEXPORT std::shared_ptr< GameSpecificPacketData > ReadGameSpecificPacketFromPacket(bool responsepacket, sf::Packet &packet)
bool SharedPtrVecSortComparison(const std::shared_ptr< BaseGameSpecificPacketFactory > &first, const std::shared_ptr< BaseGameSpecificPacketFactory > &second)
DLLEXPORT void Warning(const std::string &data) override
Definition: Logger.cpp:190
static std::string ToString(const T &val)
Definition: Convert.h:72
DLLEXPORT void PassGameSpecificDataToPacket(GameSpecificPacketData *datatosend, sf::Packet &packet)
Handles construction of all game specific packets.
int TypeIDNumber
The integer identifying when this factory needs to be used.
DLLEXPORT GameSpecificPacketData(BaseGameSpecificResponsePacket *newddata)
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
std::shared_ptr< BaseGameSpecificPacketFactory > _FindFactoryForType(int typenumber, bool requesttype)
Base class that is passed to the list of type handlers to GameSpecificPacketHandler.
#define DLLEXPORT
Definition: Include.h:115
Class that contains all data associated with a game specific packet.
static GameSpecificPacketHandler * Staticaccess
The access mask controls which registered functions and classes a script sees.
Definition: GameModule.h:12
#define SAFE_DELETE(x)
Definition: Define.h:116
DLLEXPORT BaseGameSpecificPacketFactory(int typenumber, bool isrequesttype)
Class that encapsulates common networking functionality that is required by all networked programs...
Base class for all user defined request packets.
DLLEXPORT void RegisterNewTypeFactory(BaseGameSpecificPacketFactory *newdfactoryobject)
Adds a new type that can be handled.