EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ItemDB.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: Allan
24 */
25 
26 
27 #include "eve-server.h"
28 
29 #include "inventory/ItemDB.h"
30 
31 
33  /* called by RefPtr<_Ty> _Load() at InventoryItem.h:189 */
34  DBQueryResult res;
35 
36  // For ranges of itemIDs we use specialized tables:
37  if (IsRegionID(itemID)) {
38  //region
39  if (!sDatabase.RunQuery(res,
40  "SELECT"
41  " regionName, 3 AS typeID, factionID, 1 AS locationID, 0 AS flag, 0 AS contraband,"
42  " 1 AS singleton, 1 AS quantity, x, y, z, '' AS customInfo"
43  " FROM mapRegions"
44  " WHERE regionID=%u", itemID))
45  {
46  codelog(DATABASE__ERROR, "Error in query for region %u: %s", itemID, res.error.c_str());
47  return false;
48  }
49  } else if (IsConstellationID(itemID)) {
50  //contellation
51  if (!sDatabase.RunQuery(res,
52  "SELECT"
53  " constellationName, 4 AS typeID, factionID, regionID, 0 AS flag, 0 AS contraband,"
54  " 1 AS singleton, 1 AS quantity, x, y, z, '' AS customInfo"
55  " FROM mapConstellations"
56  " WHERE constellationID=%u", itemID))
57  {
58  codelog(DATABASE__ERROR, "Error in query for contellation %u: %s", itemID, res.error.c_str());
59  return false;
60  }
61  } else if (sDataMgr.IsSolarSystem(itemID)) {
62  //solar system
63  if (!sDatabase.RunQuery(res,
64  "SELECT"
65  " solarSystemName, 5 AS typeID, factionID, constellationID, 0 AS flag, 0 AS contraband,"
66  " 1 AS singleton, 1 AS quantity, x, y, z, '' AS customInfo"
67  " FROM mapSolarSystems"
68  " WHERE solarSystemID=%u", itemID))
69  {
70  codelog(DATABASE__ERROR, "Error in query for solar system %u: %s", itemID, res.error.c_str());
71  return false;
72  }
73  } else if (IsStargateID(itemID)) {
74  //use mapDenormalize LEFT-JOIN-ing mapSolarSystems to get factionID
75  if (!sDatabase.RunQuery(res,
76  "SELECT"
77  " itemName, typeID, factionID, solarSystemID, 0 AS flag, 0 AS contraband,"
78  " 1 AS singleton, 1 AS quantity, mapDenormalize.x, mapDenormalize.y, mapDenormalize.z, '' AS customInfo"
79  " FROM mapDenormalize"
80  " LEFT JOIN mapSolarSystems USING (solarSystemID)"
81  " WHERE itemID=%u", itemID))
82  {
83  codelog(DATABASE__ERROR, "Error in query for stargate %u: %s", itemID, res.error.c_str());
84  return false;
85  }
86  } else if (sDataMgr.IsStation(itemID)) {
87  //station
88  if (!sDatabase.RunQuery(res,
89  "SELECT"
90  " stationName, stationTypeID, corporationID, solarSystemID, 0 AS flag, 0 AS contraband,"
91  " 1 AS singleton, 1 AS quantity, x, y, z, '' AS customInfo"
92  " FROM staStations"
93  " WHERE stationID=%u", itemID))
94  {
95  codelog(DATABASE__ERROR, "Error in query for station %u: %s", itemID, res.error.c_str());
96  return false;
97  }
98  } else if (IsCelestialID(itemID)) {
99  //use mapDenormalize
100  if (!sDatabase.RunQuery(res,
101  "SELECT"
102  " itemName, typeID, 1 AS ownerID, solarSystemID, 0 AS flag, 0 AS contraband,"
103  " 1 AS singleton, 1 AS quantity, x, y, z, '' AS customInfo"
104  " FROM mapDenormalize"
105  " WHERE itemID=%u", itemID))
106  {
107  codelog(DATABASE__ERROR, "Error in query for universe celestial %u: %s", itemID, res.error.c_str());
108  return false;
109  }
110  } else if (IsAsteroidID(itemID)) {
111  //use sysAsteroids
112  if (!sDatabase.RunQuery(res,
113  "SELECT"
114  " itemName, typeID, 1 AS ownerID, systemID, 0 AS flag, 0 AS contraband,"
115  " 1 AS singleton, quantity, x, y, z, '' AS customInfo"
116  " FROM sysAsteroids"
117  " WHERE itemID=%u", itemID))
118  {
119  codelog(DATABASE__ERROR, "Error in query for asteroid %u: %s", itemID, res.error.c_str());
120  return false;
121  }
122  } else if (IsCharacterID(itemID)) {
123  //use chrCharacters
124  if (!sDatabase.RunQuery(res,
125  "SELECT"
126  " characterName, typeID, 1 AS ownerID, solarSystemID, flag, 0 AS contraband,"
127  " 1 AS singleton, 1 AS quantity, 0 AS x, 0 AS y, 0 AS z, '' AS customInfo"
128  " FROM chrCharacters"
129  " WHERE characterID=%u", itemID))
130  {
131  codelog(DATABASE__ERROR, "Error in query for character %u: %s", itemID, res.error.c_str());
132  return false;
133  }
134  } else if (IsOfficeID(itemID)) {
135  //use staOffices
136  if (!sDatabase.RunQuery(res,
137  "SELECT"
138  " name, typeID, corporationID, solarSystemID, flag, 0 AS contraband,"
139  " 1 AS singleton, 1 AS quantity, 0 AS x, 0 AS y, 0 AS z, '' AS customInfo"
140  " FROM staOffices"
141  " WHERE itemID=%u", itemID))
142  {
143  codelog(DATABASE__ERROR, "Error in query for character %u: %s", itemID, res.error.c_str());
144  return false;
145  }
146  } else {
147  //fallback to entity
148  if (!sDatabase.RunQuery(res,
149  "SELECT"
150  " itemName, typeID, ownerID, locationID, flag, contraband,"
151  " singleton, quantity, x, y, z, customInfo"
152  " FROM entity WHERE itemID=%u", itemID))
153  {
154  codelog(DATABASE__ERROR, "Error in query for item %u: %s", itemID, res.error.c_str());
155  return false;
156  }
157  }
158 
159  DBResultRow row;
160  if(!res.GetRow(row)) {
161  _log(DATABASE__MESSAGE, "ItemDB::GetItem() - Item %u not found.", itemID);
162  return false;
163  }
164 
165  into.name = row.GetText(0);
166  into.typeID = row.GetUInt(1);
167  into.ownerID = (row.IsNull(2) ? 1 : row.GetUInt(2));
168  into.locationID = (row.IsNull(3) ? 0 : row.GetUInt(3));
169  into.flag = (EVEItemFlags)row.GetUInt(4);
170  into.contraband = row.GetInt(5) ? true : false;
171  into.singleton = row.GetInt(6) ? true : false;
172  into.quantity = row.GetUInt(7);
173 
174  into.position.x = row.GetDouble(8);
175  into.position.y = row.GetDouble(9);
176  into.position.z = row.GetDouble(10);
177 
178  into.customInfo = (row.IsNull(11) ? "" : row.GetText(11));
179 
180  return true;
181 }
182 
184  // check for common errors ('common' is relative.)
185  if (data.position.isNaN() or data.position.isInf())
186  return 0; // make error here?
187 
188  DBerror err;
189  uint32 uid = 0;
190 
191  std::string nameEsc, customInfoEsc;
192  sDatabase.DoEscapeString(nameEsc, data.name);
193  sDatabase.DoEscapeString(customInfoEsc, data.customInfo);
194 
195  if(!sDatabase.RunQueryLID(err, uid,
196  "INSERT INTO entity ("
197  " itemName, typeID, ownerID, locationID, flag,"
198  " contraband, singleton, quantity, x, y, z,"
199  " customInfo) "
200  "VALUES('%s', %u, %u, %u, %u,%u,"
201  " %u, %u, %f, %f, %f, '%s' )",
202  nameEsc.c_str(), data.typeID, data.ownerID, data.locationID, data.flag, data.contraband?1:0,
203  data.singleton?1:0, data.quantity, data.position.x, data.position.y, data.position.z, customInfoEsc.c_str()
204  )) {
205  codelog(DATABASE__ERROR, "Failed to insert new entity: %s", err.c_str());
206  return 0;
207  }
208 
209  return uid;
210 }
211 
213 {
214  DBerror err;
215  sDatabase.RunQuery(err, "UPDATE entity SET locationID = %u, flag = %u WHERE itemID = %u", \
216  locationID, (uint16)flag, itemID);
217 }
218 
220  // First check whether they are trying to save proper item:
221  if (IsStaticMapItem(itemID)) {
222  _log(ITEM__ERROR, "Refusing to modify static map object %u.", itemID);
223  return false;
224  }
225 
226  // check for common error ('common' is relative.)
227  if (data.position.isNaN())
228  return false; // make error here?
229 
230  std::string nameEsc, customInfoEsc;
231  sDatabase.DoEscapeString(nameEsc, data.name);
232  sDatabase.DoEscapeString(customInfoEsc, data.customInfo);
233 
234  DBerror err;
235  if(!sDatabase.RunQuery(err,
236  "UPDATE entity"
237  " SET"
238  " itemName = '%s',"
239  " ownerID = %u,"
240  " locationID = %u,"
241  " flag = %u,"
242  " singleton = %u,"
243  " quantity = %u,"
244  " x = %f, y = %f, z = %f,"
245  " customInfo = '%s'"
246  " WHERE itemID = %u",
247  nameEsc.c_str(),
248  data.ownerID,
249  data.locationID,
250  (uint16)data.flag,
251  (data.singleton?1:0),
252  data.quantity,
253  data.position.x, data.position.y, data.position.z,
254  customInfoEsc.c_str(),
255  itemID))
256  {
257  codelog(DATABASE__ERROR, "Error in query: %s.", err.c_str());
258  return false;
259  }
260 
261  return true;
262 }
263 
264 void ItemDB::SaveItems(std::vector<Inv::SaveData>& data)
265 {
266  std::ostringstream Inserts;
267  // start the insert into command.
268  Inserts << "INSERT INTO entity";
269  Inserts << " (itemID, typeID, ownerID, locationID, flag, contraband, singleton, quantity, x, y, z, customInfo)";
270  bool first = true;
271  for (auto cur : data) {
272  if (cur.position.isNaN() or cur.position.isInf()) {
273  _log(DATABASE__ERROR, "ItemDB::SaveItems() - %u has invalid position", cur.itemID);
274  continue;
275  }
276  if (cur.locationID == 0) {
277  _log(DATABASE__ERROR, "ItemDB::SaveItems() - %u has invalid location", cur.itemID);
278  continue;
279  }
280  if (first) {
281  Inserts << " VALUES ";
282  first = false;
283  } else {
284  Inserts << ", ";
285  }
286  Inserts << "(" << cur.itemID << ", " << cur.typeID << ", " << cur.ownerID << ", " << cur.locationID << ", ";
287  Inserts << cur.flag << ", " << cur.contraband << ", " << (cur.singleton ? 1 : 0) << ", ";
288  Inserts << cur.quantity << ", " << std::to_string(cur.position.x) << ", " << std::to_string(cur.position.y) << ", " << std::to_string(cur.position.z);
289  Inserts << ", '" << cur.customInfo << "')";
290  }
291 
292  if (!first) {
293  Inserts << "ON DUPLICATE KEY UPDATE ";
294  Inserts << "quantity=VALUES(quantity), ";
295  Inserts << "ownerID=VALUES(ownerID), ";
296  Inserts << "locationID=VALUES(locationID), ";
297  Inserts << "flag=VALUES(flag), ";
298  Inserts << "singleton=VALUES(singleton), ";
299  Inserts << "quantity=VALUES(quantity), ";
300  Inserts << "x=VALUES(x), ";
301  Inserts << "y=VALUES(y), ";
302  Inserts << "z=VALUES(z), ";
303  Inserts << "customInfo=VALUES(customInfo) ";
304  DBerror err;
305  if (!sDatabase.RunQuery(err, Inserts.str().c_str()))
306  _log(DATABASE__ERROR, "SaveItems - unable to save data - %s", err.c_str());
307  }
308 }
309 
310 void ItemDB::SaveAttributes(bool isChar, std::vector<Inv::AttrData>& data)
311 {
312  std::ostringstream Inserts;
313  // start the insert into command.
314  if (isChar) {
315  DBerror err;
316  sDatabase.RunQuery(err, "DELETE FROM chrCharacterAttributes WHERE charID = %u", data[0].itemID);
317  Inserts << "INSERT INTO chrCharacterAttributes";
318  Inserts << " (charID, attributeID, valueInt, valueFloat)";
319  } else {
320  Inserts << "INSERT INTO entity_attributes";
321  Inserts << " (itemID, attributeID, valueInt, valueFloat)";
322  }
323  bool first(true);
324  for (auto cur : data) {
325  if (first) {
326  Inserts << " VALUES ";
327  first = false;
328  } else
329  Inserts << ", ";
330  Inserts << "(" << cur.itemID << ", " << cur.attrID << ", ";
331  if (cur.type) {
332  Inserts << "NULL, " << cur.valueFloat << ")";
333  } else {
334  Inserts << cur.valueInt << ", NULL)";
335  }
336  }
337 
338  if (!first) {
339  Inserts << "ON DUPLICATE KEY UPDATE ";
340  Inserts << "valueInt=VALUES(valueInt), ";
341  Inserts << "valueFloat=VALUES(valueFloat)";
342  DBerror err;
343  if (!sDatabase.RunQuery(err, Inserts.str().c_str()))
344  _log(DATABASE__ERROR, "SaveItems - unable to save data - %s", err.c_str());
345  }
346 }
347 
349  if (IsStaticMapItem(itemID)) {
350  _log(ITEM__ERROR, "Refusing to delete static map object %u.", itemID);
351  return false;
352  }
353 
354  DBerror err;
355  if (!sDatabase.RunQuery(err, "DELETE FROM entity WHERE itemID = %u", itemID)) {
356  codelog(DATABASE__ERROR, "Failed to delete item %u: %s", itemID, err.c_str());
357  return false;
358  }
359 
360  if (!sDatabase.RunQuery(err, "DELETE FROM entity_attributes WHERE itemID=%u", itemID)) {
361  codelog(DATABASE__ERROR, "Failed to delete item %u: %s", itemID, err.c_str());
362  return false;
363  }
364  return true;
365 }
366 
367 void ItemDB::GetItems(uint16 catID, std::map< uint16, std::string >& typeIDs) {
368 
369  DBQueryResult res;
370 
371  if (!sDatabase.RunQuery(res,
372  "SELECT"
373  " typeID,"
374  " typeName"
375  " FROM invTypes "
376  " WHERE groupID IN"
377  " (SELECT groupID"
378  " FROM invGroups"
379  " WHERE categoryID = %u)",
380  catID))
381  {
382  codelog(DATABASE__ERROR, "Failed to query types for catID %u: %s.", catID, res.error.c_str());
383  return;
384  }
385 
386  DBResultRow row;
387  while(res.GetRow(row))
388  typeIDs.emplace(row.GetUInt(0), row.GetText(1));
389 }
static bool SaveItem(uint32 itemID, const ItemData &data)
Definition: ItemDB.cpp:219
#define sDatabase
Definition: dbcore.h:199
#define IsConstellationID(itemID)
Definition: EVE_Defines.h:276
const char * GetText(uint32 index) const
Definition: dbcore.h:104
#define IsAsteroidID(itemID)
Definition: EVE_Defines.h:259
#define _log(type, fmt,...)
Definition: logsys.h:124
int32 GetInt(uint32 index) const
Definition: dbcore.cpp:635
uint32 locationID
Definition: ItemType.h:190
uint32 GetUInt(uint32 index) const
Definition: dbcore.cpp:658
#define IsCelestialID(itemID)
Definition: EVE_Defines.h:288
double GetDouble(uint32 index) const
Definition: dbcore.cpp:693
static void SaveItems(std::vector< Inv::SaveData > &data)
Definition: ItemDB.cpp:264
EVEItemFlags
Definition: EVE_Flags.h:13
GPoint position
Definition: ItemType.h:192
GaExpInl bool isNaN() const
Definition: GaTypes.h:194
GaFloat x
Definition: GaTypes.h:207
std::string customInfo
Definition: ItemType.h:194
bool GetRow(DBResultRow &into)
Definition: dbcore.cpp:552
const char * c_str() const
Definition: dbcore.h:48
#define codelog(type, fmt,...)
Definition: logsys.h:128
static uint32 NewItem(const ItemData &data)
Definition: ItemDB.cpp:183
bool IsNull(uint32 index) const
Definition: dbcore.h:102
uint32 quantity
Definition: ItemType.h:191
GaExpInl bool isInf() const
Definition: GaTypes.h:197
#define IsCharacterID(itemID)
Definition: EVE_Defines.h:206
unsigned __int32 uint32
Definition: eve-compat.h:50
uint16 typeID
Definition: ItemType.h:188
static void SaveAttributes(bool isChar, std::vector< Inv::AttrData > &data)
Definition: ItemDB.cpp:310
EVEItemFlags flag
Definition: ItemType.h:187
GaFloat y
Definition: GaTypes.h:207
static void UpdateLocation(uint32 itemID, uint32 locationID, EVEItemFlags flag)
Definition: ItemDB.cpp:212
#define IsOfficeID(itemID)
Definition: EVE_Defines.h:253
DBerror error
Definition: dbcore.h:69
static bool DeleteItem(uint32 itemID)
Definition: ItemDB.cpp:348
#define IsStaticMapItem(itemID)
Definition: EVE_Defines.h:270
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
#define IsStargateID(itemID)
Definition: EVE_Defines.h:291
uint32 ownerID
Definition: ItemType.h:189
bool contraband
Definition: ItemType.h:185
#define IsRegionID(itemID)
Definition: EVE_Defines.h:273
unsigned __int16 uint16
Definition: eve-compat.h:48
static bool GetItem(uint32 itemID, ItemData &into)
Definition: ItemDB.cpp:32
std::string name
Definition: ItemType.h:193
static void GetItems(uint16 catID, std::map< uint16, std::string > &typeIDs)
Definition: ItemDB.cpp:367
Definition: dbcore.h:39
bool singleton
Definition: ItemType.h:186
GaFloat z
Definition: GaTypes.h:207
#define sDataMgr