EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
PyService.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
24 */
25 
26 #include "eve-server.h"
27 
28 #include "Client.h"
29 #include "PyBoundObject.h"
30 #include "PyService.h"
31 
32 PyService::PyService(PyServiceMgr *mgr, const char *serviceName)
33 : m_manager(mgr),
34  m_name(serviceName)
35 {
36 }
37 
39 {
40 }
41 
42 //overload this to hack in our special bind routines at the service level
43 PyResult PyService::Call(const std::string &method, PyCallArgs &args) {
44  if (method == "MachoResolveObject"){
45  _log(SERVICE__CALLS, "%s::MachoResolveObject()", GetName());
46  return Handle_MachoResolveObject(args);
47  } else if (method == "MachoBindObject") {
48  _log(SERVICE__CALLS, "%s::MachoBindObject()", GetName());
49  return Handle_MachoBindObject(args);
50  } else {
51  _log(SERVICE__CALLS, "%s::%s()", GetName(), method.c_str());
52  args.Dump(SERVICE__CALL_TRACE);
53  return PyCallable::Call(method, args);
54  }
55 }
56 
57 
58 /*
59  * For now, we are going to keep it simple by trying to use only a single
60  * node ID, this may have to change some day.
61 */
62 
64  //returns nodeID
65  _log(SERVICE__MESSAGE, "%s Service: MachoResolveObject requested, returning %u", GetName(), m_manager->GetNodeID());
66  return new PyInt(m_manager->GetNodeID());
67 }
68 
69 
71 {
72  CallMachoBindObject args;
73  if (!args.Decode(&call.tuple)) {
74  codelog( SERVICE__ERROR, "%s Service: Failed to decode arguments", GetName() );
75  return nullptr;
76  }
77 
78  _log( SERVICE__MESSAGE, "%s Service: Processing MachoBindObject", GetName() );
79 
80  //first we need to get our implementation to actually create the object they are trying to bind to.
81  PyBoundObject* obj = CreateBoundObject(call.client, args.bindParams);
82  if (obj == nullptr) {
83  _log( SERVICE__ERROR, "%s Service: Unable to create bound object:", GetName());
84  args.bindParams->Dump(SERVICE__ERROR, " ");
85 
86  return nullptr;
87  }
88 
89  //now we register
90  PyTuple* rsp = new PyTuple(2);
91  PyDict* oid = new PyDict();
92  rsp->SetItem(0, m_manager->BindObject(call.client, obj, nullptr, oid));
93 
94  if (args.call->IsNone()) {
95  //no call was specified...
96  rsp->SetItem(1, PyStatic.NewNone());
97  } else {
98  CallMachoBindObject_call boundcall;
99  if (!boundcall.Decode(&args.call)) {
100  codelog(SERVICE__ERROR, "%s Service: Failed to decode boundcall arguments", GetName());
101  return nullptr;
102  }
103 
104  _log(SERVICE__MESSAGE, "%s Service: MachoBindObject also contains call to %s", GetName(), boundcall.method_name.c_str());
105 
106  PyCallArgs sub_args(call.client, boundcall.arguments, boundcall.dict_arguments);
107 
108  //do the call:
109  PyResult result = obj->Call(boundcall.method_name, sub_args);
110 
111  rsp->SetItem(1, result.ssResult);
112  }
113 
114  return PyResult(rsp, oid);
115 }
116 
117 const char *const PyService::s_checkTimeStrings[_checkCount] = {
118  "always",
119  "never",
120  "year",
121  "6 months",
122  "3 months",
123  "month",
124  "week",
125  "day",
126  "12 hours",
127  "6 hours",
128  "3 hours",
129  "2 hours",
130  "1 hour",
131  "30 minutes",
132  "15 minutes",
133  "5 minutes",
134  "1 minute",
135  "30 seconds",
136  "15 seconds",
137  "5 seconds",
138  "1 second"
139 };
140 
141 /* this is untested... */
142 PyObject *PyService::_BuildCachedReturn( PySubStream** in_result, const char* sessionInfo, CacheCheckTime check )
143 {
144  objectCaching_CachedMethodCallResult cached;
145 
146  PySubStream* result = *in_result;
147  *in_result = nullptr; //consume it.
148 
149  //we need to checksum the marshaled data...
150  result->EncodeData();
151  if (!result->data()) {
152  _log( SERVICE__ERROR, "%s: Failed to build cached return", GetName() );
153 
154  PyDecRef( result );
155  return nullptr;
156  }
157 
158  cached.call_return = result; //this entire result is going to get cloned in the Encode(), and then destroyed when we return... what a waste...
159  cached.sessionInfo = sessionInfo;
160  cached.clientWhen = s_checkTimeStrings[ check ];
161 
162  cached.timeStamp = Win32TimeNow();
163  //we can use whatever checksum we want here, as the client just remembers it and sends it back to us.
164  cached.version = crc_hqx( &result->data()->content()[0], result->data()->content().size(), 0 );
165 
166  return cached.Encode();
167 }
168 
170 {
171  _log( SERVICE__ERROR, "Called default CreateBoundObject()");
172  EvE::traceStack();
173  return nullptr;
174 }
Base Python wire object.
Definition: PyRep.h:66
#define _log(type, fmt,...)
Definition: logsys.h:124
PyService(PyServiceMgr *mgr, const char *serviceName)
Definition: PyService.cpp:32
Python's dictionary.
Definition: PyRep.h:719
const Buffer & content() const
Get the const PyBuffer content.
Definition: PyRep.h:407
virtual PyResult Call(const std::string &method, PyCallArgs &args)
PyBuffer * data() const
Definition: PyRep.h:1047
uint32 GetNodeID() const
Definition: PyServiceMgr.h:67
Python tuple.
Definition: PyRep.h:567
const char * GetName() const
Definition: PyService.h:54
CacheCheckTime
Definition: PyService.h:57
PyObject * _BuildCachedReturn(PySubStream **result, const char *sessionInfo, CacheCheckTime check)
Definition: PyService.cpp:142
* args
PyRep * ssResult
Definition: PyCallable.h:65
Python object.
Definition: PyRep.h:826
#define codelog(type, fmt,...)
Definition: logsys.h:128
void SetItem(size_t index, PyRep *object)
Stores Python object.
Definition: PyRep.h:610
virtual PyResult Handle_MachoResolveObject(PyCallArgs &call)
Definition: PyService.cpp:63
Python integer.
Definition: PyRep.h:231
virtual PyResult Handle_MachoBindObject(PyCallArgs &call)
Definition: PyService.cpp:70
PyServiceMgr *const m_manager
Definition: PyService.h:91
#define PyStatic
Definition: PyRep.h:1209
int64 Win32TimeNow()
Definition: utils_time.cpp:70
uint16 crc_hqx(const uint8 *data, size_t len, uint16 crc)
Definition: misc.cpp:67
virtual PyResult Call(const std::string &method, PyCallArgs &args)
Definition: PyService.cpp:43
#define PyDecRef(op)
Definition: PyRep.h:57
Client *const client
Definition: PyCallable.h:49
Definition: Client.h:66
static const char *const s_checkTimeStrings[_checkCount]
Definition: PyService.h:81
virtual PyBoundObject * CreateBoundObject(Client *pClient, const PyRep *bind_args)
Definition: PyService.cpp:169
PySubStruct * BindObject(Client *pClient, PyBoundObject *pObj, PyDict *dict=nullptr, PyDict *oid=nullptr)
size_type size() const
Definition: Buffer.h:610
void Dump(LogType type) const
Definition: PyCallable.cpp:81
void traceStack(void)
Definition: misc.cpp:169
virtual PyResult Call(const std::string &method, PyCallArgs &args)
Definition: PyCallable.cpp:39
virtual ~PyService()
Definition: PyService.cpp:38
void EncodeData() const
Definition: PyRep.cpp:1109
PyTuple * tuple
Definition: PyCallable.h:50