EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
BookmarkService.cpp
Go to the documentation of this file.
1 /*
2  ------------------------------------------------------------------------------------
3  LICENSE:
4  ------------------------------------------------------------------------------------
5  This file is part of EVEmu: EVE Online Server Emulator
6  Copyright 2006 - 2021 The EVEmu Team
7  For the latest information visit https://evemu.dev
8  ------------------------------------------------------------------------------------
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13 
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License along with
19  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20  Place - Suite 330, Boston, MA 02111-1307, USA, or go to
21  http://www.gnu.org/copyleft/lesser.txt.
22  ------------------------------------------------------------------------------------
23  Author: Zhur, Aknor Jaden
24  Rewrite: Allan
25 */
26 
27 
28 #include "eve-server.h"
29 
30 #include "PyServiceCD.h"
31 #include "PyBoundObject.h"
32 #include "packets/Bookmarks.h"
33 #include "system/BookmarkService.h"
34 #include "system/SystemManager.h"
36 
37 /*
38 BOOKMARK__ERROR
39 BOOKMARK__WARNING
40 BOOKMARK__MESSAGE
41 BOOKMARK__DEBUG
42 BOOKMARK__INFO
43 BOOKMARK__TRACE
44 BOOKMARK__CALL_DUMP
45 BOOKMARK__RSP_DUMP
46 */
47 
48 
50 
52 : PyService(mgr, "bookmark"),
53  m_dispatch(new Dispatcher(this))
54 {
55  _SetCallDispatcher(m_dispatch);
56 
57  PyCallable_REG_CALL(BookmarkService, GetBookmarks);
58  PyCallable_REG_CALL(BookmarkService, CreateFolder);
59  PyCallable_REG_CALL(BookmarkService, UpdateFolder);
60  PyCallable_REG_CALL(BookmarkService, DeleteFolder);
61  PyCallable_REG_CALL(BookmarkService, BookmarkLocation);
62  PyCallable_REG_CALL(BookmarkService, BookmarkScanResult);
63  PyCallable_REG_CALL(BookmarkService, DeleteBookmarks);
64  PyCallable_REG_CALL(BookmarkService, MoveBookmarksToFolder);
65  PyCallable_REG_CALL(BookmarkService, AddBookmarkFromVoucher);
66  PyCallable_REG_CALL(BookmarkService, CopyBookmarks);
67 
68 }
69 
71  delete m_dispatch;
72 }
73 
74 bool BookmarkService::LookupBookmark(uint32 bookmarkID, uint32& itemID, uint16& typeID, uint32& locationID, double& x, double& y, double& z) {
75  return m_db.GetBookmarkInformation(bookmarkID, itemID, typeID, locationID, x, y, z);
76 }
77 
78 PyResult BookmarkService::Handle_GetBookmarks(PyCallArgs &call) {
79  PyTuple* result = new PyTuple(2);
80  result->SetItem(0, m_db.GetBookmarks(call.client->GetCharacterID()));
81  result->SetItem(1, m_db.GetFolders(call.client->GetCharacterID()));
82  result->Dump(BOOKMARK__RSP_DUMP, " ");
83  return result;
84 }
85 
86 PyResult BookmarkService::Handle_CreateFolder(PyCallArgs &call) {
87  call.Dump(BOOKMARK__CALL_DUMP);
89  std::string name = PyRep::StringContent(call.tuple->GetItem( 0 ));
90 
91  uint32 ownerID = call.client->GetCharacterID();
92  Rsp_CreateFolder result;
93  result.ownerID = ownerID;
94  result.folderID = m_db.SaveNewFolder(name, ownerID);
95  result.folderName = name;
96  result.creatorID = ownerID;
97 
98  result.Dump(BOOKMARK__RSP_DUMP, " ");
99  return result.Encode();
100 }
101 
102 PyResult BookmarkService::Handle_UpdateFolder(PyCallArgs &call) {
103  call.Dump(BOOKMARK__CALL_DUMP);
104  Call_UpdateFolder args;
105  if (!args.Decode(&call.tuple)) {
106  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
107  return PyStatic.NewFalse();
108  }
109 
111  if (!m_db.UpdateFolder(args.folderID, PyRep::StringContent(args.folderName)))
112  return PyStatic.NewFalse();
113 
114  return PyStatic.NewTrue();
115 }
116 
117 PyResult BookmarkService::Handle_DeleteFolder(PyCallArgs &call) {
118  // bookmarks = self.bookmarkMgr.DeleteFolder(folderID)
119  call.Dump(BOOKMARK__CALL_DUMP);
120 
121  uint32 folderID(PyRep::IntegerValueU32(call.tuple->GetItem(0)));
122 
123  // call db to get list of bmIDs in deleted folder. return result with this data
124  std::vector< int32 > bmIDs;
125  bmIDs.clear();
126  m_db.GetBookmarkByFolderID(folderID, bmIDs);
127 
128  PyList* list = new PyList();
129  for (auto cur : bmIDs) {
130  PyDict* dict = new PyDict();
131  dict->SetItemString("bookmarkID", new PyInt(cur));
132  list->AddItem(new PyObject("util.KeyVal", dict));
133  }
134 
135  m_db.DeleteFolder(folderID);
136 
137  return list;
138 }
139 
140 PyResult BookmarkService::Handle_BookmarkLocation(PyCallArgs &call) {
141  /* bookmarkID, itemID, typeID, x, y, z, locationID = sm.RemoteSvc('bookmark').BookmarkLocation(itemID, ownerID, memo, comment, folderID) */
142 
143  call.Dump(BOOKMARK__CALL_DUMP);
144  Call_BookmarkLocation args;
145  if (!args.Decode(&call.tuple)) {
146  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
147  return nullptr;
148  }
149 
150  BmData data = BmData();
151  data.memo = PyRep::StringContent(args.memo);
152  data.note = PyRep::StringContent(args.comment);
153  data.ownerID = call.client->GetCharacterID();
154  data.creatorID = data.ownerID;
155  data.created = GetFileTimeNow();
156 
157  // Check for presence of folderID in the packet
158  if (call.byname.find("folderID") != call.byname.end())
159  data.folderID = PyRep::IntegerValueU32(call.byname.find("folderID")->second);
160 
161  if (IsPlayerItem(args.itemID)) { // entity #'s above 140m are player-owned. player is in ship
163  data.point = call.client->GetShipSE()->GetPosition(); // Get x,y,z location. bm type is coordinate as "spot in xxx system"
164  data.locationID = call.client->GetLocationID(); // locationID of bm is current sol system
165  data.itemID = data.locationID; // itemID = locationID for coord bm. shows jumps, s/c/r in bm window, green in system
166  } else if (sDataMgr.IsStation(args.itemID)) { // not player-owned, check for station.
167  SystemEntity* pSE = call.client->SystemMgr()->GetSE(args.itemID);
168  if (pSE == nullptr) {
169  // send player error also
170  return nullptr;
171  }
172  data.typeID = pSE->GetTypeID();
173  data.itemID = args.itemID; // this is stationID (for bm description)
174  data.locationID = call.client->GetSystemID(); // get sol system of current station
175  } else { // char is passing systemID from map. char is marking a solar systemID for bm
176  if (IsRegionID(args.itemID)) {
178  } else if (IsConstellationID(args.itemID)) {
180  } else if (sDataMgr.IsSolarSystem(args.itemID)) {
182  }
183  data.locationID = args.itemID; // this is systemID from map
184  data.itemID = data.locationID; // itemID = locationID for coord bm. shows jumps, s/c/r in bm window, green in system
185  }
186 
187  m_db.SaveNewBookmark(data);
188 
189  // (bookmarkID, itemID, typeID, x, y, z, locationID)
190  Rsp_BookmarkLocation result;
191  result.bookmarkID = data.bookmarkID;
192  result.itemID = (data.typeID == EVEDB::invTypes::SolarSystem ? 0 : data.itemID); // itemID = 0 when typeID is SolarSystem
193  result.typeID = data.typeID;
194  result.x = data.point.x;
195  result.y = data.point.y;
196  result.z = data.point.z;
197  result.locationID = data.locationID;
198  result.Dump(BOOKMARK__RSP_DUMP, " ");
199  return result.Encode();
200 }
201 
202 PyResult BookmarkService::Handle_BookmarkScanResult(PyCallArgs &call)
203 {
204  // bookmarkID, itemID, typeID, x, y, z, locationID = self.bookmarkMgr.BookmarkScanResult(locationID, memo, comment, resultID, ownerID, folderID=0)
205 
206  call.Dump(BOOKMARK__CALL_DUMP);
207  Call_BookmarkScanResult args;
208  if (!args.Decode(&call.tuple)) {
209  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
210  return nullptr;
211  }
212  //args.Dump(BOOKMARK__CALL_DUMP, " ");
213  /*
214  * 22:25:58 [SvcCallDump] Tuple: 5 elements
215  * 22:25:58 [SvcCallDump] [ 0] Integer field: 30000053
216  * 22:25:58 [SvcCallDump] [ 1] String: 'test dungeon 2 '
217  * 22:25:58 [SvcCallDump] [ 2] WString: 'dungeon notes here'
218  * 22:25:58 [SvcCallDump] [ 3] String: 'XIG-040'
219  * 22:25:58 [SvcCallDump] [ 4] Integer field: 140000000
220  */
221  BmData data = BmData();
222  data.memo = PyRep::StringContent(args.memo);
223  data.note = PyRep::StringContent(args.comment);
224  data.ownerID = args.ownerID;
225  data.creatorID = data.ownerID;
226  data.created = GetFileTimeNow();
227  data.locationID = args.locationID;
229  data.point = ManagerDB::GetAnomalyPos(args.resultID);
230 
231  if (call.byname.find("folderID") != call.byname.end())
232  data.folderID = PyRep::IntegerValueU32(call.byname.find("folderID")->second);
233 
234  m_db.SaveNewBookmark(data);
235 
236  // (bookmarkID, itemID, typeID, x, y, z, locationID)
237  Rsp_BookmarkLocation result;
238  result.bookmarkID = data.bookmarkID;
239  result.itemID = data.itemID; // scan bm returns none here
240  result.typeID = data.typeID;
241  result.x = data.point.x;
242  result.y = data.point.y;
243  result.z = data.point.z;
244  result.locationID = data.locationID;
245  result.Dump(BOOKMARK__RSP_DUMP, " ");
246  return result.Encode();
247 }
248 
249 PyResult BookmarkService::Handle_DeleteBookmarks(PyCallArgs &call) {
250  call.Dump(BOOKMARK__CALL_DUMP);
251  Call_DeleteBookmarks args;
252  if (!args.Decode(&call.tuple)) {
253  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
254  return PyStatic.NewNone();
255  }
256 
257  if (args.object->IsNone())
258  return PyStatic.NewNone();
259 
260  PyList* bmList = args.object->header()->AsTuple()->GetItem(1)->AsTuple()->GetItem(0)->AsList();
261  //std::vector<int32> bmIDs;
262  for (size_t i = 0; i < bmList->size(); ++i)
263  m_db.ChangeOwner(bmList->GetItem(i)->AsInt()->value());
264  //bmIDs.push_back(bmList->GetItem(i)->AsInt()->value());
265 
266  // player is deleting this bm from their pnp window. there may be copies, so dont remove from db
267  // instead, to keep this in db and avoid appearance in players pnp window, just change owner to system
268  // m_db.DeleteBookmarks(&bmIDs);
269  return PyStatic.NewNone();
270 }
271 
272 
273 PyResult BookmarkService::Handle_MoveBookmarksToFolder(PyCallArgs &call) {
274  // rows = bookmarkMgr.MoveBookmarksToFolder(folderID, bookmarkIDs)
275  call.Dump(BOOKMARK__CALL_DUMP);
276  Call_MoveBookmarksToFolder args;
277  if (!args.Decode(&call.tuple)) {
278  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
279  return nullptr;
280  }
281  //args.Dump(BOOKMARK__CALL_DUMP, " ");
282 
283  if (args.object->IsNone())
284  return PyStatic.NewNone();
285 
286  PyList* bmList = args.object->header()->AsTuple()->GetItem(1)->AsTuple()->GetItem(0)->AsList();
287 
288  std::vector<int32> bmIDs;
289  for (size_t i = 0; i < bmList->size(); ++i)
290  bmIDs.push_back(bmList->GetItem(i)->AsInt()->value());
291 
292  m_db.MoveBookmarkToFolder(args.folderID, &bmIDs);
293 
294  return m_db.GetBookmarksInFolder(args.folderID);
295 }
296 
297 PyResult BookmarkService::Handle_AddBookmarkFromVoucher(PyCallArgs &call) {
307  call.Dump(BOOKMARK__CALL_DUMP);
308  Call_AddBookmarkFromVoucher args;
309  if (!args.Decode(&call.tuple)) {
310  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
311  return nullptr;
312  }
313  /*
314  * args.itemID
315  * args.ownerID
316  * args.folderID
317  */
318  InventoryItemRef iRef = sItemFactory.GetItem(args.itemID);
319  if (iRef.get() == nullptr) {
320  codelog(ITEM__ERROR, "%s: Failed to retrieve bookmark data for voucherID %u", call.client->GetName(), args.itemID);
321  return nullptr;
322  }
323 
324  // get existing bm data this is a copy of
325  BmData data = BmData();
326  data.bookmarkID = atoi(iRef->customInfo().c_str());
327  m_db.GetVoucherData(data);
328 
329  // update folderID and ownerID
330  data.folderID = args.folderID;
331  data.ownerID = args.ownerID;
332 
333  // create new bm entry for this copy
334  m_db.SaveNewBookmark(data);
335 
336  // delete voucher do we need to?
337  //iRef->Delete();
338 
339  // return new bm data to client
340  PyDict* dict = new PyDict();
341  dict->SetItemString("bookmarkID", new PyInt(data.bookmarkID));
342  dict->SetItemString("ownerID", new PyInt(data.ownerID));
343  dict->SetItemString("itemID", new PyInt(data.itemID));
344  dict->SetItemString("typeID", new PyInt(data.typeID));
345  dict->SetItemString("flag", PyStatic.NewNone());
346  dict->SetItemString("memo", new PyString(data.memo));
347  dict->SetItemString("created", new PyLong(data.created));
348  dict->SetItemString("x", new PyFloat(data.point.x));
349  dict->SetItemString("y", new PyFloat(data.point.y));
350  dict->SetItemString("z", new PyFloat(data.point.z));
351  dict->SetItemString("locationID", new PyInt(data.locationID));
352  dict->SetItemString("note", new PyString(data.note));
353  dict->SetItemString("creatorID", new PyInt(data.creatorID));
354  if (data.folderID > 0) {
355  dict->SetItemString("folderID", new PyInt(data.folderID));
356  } else {
357  dict->SetItemString("folderID", PyStatic.NewNone());
358  }
359 
360  return new PyObject("util.KeyVal", dict);
361 }
362 
363 
364 PyResult BookmarkService::Handle_CopyBookmarks(PyCallArgs &call) {
365  //newBookmarks, message = bookmarkMgr.CopyBookmarks(bookmarksToCopy, folderID)
366 
367  //{'FullPath': u'UI/Messages', 'messageID': 258505, 'label': u'CantTradeMissionBookmarksBody'}(u'You cannot trade or copy mission bookmarks.', None, None)
368 
369  // this is called when dropping bms on corp header in bm window
370 
371  call.Dump(BOOKMARK__CALL_DUMP);
372  Call_CopyBookmarks args;
373  if (!args.Decode(&call.tuple)) {
374  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
375  return new_tuple(PyStatic.NewNone(), PyStatic.NewNone());
376  }
377  //args.Dump(BOOKMARK__CALL_DUMP, " ");
378 
379  if (args.object->IsNone())
380  return new_tuple(PyStatic.NewNone(), PyStatic.NewNone());
381 
382  PyList* bmList = args.object->header()->AsTuple()->GetItem(1)->AsTuple()->GetItem(0)->AsList();
383 
384  PyList* list = new PyList();
385  for (size_t i = 0; i < bmList->size(); ++i) {
386  InventoryItemRef iRef = sItemFactory.GetItem(bmList->GetItem(i)->AsInt()->value());
387  if (iRef.get() == nullptr) {
388  codelog(ITEM__ERROR, "%s: Failed to retrieve bookmark data for voucherID %u", call.client->GetName(), bmList->GetItem(i)->AsInt()->value());
389  continue;
390  }
391 
392  // get existing bm data this is a copy of
393  BmData data = BmData();
394  data.bookmarkID = atoi(iRef->customInfo().c_str());
395  m_db.GetVoucherData(data);
396 
397  // update folderID and ownerID
398  data.folderID = args.folderID;
399  data.ownerID = call.client->GetCharacterID();
400 
401  // create new bm entry for this copy
402  m_db.SaveNewBookmark(data);
403 
404  // return new bm data to client
405  PyDict* dict = new PyDict();
406  dict->SetItemString("bookmarkID", new PyInt(data.bookmarkID));
407  dict->SetItemString("ownerID", new PyInt(data.ownerID));
408  dict->SetItemString("itemID", new PyInt(data.itemID));
409  dict->SetItemString("typeID", new PyInt(data.typeID));
410  dict->SetItemString("flag", PyStatic.NewNone());
411  dict->SetItemString("memo", new PyString(data.memo));
412  dict->SetItemString("created", new PyLong(data.created));
413  dict->SetItemString("x", new PyFloat(data.point.x));
414  dict->SetItemString("y", new PyFloat(data.point.y));
415  dict->SetItemString("z", new PyFloat(data.point.z));
416  dict->SetItemString("locationID", new PyInt(data.locationID));
417  dict->SetItemString("note", new PyString(data.note));
418  dict->SetItemString("creatorID", new PyInt(data.creatorID));
419  if (data.folderID > 0) {
420  dict->SetItemString("folderID", new PyInt(data.folderID));
421  } else {
422  dict->SetItemString("folderID", PyStatic.NewNone());
423  }
424 
425  list->AddItem(new PyObject("util.KeyVal", dict));
426  }
427 
428  PyTuple* tuple = new PyTuple(2);
429  tuple->SetItem(0, list);
430  tuple->SetItem(1, PyStatic.NewNone());
431  return tuple;
432 }
PyTuple * AsTuple()
Definition: PyRep.h:138
Dispatcher *const m_dispatch
SystemEntity * GetSE(uint32 entityID) const
static std::string StringContent(PyRep *pRep)
Definition: PyRep.cpp:103
uint32 GetLocationID() const
Definition: Client.h:151
int64 created
Definition: BookmarkDB.h:51
void GetVoucherData(BmData &data)
Definition: BookmarkDB.cpp:383
#define IsConstellationID(itemID)
Definition: EVE_Defines.h:276
uint32 GetSystemID() const
Definition: Client.h:152
itemID[count] Create count or of the specified() x() y(z)-Jump to the specified position in space.Stopped." ) COMMAND( translocate
std::string memo
Definition: BookmarkDB.h:53
PyRep * GetItem(size_t index) const
Returns Python object.
Definition: PyRep.h:602
Python string.
Definition: PyRep.h:430
int32 value() const
Definition: PyRep.h:247
Python's dictionary.
Definition: PyRep.h:719
void GetBookmarkByFolderID(int32 folderID, std::vector< int32 > &bmIDs)
Definition: BookmarkDB.cpp:66
std::map< std::string, PyRep * > byname
Definition: PyCallable.h:51
PyRep * GetBookmarksInFolder(uint32 folderID)
Definition: BookmarkDB.cpp:34
uint32 SaveNewFolder(std::string folderName, uint32 ownerID)
Definition: BookmarkDB.cpp:323
static GPoint GetAnomalyPos(std::string &string)
Definition: ManagerDB.cpp:348
const std::string & customInfo() const
Python floating point number.
Definition: PyRep.h:292
int32 GetCharacterID() const
Definition: Client.h:113
PyCallable_Make_InnerDispatcher(BookmarkService) BookmarkService
static uint32 IntegerValueU32(PyRep *pRep)
Definition: PyRep.cpp:134
uint32 folderID
Definition: BookmarkDB.h:49
Python tuple.
Definition: PyRep.h:567
const char * GetName() const
Definition: PyService.h:54
GaFloat x
Definition: GaTypes.h:207
void Dump(FILE *into, const char *pfx) const
Dumps object to file.
Definition: PyRep.cpp:84
const GPoint & GetPosition() const
Definition: SystemEntity.h:211
bool GetBookmarkInformation(uint32 bookmarkID, uint32 &itemID, uint16 &typeID, uint32 &locationID, double &x, double &y, double &z)
Definition: BookmarkDB.cpp:205
void AddItem(PyRep *i)
Definition: PyRep.h:701
bool LookupBookmark(uint32 bookmarkID, uint32 &itemID, uint16 &typeID, uint32 &locationID, double &x, double &y, double &z)
PyRep * GetItem(size_t index) const
Returns Python object.
Definition: PyRep.h:674
* args
uint32 creatorID
Definition: BookmarkDB.h:50
uint32 locationID
Definition: BookmarkDB.h:48
uint32 ownerID
Definition: BookmarkDB.h:46
GPoint point
Definition: BookmarkDB.h:52
void ChangeOwner(uint32 bookmarkID, uint32 ownerID=1)
Definition: BookmarkDB.cpp:301
#define IsPlayerItem(itemID)
Definition: EVE_Defines.h:256
Python object.
Definition: PyRep.h:826
PyTuple * new_tuple(int64 arg1)
Definition: PyRep.cpp:1160
bool UpdateFolder(int32 folderID, std::string folderName)
Definition: BookmarkDB.cpp:340
void SaveNewBookmark(BmData &data)
Definition: BookmarkDB.cpp:236
#define codelog(type, fmt,...)
Definition: logsys.h:128
void SetItem(size_t index, PyRep *object)
Stores Python object.
Definition: PyRep.h:610
SystemManager * SystemMgr() const
Definition: Client.h:92
PyList * AsList()
Definition: PyRep.h:140
Python integer.
Definition: PyRep.h:231
virtual ~BookmarkService()
#define PyStatic
Definition: PyRep.h:1209
X * get() const
Definition: RefPtr.h:213
const char * GetName() const
Definition: Client.h:94
Client *const client
Definition: PyCallable.h:49
#define PyCallable_REG_CALL(c, m)
Definition: PyServiceCD.h:78
bool DeleteFolder(int32 folderID)
Definition: BookmarkDB.cpp:356
unsigned __int32 uint32
Definition: eve-compat.h:50
PyRep * GetBookmarks(uint32 ownerID)
Definition: BookmarkDB.cpp:79
GaFloat y
Definition: GaTypes.h:207
double GetFileTimeNow()
Definition: utils_time.cpp:84
PyRep * GetFolders(uint32 ownerID)
Definition: BookmarkDB.cpp:134
ShipSE * GetShipSE()
Definition: Client.h:168
uint32 bookmarkID
Definition: BookmarkDB.h:45
typeID Spawn an NPC with the specified type text Search for items matching the specified query() type()() itemID() copy() materialLevel()() itemID(attributeID)-Retrieves attribute value." ) COMMAND( setattr
void Dump(LogType type) const
Definition: PyCallable.cpp:81
size_t size() const
Definition: PyRep.h:663
#define sItemFactory
Definition: ItemFactory.h:165
uint16 typeID
Definition: BookmarkDB.h:44
void MoveBookmarkToFolder(int32 folderID, std::vector< int32 > *bookmarkList)
Definition: BookmarkDB.cpp:369
Dispatcher *const m_dispatch
uint16 GetTypeID()
Definition: SystemEntity.h:203
#define IsRegionID(itemID)
Definition: EVE_Defines.h:273
PyInt * AsInt()
Definition: PyRep.h:122
unsigned __int16 uint16
Definition: eve-compat.h:48
uint32 itemID
Definition: BookmarkDB.h:47
Python list.
Definition: PyRep.h:639
GaFloat z
Definition: GaTypes.h:207
void SetItemString(const char *key, PyRep *value)
SetItemString adds or sets a database entry.
Definition: PyRep.h:812
Python long integer.
Definition: PyRep.h:261
std::string note
Definition: BookmarkDB.h:54
PyTuple * tuple
Definition: PyCallable.h:50
#define sDataMgr