EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
BulkMgrService.cpp
Go to the documentation of this file.
1 
96 #include "eve-server.h"
97 
98 #include "PyServiceCD.h"
99 #include "cache/BulkDB.h"
100 #include "cache/BulkMgrService.h"
101 #include "packets/BulkDataPkts.h"
102 
104 
106 : PyService(mgr, "bulkMgr"),
107  m_dispatch(new Dispatcher(this))
108 {
109  _SetCallDispatcher(m_dispatch);
110 
112  PyCallable_REG_CALL(BulkMgrService, UpdateBulk);
113  PyCallable_REG_CALL(BulkMgrService, GetVersion);
114  PyCallable_REG_CALL(BulkMgrService, GetFullFiles);
115  PyCallable_REG_CALL(BulkMgrService, GetAllBulkIDs);
116  PyCallable_REG_CALL(BulkMgrService, GetFullFilesChunk);
117  PyCallable_REG_CALL(BulkMgrService, GetUnsubmittedChunk);
118  PyCallable_REG_CALL(BulkMgrService, GetUnsubmittedChanges);
119 
120 }
121 
123  delete m_dispatch;
124 }
125 /*
126 BULKDATA__ERROR=1
127 BULKDATA__WARNING=0
128 BULKDATA__MESSAGE=0
129 BULKDATA__DEBUG=0
130 BULKDATA__INFO=0
131 BULKDATA__TRACE=0
132 BULKDATA__DUMP=0
133 */
134 PyResult BulkMgrService::Handle_UpdateBulk(PyCallArgs &call)
135 {
136  /*
137  sLog.White( "BulkMgrService::Handle_UpdateBulk()", "size= %u", call.tuple->size() );
138  call.Dump(BULKDATA__DUMP);
139  updateData = self.bulkMgr.UpdateBulk(changeID, hashValue, branch)
140 
141  updateType = updateData['type']
142  self.allowUnsubmitted = updateData['allowUnsubmitted']
143  if 'version' in updateData:
144  serverVersion = updateData['version']
145  if 'data' in updateData: -- list of bulkdata fileID 'numbers' that have changed.
146  updateInfo = updateData['data']
147  */
148 
149  Call_UpdateBulk args;
150  if (!args.Decode(&call.tuple)) {
151  _log(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
152  return PyStatic.NewNone();
153  }
154 
155  PyDict* res = new PyDict();
156  // bulkDataChangeID found in eve-common/EVE_Defines.h and defines the serverVersion of this set of bulkdata
157  if (args.changeID != bulkDataChangeID) {
159  } else if (args.branch != bulkDataBranch) {
161  } else if (args.hashValue->IsNone()) { //241bfba3c85c1bb4680be745e6c7d1ee
162  // not right response, but easiest to hack, as it compares servers fileIDs to local fileIDs and removes matching ids
164  // make list of fileIDs to send to client.
165  PyList* list = new PyList();
166  list->AddItem(new PyInt(800002)); //cacheDogmaOperands
167  list->AddItem(new PyInt(800003)); //cacheDogmaExpressions
168  list->AddItem(new PyInt(800004)); //cacheDogmaAttributes
169  list->AddItem(new PyInt(800005)); //cacheDogmaEffects
170  list->AddItem(new PyInt(800006)); //cacheDogmaTypeAttributes
171  list->AddItem(new PyInt(800007)); //cacheDogmaTypeEffects
172  res->SetItemString("data", list);
173  } else {
174  res->SetItemString("type", new PyInt(updateBulkStatusOK));
175  }
176 
177  res->SetItemString("version", new PyInt(bulkDataChangeID));
178  res->SetItemString("allowUnsubmitted", PyStatic.NewFalse());
179 
180  /*
181  res->SetItemString("data", new PyList(0));
182  data is PyDict of 'chunkCount','chunk','changedTablesKeys','toBeDeleted','changedTablesKeys','branch' when 'type' = updateBulkStatusNeedToUpdate
183  */
184  if (is_log_enabled(BULKDATA__TRACE))
185  res->Dump(BULKDATA__TRACE, " ");
186 
187  return res;
188 }
189 
190 PyResult BulkMgrService::Handle_GetFullFiles(PyCallArgs &call)
191 {
192  /*
193  sLog.White( "BulkMgrService::Handle_GetFullFiles()", "size= %u", call.tuple->size() );
194  call.Dump(BULKDATA__DUMP);
195  toBeChanged, bulksEndingInChunk, numberOfChunks, chunkSetID, self.allowUnsubmitted = self.bulkMgr.GetFullFiles(toGet)
196  -- toGet is sent as PyList of fileIDs server should send back
197 
198  -- response
199  [PyTuple 1 items]
200  [PySubStream 151253 bytes]
201  [PyTuple 5 items]
202  [PyDict 3 kvp] << toBeChanged
203  [PyInt 800001] << fileID
204  [PyObjectEx Type2] << file data
205  [PyTuple 2 items]
206  [PyTuple 1 items]
207  [PyToken dbutil.CRowset]
208  [PyDict 1 kvp]
209  [PyString "header"]
210  [PyList 2 items] << bulksEndingInChunk
211  [PyInt 800001]
212  [PyInt 800002]
213  [PyInt 197] << numberOfChunks
214  [PyInt 0] << chunkSetID
215  [PyBool False] << allowUnsubmitted
216  */
217  Call_GetFullFiles args;
218  if (!args.Decode(&call.tuple)) {
219  _log(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
220  return PyStatic.NewNone();
221  }
222 
223  PyTuple* response = new PyTuple(5);
224  // toBeChanged is populated with k,v of bulkFileID, CRowset
225  PyDict* toBeChanged = new PyDict();
226  // bulksEndingInChunk is populated when the last data of a file has been sent.
227  // each complete (or completed) data file's ID is put into this list.
228  // multiple files can be sent in this call, with their listIDs inserted into bulksEndingInChunk list.
229  // fileIDs here tell the client to save the file in it's cache
230  PyList* bulksEndingInChunk = new PyList(); // bulksEndingIn(this)Chunk
231 
232  if (args.toGet->IsNone()) {
233  // toGet = null. this means get all bulkdata files
234  toBeChanged->SetItem(new PyInt(800002), sBulkDB.GetBulkData(0));
235  bulksEndingInChunk->AddItem(new PyInt(800002));
236  toBeChanged->SetItem(new PyInt(800004), sBulkDB.GetBulkData(1));
237  bulksEndingInChunk->AddItem(new PyInt(800004));
238  toBeChanged->SetItem(new PyInt(800005), sBulkDB.GetBulkData(2));
239  bulksEndingInChunk->AddItem(new PyInt(800005));
240  // will have to determine what files are needed using hash, and then how to arrange and send this data correctly
241  response->SetItem(2, new PyInt(sBulkDB.GetNumChunks())); //numberOfChunks
242  response->SetItem(3, PyStatic.NewZero()); //chunkSetID
243  } else if (args.toGet->IsList()) {
244  PyList::const_iterator itr = args.toGet->AsList()->begin(), end = args.toGet->AsList()->end();
245  uint8 setID(1);
246  while (itr != end) {
247  switch (PyRep::IntegerValueU32(*itr)) {
248  case 800002: {
249  toBeChanged->SetItem(new PyInt(800002), sBulkDB.GetBulkData(0));
250  bulksEndingInChunk->AddItem(new PyInt(800002));
251  } break;
252  case 800004: {
253  toBeChanged->SetItem(new PyInt(800004), sBulkDB.GetBulkData(1));
254  bulksEndingInChunk->AddItem(new PyInt(800004));
255  } break;
256  case 800005: {
257  toBeChanged->SetItem(new PyInt(800005), sBulkDB.GetBulkData(2));
258  bulksEndingInChunk->AddItem(new PyInt(800005));
259  } break;
260  // these are hacked, but this whole system is...however, these *shouldnt* be called
261  case 800003: {
262  setID = 2;
263  toBeChanged->SetItem(new PyInt(800003), sBulkDB.GetBulkDataChunks(0, 1));
264  } break;
265  case 800006: {
266  setID = 3;
267  toBeChanged->SetItem(new PyInt(800006), sBulkDB.GetBulkDataChunks(0, 7));
268  } break;
269  case 800007: {
270  setID = 4;
271  toBeChanged->SetItem(new PyInt(800007), sBulkDB.GetBulkDataChunks(0, 3));
272  } break;
273  }
274  ++itr;
275  }
276  // will have to determine what files are needed, and how to arrange this data correctly
277  response->SetItem(2, new PyInt(sBulkDB.GetNumChunks(setID))); //numberOfChunks
278  response->SetItem(3, new PyInt(setID)); //chunkSetID
279  } else {
280  _log(BULKDATA__ERROR, "BulkMgrService::Handle_GetFullFiles(): args.toGet->TypeString() is %s", args.toGet->TypeString());
281  return PyStatic.NewNone();
282  }
283 
284  response->SetItem(0, toBeChanged);
285 
286  // if bulksEndingInChunk is empty, a PyNone is returned, stating this is only partial file data
287  if (bulksEndingInChunk->size() > 0) {
288  response->SetItem(1, bulksEndingInChunk);
289  } else {
290  response->SetItem(1, PyStatic.NewNone());
291  }
292 
293  response->SetItem(4, PyStatic.NewFalse()); //allowUnsubmitted isnt supported (yet)
294 
295  if (is_log_enabled(BULKDATA__TRACE))
296  response->Dump(BULKDATA__TRACE, " ");
297 
298  return response;
299 }
300 
301 PyResult BulkMgrService::Handle_GetFullFilesChunk(PyCallArgs &call)
302 {
303  /*
304  sLog.White( "BulkMgrService::Handle_GetFullFilesChunk()", "size= %u", call.tuple->size() );
305  call.Dump(BULKDATA__DUMP);
306  toBeChanged, bulksEndingInChunk = self.bulkMgr.GetFullFilesChunk(chunkSetID, chunkNumber)
307  this breaks files up into ?kb chunks for sending to client. client requests "chunkSetID" and "chunkNumber", where chunkSetID is ???
308  */
309  Call_GetFullFilesChunk args;
310  if (!args.Decode(&call.tuple)) {
311  _log(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
312  return PyStatic.NewNone();
313  }
314 
315  PyTuple* response = new PyTuple(2);
316  PyDict* toBeChanged = new PyDict();
317  int32 bulkFileID = sBulkDB.GetFileIDfromChunk(args.chunkSetID, args.chunkNumber);
318  if (bulkFileID < 0) {
319  _log(BULKDATA__ERROR, "BulkMgrService::Handle_GetFullFilesChunk(): chunkSetID: %u, chunkNumber: %u, bulkFileID: %i", args.chunkSetID, args.chunkNumber, bulkFileID);
320  // make and send client error also. may be able to throw here.
321  return PyStatic.NewNone();
322  }
323 
324  _log(BULKDATA__INFO, "BulkMgrService::Handle_GetFullFilesChunk(): bulkFileID: %i, chunkSetID: %u, chunkNumber: %u", bulkFileID, args.chunkSetID, args.chunkNumber);
325  toBeChanged->SetItem(new PyInt(bulkFileID), sBulkDB.GetBulkDataChunks(args.chunkSetID, args.chunkNumber));
326 
327  // 2, 4, 36
328  if (args.chunkSetID == 0) {
329  if (args.chunkNumber == 2) {
330  PyList* bulksEndingInChunk = new PyList();
331  bulksEndingInChunk->AddItem(new PyInt(bulkFileID));
332  response->SetItem(1, bulksEndingInChunk);
333  } else if (args.chunkNumber == 6) {
334  PyList* bulksEndingInChunk = new PyList();
335  bulksEndingInChunk->AddItem(new PyInt(bulkFileID));
336  response->SetItem(1, bulksEndingInChunk);
337  } else if (args.chunkNumber == 42) {
338  PyList* bulksEndingInChunk = new PyList();
339  bulksEndingInChunk->AddItem(new PyInt(bulkFileID));
340  response->SetItem(1, bulksEndingInChunk);
341  } else {
342  response->SetItem(1, PyStatic.NewNone());
343  }
344  } else if (args.chunkSetID == 1) {
345 
346  } else if (args.chunkSetID == 2) {
347 
348  } else if (args.chunkSetID == 3) {
349 
350  }
351 
352  response->SetItem(0, toBeChanged);
353  return response;
354 }
355 
356 PyResult BulkMgrService::Handle_GetVersion(PyCallArgs &call)
357 {
358  // changeID, branch = self.bulkMgr.GetVersion()
359 /*
360  sLog.White( "BulkMgrService::Handle_GetVersion()", "size= %u", call.tuple->size() );
361  call.Dump(BULKDATA__DUMP);
362 */
363  PyTuple* tuple = new PyTuple(2);
364  tuple->SetItem(0, new PyInt(bulkDataChangeID));
365  tuple->SetItem(1, new PyInt(bulkDataBranch));
366  return tuple;
367 }
368 
369 PyResult BulkMgrService::Handle_GetAllBulkIDs(PyCallArgs &call)
370 {
371  /*
372  sLog.White( "BulkMgrService::Handle_GetAllBulkIDs()", "size= %u", call.tuple->size() );
373  call.Dump(BULKDATA__DUMP);
374  * serverBulkIDs = self.bulkMgr.GetAllBulkIDs()
375  * PyList of fileIDs of updated data files to be sent to client in bulk
376  */
377 
378  // hard-code a list of 'new' dgm fileIDs here. (updated and edited dogma data)
379  // this can also be used to update other data files as needed
380  PyList* list = new PyList();
381  list->AddItem(new PyInt(800002)); //cacheDogmaOperands
382  list->AddItem(new PyInt(800003)); //cacheDogmaExpressions
383  list->AddItem(new PyInt(800004)); //cacheDogmaAttributes
384  list->AddItem(new PyInt(800005)); //cacheDogmaEffects
385  list->AddItem(new PyInt(800006)); //cacheDogmaTypeAttributes
386  list->AddItem(new PyInt(800007)); //cacheDogmaTypeEffects
387  return list;
388 }
389 
390 PyResult BulkMgrService::Handle_GetChunk(PyCallArgs &call)
391 {
392  sLog.White( "BulkMgrService::Handle_GetChunk()", "size= %u", call.tuple->size() );
393  call.Dump(BULKDATA__DUMP);
394  /*
395  * toBeChanged = self.bulkMgr.GetChunk(changeID, chunkNumber)
396  * changeID is from GetVersion()
397  * chunkNumber is incremented during loop when bulkdata return 'type' = updateBulkStatusNeedToUpdate
398  * need more info to properly implement this
399  */
400  Call_GetChunk args;
401  if (!args.Decode(&call.tuple)) {
402  _log(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
403  return PyStatic.NewNone();
404  }
405  /*
406  * args.changeID;
407  * args.chunkNumber;
408  */
409  return PyStatic.NewNone();
410 }
411 
412 PyResult BulkMgrService::Handle_GetUnsubmittedChunk(PyCallArgs &call)
413 {
414  sLog.White( "BulkMgrService::Handle_GetUnsubmittedChunk()", "size= %u", call.tuple->size() );
415  call.Dump(BULKDATA__DUMP);
416  /*
417  toBeChanged = self.bulkMgr.GetUnsubmittedChunk(chunkNumber)
418  need more info to properly implement this
419  */
420  Call_GetUnsubmittedChunk args;
421  if (!args.Decode(&call.tuple)) {
422  _log(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
423  return PyStatic.NewNone();
424  }
425  //args.chunkNumber;
426 
427  return PyStatic.NewNone();
428 }
429 
430 PyResult BulkMgrService::Handle_GetUnsubmittedChanges(PyCallArgs &call)
431 {
432  sLog.White( "BulkMgrService::Handle_GetUnsubmittedChanges()", "size= %u", call.tuple->size() );
433  call.Dump(BULKDATA__DUMP);
434  /*
435  unsubmitted = self.bulkMgr.GetUnsubmittedChanges()
436  PyDict of 'toBeChanged','toBeDeleted','changedTablesKeys','chunkCount'
437  this one is complicated. will need work if we're allowing unsubmitted (whatever that means)
438  need more info to properly implement this
439  */
440  return PyStatic.NewNone();
441 }
Dispatcher *const m_dispatch
unsigned __int8 uint8
Definition: eve-compat.h:46
#define _log(type, fmt,...)
Definition: logsys.h:124
#define bulkDataBranch
Definition: EVE_Defines.h:73
Python's dictionary.
Definition: PyRep.h:719
size_t size() const
Definition: PyRep.h:591
storage_type::const_iterator const_iterator
Definition: PyRep.h:644
static uint32 IntegerValueU32(PyRep *pRep)
Definition: PyRep.cpp:134
Python tuple.
Definition: PyRep.h:567
const char * GetName() const
Definition: PyService.h:54
void Dump(FILE *into, const char *pfx) const
Dumps object to file.
Definition: PyRep.cpp:84
void AddItem(PyRep *i)
Definition: PyRep.h:701
signed __int32 int32
Definition: eve-compat.h:49
* args
#define is_log_enabled(type)
Definition: logsys.h:78
#define sLog
Evaluates to a NewLog instance.
Definition: LogNew.h:250
#define sBulkDB
Definition: BulkDB.h:54
void SetItem(size_t index, PyRep *object)
Stores Python object.
Definition: PyRep.h:610
Python integer.
Definition: PyRep.h:231
#define bulkDataChangeID
Definition: EVE_Defines.h:76
#define PyStatic
Definition: PyRep.h:1209
#define PyCallable_REG_CALL(c, m)
Definition: PyServiceCD.h:78
PyCallable_Make_InnerDispatcher(BulkMgrService) BulkMgrService
Dispatcher *const m_dispatch
virtual ~BulkMgrService()
void Dump(LogType type) const
Definition: PyCallable.cpp:81
size_t size() const
Definition: PyRep.h:663
void SetItem(PyRep *key, PyRep *value)
SetItem adds or sets a database entry.
Definition: PyRep.cpp:713
Python list.
Definition: PyRep.h:639
void SetItemString(const char *key, PyRep *value)
SetItemString adds or sets a database entry.
Definition: PyRep.h:812
PyTuple * tuple
Definition: PyCallable.h:50