EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
DogmaIMService.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  This program is distributed in the hope that it will be useful, but WITHOUT
14  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16  You should have received a copy of the GNU Lesser General Public License along with
17  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18  Place - Suite 330, Boston, MA 02111-1307, USA, or go to
19  http://www.gnu.org/copyleft/lesser.txt.
20  ------------------------------------------------------------------------------------
21  Author: Zhur
22  Rewrite: Allan
23 */
24 
25 #include "eve-server.h"
26 
27 #include "EVEServerConfig.h"
28 #include "PyBoundObject.h"
29 #include "PyServiceCD.h"
30 #include "cache/ObjCacheService.h"
31 #include "dogmaim/DogmaIMService.h"
32 #include "pos/Tower.h"
34 #include "system/Container.h"
35 #include "system/SystemManager.h"
36 #include "station/Station.h"
37 
43 : public PyBoundObject
44 {
45 public:
47 
49  : PyBoundObject(mgr),
50  m_dispatch(new Dispatcher(this)),
51  m_locationID(locationID),
53  {
55 
56  m_strBoundObjectName = "DogmaIMBound";
57 
58  PyCallable_REG_CALL(DogmaIMBound, ChangeDroneSettings);
59  PyCallable_REG_CALL(DogmaIMBound, LinkWeapons);
60  PyCallable_REG_CALL(DogmaIMBound, LinkAllWeapons);
61  PyCallable_REG_CALL(DogmaIMBound, UnlinkModule);
62  PyCallable_REG_CALL(DogmaIMBound, UnlinkAllModules);
63  PyCallable_REG_CALL(DogmaIMBound, OverloadRack);
64  PyCallable_REG_CALL(DogmaIMBound, StopOverloadRack);
65  PyCallable_REG_CALL(DogmaIMBound, CharGetInfo);
66  PyCallable_REG_CALL(DogmaIMBound, ItemGetInfo);
67  PyCallable_REG_CALL(DogmaIMBound, GetAllInfo);
68  PyCallable_REG_CALL(DogmaIMBound, DestroyWeaponBank);
69  PyCallable_REG_CALL(DogmaIMBound, GetCharacterBaseAttributes);
71  PyCallable_REG_CALL(DogmaIMBound, Deactivate);
73  PyCallable_REG_CALL(DogmaIMBound, StopOverload);
74  PyCallable_REG_CALL(DogmaIMBound, CancelOverloading);
75  PyCallable_REG_CALL(DogmaIMBound, SetModuleOnline);
76  PyCallable_REG_CALL(DogmaIMBound, TakeModuleOffline);
77  PyCallable_REG_CALL(DogmaIMBound, LoadAmmoToBank);
78  PyCallable_REG_CALL(DogmaIMBound, LoadAmmoToModules);
79  PyCallable_REG_CALL(DogmaIMBound, GetTargets);
80  PyCallable_REG_CALL(DogmaIMBound, GetTargeters);
81  PyCallable_REG_CALL(DogmaIMBound, AddTarget); //AddTargetOBO
82  PyCallable_REG_CALL(DogmaIMBound, RemoveTarget);
83  PyCallable_REG_CALL(DogmaIMBound, ClearTargets);
84  PyCallable_REG_CALL(DogmaIMBound, InitiateModuleRepair);
85  PyCallable_REG_CALL(DogmaIMBound, StopModuleRepair);
86  PyCallable_REG_CALL(DogmaIMBound, MergeModuleGroups);
87  PyCallable_REG_CALL(DogmaIMBound, PeelAndLink);
88  }
89  virtual ~DogmaIMBound() {delete m_dispatch;}
90  virtual void Release() {
91  //I hate this statement
92  delete this;
93  }
94 
95  PyCallable_DECL_CALL(ChangeDroneSettings);
96  PyCallable_DECL_CALL(LinkWeapons);
97  PyCallable_DECL_CALL(LinkAllWeapons);
98  PyCallable_DECL_CALL(UnlinkModule);
99  PyCallable_DECL_CALL(UnlinkAllModules);
100  PyCallable_DECL_CALL(OverloadRack);
101  PyCallable_DECL_CALL(StopOverloadRack);
102  PyCallable_DECL_CALL(CharGetInfo);
103  PyCallable_DECL_CALL(ItemGetInfo);
104  PyCallable_DECL_CALL(GetAllInfo);
105  PyCallable_DECL_CALL(DestroyWeaponBank);
106  PyCallable_DECL_CALL(GetCharacterBaseAttributes);
107  PyCallable_DECL_CALL(Activate);
108  PyCallable_DECL_CALL(Deactivate);
109  PyCallable_DECL_CALL(Overload);
110  PyCallable_DECL_CALL(StopOverload);
111  PyCallable_DECL_CALL(CancelOverloading);
112  PyCallable_DECL_CALL(SetModuleOnline);
113  PyCallable_DECL_CALL(TakeModuleOffline);
114  PyCallable_DECL_CALL(LoadAmmoToBank);
115  PyCallable_DECL_CALL(LoadAmmoToModules);
116  PyCallable_DECL_CALL(GetTargets);
117  PyCallable_DECL_CALL(GetTargeters);
118  PyCallable_DECL_CALL(AddTarget);
119  PyCallable_DECL_CALL(RemoveTarget);
120  PyCallable_DECL_CALL(ClearTargets);
121  PyCallable_DECL_CALL(InitiateModuleRepair);
122  PyCallable_DECL_CALL(StopModuleRepair);
123  PyCallable_DECL_CALL(MergeModuleGroups);
124  PyCallable_DECL_CALL(PeelAndLink);
125 
126  /* OBO == ?? (pos targeting)
127  * flag, targetList = self.GetDogmaLM().AddTargetOBO(sid, tid) (structureID, targetID)
128  * self.GetDogmaLM().RemoveTargetOBO(sid, tid) (structureID, targetID)
129  */
130 protected:
131  Dispatcher* const m_dispatch;
132 
135 };
136 
138 
139 
141 : PyService(mgr, "dogmaIM"), // IM = Instance Manager, also LM = Location Manager
142  m_dispatch(new Dispatcher(this))
143 {
144  _SetCallDispatcher(m_dispatch);
145 
146  PyCallable_REG_CALL(DogmaIMService, GetAttributeTypes);
147 }
148 
150  delete m_dispatch;
151 }
152 
153 PyResult DogmaIMService::Handle_GetAttributeTypes(PyCallArgs& call) {
154  PyString* str = new PyString("dogmaIM.attributesByName" );
155  PyRep* result = m_manager->cache_service->GetCacheHint( str );
156  PyDecRef( str );
157  return result;
158 }
159 
161  DogmaLM_BindArgs args;
162  //crap
163  PyRep* tmp(bind_args->Clone());
164  if (!args.Decode(&tmp)) {
165  codelog(SERVICE__ERROR, "%s: Failed to decode bind args.", GetName());
166  return nullptr;
167  }
168 
169  return new DogmaIMBound(m_manager, args.locationID, args.groupID);
170 }
171 
172 PyResult DogmaIMBound::Handle_CharGetInfo(PyCallArgs& call) {
173  return call.client->GetChar()->GetCharInfo();
174 }
175 
176 PyResult DogmaIMBound::Handle_ClearTargets(PyCallArgs& call) {
177  call.client->GetShipSE()->TargetMgr()->ClearTargets();
178  //call.client->GetShipSE()->TargetMgr()->OnTarget(nullptr, TargMgr::Mode::Clear, TargMgr::Msg::ClientReq);
179  return nullptr;
180 }
181 
182 PyResult DogmaIMBound::Handle_GetTargets(PyCallArgs& call) {
183  return call.client->GetShipSE()->TargetMgr()->GetTargets();
184 }
185 
186 PyResult DogmaIMBound::Handle_GetTargeters(PyCallArgs& call) {
187  return call.client->GetShipSE()->TargetMgr()->GetTargeters();
188 }
189 
190 PyResult DogmaIMBound::Handle_GetCharacterBaseAttributes(PyCallArgs& call)
191 {
192  CharacterRef cref = call.client->GetChar();
193  PyDict* result = new PyDict();
198  result->SetItem(new PyInt(AttrMemory), cref->GetAttribute(AttrMemory).GetPyObject());
199  return result;
200 }
201 
202 
203 PyResult DogmaIMBound::Handle_ItemGetInfo(PyCallArgs& call) {
204  // called when item 'row' info not in shipState data from GetAllInfo() return
205  Call_SingleIntegerArg args;
206  if (!args.Decode(&call.tuple)) {
207  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
208  return PyStatic.NewNone();
209  }
210 
211  InventoryItemRef itemRef = sItemFactory.GetItem(args.arg);
212  if (itemRef.get() == nullptr ) {
213  _log(INV__ERROR, "Unable to load item %u", args.arg);
214  return PyStatic.NewNone();
215  }
216 
217  PyObject* obj = itemRef->ItemGetInfo();
218  if (is_log_enabled(ITEM__DEBUG))
219  obj->Dump(ITEM__DEBUG, " ");
220  return obj;
221 }
222 
223 PyResult DogmaIMBound::Handle_SetModuleOnline(PyCallArgs& call) {
224  Client* pClient(call.client);
225 
226  if (pClient->IsInSpace()) {
227  DestinyManager* pDestiny = pClient->GetShipSE()->DestinyMgr();
228  if (pDestiny == nullptr) {
229  _log(PLAYER__ERROR, "%s: Client has no destiny manager!", pClient->GetName());
230  return PyStatic.NewNone();
231  } else if (pDestiny->IsWarping()) {
233  pClient->SendNotifyMsg("You can't do this while warping");
234  return PyStatic.NewNone();
235  }
236  }
237 
238  Call_TwoIntegerArgs args; //locationID, moduleID
239 
240  if (!args.Decode(&call.tuple)) {
241  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
242  return PyStatic.NewNone();
243  }
244 
245  pClient->GetShip()->Online(args.arg2);
246 
247  // returns nodeID and timestamp
248  PyTuple* tuple = new PyTuple(2);
249  tuple->SetItem(0, new PyString(GetBindStr())); // node info here
250  tuple->SetItem(1, new PyLong(GetFileTimeNow()));
251  return tuple;
252 }
253 
254 PyResult DogmaIMBound::Handle_TakeModuleOffline(PyCallArgs& call) {
255  Client* pClient(call.client);
256 
257  if (pClient->IsInSpace()) {
258  DestinyManager* pDestiny = pClient->GetShipSE()->DestinyMgr();
259  if (pDestiny == nullptr) {
260  _log(PLAYER__ERROR, "%s: Client has no destiny manager!", pClient->GetName());
261  return PyStatic.NewNone();
262  } else if (pDestiny->IsWarping()) {
264  pClient->SendNotifyMsg("You can't do this while warping");
265  return PyStatic.NewNone();
266  }
267  }
268 
269  Call_TwoIntegerArgs args; //locationID, moduleID
270  if (!args.Decode(&call.tuple)) {
271  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
272  return PyStatic.NewNone();
273  }
274 
275  pClient->GetShip()->Offline(args.arg2);
276 
277  // returns nodeID and timestamp
278  PyTuple* tuple = new PyTuple(2);
279  tuple->SetItem(0, new PyString(GetBindStr())); // node info here
280  tuple->SetItem(1, new PyLong(GetFileTimeNow()));
281  return tuple;
282 }
283 
284 PyResult DogmaIMBound::Handle_LoadAmmoToModules(PyCallArgs& call) {
285  // self.remoteDogmaLM.LoadAmmoToModules(shipID, moduleIDs, chargeTypeID, itemID, ammoLocationID, qty=qty)
286  // NOTE: this call seems to be a list of moduleIDs with ONLY a single module.
287  /* 02:13:11 [SvcCall] Tuple: 5 elements
288  * 02:13:11 [SvcCall] [ 0] Integer field: 140000602 <- ship
289  * 02:13:11 [SvcCall] [ 1] List: 1 elements
290  * 02:13:11 [SvcCall] [ 1] [ 0] Integer field: 140000454 <- moduleList
291  * 02:13:11 [SvcCall] [ 2] Integer field: 196 <- charge type
292  * 02:13:11 [SvcCall] [ 3] Integer field: 140000623 <- charge item
293  * 02:13:11 [SvcCall] [ 4] Integer field: 60014749 <- charge location
294  * 02:13:11 [SvcCall] Call Named Arguments:
295  * 02:13:11 [SvcCall] Argument 'qty':
296  * 02:13:11 [SvcCall] (None)
297  */
298  _log(MODULE__TRACE, "DogmaIMBound::Handle_LoadAmmoToModules()");
299  call.Dump(MODULE__TRACE);
300  Call_Dogma_LoadAmmoToModules args;
301  if (!args.Decode(&call.tuple)) {
302  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
303  return nullptr;
304  }
305 
306  if (args.moduleIDs.empty())
307  return nullptr;
308  if (args.moduleIDs.size() > 1) {
309  sLog.Error("DogmaIMBound::Handle_LoadAmmoToModules()", "args.moduleIDs.size = %u.", args.moduleIDs.size() );
310  call.Dump(MODULE__WARNING);
311  }
312 
313  // Get Reference to Ship and Charge
314  ShipItemRef sRef = call.client->GetShip();
315  GenericModule* pMod = sRef->GetModule(sItemFactory.GetItem(args.moduleIDs[0])->flag());
316  if (pMod == nullptr)
317  throw UserError ("ModuleNoLongerPresentForCharges");
318 
319  InventoryItemRef cRef = sItemFactory.GetItem(args.itemID);
320  sRef->LoadCharge(cRef, pMod->flag());
321 
322  // returns nodeID and timestamp
323  PyTuple* tuple = new PyTuple(2);
324  tuple->SetItem(0, new PyString(GetBindStr())); // node info here
325  tuple->SetItem(1, new PyLong(GetFileTimeNow()));
326  return tuple;
327 }
328 
329 PyResult DogmaIMBound::Handle_LoadAmmoToBank(PyCallArgs& call) {
330  /* NOTE: this to load ALL modules in weapon bank, if possible.
331  * self.remoteDogmaLM.LoadAmmoToBank(shipID, masterID, chargeTypeID, itemIDs, chargeLocationID, qty)
332  * ship, module, charge type, charge item, charge location, stack qty (usually none - havent found otherwise)
333  * ******* UPDATED VAR NAMES TO MATCH CLIENT CODE -allan 26Jul14 *************
334  */
335  _log(MODULE__TRACE, "DogmaIMBound::Handle_LoadAmmoToBank()");
336  call.Dump(MODULE__TRACE);
337  Call_Dogma_LoadAmmoToBank args;
338  if (!args.Decode(&call.tuple)) {
339  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
340  return nullptr;
341  }
342  /*
343  args.shipID
344  args.masterID
345  args.chargeTypeID
346  args.itemIDs
347  args.chargeLocationID
348  args.qty
349  */
350  if (args.itemIDs.empty())
351  return nullptr;
352 
353  // Get Reference to Ship, Module, and Charge
354  ShipItemRef sRef = call.client->GetShip();
355  if (sRef->itemID() != args.shipID)
356  sLog.Error("DogmaIMBound::Handle_LoadAmmoToBank()", "passed shipID %u != current shipID %u.", args.shipID, sRef->itemID() );
357 
358  // if shipID passed in call isnt active ship (from client->GetShip()), would this work right?
359  GenericModule* pMod = sRef->GetModule(sItemFactory.GetItem(args.masterID)->flag());
360  if (pMod == nullptr)
361  throw UserError ("ModuleNoLongerPresentForCharges");
362 
363  // figure out how to use args.qty for loading less-than-full charges
364  // LoadCharge() can be easily updated to do this.
365  if (pMod->IsLinked()) {
366  sRef->LoadLinkedWeapons(pMod, args.itemIDs);
367  } else {
368  sRef->LoadCharge(sItemFactory.GetItem(args.itemIDs.at(0)), pMod->flag());
369  }
370 
371  // not sure why im not using this, as call is to load bank...
372  //sRef->LoadChargesToBank(pMod->flag(), args.itemIDs);
373 
374  // returns nodeID and timestamp
375  PyTuple* tuple = new PyTuple(2);
376  tuple->SetItem(0, new PyString(GetBindStr())); // node info here
377  tuple->SetItem(1, new PyLong(GetFileTimeNow()));
378  return tuple;
379 }
380 
381 PyResult DogmaIMBound::Handle_AddTarget(PyCallArgs& call) {
382  // flag, targetList = self.GetDogmaLM().AddTargetOBO(sid, tid)
383  // flag, targetList = self.GetDogmaLM().AddTarget(tid)
384  // as a note, targetList isnt used once call returns to client
385  // throws here void returns. client will raise throw (and ignore return)
386  Call_SingleIntegerArg args;
387  if (!args.Decode(&call.tuple)) {
388  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
389  return PyStatic.NewNone();
390  }
391  // calling client tests
392  Client* pClient(call.client);
393  if (pClient->IsJump())
394  throw UserError ("CantTargetWhileJumping");
395 
396  if (pClient->GetShipID() == args.arg)
397  throw UserError ("DeniedTargetSelf");
398 
400  if (pClient->IsUncloak())
401  throw UserError ("DeinedTargetAfterCloak");
402 
403  if (pClient->IsDocked()) {
404  pClient->SendNotifyMsg("You can't do this while docked");
405  Rsp_Dogma_AddTarget rsp;
406  rsp.flag = false;
407  rsp.targetList.push_back(args.arg);
408  return rsp.Encode();
409  }
410  // caller ship tests
411  ShipSE* mySE = pClient->GetShipSE();
412  if ( mySE->TargetMgr() == nullptr)
413  throw UserError ("DeniedTargetingAttemptFailed")
414  .AddFormatValue ("target", new PyInt (args.arg));
416  if (mySE->IsFrozen())
417  throw UserError ("DeniedTargetSelfFrozen")
418  .AddFormatValue ("targetName", new PyString (mySE->GetName ()));
420  if (mySE->IsInvul())
421  throw UserError ("DeniedInvulnerable");
422 
423  if (mySE->SysBubble() == nullptr) {
424  _log(DESTINY__ERROR, "Client %s does not have a bubble.", pClient->GetName());
425  throw UserError ("DeniedTargettingAttemptFailed")
426  .AddFormatValue ("target", new PyInt (args.arg));
427  }
428  if (mySE->SysBubble()->HasTower()) {
429  TowerSE* ptSE = mySE->SysBubble()->GetTowerSE();
430  if (ptSE->HasForceField() && mySE->GetPosition().distance(ptSE->GetPosition()) < ptSE->GetSOI())
431  throw UserError ("DeniedTargetingInsideField")
432  .AddFormatValue ("target", new PyInt (args.arg));
433  }
434 
435  // caller destiny tests
436  DestinyManager* pMyDestiny = mySE->DestinyMgr();
437  if (pMyDestiny == nullptr) {
438  _log(PLAYER__ERROR, "%s: Client has no destiny manager!", pClient->GetName());
439  throw UserError ("DeniedTargetingAttemptFailed")
440  .AddFormatValue ("target", new PyInt (args.arg));
441  }
442  if (pMyDestiny->IsCloaked())
443  throw UserError ("CantTargetWhileCloaked");
444  // throw UserError ("DeniedTargetingCloaked");
445 
446  // verify caller sysMgr
447  SystemManager* pSysMgr = pClient->SystemMgr();
448  if (pSysMgr == nullptr) {
449  _log(PLAYER__WARNING, "Unable to find system manager for '%s'", pClient->GetName());
450  throw UserError ("DeniedTargetingAttemptFailed")
451  .AddFormatValue ("target", new PyInt (args.arg));
452  }
453 
454  // target tests
455  SystemEntity* tSE = pSysMgr->GetSE(args.arg);
456  if (tSE == nullptr) {
457  _log(INV__WARNING, "Unable to find entity %u in system %u from '%s'", args.arg, pSysMgr->GetID(), pClient->GetName());
458  throw UserError ("DeniedTargetingAttemptFailed")
459  .AddFormatValue ("target", new PyInt (args.arg));
460  }
461  if ((tSE->IsStaticEntity())
462  or (tSE->IsLogin())
463  or (tSE->GetSelf()->HasAttribute(AttrUntargetable)))
464  throw UserError ("DeniedTargetEvadesSensors")
465  .AddFormatValue ("targetName", new PyString (tSE->GetName ()));
467  if (tSE->IsInvul())
468  throw CustomError ("Cannot Engage %s as they are invulnerable.", tSE->GetName());
469  //throw UserError ("DeniedTargetInvulnerable");
471  if (tSE->IsFrozen())
472  throw UserError ("DeniedTargetOtherFrozen")
473  .AddFormatValue ("targetName", new PyString (tSE->GetName ()));
474 
475  if (tSE->HasPilot()) {
477  if ( tSE->GetPilot()->IsInvul())
478  throw CustomError ("Cannot Engage %s as they are invulnerable.", tSE->GetName());
479  //throw UserError ("DeniedTargetInvulnerable");
480  if ( tSE->GetPilot()->IsSessionChange())
481  throw UserError ("DeniedTargetEvadesSensors")
482  .AddFormatValue ("targetName", new PyString (tSE->GetName ()));
483  }
484 
485  // this is to allow use of target name, after tSE is init'd
486  if (pMyDestiny->IsWarping()) {
487  _log(TARGET__WARNING, "Handle_AddTarget - TargMgr.StartTargeting() failed - warping.");
488  throw UserError ("DeniedTargetSelfWarping")
489  .AddFormatValue ("targetName", new PyString (tSE->GetName ()));
490  }
491  if (tSE->DestinyMgr() != nullptr) {
492  if (tSE->DestinyMgr()->IsCloaked())
493  throw UserError ("DeniedTargetingTargetCloaked");
494  if (tSE->DestinyMgr()->IsWarping()) {
495  _log(TARGET__WARNING, "Handle_AddTarget - TargMgr.StartTargeting() failed - target warping.");
496  throw UserError ("DeniedTargetOtherWarping")
497  .AddFormatValue ("targetName", new PyString (tSE->GetName ()));
498  }
499  }
500 
501  // target bubble tests
502  if (tSE->SysBubble() == nullptr) {
503  _log(DESTINY__ERROR, "Target %s does not have a bubble.", tSE->GetName());
504  throw UserError ("DeniedTargetingAttemptFailed")
505  .AddFormatValue ("target", new PyInt (args.arg));
506  }
507  if (tSE->IsPOSSE())
508  if (tSE->GetPOSSE()->IsReinforced())
509  throw UserError ("DeniedTargetReinforcedStructure")
510  .AddFormatValue ("target", new PyInt (args.arg));
511  if (tSE->SysBubble()->HasTower()) {
512  TowerSE* ptSE = tSE->SysBubble()->GetTowerSE();
513  if (ptSE->HasForceField() && tSE->GetPosition().distance(ptSE->GetPosition()) < ptSE->GetSOI())
514  throw UserError ("DeniedTargetForceField")
515  .AddFormatValue ("target", new PyInt (args.arg))
516  .AddFormatValue ("range", new PyInt (ptSE->GetSOI ()))
517  .AddFormatValue ("item", new PyInt (ptSE->GetID ()));
518  }
519 
520  if (sConfig.debug.IsTestServer)
521  if (is_log_enabled(TARGET__MESSAGE)) {
522  GVector vectorToTarget( mySE->GetPosition(), tSE->GetPosition());
523  _log(TARGET__MESSAGE, "DogmaIM::AddTarget() - %s(%u) targeting %s(%u) at distance of %.2f meters.", \
524  mySE->GetName(), mySE->GetID(), tSE->GetName(), args.arg, vectorToTarget.length() );
525  }
526 
527  if (!mySE->TargetMgr()->StartTargeting( tSE, pClient->GetShip())) {
528  _log(TARGET__WARNING, "AddTarget() - TargMgr.StartTargeting() failed.");
529  throw UserError ("DeniedTargetingAttemptFailed")
530  .AddFormatValue ("target", new PyInt (args.arg));
531  }
532 
533  Rsp_Dogma_AddTarget rsp;
534  rsp.flag = true; // false = immediate target lock in client, true = wait for OnTarget::add from server for lock
535  rsp.targetList.push_back(args.arg); // not used in client
536  return rsp.Encode();
537 }
538 
539 PyResult DogmaIMBound::Handle_RemoveTarget(PyCallArgs& call) {
540  Client* pClient(call.client);
541 
542  Call_SingleIntegerArg args;
543  if (!args.Decode(&call.tuple)) {
544  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
545  return nullptr;
546  }
547 
548  SystemManager* pSysMgr = pClient->SystemMgr();
549  if (pSysMgr == nullptr) {
550  _log(SERVICE__ERROR, "Unable to find system manager for '%s'", pClient->GetName());
551  return nullptr;
552  }
553  SystemEntity* pTSE = pSysMgr->GetSE(args.arg);
554  if (pTSE == nullptr) {
555  _log(SERVICE__ERROR, "Unable to find entity %u in system %u for '%s'", args.arg, pSysMgr->GetID(), pClient->GetName());
556  return nullptr;
557  }
558 
559  if (sConfig.debug.IsTestServer)
560  if (is_log_enabled(TARGET__MESSAGE)) {
561  GVector vectorToTarget(pClient->GetShipSE()->GetPosition(), pTSE->GetPosition());
562  _log(TARGET__MESSAGE, "Handle_RemoveTarget() - Removed %s(%u) - Range to Target: %.2f meters.", \
563  pTSE->GetName(),pTSE->GetID(), vectorToTarget.length() );
564  }
565 
566  // tell our ship this target has been removed
567  pClient->GetShipSE()->RemoveTarget(pTSE);
568  return nullptr;
569 }
570 
571 
572 PyResult DogmaIMBound::Handle_GetAllInfo(PyCallArgs& call)
573 {
574  // added more return data and updated logic (almost complete and mostly accurate) -allan 26Mar16
575  // completed. -allan 7Jan19
576  // Start the Code
577  Client* pClient(call.client);
578 
579  Call_TwoBoolArgs args; // arg1: getCharInfo, arg2: getShipInfo
580  if (!args.Decode(&call.tuple)) {
581  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
582  return PyStatic.NewNone();
583  }
584 
585  // Create the response dictionary
586  PyDict* rsp = new PyDict();
587  rsp->SetItemString("activeShipID", new PyInt(pClient->GetShipID()));
588  // Set "locationInfo" in the Dictionary
596  if (args.arg2) {
597  rsp->SetItemString("locationInfo", new PyDict());
598  } else {
599  rsp->SetItemString("locationInfo", PyStatic.NewNone());
600  }
601 
602  // Set "shipModifiedCharAttribs" in the Dictionary
604  rsp->SetItemString("shipModifiedCharAttribs", PyStatic.NewNone());
605 
606  // Set "charInfo" in the Dictionary -fixed 24Mar16
607  sItemFactory.SetUsingClient(pClient);
608  if (args.arg1) {
609  PyDict* charResult = pClient->GetChar()->GetCharInfo();
610  if (charResult == nullptr) {
611  _log(SERVICE__ERROR, "Unable to build char info for char %u", pClient->GetCharacterID());
612  sItemFactory.UnsetUsingClient();
613  return PyStatic.NewNone();
614  }
615  rsp->SetItemString("charInfo", charResult);
616  } else {
617  rsp->SetItemString("charInfo", new PyDict());
618  }
619 
620  // Set "shipInfo" in the Dictionary -fixed 26Mar16
621  if (args.arg2) {
622  PyDict* shipResult = pClient->GetShip()->GetShipInfo();
623  if (shipResult == nullptr) {
624  _log(SERVICE__ERROR, "Unable to build ship info for ship %u", pClient->GetShipID());
625  sItemFactory.UnsetUsingClient();
626  return PyStatic.NewNone();
627  }
628  rsp->SetItemString("shipInfo", shipResult);
629  } else {
630  rsp->SetItemString("shipInfo", new PyDict());
631  }
632 
633  // Set "shipState" in the Dictionary -fixed 26Mar16 -UD to add linked weapons 7Jan19
634  if (pClient->GetShip().get() == nullptr) {
635  _log(SERVICE__ERROR, "Unable to build shipState for %u", pClient->GetShipID());
636  return PyStatic.NewNone();
637  }
638  PyTuple* rspShipState = new PyTuple(3);
639  rspShipState->items[0] = pClient->GetShip()->GetShipState(); // fitted module list
640  rspShipState->items[1] = pClient->GetShip()->GetChargeState(); // loaded charges (subLocation)
641  rspShipState->items[2] = pClient->GetShip()->GetLinkedWeapons(); // linked weapons
642  rsp->SetItemString("shipState", rspShipState);
643 
644  if (is_log_enabled(SHIP__STATE))
645  rsp->Dump(SHIP__STATE, " ");
646 
647  sItemFactory.UnsetUsingClient();
648  return new PyObject("util.KeyVal", rsp );
649 }
650 
651 PyResult DogmaIMBound::Handle_LinkWeapons(PyCallArgs& call) {
652  /* data = self.remoteDogmaLM.LinkWeapons(shipID, masterID, fromID)
653  *
654  * def SetWeaponBanks(self, shipID, data):
655  * self.slaveModulesByMasterModule[shipID] = defaultdict(set)
656  * if data is None:
657  * return
658  * for masterID, slaveIDs in data.iteritems():
659  * for slaveID in slaveIDs:
660  * self.slaveModulesByMasterModule[shipID][masterID].add(slaveID)
661  */
662 
663  Call_Dogma_LinkWeapons args;
664  if (!args.Decode(&call.tuple)) {
665  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
666  return nullptr;
667  }
668  /* args.shipID
669  * args.masterID
670  * args.slaveID
671  */
672  if (!IsPlayerItem(args.shipID))
673  return nullptr;
674 
675  SystemManager* pSysMgr(call.client->SystemMgr());
676  ShipItemRef sRef(nullptr);
677  if (call.client->IsDocked()) {
678  sRef = pSysMgr->GetStationFromInventory(call.client->GetStationID())->GetShipFromInventory(args.shipID);
679  } else {
680  sRef = pSysMgr->GetShipFromInventory(args.shipID);
681  }
682  if (sRef.get() == nullptr) {
683  _log(INV__ERROR, "ShipRef not found in containers inventory for %s", call.client->GetName());
684  call.client->SendErrorMsg("Your ship was not found. Ref: ServerError xxxxx");
685  return nullptr;
686  }
687  sRef->LinkWeapon(args.masterID, args.slaveID);
688  return sRef->GetLinkedWeapons();
689 }
690 
691 PyResult DogmaIMBound::Handle_LinkAllWeapons(PyCallArgs& call) {
692  Call_SingleIntegerArg arg;
693  if (!arg.Decode(&call.tuple)) {
694  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
695  return nullptr;
696  }
697 
698  if (!IsPlayerItem(arg.arg))
699  return nullptr;
700 
701  SystemManager* pSysMgr(call.client->SystemMgr());
702  ShipItemRef sRef(nullptr);
703  if (call.client->IsDocked()) {
704  sRef = pSysMgr->GetStationFromInventory(call.client->GetStationID())->GetShipFromInventory(arg.arg);
705  } else {
706  sRef = pSysMgr->GetShipFromInventory(arg.arg);
707  }
708  if (sRef.get() == nullptr) {
709  _log(INV__ERROR, "ShipRef not found in containers inventory for %s", call.client->GetName());
710  call.client->SendErrorMsg("Your ship was not found. Ref: ServerError xxxxx");
711  return nullptr;
712  }
713  // locate and link all weapons on ship, if possible.
714  sRef->LinkAllWeapons();
715  return sRef->GetLinkedWeapons();
716 }
717 
718 PyResult DogmaIMBound::Handle_DestroyWeaponBank(PyCallArgs& call) {
719  //self.remoteDogmaLM.DestroyWeaponBank(shipID, itemID)
720  Call_TwoIntegerArgs args;
721  if (!args.Decode(&call.tuple)) {
722  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
723  return nullptr;
724  }
725 
726  if (!IsPlayerItem(args.arg1) or !IsPlayerItem(args.arg2))
727  return nullptr;
728 
729  SystemManager* pSysMgr(call.client->SystemMgr());
730  ShipItemRef sRef(nullptr);
731  if (call.client->IsDocked()) {
732  sRef = pSysMgr->GetStationFromInventory(call.client->GetStationID())->GetShipFromInventory(args.arg1);
733  } else {
734  sRef = pSysMgr->GetShipFromInventory(args.arg1);
735  }
736  if (sRef.get() == nullptr) {
737  _log(INV__ERROR, "ShipRef not found in containers inventory for %s", call.client->GetName());
738  call.client->SendErrorMsg("Your ship was not found. Ref: ServerError xxxxx");
739  return nullptr;
740  }
741  sRef->UnlinkGroup(args.arg2);
742  return nullptr;
743 }
744 
745 PyResult DogmaIMBound::Handle_UnlinkAllModules(PyCallArgs& call) {
746  //info = self.remoteDogmaLM.UnlinkAllModules(shipID)
747  Call_SingleIntegerArg arg;
748  if (!arg.Decode(&call.tuple)) {
749  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
750  return nullptr;
751  }
752 
753  if (!IsPlayerItem(arg.arg))
754  return nullptr;
755 
756  SystemManager* pSysMgr(call.client->SystemMgr());
757  ShipItemRef sRef(nullptr);
758  if (call.client->IsDocked()) {
759  sRef = pSysMgr->GetStationFromInventory(call.client->GetStationID())->GetShipFromInventory(arg.arg);
760  } else {
761  sRef = pSysMgr->GetShipFromInventory(arg.arg);
762  }
763  if (sRef.get() == nullptr) {
764  _log(INV__ERROR, "ShipRef not found in containers inventory for %s", call.client->GetName());
765  call.client->SendErrorMsg("Your ship was not found. Ref: ServerError xxxxx");
766  return nullptr;
767  }
768  sRef->UnlinkAllWeapons();
769  return sRef->GetLinkedWeapons();
770 }
771 
772 PyResult DogmaIMBound::Handle_UnlinkModule(PyCallArgs& call) {
773  // slaveID = self.remoteDogmaLM.UnlinkModule(shipID, moduleID)
774  sLog.Warning("DogmaIMBound::Handle_UnlinkModule()", "size=%u", call.tuple->size());
775  call.Dump(SHIP__MESSAGE);
776 
777  Call_TwoIntegerArgs args;
778  if (!args.Decode(&call.tuple)) {
779  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
780  return PyStatic.NewZero();
781  }
782 
783  if (!IsPlayerItem(args.arg1) or !IsPlayerItem(args.arg2))
784  return PyStatic.NewZero();
785 
786  SystemManager* pSysMgr(call.client->SystemMgr());
787  ShipItemRef sRef(nullptr);
788  if (call.client->IsDocked()) {
789  sRef = pSysMgr->GetStationFromInventory(call.client->GetStationID())->GetShipFromInventory(args.arg1);
790  } else {
791  sRef = pSysMgr->GetShipFromInventory(args.arg1);
792  }
793  if (sRef.get() == nullptr) {
794  _log(INV__ERROR, "ShipRef not found in containers inventory for %s", call.client->GetName());
795  call.client->SendErrorMsg("Your ship was not found. Ref: ServerError xxxxx");
796  return PyStatic.NewZero();
797  }
798 
799  return new PyInt(sRef->UnlinkWeapon(args.arg2));
800 }
801 
802 PyResult DogmaIMBound::Handle_MergeModuleGroups(PyCallArgs& call) {
803  //info = self.remoteDogmaLM.MergeModuleGroups(shipID, masterID, slaveID)
804  sLog.Warning("DogmaIMBound::Handle_MergeModuleGroups()", "size=%u", call.tuple->size());
805  call.Dump(SHIP__MESSAGE);
806 
807  Call_Dogma_LinkWeapons args;
808  if (!args.Decode(&call.tuple)) {
809  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
810  return nullptr;
811  }
812  /* args.shipID
813  * args.masterID
814  * args.slaveID
815  */
816  if (!IsPlayerItem(args.shipID))
817  return nullptr;
818  SystemManager* pSysMgr(call.client->SystemMgr());
819  ShipItemRef sRef(nullptr);
820  if (call.client->IsDocked()) {
821  sRef = pSysMgr->GetStationFromInventory(call.client->GetStationID())->GetShipFromInventory(args.shipID);
822  } else {
823  sRef = pSysMgr->GetShipFromInventory(args.shipID);
824  }
825  if (sRef.get() == nullptr) {
826  _log(INV__ERROR, "ShipRef not found in containers inventory for %s", call.client->GetName());
827  call.client->SendErrorMsg("Your ship was not found. Ref: ServerError xxxxx");
828  return nullptr;
829  }
830 
831  // merge slaveID group into masterID group
832  sRef->MergeModuleGroups(args.masterID, args.slaveID);
833 
834  return sRef->GetLinkedWeapons();
835 }
836 
837 PyResult DogmaIMBound::Handle_PeelAndLink(PyCallArgs& call) {
838  //info = self.remoteDogmaLM.PeelAndLink(shipID, masterID, slaveID)
839  sLog.Warning("DogmaIMBound::Handle_PeelAndLink()", "size=%u", call.tuple->size());
840  call.Dump(SHIP__MESSAGE);
841 
842  Call_Dogma_LinkWeapons args;
843  if (!args.Decode(&call.tuple)) {
844  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
845  return nullptr;
846  }
847  /* args.shipID
848  * args.masterID
849  * args.slaveID
850  */
851  if (!IsPlayerItem(args.shipID))
852  return nullptr;
853  SystemManager* pSysMgr(call.client->SystemMgr());
854  ShipItemRef sRef(nullptr);
855  if (call.client->IsDocked()) {
856  sRef = pSysMgr->GetStationFromInventory(call.client->GetStationID())->GetShipFromInventory(args.shipID);
857  } else {
858  sRef = pSysMgr->GetShipFromInventory(args.shipID);
859  }
860  if (sRef.get() == nullptr) {
861  _log(INV__ERROR, "ShipRef not found in containers inventory for %s", call.client->GetName());
862  call.client->SendErrorMsg("Your ship was not found. Ref: ServerError xxxxx");
863  return nullptr;
864  }
865 
866  // remove slaveID from existing group and add to masterID group
867  sRef->PeelAndLink(args.masterID, args.slaveID);
868  return sRef->GetLinkedWeapons();
869 }
870 
871 PyResult DogmaIMBound::Handle_Activate(PyCallArgs& call)
872 {
873  // ret = self.GetDogmaLM().Activate(itemID, effectName, target, repeat) - i cant find where this return is used but is "1" in packet logs
874  // dogmaLM.Activate(itemID, const.effectOnlineForStructures)
875  // dogmaLM.Activate(itemID, const.effectAnchorDrop)
876  // dogmaLM.Activate(itemID, const.effectAnchorLift)
877  // dogmaLM.Activate(itemID, const.effectAnchorLiftForStructures)
878  Client* pClient(call.client);
879 
880  if (!pClient->IsInSpace()) {
881  pClient->SendNotifyMsg("You can't do this while docked.");
882  return PyStatic.NewZero();
883  }
884  /*
885  * {'FullPath': u'UI/Messages', 'messageID': 260384, 'label': u'AnchorLocationUnsuitableBody'}(u'You cannot safely anchor {[item]typeID.nameWithArticle} within {[numeric]distance.distance} of large objects in space.', None, {u'{[numeric]distance.distance}': {'conditionalValues': [], 'variableType': 9, 'propertyName': 'distance', 'args': 256, 'kwargs': {}, 'variableName': 'distance'}, u'{[item]typeID.nameWithArticle}': {'conditionalValues': [], 'variableType': 2, 'propertyName': 'nameWithArticle', 'args': 0, 'kwargs': {}, 'variableName': 'typeID'}})
886  * {'FullPath': u'UI/Messages', 'messageID': 260389, 'label': u'AnchorProximityUnsuitableBody'}(u'You cannot anchor an item of group {anchorGroupName} within {[numeric]distance.distance} of items of group {ballGroupName} in space.', None, {u'{ballGroupName}': {'conditionalValues': [], 'variableType': 10, 'propertyName': None, 'args': 0, 'kwargs': {}, 'variableName': 'ballGroupName'}, u'{anchorGroupName}': {'conditionalValues': [], 'variableType': 10, 'propertyName': None, 'args': 0, 'kwargs': {}, 'variableName': 'anchorGroupName'}, u'{[numeric]distance.distance}': {'conditionalValues': [], 'variableType': 9, 'propertyName': 'distance', 'args': 256, 'kwargs': {}, 'variableName': 'distance'}})
887  * {'FullPath': u'UI/Messages', 'messageID': 260403, 'label': u'AnchoringObjectBody'}(u'Anchoring the selected object, it will take around {[numeric]delay, decimalPlaces=1} {[numeric]delay -> "second", "seconds"} to do so.', None, {u'{[numeric]delay -> "second", "seconds"}': {'conditionalValues': [u'second', u'seconds'], 'variableType': 9, 'propertyName': None, 'args': 320, 'kwargs': {}, 'variableName': 'delay'}, u'{[numeric]delay, decimalPlaces=1}': {'conditionalValues': [], 'variableType': 9, 'propertyName': None, 'args': 512, 'kwargs': {'decimalPlaces': 1}, 'variableName': 'delay'}})
888  *
889  */
890  if (call.tuple->size() == 2) {
891  call.Dump(POS__DUMP);
892  // anchor cargo and pos items
893  // online pos items
894  Call_TwoIntegerArgs args;
895  if (!args.Decode(&call.tuple)) {
896  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
897  return PyStatic.NewZero();
898  }
899  /* this is deactivate call....
900  22:06:59 W DogmaIMBound::Handle_Activate(): size=2
901  22:06:59 [POS:Dump] Call Arguments:
902  22:06:59 [POS:Dump] Tuple: 2 elements
903  22:06:59 [POS:Dump] [ 0] Integer: 140000061
904  22:06:59 [POS:Dump] [ 1] Integer: 1023 << deactivate
905 
906  anchorDrop = 649, // effects.AnchorDrop
907  anchorLift = 650, // effects.AnchorLift
908  onlineForStructures = 901, // effects.StructureOnline
909  anchorDropForStructures = 1022, // effects.AnchorDrop
910  anchorLiftForStructures = 1023, // effects.AnchorLift
911  anchorDropOrbital = 4769, // effects.AnchorDrop
912  anchorLiftOrbital = 4770, // effects.AnchorLift
913  */
914 
915  SystemEntity* pSE = pClient->SystemMgr()->GetSE(args.arg1);
916  if (pSE == nullptr) {
917  sLog.Error("DogmaIMBound::Handle_Activate()", "%u is not a valid EntityID in this system.", args.arg1);
918  return PyStatic.NewZero();
919  }
920  // determine if this pSE is pos or cont.
921  //call (de)activate on pSE, pass effectID, send effect to clients (bubblecast) then set timers.
922  if (pSE->IsPOSSE()) {
923  /* these two may be called in posMgr...
924  if ((args.arg2 == anchorDropForStructures)
925  or (args.arg2 == anchorDropOrbital)) {
926  pSE->GetPOSSE()->SetAnchor(args.arg2);
927  } else */ if (args.arg2 == anchorLiftForStructures) {
928  pSE->GetPOSSE()->PullAnchor();
929  } else if (args.arg2 == onlineForStructures) {
930  pSE->GetPOSSE()->Activate(args.arg2);
931  }
932  } else if (pSE->IsContainerSE()) {
933  // not sure what calls are for containers yet
934  pSE->GetContSE()->Activate(args.arg2);
935  } else {
936  ; // make error here
937  }
938  } else if (call.tuple->size() == 4) {
939  // activate ship module
940  Call_Dogma_Activate args;
941  if (!args.Decode(&call.tuple)) {
942  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
943  return PyStatic.NewZero();
944  }
945 
946  pClient->GetShip()->Activate(args.itemID, args.effectName, args.target, args.repeat);
947  }
948  // are there any other cases to test for here?
949 
950  // returns 1 on success (throw error otherwise)
951  return PyStatic.NewOne();
952 }
953 
954 
955 PyResult DogmaIMBound::Handle_Deactivate(PyCallArgs& call)
956 {
957  // return self.statemanager.Deactivate(self.itemID, self.effectName)
958  // dogmaLM.Deactivate(itemID, const.effectOnlineForStructures)
959  sLog.Warning("DogmaIMBound::Handle_Deactivate()", "size=%u", call.tuple->size());
960  call.Dump(SHIP__MESSAGE);
961 
962  Client* pClient(call.client);
963 
964  if (!pClient->IsInSpace()) {
965  pClient->SendNotifyMsg("You can't do this while docked");
966  return PyStatic.NewNone();
967  }
968 
969  if (call.tuple->items.at(1)->IsInt()) {
970  // if effect is integer, call is for pos or container
971  call.Dump(POS__DUMP);
972  Call_TwoIntegerArgs args;
973  if (!args.Decode(&call.tuple)) {
974  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
975  return PyStatic.NewNone();
976  }
977  SystemEntity* pSE = pClient->SystemMgr()->GetSE(args.arg1);
978  if (pSE == nullptr) {
979  sLog.Error("DogmaIMBound::Handle_Deactivate()", "%u is not a valid EntityID in this system.", args.arg1);
980  return PyStatic.NewNone();
981  }
982  /*
983  * 22:24:28 W DogmaIMBound::Handle_Deactivate(): size=2
984  * 22:24:28 [POS:Dump] Call Arguments:
985  * 22:24:28 [POS:Dump] Tuple: 2 elements
986  * 22:24:28 [POS:Dump] [ 0] Integer: 140000061
987  * 22:24:28 [POS:Dump] [ 1] Integer: 901
988  */
989  // determine if this pSE is pos or cont.
990  //call activate on pSE, pass effectID, send effect to clients (bubblecast) then set timers.
991  if (pSE->IsPOSSE()) {
992  pSE->GetPOSSE()->Deactivate(args.arg2);
993  } else if (pSE->IsContainerSE()) {
994  pSE->GetContSE()->Deactivate(args.arg2);
995  } else {
996  ; // make error here
997  }
998  } else if (call.tuple->items.at(1)->IsWString()) {
999  //if effect is wide string, then call is for module, including calls to online/offline (rclick module in HUD)
1000  Call_Dogma_Deactivate args;
1001  if (!args.Decode(&call.tuple)) {
1002  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
1003  return PyStatic.NewNone();
1004  }
1005 
1006  pClient->GetShip()->Deactivate(args.itemID, args.effectName);
1007  }
1008  // are there any other cases to test for?
1009 
1010  // returns None()
1011  return PyStatic.NewNone();
1012 }
1013 
1014 PyResult DogmaIMBound::Handle_Overload(PyCallArgs& call) {
1015  /*
1016  * 23:52:45 L DogmaIMBound::Handle_Overload(): size=2
1017  * 23:52:45 [SvcCallDump] Call Arguments:
1018  * 23:52:45 [SvcCallDump] Tuple: 2 elements
1019  * 23:52:45 [SvcCallDump] [ 0] Integer field: 140002542
1020  * 23:52:45 [SvcCallDump] [ 1] Integer field: 3035
1021  */
1022  // self.GetDogmaLM().Overload(itemID, effectID)
1023 
1024  Client* pClient(call.client);
1025  Call_TwoIntegerArgs args; //itemID, effectID
1026  if (!args.Decode(&call.tuple)) {
1027  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
1028  return nullptr;
1029  }
1030 
1031  //TODO: need to verify pilot can OL modules
1032  // AttrRequiredThermoDynamicsSkill
1033  pClient->GetShip()->Overload(args.arg1);
1034  return nullptr;
1035 }
1036 
1037 // this one is called from Deactivate() when module is OL
1038 PyResult DogmaIMBound::Handle_StopOverload(PyCallArgs& call)
1039 {
1040  Client* pClient(call.client);
1041  Call_TwoIntegerArgs args;
1042  if (!args.Decode(&call.tuple)) {
1043  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
1044  return PyStatic.NewNone();
1045  }
1046 
1047  // cancel overload then deactivate module
1048  pClient->GetShip()->CancelOverloading(args.arg1);
1049  pClient->GetShip()->Deactivate(args.arg1, sFxDataMgr.GetEffectName(args.arg2));
1050  // returns none
1051  return PyStatic.NewNone();
1052 }
1053 
1054 PyResult DogmaIMBound::Handle_CancelOverloading(PyCallArgs& call) {
1055  // self.dogmaLM.CancelOverloading(itemID)
1056 
1057  Client* pClient(call.client);
1058  Call_SingleIntegerArg args; //itemID
1059  if (!args.Decode(&call.tuple)) {
1060  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
1061  return nullptr;
1062  }
1063 
1064  pClient->GetShip()->CancelOverloading(args.arg);
1065  return nullptr;
1066 }
1067 
1068 PyResult DogmaIMBound::Handle_OverloadRack(PyCallArgs& call) {
1069  /* moduleIDs = self.GetDogmaLM().OverloadRack(itemID)
1070  * moduleIDs is list of modules in rack.
1071  */
1072  Client* pClient(call.client);
1073  Call_SingleIntegerArg args;
1074  if (!args.Decode(&call.tuple)) {
1075  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
1076  return new PyList();
1077  }
1078 
1079  // not supported yet
1080  PyList* list = new PyList();
1081  return list;
1082 }
1083 
1084 PyResult DogmaIMBound::Handle_StopOverloadRack(PyCallArgs& call) {
1085  /* moduleIDs = self.GetDogmaLM().StopOverloadRack(itemID)
1086  * moduleIDs is list of modules in rack.
1087  */
1088  Client* pClient(call.client);
1089  Call_SingleIntegerArg args;
1090  if (!args.Decode(&call.tuple)) {
1091  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
1092  return new PyList();
1093  }
1094 
1095  // not supported yet
1096  PyList* list = new PyList();
1097  return list;
1098 }
1099 
1100 PyResult DogmaIMBound::Handle_InitiateModuleRepair(PyCallArgs& call) {
1101  // this is for repairing modules using nanite paste (button's ring turns white). return bool.
1102  // res = self.GetDogmaLM().InitiateModuleRepair(itemID)
1103  // see notes in ModuleManager::ModuleRepair()
1104 
1105  Call_SingleIntegerArg args;
1106  if (!args.Decode(&call.tuple)) {
1107  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
1108  return PyStatic.NewFalse();
1109  }
1110 
1111  return call.client->GetShip()->ModuleRepair(args.arg);
1112 }
1113 
1114 PyResult DogmaIMBound::Handle_StopModuleRepair(PyCallArgs& call) {
1115  // self.GetDogmaLM().StopModuleRepair(itemID)
1116 
1117  Call_SingleIntegerArg args;
1118  if (!args.Decode(&call.tuple)) {
1119  codelog(SERVICE__ERROR, "%s: Failed to decode arguments.", GetName());
1120  return nullptr;
1121  }
1122 
1123  call.client->GetShip()->StopModuleRepair(args.arg);
1124 
1125  // returns nothing
1126  return nullptr;
1127 }
1128 
1129 PyResult DogmaIMBound::Handle_ChangeDroneSettings(PyCallArgs& call) {
1130  /*
1131  * 21:59:29 L DogmaIMBound::Handle_ChangeDroneSettings(): size=1
1132  * 21:59:29 [SvcCall] Call Arguments:
1133  * 22:04:44 [SvcCall] Tuple: 1 elements
1134  * 22:04:44 [SvcCall] [ 0] Dictionary: 3 entries
1135  * 22:04:44 [SvcCall] [ 0] [ 0] Key: Integer field: 1283 <-- AttrFightersAttackAndFollow
1136  * 22:04:44 [SvcCall] [ 0] [ 0] Value: Integer field: 1
1137  * 22:04:44 [SvcCall] [ 0] [ 1] Key: Integer field: 1275 <-- AttrDroneIsAgressive
1138  * 22:04:44 [SvcCall] [ 0] [ 1] Value: Integer field: 1
1139  * 22:04:44 [SvcCall] [ 0] [ 2] Key: Integer field: 1297 <-- AttrDroneFocusFire
1140  * 22:04:44 [SvcCall] [ 0] [ 2] Value: Integer field: 1
1141  */
1142 
1143  if (!call.tuple->GetItem(0)->IsDict()) {
1144  codelog(DRONE__ERROR, "Tuple Item is wrong type: %s. Expected PyDict.", call.tuple->GetItem(0)->TypeString());
1145  return nullptr;
1146  }
1147 
1148  PyDict* dict = call.tuple->GetItem(0)->AsDict();
1149 
1150  std::map<int16, int8> attribs;
1151  for (PyDict::const_iterator itr = dict->begin(); itr != dict->end(); ++itr)
1152  attribs[PyRep::IntegerValueU32(itr->first)] = PyRep::IntegerValue(itr->second);
1153 
1154  call.client->GetShipSE()->UpdateDrones(attribs);
1155 
1156  // returns nothing
1157  return nullptr;
1158 }
virtual bool IsFrozen()
Definition: Ship.h:325
Base Python wire object.
Definition: PyRep.h:66
#define sConfig
A macro for easier access to the singleton.
Dispatcher *const m_dispatch
bool IsSessionChange()
Definition: Client.h:241
PyList * GetTargets() const
PyRep * ModuleRepair(uint32 modID)
Definition: Ship.h:155
void StopModuleRepair(uint32 modID)
Definition: Ship.h:156
SystemEntity * GetSE(uint32 entityID) const
virtual ShipSE * GetShipSE()
Definition: Ship.h:309
void SendErrorMsg(const char *fmt,...)
Definition: Client.cpp:2719
#define _log(type, fmt,...)
Definition: logsys.h:124
Dispatcher *const m_dispatch
PyRep * GetItem(size_t index) const
Returns Python object.
Definition: PyRep.h:602
Python string.
Definition: PyRep.h:430
Python's dictionary.
Definition: PyRep.h:719
bool HasAttribute(const uint16 attrID) const
size_t size() const
Definition: PyRep.h:591
PyRep * GetPyObject()
converts the EvilNumber into a python object.
Definition: EvilNumber.cpp:109
virtual PyRep * Clone() const =0
Clones object.
SystemBubble * SysBubble()
Definition: SystemEntity.h:195
PyCallable_Make_InnerDispatcher(DogmaIMService) DogmaIMService
virtual bool HasPilot()
Definition: SystemEntity.h:258
uint32 UnlinkWeapon(uint32 moduleID)
Definition: Ship.cpp:1522
virtual Client * GetPilot()
Definition: SystemEntity.h:259
bool IsInvul()
Definition: Client.h:234
PyRep * GetCacheHint(const PyRep *objectID)
void Deactivate(int32 effectID)
Definition: Container.cpp:299
uint32 GetID() const
Definition: SystemManager.h:80
static uint32 IntegerValueU32(PyRep *pRep)
Definition: PyRep.cpp:134
std::string m_strBoundObjectName
Definition: PyBoundObject.h:54
UserError & AddFormatValue(const char *name, PyRep *value)
Fluent version of the protected AddKeyword, allows for adding a keyword to the exception.
void LoadLinkedWeapons(GenericModule *pMod, std::vector< int32 > &chargeIDs)
Definition: Ship.cpp:684
virtual ~DogmaIMService()
void ClearTargets(bool notify=true)
TargetManager * TargetMgr()
Definition: SystemEntity.h:197
CharacterRef GetChar() const
Definition: Client.h:164
Python tuple.
Definition: PyRep.h:567
const char * GetName() const
Definition: PyService.h:54
uint16 GetSOI()
Definition: Tower.h:90
void UpdateDrones(std::map< int16, int8 > &attribs)
Definition: Ship.cpp:2843
Definition: Ship.h:301
Advanced version of UserError that allows to send a full custom message.
Definition: PyExceptions.h:453
void Dump(FILE *into, const char *pfx) const
Dumps object to file.
Definition: PyRep.cpp:84
const GPoint & GetPosition() const
Definition: SystemEntity.h:211
TowerSE * GetTowerSE()
Definition: SystemBubble.h:142
void _SetCallDispatcher(CallDispatcher *d)
Definition: PyCallable.h:87
* args
PyList * GetTargeters() const
#define is_log_enabled(type)
Definition: logsys.h:78
#define sLog
Evaluates to a NewLog instance.
Definition: LogNew.h:250
ShipItemRef GetShipFromInventory(uint32 shipID)
virtual PyBoundObject * CreateBoundObject(Client *pClient, const PyRep *bind_args)
DestinyManager * DestinyMgr()
Definition: SystemEntity.h:198
SystemManager * SystemMgr()
Definition: SystemEntity.h:196
void Deactivate(int32 effectID)
Definition: Structure.cpp:856
PyRep * GetLinkedWeapons()
Definition: Ship.cpp:1691
InventoryItemRef GetSelf()
Definition: SystemEntity.h:202
void LinkAllWeapons()
Definition: Ship.cpp:1416
#define IsPlayerItem(itemID)
Definition: EVE_Defines.h:256
Python object.
Definition: PyRep.h:826
void PullAnchor()
Definition: Structure.cpp:734
#define codelog(type, fmt,...)
Definition: logsys.h:128
void SetItem(size_t index, PyRep *object)
Stores Python object.
Definition: PyRep.h:610
bool IsDocked()
Definition: Client.h:229
SystemManager * SystemMgr() const
Definition: Client.h:92
virtual bool IsContainerSE()
Definition: SystemEntity.h:157
void PeelAndLink(uint32 masterID, uint32 slaveID)
Definition: Ship.cpp:1411
#define sFxDataMgr
std::string GetBindStr() const
void Activate(int32 effectID)
Definition: Structure.cpp:775
Python integer.
Definition: PyRep.h:231
PyDict * AsDict()
Definition: PyRep.h:142
uint32 GetID()
Definition: SystemEntity.h:207
PyServiceMgr *const m_manager
Definition: PyService.h:91
#define PyStatic
Definition: PyRep.h:1209
X * get() const
Definition: RefPtr.h:213
ShipItemRef GetShip() const
Definition: Client.h:167
const char * GetName() const
Definition: Client.h:94
const char * GetName() const
Definition: SystemEntity.h:210
PyCallable_Make_Dispatcher(DogmaIMBound) DogmaIMBound(PyServiceMgr *mgr
#define PyDecRef(op)
Definition: PyRep.h:57
Client *const client
Definition: PyCallable.h:49
Python object "ccp_exceptions.UserError".
Definition: PyExceptions.h:121
#define PyCallable_REG_CALL(c, m)
Definition: PyServiceCD.h:78
Definition: Client.h:66
StationItemRef GetStationFromInventory(uint32 stationID)
unsigned __int32 uint32
Definition: eve-compat.h:50
PyCallable_DECL_CALL(ChangeDroneSettings)
virtual StructureSE * GetPOSSE()
Definition: SystemEntity.h:116
virtual ~DogmaIMBound()
virtual bool IsPOSSE()
Definition: SystemEntity.h:163
virtual bool IsFrozen()
Definition: SystemEntity.h:185
void UnlinkAllWeapons()
Definition: Ship.cpp:1651
uint32 uint32 groupID
const_iterator begin() const
Definition: PyRep.h:766
Dispatcher *const m_dispatch
double GetFileTimeNow()
Definition: utils_time.cpp:84
EVEItemFlags flag()
void Activate(int32 effectID)
Definition: Container.cpp:282
bool IsDict() const
Definition: PyRep.h:110
GenericModule * GetModule(EVEItemFlags flag)
Definition: Ship.h:173
ShipSE * GetShipSE()
Definition: Client.h:168
storage_type::const_iterator const_iterator
Definition: PyRep.h:750
bool HasTower()
Definition: SystemBubble.h:141
virtual void Release()
virtual bool IsLogin()
Definition: SystemEntity.h:183
EvilNumber GetAttribute(const uint16 attrID) const
ObjCacheService * cache_service
Definition: PyServiceMgr.h:78
void Dump(LogType type) const
Definition: PyCallable.cpp:81
virtual bool IsInvul()
Definition: SystemEntity.h:184
const_iterator end() const
Definition: PyRep.h:767
Definition: Tower.h:19
PyObject * ItemGetInfo()
virtual ContainerSE * GetContSE()
Definition: SystemEntity.h:107
#define sItemFactory
Definition: ItemFactory.h:165
int32 GetStationID() const
Definition: Client.h:114
storage_type items
Definition: PyRep.h:628
PyDict * GetCharInfo()
Definition: Character.cpp:1183
Definition: gpoint.h:70
static int64 IntegerValue(PyRep *pRep)
Definition: PyRep.cpp:118
GaExpInl GaFloat distance(const GaVec3 &oth) const
Definition: GaTypes.h:158
virtual bool IsStaticEntity()
Definition: SystemEntity.h:146
void MergeModuleGroups(uint32 masterID, uint32 slaveID)
Definition: Ship.cpp:1406
bool HasForceField()
Definition: Tower.h:76
void SetItem(PyRep *key, PyRep *value)
SetItem adds or sets a database entry.
Definition: PyRep.cpp:713
bool IsReinforced()
Definition: Structure.h:194
void LoadCharge(InventoryItemRef cRef, EVEItemFlags flag)
Definition: Ship.cpp:601
const char * TypeString() const
Definition: PyRep.cpp:76
virtual bool IsInvul()
Definition: Ship.cpp:2529
Python list.
Definition: PyRep.h:639
bool StartTargeting(SystemEntity *tSE, ShipItemRef sRef)
uint32 itemID() const
Definition: InventoryItem.h:98
void SetItemString(const char *key, PyRep *value)
SetItemString adds or sets a database entry.
Definition: PyRep.h:812
void UnlinkGroup(uint32 memberID, bool update=false)
Definition: Ship.cpp:1602
const char * GetName() const
Definition: PyBoundObject.h:44
Python long integer.
Definition: PyRep.h:261
PyTuple * tuple
Definition: PyCallable.h:50
void LinkWeapon(uint32 masterID, uint32 slaveID)
Definition: Ship.cpp:1365